diff --git a/lib/controller/annaucement_controller.dart b/lib/controller/annaucement_controller.dart index 6b928f3..51370a3 100644 --- a/lib/controller/annaucement_controller.dart +++ b/lib/controller/annaucement_controller.dart @@ -16,7 +16,7 @@ class AnnouncementController extends GetxController { SharedPreferences prefs = await SharedPreferences.getInstance(); String? token = prefs.getString('token'); final List? fetchedAnnouncements = - await _announcementService.fetchAnnouncements(token!); + await _announcementService.fetchAnnouncements(); announcements.assignAll(fetchedAnnouncements as Iterable); } catch (e) { errorMessage.value = e.toString(); diff --git a/lib/controller/annaucement_service.dart b/lib/controller/annaucement_service.dart index a5562b2..d86e37b 100644 --- a/lib/controller/annaucement_service.dart +++ b/lib/controller/annaucement_service.dart @@ -8,16 +8,16 @@ class AnnouncementService { final Dio _dio = Dio(); - Future?> fetchAnnouncements(String token) async { + Future?> fetchAnnouncements() async { try { String url = ApiUrls.AnnaouncementUrl; // Base URL to fetch product manuals final response = await commonApiService>( method: "GET", url: url, - additionalHeaders: { // Pass the token here - 'Authorization': 'Bearer $token', - }, + // additionalHeaders: { // Pass the token here + // 'Authorization': 'Bearer $token', + // }, fromJson: (json) { if (json['announcements'] != null) { // If the productManuals key is present, map the response to a list of ProductManualModel objects diff --git a/lib/controller/kyc_service.dart b/lib/controller/kyc_service.dart index ce1f313..924850e 100644 --- a/lib/controller/kyc_service.dart +++ b/lib/controller/kyc_service.dart @@ -2,13 +2,21 @@ import 'package:cheminova/models/kyc_model.dart'; import 'package:cheminova/utils/api_urls.dart'; import 'package:dio/dio.dart'; +import '../utils/app_interceptor.dart'; + class KycService { + + // Function to fetch KYC data from the API Future> getKycData(String token) async { try { // Make a GET request to the KYC API endpoint with authorization token - var response = await Dio().get( + + final dio = Dio(); + dio.interceptors.add(AuthInterceptor()); + + var response = await dio.get( ApiUrls.getKycUrl, // 'https://api.cnapp.co.in/api/kyc/getAll', options: Options( @@ -31,6 +39,8 @@ class KycService { } Future approveKycStatus(String token, String kycId,String status) async { + final dio = Dio(); + dio.interceptors.add(AuthInterceptor()); try { // Prepare the payload for approval directly var payload = { @@ -41,7 +51,7 @@ class KycService { // print("Payload: $payload"); // Make a PATCH request to update the KYC status - var response = await Dio().patch( + var response = await dio.patch( 'https://api.cnapp.co.in/api/kyc/update/$kycId', // URL with the KYC ID data: payload, // Payload with the status options: Options( @@ -74,6 +84,8 @@ class KycService { } Future rejectKycStatus( String token, String kycId, String? rejectionReason, String? user, String status) async { + final dio = Dio(); + dio.interceptors.add(AuthInterceptor()); try { // Prepare the payload for the PATCH request var data = { @@ -92,7 +104,7 @@ class KycService { print("Payload: $data"); // Make a PATCH request to update the KYC status - var response = await Dio().patch( + var response = await dio.patch( 'https://api.cnapp.co.in/api/kyc/update/$kycId', data: data, options: Options( diff --git a/lib/controller/notification_api_service.dart b/lib/controller/notification_api_service.dart index 343b7d1..6be7391 100644 --- a/lib/controller/notification_api_service.dart +++ b/lib/controller/notification_api_service.dart @@ -2,15 +2,17 @@ import 'package:dio/dio.dart'; import 'package:cheminova/models/notification_model.dart'; import '../utils/api_urls.dart'; +import '../utils/app_interceptor.dart'; class NotificationService { - final Dio _dio = Dio(); + // final Dio _dio = Dio(); Future?> fetchNotifications(String token, String date) async { final String url = ApiUrls.getNotificationUrl; - + final dio = Dio(); + dio.interceptors.add(AuthInterceptor()); try { - final response = await _dio.get( + final response = await dio.get( url, options: Options( headers: { diff --git a/lib/controller/place_order_service.dart b/lib/controller/place_order_service.dart index 8019a15..62910dc 100644 --- a/lib/controller/place_order_service.dart +++ b/lib/controller/place_order_service.dart @@ -6,12 +6,18 @@ import 'package:cheminova/utils/api_urls.dart'; import 'package:dio/dio.dart'; import '../models/oder_place_model.dart'; +import '../utils/app_interceptor.dart'; import '../utils/log_service.dart'; class OrderPlacedService { - final Dio dio = Dio(); - + //final Dio dio = Dio(); + // OrderPlacedService() : _dio = Dio(BaseOptions(baseUrl: 'https://api.cnapp.co.in')) { + // _dio.interceptors.add(AuthInterceptor()); + // _dio.interceptors.add(PrettyDioLogger()); + // } Future placeOrder(PlacedOrderModel orderDetails, String token) async { + final dio = Dio(); + dio.interceptors.add(AuthInterceptor()); //try { // logger.w("orderjson ${jsonEncode(orderDetails.toJson())}"); final response = await dio.post( diff --git a/lib/controller/rd_processing_service.dart b/lib/controller/rd_processing_service.dart index 0874553..c1f1b7c 100644 --- a/lib/controller/rd_processing_service.dart +++ b/lib/controller/rd_processing_service.dart @@ -6,16 +6,23 @@ import 'package:cheminova/utils/show_snackbar.dart'; import 'package:flutter/material.dart'; import 'package:dio/dio.dart'; import '../models/rd_order_item_model.dart'; +import '../utils/app_interceptor.dart'; class RDOrderPlacedService { final Dio _dio = Dio(); // Create Dio instance + // RDOrderPlacedService() : _dio = Dio(BaseOptions(baseUrl: 'https://api.cnapp.co.in')) { + // _dio.interceptors.add(AuthInterceptor()); + // _dio.interceptors.add(PrettyDioLogger()); + // } Future placRDeOrder(PlacedOrdersProcessing orderDetails, String token) async { + final dio = Dio(); + dio.interceptors.add(AuthInterceptor()); //try { // logger.w("orderjson ${jsonEncode(orderDetails.toJson())}"); - final response = await _dio.post( + final response = await dio.post( 'https://api.cnapp.co.in/api/pd-process-order', // Ensure this is your correct endpoint data: jsonEncode(orderDetails.toJson()), diff --git a/lib/controller/update_stock_service.dart b/lib/controller/update_stock_service.dart index c9896c5..77dff9b 100644 --- a/lib/controller/update_stock_service.dart +++ b/lib/controller/update_stock_service.dart @@ -4,6 +4,7 @@ import 'package:cheminova/models/product_stock_model.dart'; import 'package:dio/dio.dart'; import '../utils/api_urls.dart'; +import '../utils/app_interceptor.dart'; import '../utils/common_api_service.dart'; import '../utils/show_snackbar.dart'; @@ -14,9 +15,10 @@ class UpdateStockService{ try { // Correct API URL with orderId passed in the URL final String url = ApiUrls.ProductUpdateStockUrl; - + final dio = Dio(); + dio.interceptors.add(AuthInterceptor()); // Make the PUT request - final response = await Dio().put( + final response = await dio.put( url, // Use the correct URL here data: { "products": stock, // Send the cancellation reason as JSON diff --git a/lib/models/brand_model.dart b/lib/models/brand_model.dart index e7e45f1..53bf332 100644 --- a/lib/models/brand_model.dart +++ b/lib/models/brand_model.dart @@ -13,8 +13,13 @@ class Brand { return Brand( id: json['_id'], brandName: json['brandName'], - images: json["image"] != null - ? (json["image"] as List).map((e) => BrandImage.fromJson(e)).toList() + // images: json["image"] != null + // ? (json["image"] as List).map((e) => BrandImage.fromJson(e)).toList() + // : [], + images: json["image"] != null // Ensure you use the correct key + ? (json["image"] as List) + .map((e) => BrandImage.fromJson(e)) + .toList() : [], ); @@ -49,7 +54,7 @@ class BrandImage { factory BrandImage.fromJson(Map json) { return BrandImage( publicId: json["public_id"] ?? "", - url: json["url"] ?? "", + url: json["url"]?.toString() ?? "", imageId: json["_id"] ?? "", ); } diff --git a/lib/models/get_rd_cancelled_model.dart b/lib/models/get_rd_cancelled_model.dart index eb89d49..b6c4579 100644 --- a/lib/models/get_rd_cancelled_model.dart +++ b/lib/models/get_rd_cancelled_model.dart @@ -1,9 +1,15 @@ + + +import 'package:cheminova/models/rd_order_item_model.dart'; + +import 'brand_model.dart'; + class GetRdCancelledModel { final String id; final String paymentMode; final String shipTo; final String billTo; - final List orderItems; + final List orderItems; final double subtotal; final double gstTotal; final double grandTotal; @@ -51,8 +57,8 @@ class GetRdCancelledModel { paymentMode: json['paymentMode'], shipTo: json['shipTo'], billTo: json['billTo'], - orderItems: (json['orderItem'] as List) - .map((item) => OrderItem.fromJson(item)) + orderItems: (json['orderItem'] as List) + .map((item) => RDOrderItem.fromJson(item)) .toList(), subtotal: json['subtotal'].toDouble(), gstTotal: json['gstTotal'].toDouble(), @@ -122,7 +128,7 @@ class OrderItem { final double gst; final int hsnCode; final String description; - final List images; + final List images; final int quantity; final int remainingQuantity; final String id; @@ -154,7 +160,9 @@ class OrderItem { gst: json['GST'].toDouble(), hsnCode: json['HSN_Code'], description: json['description'] ?? '', - images: List.from(json['image']), + images : (json["image"] as List) + .map((item) => BrandImage.fromJson(item)) + .toList(), quantity: json['quantity'], remainingQuantity: json['remainingQuantity'], id: json['_id'], diff --git a/lib/models/oder_place_model.dart b/lib/models/oder_place_model.dart index d5ea5c1..f712154 100644 --- a/lib/models/oder_place_model.dart +++ b/lib/models/oder_place_model.dart @@ -64,7 +64,7 @@ class OrderItem { String description; String productStatus; final String addedBy; - List image; + List image; DateTime createdAt; DateTime updatedAt; int count; @@ -124,7 +124,9 @@ class OrderItem { description: json['description'], productStatus: json['product_Status'], addedBy: json['addedBy']['name'], // Assuming addedBy has a 'name' key - image: List.from(json['image']), + image: json['image'] is List + ? (json['image'] as List).map((e) => BrandImage.fromJson(e)).toList() + : [BrandImage.fromJson(json['image'])], createdAt: DateTime.parse(json['createdAt']), updatedAt: DateTime.parse(json['updatedAt']), count: json['count'], diff --git a/lib/models/place_order_list_model.dart b/lib/models/place_order_list_model.dart index 558900d..b8d26bf 100644 --- a/lib/models/place_order_list_model.dart +++ b/lib/models/place_order_list_model.dart @@ -1,3 +1,5 @@ +import 'brand_model.dart'; + class PlacedOrderList { final String id; final String paymentMode; @@ -95,6 +97,7 @@ class OrderItem1 { final String brandName; final double price; final int quantity; + List? image; OrderItem1({ required this.sku, @@ -102,6 +105,7 @@ class OrderItem1 { required this.categoryName, required this.brandName, required this.price, + this.image, required this.quantity, }); @@ -112,6 +116,9 @@ class OrderItem1 { categoryName: json['categoryName'], brandName: json['brandName'], price: json['price'].toDouble(), + image : (json["image"] as List) + .map((item) => BrandImage.fromJson(item)) + .toList(), quantity: json['quantity'], ); } @@ -124,13 +131,14 @@ class OrderItem1 { 'brandName': brandName, 'price': price, 'quantity': quantity, + 'image':image }; } @override String toString() { return 'OrderItem(sku: $sku, name: $name, categoryName: $categoryName, ' - 'brandName: $brandName, price: $price, quantity: $quantity)'; + 'brandName: $brandName, price: $price, quantity: $quantity,image:$image)'; } } diff --git a/lib/models/rd_order_item_model.dart b/lib/models/rd_order_item_model.dart index 015b3ab..fcef995 100644 --- a/lib/models/rd_order_item_model.dart +++ b/lib/models/rd_order_item_model.dart @@ -1,5 +1,7 @@ - class RDOrderItem { + import 'brand_model.dart'; + +class RDOrderItem { final String productId; final String sku; final String name; @@ -9,7 +11,7 @@ final int gst; // Ensure GST is int final int hsnCode; // Ensure HSN_Code is int final String description; - final List image; + final List image; int? quantity; int? remainingQuantity; int? processquantity; @@ -43,10 +45,13 @@ hsnCode: json['HSN_Code'] ?? 0, // Handle HSN_Code as int description: json['description'] ?? '', - image: List.from(json['image'] ?? []), + //image: List.from(json['image'] ?? []), + image : (json["image"] as List) + .map((item) => BrandImage.fromJson(item)) + .toList(), quantity: json['quantity'] ?? 0, // Handle quantity as int - processquantity: json['processquantity']??1, + processquantity: json['processQuantity']??1, remainingQuantity: json['remainingQuantity'] ?? 0, // Handle remainingQuantity as int ); diff --git a/lib/screens/authentication/change_password_screen.dart b/lib/screens/authentication/change_password_screen.dart index bcc9efd..7a3d59b 100644 --- a/lib/screens/authentication/change_password_screen.dart +++ b/lib/screens/authentication/change_password_screen.dart @@ -20,13 +20,13 @@ class _ChangePasswordScreenState extends State { final authController = Get.put(AuthController()); - void dispose() { - // Dispose of the text controllers when the screen is closed to free up resources - authController.currentpassController.dispose(); - authController.newpassController.dispose(); - authController.confirmpassController.dispose(); - super.dispose(); - } + // void dispose() { + // // Dispose of the text controllers when the screen is closed to free up resources + // authController.currentpassController.dispose(); + // authController.newpassController.dispose(); + // authController.confirmpassController.dispose(); + // super.dispose(); + // } // Function to validate user input and initiate password change void validateAndChangePassword() async { diff --git a/lib/screens/authentication/profile_screen.dart b/lib/screens/authentication/profile_screen.dart index a91df0c..b01de63 100644 --- a/lib/screens/authentication/profile_screen.dart +++ b/lib/screens/authentication/profile_screen.dart @@ -24,6 +24,12 @@ class _ProfileScreenState extends State { // Initialize the HomeController using GetX final homecontroller = Get.put(HomeController()); @override + void initState() { + // TODO: implement initState + super.initState(); + homecontroller.getUser(); + } + @override Widget build(BuildContext context) { // Accessing the user details from the HomeController final user = homecontroller.user; @@ -52,7 +58,10 @@ class _ProfileScreenState extends State { ], ), // Main content of the profile screen - body: SingleChildScrollView( + body: user == null + ? const Center(child: CircularProgressIndicator()) + : + SingleChildScrollView( child: Column( children: [ Container( @@ -70,7 +79,7 @@ class _ProfileScreenState extends State { children: [ const SizedBox(height: 20), // Displaying individual profile items - _buildProfileItem('Name', user!.name), + _buildProfileItem('Name', user.name), _buildProfileItem('ID', user.uniqueId), _buildProfileItem('Email ID', user.email), _buildProfileItem('Mobile Number', user.phone), diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index 7966164..2f4bb81 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -184,7 +184,7 @@ class _HomeScreenState extends State { mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ HomeCard( - title: 'RD Orders', + title: 'Retailer Orders', onTap: () => Get.to( () => RdOrderScreen(), ), diff --git a/lib/screens/kyc/kyc_retailer_info_screen.dart b/lib/screens/kyc/kyc_retailer_info_screen.dart index f6aadf1..b21086d 100644 --- a/lib/screens/kyc/kyc_retailer_info_screen.dart +++ b/lib/screens/kyc/kyc_retailer_info_screen.dart @@ -179,13 +179,18 @@ class _KycRetailerInfoScreenState extends State { ), SizedBox( height: Get.height * 0.6, - child: Obx(() { + child: + Obx(() { // Filter the list based on the selected status List filteredOrders = selectedStatus == "All" ? _kycController.kycList : _kycController.kycList.where((kyc) => kyc.status == selectedStatus).toList(); - + filteredOrders.sort((a, b) { + DateTime dateA = DateTime.parse(filteredOrders[0].createdAt.toString()); // Assuming createdAt is a string + DateTime dateB = DateTime.parse(filteredOrders[0].createdAt.toString()); + return dateB.compareTo(dateA); // Sort in descending order + }); return ListView.builder( padding: EdgeInsets.zero, shrinkWrap: true, diff --git a/lib/screens/notification/notification_screen.dart b/lib/screens/notification/notification_screen.dart index 990b98d..c4af467 100644 --- a/lib/screens/notification/notification_screen.dart +++ b/lib/screens/notification/notification_screen.dart @@ -67,7 +67,8 @@ class NotificationScreen extends StatelessWidget { ), ), drawer: MyDrawer(), - body: Obx(() { + body: + Obx(() { // Show a loading indicator while data is being fetched if (notificationController.isLoading.value) { return const Center(child: CircularProgressIndicator()); diff --git a/lib/screens/order/checkout_screen.dart b/lib/screens/order/checkout_screen.dart index 3c4ebed..e82156b 100644 --- a/lib/screens/order/checkout_screen.dart +++ b/lib/screens/order/checkout_screen.dart @@ -96,16 +96,34 @@ class _CheckoutScreenState extends State { _saveSelectedAddress(); } + // void _loadSelectedAddress() async { + // SharedPreferences prefs = await SharedPreferences.getInstance(); + // setState(() { + // _selectedShippingAddress = + // prefs.getString('selectedShippingAddress') ?? _addressList.first; + // _selectedBillingAddress = + // prefs.getString('selectedBillingAddress') ?? _addressList.first; + // }); + // } + void _loadSelectedAddress() async { SharedPreferences prefs = await SharedPreferences.getInstance(); + + _addressController + .fetchAddresses(); // Ensure address list is updated + setState(() { _selectedShippingAddress = - prefs.getString('selectedShippingAddress') ?? _addressList.first; + (prefs.getString('selectedShippingAddress') ?? + (_addressController.addressList.isNotEmpty ? _addressController.addressList.first : null)) as String?; _selectedBillingAddress = - prefs.getString('selectedBillingAddress') ?? _addressList.first; + (prefs.getString('selectedBillingAddress') ?? + (_addressController.addressList.isNotEmpty ? _addressController.addressList.first : null)) as String?; }); } + + void _onPaymentModeChanged(String? value) { setState(() { _groupValue = value!; @@ -138,7 +156,14 @@ class _CheckoutScreenState extends State { hsnCode: product.hsnCode, description: product.description, productStatus: product.productStatus, - image: [], + + // image:[], + image: product.brand.images.isNotEmpty + ? product.brand.images.map((image) => BrandImage( + publicId: image.publicId, // or any other identifier + imageId: image.imageId, url: image.url, + )).toList() + :[], createdAt: product.createdAt, updatedAt: product.createdAt, count: product.quantity, diff --git a/lib/screens/order_management/order_management_detail_screen.dart b/lib/screens/order_management/order_management_detail_screen.dart index 574bde5..5827064 100644 --- a/lib/screens/order_management/order_management_detail_screen.dart +++ b/lib/screens/order_management/order_management_detail_screen.dart @@ -1,4 +1,5 @@ import 'package:auto_size_text/auto_size_text.dart'; +import 'package:cached_network_image/cached_network_image.dart'; import 'package:cheminova/controller/get_order_placed_controller.dart'; import 'package:cheminova/controller/shiptobilltoController.dart'; import 'package:cheminova/models/oder_place_model.dart'; @@ -72,7 +73,7 @@ Future adduni()async { .map((item) => (item.quantity)) .join(', '); } - + //String? imageurl; @override Widget build(BuildContext context) { @@ -223,6 +224,7 @@ Future adduni()async { itemCount: widget.placedOrderList?.orderItem.length ?? 0, itemBuilder: (context, index) { final orderItem = widget.placedOrderList!.orderItem[index]; + final imageUrl = orderItem.image?.isNotEmpty == true ? orderItem.image![0].url : null; return orderItem != null ? Card( margin: const EdgeInsets.symmetric(vertical: 5.0), @@ -233,9 +235,26 @@ Future adduni()async { padding: const EdgeInsets.all(8.0), child: Row( children: [ - Image.asset( - "assets/images/new_product.jpeg", - // "assets/images/product.png", // Add the image URL here + // Image.asset( + // "assets/images/new_product.jpeg", + // // "assets/images/product.png", // Add the image URL here + // height: 50, + // width: 50, + // fit: BoxFit.cover, + // ), + + imageUrl != null && imageUrl.isNotEmpty && imageUrl.startsWith('http') // Check if it's a network URL/ Check if it's a network URL + ? CachedNetworkImage( + imageUrl: imageUrl, + height: 50, + width: 50, + fit: BoxFit.cover, + placeholder: (context, url) => const CircularProgressIndicator(), // Optional placeholder + errorWidget: (context, url, error) => const Icon(Icons.error), // Optional error widget + ) + : Image.asset( + // imageUrl!, + 'assets/images/no_image_available.jpg', // Placeholder image when URL is empty height: 50, width: 50, fit: BoxFit.cover, diff --git a/lib/screens/product/product_detail_screen.dart b/lib/screens/product/product_detail_screen.dart index 60fe2f1..27db4fb 100644 --- a/lib/screens/product/product_detail_screen.dart +++ b/lib/screens/product/product_detail_screen.dart @@ -1,3 +1,4 @@ +import 'package:cached_network_image/cached_network_image.dart'; import 'package:cheminova/models/product_model.dart'; import 'package:cheminova/models/product_model1.dart'; import 'package:cheminova/screens/order/checkout_screen.dart'; @@ -24,6 +25,7 @@ class ProductDetailScreen extends StatefulWidget { class _ProductDetailScreenState extends State { final CartController _cartController = Get.put(CartController());// Initialize CartController + String? imageurl; // Function to capitalize the first letter of a string String capitalizeFirstLetter(String text) { if (text.isEmpty) return text; @@ -31,6 +33,9 @@ class _ProductDetailScreenState extends State { } @override Widget build(BuildContext context) { + imageurl = widget.productModel!.brand.images.isNotEmpty + ? widget.productModel!.brand.images[0].url + : 'assets/images/no_image_available.jpg'; // Use a fallback image URL or handle it accordingly return Scaffold( extendBodyBehindAppBar: true, appBar: AppBar( @@ -105,16 +110,21 @@ class _ProductDetailScreenState extends State { ), borderRadius: BorderRadius.circular(15), ), - child: ClipRRect( + child: + ClipRRect( borderRadius: BorderRadius.circular(10), - child: Image.asset( - "assets/images/new_product.jpeg", - // "assets/images/product.png", - fit: BoxFit.cover,), - // Image.asset( - // widget.product.image, - // fit: BoxFit.cover, - // ), + child: + imageurl!.startsWith('http') // Check if it's a network URL + ? CachedNetworkImage( + imageUrl: imageurl!, + fit: BoxFit.cover, + placeholder: (context, url) => const CircularProgressIndicator(), // Optional placeholder + errorWidget: (context, url, error) => const Icon(Icons.error), // Optional error widget + ) + : Image.asset( + imageurl!, + fit: BoxFit.cover, + ), ), ), ), diff --git a/lib/screens/rd orders/partial_processing_dialog_screen.dart b/lib/screens/rd orders/partial_processing_dialog_screen.dart index d4cc809..38a120b 100644 --- a/lib/screens/rd orders/partial_processing_dialog_screen.dart +++ b/lib/screens/rd orders/partial_processing_dialog_screen.dart @@ -368,7 +368,7 @@ class _PartialProcessingDialogScreenState extends State createState() => @@ -1055,7 +1058,7 @@ class _RdOrderCancelledScreenDetailScreenState ), ], title: const Text( - "RD Cancelled Order Details", + "Retailer Cancelled Order Details", ), ), body: Stack( @@ -1276,6 +1279,7 @@ class _RdOrderCancelledScreenDetailScreenState itemCount: order.orderItem!.length ?? 0, itemBuilder: (context, index) { final orderItem =order.orderItem![index]; + final imageUrl = orderItem.image?.isNotEmpty == true ? orderItem.image![0].url : null; final subTotal = orderItem.price * orderItem.quantity!.toInt(); final GstTotalAmount = (orderItem.price * orderItem.quantity!.toInt()) *(orderItem.gst/100 ); final grandTotal = subTotal + GstTotalAmount; @@ -1289,13 +1293,32 @@ class _RdOrderCancelledScreenDetailScreenState padding: const EdgeInsets.all(8.0), child: Row( children: [ - Image.asset( - "assets/images/new_product.jpeg", - // "assets/images/product.png", + // Image.asset( + // "assets/images/new_product.jpeg", + // // "assets/images/product.png", + // height: 50, + // width: 50, + // fit: BoxFit.cover, + // ), + + + imageUrl != null && imageUrl.isNotEmpty && imageUrl.startsWith('http') // Check if it's a network URL/ Check if it's a network URL + ? CachedNetworkImage( + imageUrl: imageUrl, + height: 50, + width: 50, + fit: BoxFit.cover, + placeholder: (context, url) => const CircularProgressIndicator(), // Optional placeholder + errorWidget: (context, url, error) => const Icon(Icons.error), // Optional error widget + ) + : Image.asset( + //imageUrl!, + 'assets/images/no_image_available.jpg', // Placeholder image when URL is empty height: 50, width: 50, fit: BoxFit.cover, ), + const SizedBox(width: 10), Expanded( child: Column( @@ -1373,6 +1396,7 @@ class _RdOrderCancelledScreenDetailScreenState .toList(); final orderItem = filteredItems[index]; + final imageUrl = orderItem.image?.isNotEmpty == true ? orderItem.image![0].url : null; final subTotalProcesssItem = orderItem.price! * orderItem.remainingQuantity!.toInt(); final GstTotalAmounProcessItem = (orderItem.price! * orderItem.remainingQuantity!.toInt()) *(orderItem.gst!/100 ); final grandTotalProcessItem = subTotalProcesssItem + GstTotalAmounProcessItem; @@ -1386,13 +1410,32 @@ class _RdOrderCancelledScreenDetailScreenState padding: const EdgeInsets.all(8.0), child: Row( children: [ - Image.asset( - "assets/images/new_product.jpeg", - // "assets/images/product.png", + // Image.asset( + // "assets/images/new_product.jpeg", + // // "assets/images/product.png", + // height: 50, + // width: 50, + // fit: BoxFit.cover, + // ), + + + imageUrl != null && imageUrl.isNotEmpty && imageUrl.startsWith('http') // Check if it's a network URL/ Check if it's a network URL + ? CachedNetworkImage( + imageUrl: imageUrl, + height: 50, + width: 50, + fit: BoxFit.cover, + placeholder: (context, url) => const CircularProgressIndicator(), // Optional placeholder + errorWidget: (context, url, error) => const Icon(Icons.error), // Optional error widget + ) + : Image.asset( + //imageUrl!, + 'assets/images/no_image_available.jpg', // Placeholder image when URL is empty height: 50, width: 50, fit: BoxFit.cover, ), + const SizedBox(width: 10), Expanded( child: Column( diff --git a/lib/screens/rd orders/rd_cancelled_screen.dart b/lib/screens/rd orders/rd_cancelled_screen.dart index 257cb3e..d64673f 100644 --- a/lib/screens/rd orders/rd_cancelled_screen.dart +++ b/lib/screens/rd orders/rd_cancelled_screen.dart @@ -101,8 +101,8 @@ class _RdCancelledScreenState extends State { if (index >= 0 && index < _getRDCancleController.productRDList.length) { // Get the order ID from the list based on the index final orderId = _getRDCancleController.productRDList[index].id; - final invoiceId = _getRDCancleController.productRDList[index].invoices[0]; - + // final invoiceId = _getRDCancleController.productRDList[index].invoices; + print("orderId canceeled,$orderId"); // Retrieve the token from SharedPreferences SharedPreferences prefs = await SharedPreferences.getInstance(); String? token = prefs.getString('token'); @@ -117,7 +117,7 @@ class _RdCancelledScreenState extends State { // Navigate to the details screen with the fetched order Get.to(() => RdOrderCancelledScreenDetailScreen( placedOrderList: singleOrder, // Pass the single order instance - orderId: orderId, + //orderId: orderId, )); } else { @@ -144,6 +144,68 @@ class _RdCancelledScreenState extends State { } + // void onOrderTap(int index) async { + // try { + // // Fetch orders and wait for it to complete + // await _getRDCancleController.getRDCancleProduct(); + // + // // Debugging: Check if data is actually fetched + // print('Fetched orders count: ${_getRDCancleController.productRDList.length}'); + // + // // Ensure the list is not empty after fetching + // if (_getRDCancleController.productRDList.isEmpty) { + // Get.snackbar("Error", "No orders available to display."); + // return; + // } + // + // // Ensure index is within range + // if (index < 0 || index >= _getRDCancleController.productRDList.length) { + // Get.snackbar("Error", "Invalid order selection."); + // return; + // } + // + // // Retrieve order details + // final order = _getRDCancleController.productRDList[index].id; + // // final invoice = _getRDCancleController.productRDList[index].invoices[index]; + // // Ensure invoices are available + // if (order.isEmpty) { + // Get.snackbar("Error", "No invoice found for this order."); + // return; + // } + // + // final orderId = order; + // //final invoiceId = invoice; + // + // print("Cancelled Order ID: $orderId"); + // + // // Retrieve token + // SharedPreferences prefs = await SharedPreferences.getInstance(); + // String? token = prefs.getString('token'); + // + // if (token == null) { + // Get.snackbar("Error", "User not authenticated."); + // return; + // } + // + // // Fetch single order details + // final SingleGetOrderModel? singleOrder = + // await GetSingleProductService().getSingleOrder(token, orderId); + // + // if (singleOrder == null) { + // Get.snackbar("Error", "Unable to fetch order details."); + // return; + // } + // + // // Navigate to details screen + // await Get.to(() => RdOrderCancelledScreenDetailScreen( + // placedOrderList: singleOrder, // Pass fetched order + // orderId: orderId, + // )); + // } catch (e) { + // print('Error in onOrderTap: $e'); + // Get.snackbar("Error", "An unexpected error occurred."); + // } + // } @override @@ -174,7 +236,7 @@ class _RdCancelledScreenState extends State { ), ), ], - title: const Text("RD Cancelled Order"), + title: const Text("Retailer Cancelled Order"), ), drawer: MyDrawer(), body: Stack( diff --git a/lib/screens/rd orders/rd_delivered_details_screen.dart b/lib/screens/rd orders/rd_delivered_details_screen.dart index cb25a1a..a5a2904 100644 --- a/lib/screens/rd orders/rd_delivered_details_screen.dart +++ b/lib/screens/rd orders/rd_delivered_details_screen.dart @@ -150,7 +150,7 @@ class _RdDeliveredDetailsScreenState ), ], title: const Text( - "RD Delivered Order Details", + "Retailer Delivered Order Details", ), ), body: Stack( diff --git a/lib/screens/rd orders/rd_delivered_screen.dart b/lib/screens/rd orders/rd_delivered_screen.dart index a251850..a1cab05 100644 --- a/lib/screens/rd orders/rd_delivered_screen.dart +++ b/lib/screens/rd orders/rd_delivered_screen.dart @@ -163,7 +163,7 @@ class _RdDeliveredScreenState extends State { ), ), ], - title: const Text("RD Delivered Order"), + title: const Text("Retailer Delivered Order"), ), drawer: MyDrawer(), body: Stack( diff --git a/lib/screens/rd orders/rd_dispatched_details_screen.dart b/lib/screens/rd orders/rd_dispatched_details_screen.dart index e3c17ce..88ce29e 100644 --- a/lib/screens/rd orders/rd_dispatched_details_screen.dart +++ b/lib/screens/rd orders/rd_dispatched_details_screen.dart @@ -198,7 +198,10 @@ class _RdDispatchedDetailsDetailScreenState SnackBar(content: Text('Please select a delivery date.')), ); } - Navigator.of(context).pop(); // Close the dialog after submission + Navigator.push(context, MaterialPageRoute(builder: (context){ + return RdDeliveredScreen(); + })); + // Navigator.of(context).pop(); // Close the dialog after submission }, child: Text('Confirm'), ), @@ -312,7 +315,7 @@ class _RdDispatchedDetailsDetailScreenState ), ], title: const Text( - "RD Dispatched Order Details", + "Retailer Dispatched Order Details", ), ), body: Stack( diff --git a/lib/screens/rd orders/rd_dispatched_scree.dart b/lib/screens/rd orders/rd_dispatched_scree.dart index 1f278aa..7fb3cac 100644 --- a/lib/screens/rd orders/rd_dispatched_scree.dart +++ b/lib/screens/rd orders/rd_dispatched_scree.dart @@ -172,7 +172,7 @@ class _RdDispatchedScreenState extends State { ), ), ], - title: const Text("RD Dispatched Order"), + title: const Text("Retailer Dispatched Order"), ), drawer: MyDrawer(), body: Stack( diff --git a/lib/screens/rd orders/rd_order_details_screen.dart b/lib/screens/rd orders/rd_order_details_screen.dart index 0326dbe..e3bb91b 100644 --- a/lib/screens/rd orders/rd_order_details_screen.dart +++ b/lib/screens/rd orders/rd_order_details_screen.dart @@ -1,733 +1,5 @@ -import 'package:auto_size_text/auto_size_text.dart'; -import 'package:cheminova/controller/get_order_placed_controller.dart'; -import 'package:cheminova/controller/rd_get_order_controller.dart'; -import 'package:cheminova/models/oder_place_model.dart'; -import 'package:cheminova/models/order_item_model.dart'; -import 'package:cheminova/models/place_order_list_model.dart'; -import 'package:cheminova/models/rd_get_order_model.dart'; -import 'package:cheminova/models/rd_order_item_model.dart'; -import 'package:cheminova/models/rd_placed_order_model.dart'; -import 'package:cheminova/screens/rd%20orders/partial_processing_dialog_screen.dart'; - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; -import 'package:get/get.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:intl/intl.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - -import '../../controller/cart_controller.dart'; -import '../../controller/rd_processing_order_controller.dart'; -import '../../models/product_model1.dart'; -import '../../utils/show_snackbar.dart'; - -class RdOrderDetailScreen extends StatefulWidget { - //final Product? productModel; - // PlacedOrderList and PlacedOrderModel are optional parameters passed to this screen - PlacedOrdersResponse? placedOrderList; -// PlacedOrderModel? placedOrderModel; - // Constructor for initializing the screen with placed order details - RdOrderDetailScreen({super.key,this.placedOrderList}); - - @override - State createState() => - _RdOrderDetailScreenState(); -} - - -class _RdOrderDetailScreenState - extends State { - // Controllers for managing cart and placed orders - - final GetProductRDController _getPlacedOrderController = Get.put(GetProductRDController()); - final RDOrderPlacedController controller = Get.put(RDOrderPlacedController()); - String? orderId; - final List statusOptions = [ - "new", - "pending", - "processing", - "dispatched", - "cancelled", - "delivered", - ]; - - - List _statusList = ["new", "processing", "partial processing", "cancelled"]; // Default status list - - // Define different status lists for different categories - final Map> statusLists = { - "new": ["new", "processing", "partial processing", "cancelled"], - "pending": ["pending", "processing", "dispatched", "cancelled"], - "dispatched": ["dispatched", "delivered", "returned", "cancelled"], - "delivered": ["delivered", "returned", "cancelled"], - }; - String selectedStatus = "new"; - String _groupValue = "cheque"; - // Function to format date from the API to a more readable format - - - // This function updates the dropdown list dynamically based on category selection - void updateStatusList(String category) { - setState(() { - _statusList = statusLists[category]!; // Update status list based on the selected category - selectedStatus = _statusList.first; // Set the default selection to the first item - }); - } - - String formatDate(String apiDate) { - // Parse the API date string into a DateTime object - DateTime parsedDate = DateTime.parse(apiDate).toLocal(); // Convert to local time - - // Format the date and time according to your specified format - String formattedDate = DateFormat('EEE MMM dd yyyy').format(parsedDate); - - return formattedDate; // Return the formatted date string - } - - // Function to capitalize the first letter of a string - String capitalizeFirstLetter(String text) { - if (text.isEmpty) return text; - return text[0].toUpperCase() + text.substring(1).toLowerCase(); - } - - - void _onPaymentModeChanged(String? value) { - setState(() { - _groupValue = value!; - }); - _saveSelectedPaymentMode(); - } - - - void _saveSelectedPaymentMode() async { - SharedPreferences prefs = await SharedPreferences.getInstance(); - await prefs.setString('selectedPaymentMode', _groupValue); - } - - void _loadSelectedPaymentMode() async { - SharedPreferences prefs = await SharedPreferences.getInstance(); - setState(() { - _groupValue = prefs.getString('selectedPaymentMode') ?? 'cheque'; - }); - } - // Function to collect unique order IDs and corresponding order details - Future adduni()async { - final Set uniqueOrderIds = {}; - final List uniqueOrders = []; - // Loop through placed orders and add unique orders to the list - for (var order in _getPlacedOrderController.productRDList) { - if (uniqueOrderIds.add(order.uniqueId)) { - uniqueOrders.add(order); - } - } - final order = uniqueOrders[0]; - - // Combine product names, categories, and quantities into strings - final productNames = order.orderItem - .map((item) => (item.name)) - .join(', '); - final categotyName = order.orderItem - .map((item) => (item.categoryName)) - .join(', '); - final quantity = order.orderItem - .map((item) => (item.quantity)) - .join(', '); - } - @override - void initState() { - // TODO: implement initState - super.initState(); - selectedStatus= widget.placedOrderList?.status ?? 'new'; - // controller.fetchOrderItems(widget.placedOrderList!.id); - } - void _showConfirmationDialog() { - String dialogTitle; - String dialogContent; - TextEditingController reasonController = TextEditingController(); - - // Set dialog title and content based on selected status - switch (selectedStatus) { - case "processing": - dialogTitle = "Update Order Status"; - dialogContent = "Are you sure you want to update the status to processing?"; - break; - case "partial processing": - dialogTitle = "Update to Partial Processing"; - dialogContent = "Are you sure you want to update the status to 'Partial Processing'?"; - break; - case "cancelled": - dialogTitle = "Cancellation Reason"; - dialogContent = "Please provide a reason for cancelling the order:"; - break; - default: - dialogTitle = "Update Order Status"; - dialogContent = "Are you sure you want to update the status to '$selectedStatus'?"; - break; - } - - showDialog( - context: context, - builder: (context) { - return AlertDialog( - title: Text(dialogTitle), - content: selectedStatus == "cancelled" - ? Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text(dialogContent), - SizedBox(height: 10), - TextField( - controller: reasonController, - decoration: InputDecoration( - labelText: 'Cancellation Reason', - border: OutlineInputBorder(), - ), - ), - ], - ) - : Text(dialogContent), - actions: [ - TextButton( - onPressed: () async { - if (selectedStatus == "cancelled") { - // Ensure the reason is provided for cancellation - if (reasonController.text.isEmpty) { - showSnackbar("Please provide a reason for cancelling the order."); - return; // Exit early if reason is empty - } - - // Proceed with cancellation - await controller.CancleRDProduct(widget.placedOrderList!.id, reasonController.text); - - // Notify user about successful cancellation - showSnackbar("Order cancelled successfully"); - - // Update the status in your UI or backend to reflect the cancelled state - setState(() { - // Update the status in the local model/UI - }); - - // Close the dialog after a short delay - Future.delayed(Duration(seconds: 1), () { - Navigator.of(context).pop(); // Close the dialog - }); - - return; // Exit here to prevent further processing - } - - if (selectedStatus == "partial processing") { - // Get.to(() => PartialProcessingDialogScreen(productModel: widget.placedOrderList)); - - return; - } - - - // Create a map to track products by their IDs and aggregate quantities - Map orderItemMap = {}; - - // Populate the map with items and their quantities - for (var item in _getPlacedOrderController.productRDList) { - var productId = item.orderItem[0].productId; - - if (orderItemMap.containsKey(productId)) { - // If the product already exists, aggregate the quantity - var existingItem = orderItemMap[productId]!; - existingItem.quantity = (existingItem.quantity ?? 0) + (item.orderItem[0].quantity ?? 0); - existingItem.remainingQuantity = (existingItem.remainingQuantity ?? 0) + (item.orderItem[0].remainingQuantity ?? 0); - existingItem.processquantity = (existingItem.processquantity ?? 0) + (item.orderItem[0].processquantity ?? 0); - } else { - // If it's a new product, add it to the map - orderItemMap[productId] = RDOrderItem( - productId: productId, - sku: item.orderItem[0].sku, - name: item.orderItem[0].name, - categoryName: item.orderItem[0].categoryName, - brandName: item.orderItem[0].brandName, - price: item.orderItem[0].price, - gst: item.orderItem[0].gst.toInt(), - hsnCode: item.orderItem[0].hsnCode, - description: item.orderItem[0].description, - image: [], // Handle images appropriately - quantity: item.orderItem[0].quantity ?? 0, - remainingQuantity: item.orderItem[0].remainingQuantity ?? 0, - processquantity: item.orderItem[0].processquantity ?? 0, - ); - } - } - - // Convert the map to a list - List orderItems = orderItemMap.values.toList(); - - // Ensure the placed order contains the correct orderId and items - controller.placedOrder1.value = PlacedOrdersProcessing( - orderId: widget.placedOrderList!.id, - invoiceItems: orderItems, - ); - - // Debugging: Print the JSON payload - print("Sending order payload: ${controller.placedOrder1.value.toJson()}"); - - // Place the order and catch any errors - await controller.placeRDOrder(); - - showSnackbar("Order processed and invoice created successfully"); - Navigator.of(context).pop(); - // Close the dialog after a short delay - - // Close the dialog - -// Refresh the UI// Refresh the UI - }, - child: Text("Confirm"), - ), - TextButton( - onPressed: () { - Navigator.of(context).pop(); // Close the dialog - }, - child: Text("Cancel"), - ), - ], - ); - }, - ); - } - - - - - - @override - Widget build(BuildContext context) { - return Scaffold( - extendBodyBehindAppBar: true, - appBar: AppBar( - backgroundColor: Colors.transparent, - elevation: 0, - leading: GestureDetector( - onTap: () {}, - child: Padding( - padding: const EdgeInsets.all(16.0), - child: SvgPicture.asset( - 'assets/svg/menu.svg', - ), - ), - ), - actions: [ - GestureDetector( - onTap: () => Get.back(), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: SvgPicture.asset( - 'assets/svg/back_arrow.svg', - ), - ), - ), - ], - title: const Text( - "Order Detail", - ), - ), - body: Stack( - fit: StackFit.expand, - children: [ - Image.asset( - 'assets/images/image_1.png', - fit: BoxFit.cover, - ), - SafeArea( - child: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - SizedBox( - height: Get.height * 0.02, - ), - Card( - margin: const EdgeInsets.symmetric(horizontal: 18), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(19), - side: const BorderSide(color: Color(0xFFFDFDFD)), - ), - color: const Color(0xFFB4D1E5).withOpacity(0.9), - child: Padding( - padding: const EdgeInsets.all(12.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - - Card( - child: Column( - children: [ - SizedBox( - width: Get.width, - child: Padding( - padding: - const EdgeInsets.fromLTRB(8, 8, 8, 0), - child: Text( - "Order Summary", - style: GoogleFonts.roboto( - fontSize: Get.width * 0.05, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - _buildRow("Order ID:", widget.placedOrderList!.uniqueId, Get.width * 0.04), - _buildRow("Order Date:", formatDate("${widget.placedOrderList!.createdAt}"), Get.width * 0.04), - _buildRow("Total Items:", "${widget.placedOrderList!.orderItem.length}", Get.width * 0.04), - _buildRow("Sub Total:", "₹ ${widget.placedOrderList!.subtotal}", Get.width * 0.04), - _buildRow("GST:", "₹ ${widget.placedOrderList!.gstTotal}", Get.width * 0.04), - _buildRow("Total Amount:", "₹ ${widget.placedOrderList!.grandTotal}", Get.width * 0.04), - - - ], - ), - ), - const SizedBox(height: 8), - Card( - child: SizedBox( - height: Get.height * 0.22, - child: Padding( - padding: EdgeInsets.all(Get.width * 0.02), - child: ListView.builder( - padding: EdgeInsets.zero, - itemCount: widget.placedOrderList?.orderItem.length ?? 0, - itemBuilder: (context, index) { - final orderItem = widget.placedOrderList!.orderItem[index]; - return orderItem != null - ? Card( - margin: const EdgeInsets.symmetric(vertical: 5.0), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - children: [ - Image.asset( - "assets/images/new_product.jpeg", - // "assets/images/product.png", // Add the image URL here - height: 50, - width: 50, - fit: BoxFit.cover, - ), - const SizedBox(width: 10), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Text( - capitalizeFirstLetter(orderItem.name), - style: GoogleFonts.roboto( - fontSize: Get.width * 0.04, - fontWeight: FontWeight.bold, - ), - ), - Text( - "Quantity: ${orderItem.quantity}", - style: GoogleFonts.roboto( - fontSize: Get.width * 0.03, - ), - ), - Text("Price: ${orderItem.price}"), - Text("Subtotal : ${widget.placedOrderList!.subtotal}"), - Text("Gst : ${orderItem.gst}%"), - Text("GST : ${widget.placedOrderList!.gstTotal}"), - Text("Total Amount : ${widget.placedOrderList!.grandTotal}"), - ], - ), - ), - ], - ), - ), - ) - : const SizedBox.shrink(); - }, - ), - ), - ), - ), - const SizedBox(height: 8), - SizedBox( - height: Get.height* 0.19, - child: Card( - child: Column( - children: [ - SizedBox( - width: Get.width, - child: Padding( - padding: - const EdgeInsets.fromLTRB(8, 8, 8, 0), - child: Text( - "Customer Details", - style: GoogleFonts.roboto( - fontSize: Get.width * 0.05, - fontWeight: FontWeight.w500, - ), - ), - ), - ), - _buildRow("Name:", " Roshan Garg", Get.width * 0.04), - _buildRow("Email:", "roshangarg28@gmail.com", Get.width * 0.04), - _buildRow("Mobile Number:", "8876785448", Get.width * 0.04), - - - ], - ), - ), - ), - const SizedBox(height: 8), - Card( - child: Column( - children: [ - SizedBox( - width: Get.width, - child: Padding( - padding: - const EdgeInsets.fromLTRB(8, 8, 8, 0), - child: Text( - "Billing Information", - style: GoogleFonts.roboto( - fontSize: Get.width * 0.05, - fontWeight: FontWeight.w500, - ), - ), - ), - ), - _buildInfoRow("Address", widget.placedOrderList!.billTo, Get.width * 0.04) - - ], - ), - ), - const SizedBox(height: 8), - // Card for displaying shipping information - Card( - child: Column( - children: [ - SizedBox( - width: Get.width, - child: Padding( - padding: - const EdgeInsets.fromLTRB(8, 8, 8, 0), - child: Text( - "Shipping Information", - style: GoogleFonts.roboto( - fontSize: Get.width * 0.05, - fontWeight: FontWeight.w500, - ), - ), - ), - ), - _buildInfoRow("Address", widget.placedOrderList!.shipTo, Get.width * 0.04) - - - ], - ), - ), - const SizedBox(height: 8), - Card( - child: Column( - children: [ - SizedBox( - width: Get.width, - height: Get.height*0.05, - child: Padding( - padding: - const EdgeInsets.fromLTRB(8, 8, 8, 0), - child: Row( - children: [ - Text( - "Payment Mode : ", - style: GoogleFonts.roboto( - fontSize: Get.width * 0.04, - fontWeight: FontWeight.w500, - ), - ), - Text(capitalizeFirstLetter(widget.placedOrderList!.paymentMode)), - // Text("${widget.placedOrderList!.paymentMode}",maxLines: 4, - // overflow:TextOverflow.ellipsis,) - ], - ), - ), - ), - - - ], - ), - ), - const SizedBox(height: 8), - Card( - child: Column( - children: [ - SizedBox( - width: Get.width, - height: Get.height*0.05, - child: Padding( - padding: - const EdgeInsets.fromLTRB(8, 8, 8, 0), - child: Row( - children: [ - Text( - "Order Status :", - style: GoogleFonts.roboto( - fontSize: Get.width * 0.04, - fontWeight: FontWeight.w500, - ), - ), - SizedBox(width: Get.width*0.01,), - Text(capitalizeFirstLetter(selectedStatus)), - // Text("${widget.placedOrderList!.status}",maxLines: 4, - // overflow:TextOverflow.ellipsis,) - ], - ), - ), - ), - - - ], - ), - ), - const SizedBox(height: 8), - SizedBox( - height: Get.height * 0.05, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const Text( - "Status: ", - style: TextStyle(fontWeight: FontWeight.bold), - ), - SizedBox(width: 10), // Space between label and dropdown - Expanded( - child: DropdownButtonFormField( - value: selectedStatus, - decoration: InputDecoration( - filled: true, - fillColor: Colors.white, // White background - contentPadding: EdgeInsets.symmetric( - vertical: 10, horizontal: 12), - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(10), - borderSide: BorderSide( - color: Colors.grey, - width: 1, - ), - ), - ), - items: _statusList.map((String status) { - return DropdownMenuItem( - value: status, - child: Text(capitalizeFirstLetter(status)), - ); - }).toList(), - onChanged: (newValue) { - setState(() { - selectedStatus = newValue!; - }); - }, - ), - ), - ], - ), - ), - if (selectedStatus == "processing" || - selectedStatus == "partial processing" || - selectedStatus == "cancelled") - SizedBox( - width: Get.width * 0.4, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: ElevatedButton( - onPressed: () { - // Show confirmation dialog - _showConfirmationDialog(); - }, - // Get.to(() => - // RdOrderDetailScreen( - // placedOrderList: uniqueOrders[index])), // Navigate to detail screen - style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: const Color(0xFF004791), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10)), - ), - child: Text("Update Status", style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.w400)), - ), - ), - ) - - ], - ), - ), - ), - SizedBox(height: Get.height * 0.04), - - ], - ), - ), - ), - ], - ), - ); - } -} -Widget _buildRow(String label, String value, double fontSize) { - return SizedBox( - width: Get.width, - child: Padding( - padding: const EdgeInsets.fromLTRB(8, 8, 8, 0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - label, - style: GoogleFonts.roboto( - fontSize: fontSize, - fontWeight: FontWeight.bold, - ), - ), - Text(value), - ], - ), - ), - ); -} - -Widget _buildInfoRow(String label, String value, double fontSize) { - return SizedBox( - width: Get.width, - child: Padding( - padding: const EdgeInsets.fromLTRB(8, 8, 8, 0), - child: Row( - children: [ - Text( - "$label ", - style: GoogleFonts.roboto( - fontSize: fontSize, - fontWeight: FontWeight.bold, - ), - ), - Expanded( - child: Text( - value, - maxLines: 4, - overflow: TextOverflow.ellipsis, - ), - ), - ], - ), - ), - ); - -} - - - - - // import 'package:auto_size_text/auto_size_text.dart'; +// import 'package:cached_network_image/cached_network_image.dart'; // import 'package:cheminova/controller/get_order_placed_controller.dart'; // import 'package:cheminova/controller/rd_get_order_controller.dart'; // import 'package:cheminova/models/oder_place_model.dart'; @@ -805,13 +77,15 @@ Widget _buildInfoRow(String label, String value, double fontSize) { // } // // String formatDate(String apiDate) { +// // Parse the API date string into a DateTime object +// DateTime parsedDate = DateTime.parse(apiDate).toLocal(); // Convert to local time // -// DateTime parsedDate = DateTime.parse(apiDate); +// // Format the date and time according to your specified format +// String formattedDate = DateFormat('EEE MMM dd yyyy').format(parsedDate); // -// String formattedDate = DateFormat('dd-MMM-yyyy').format(parsedDate); -// -// return formattedDate; +// return formattedDate; // Return the formatted date string // } +// // // Function to capitalize the first letter of a string // String capitalizeFirstLetter(String text) { // if (text.isEmpty) return text; @@ -868,7 +142,6 @@ Widget _buildInfoRow(String label, String value, double fontSize) { // selectedStatus= widget.placedOrderList?.status ?? 'new'; // // controller.fetchOrderItems(widget.placedOrderList!.id); // } -// // void _showConfirmationDialog() { // String dialogTitle; // String dialogContent; @@ -938,17 +211,19 @@ Widget _buildInfoRow(String label, String value, double fontSize) { // // // Close the dialog after a short delay // Future.delayed(Duration(seconds: 1), () { -// Get.back(); // Close the dialog +// Navigator.of(context).pop(); // Close the dialog // }); // // return; // Exit here to prevent further processing // } // // if (selectedStatus == "partial processing") { -// Get.to(() => PartialProcessingDialogScreen(productModel: widget.placedOrderList)); +// // Get.to(() => PartialProcessingDialogScreen(productModel: widget.placedOrderList)); +// // return; // } // +// // // Create a map to track products by their IDs and aggregate quantities // Map orderItemMap = {}; // @@ -958,8 +233,10 @@ Widget _buildInfoRow(String label, String value, double fontSize) { // // if (orderItemMap.containsKey(productId)) { // // If the product already exists, aggregate the quantity -// var existingItem = orderItemMap[productId]!; // Get the existing item +// var existingItem = orderItemMap[productId]!; // existingItem.quantity = (existingItem.quantity ?? 0) + (item.orderItem[0].quantity ?? 0); +// existingItem.remainingQuantity = (existingItem.remainingQuantity ?? 0) + (item.orderItem[0].remainingQuantity ?? 0); +// existingItem.processquantity = (existingItem.processquantity ?? 0) + (item.orderItem[0].processquantity ?? 0); // } else { // // If it's a new product, add it to the map // orderItemMap[productId] = RDOrderItem( @@ -969,13 +246,13 @@ Widget _buildInfoRow(String label, String value, double fontSize) { // categoryName: item.orderItem[0].categoryName, // brandName: item.orderItem[0].brandName, // price: item.orderItem[0].price, -// gst: item.orderItem[0].gst, +// gst: item.orderItem[0].gst.toInt(), // hsnCode: item.orderItem[0].hsnCode, // description: item.orderItem[0].description, // image: [], // Handle images appropriately -// quantity: item.orderItem[0].quantity??0, -// remainingQuantity: item.orderItem[0].remainingQuantity??0, -// processquantity: item.orderItem[0].processquantity??0, +// quantity: item.orderItem[0].quantity ?? 0, +// remainingQuantity: item.orderItem[0].remainingQuantity ?? 0, +// processquantity: item.orderItem[0].processquantity ?? 0, // ); // } // } @@ -990,23 +267,24 @@ Widget _buildInfoRow(String label, String value, double fontSize) { // ); // // // Debugging: Print the JSON payload -// print(controller.placedOrder1.value.toJson()); +// print("Sending order payload: ${controller.placedOrder1.value.toJson()}"); // +// // Place the order and catch any errors // await controller.placeRDOrder(); // // showSnackbar("Order processed and invoice created successfully"); +// Navigator.of(context).pop(); +// // Close the dialog after a short delay // -// Future.delayed(Duration(seconds: 1), () { -// Get.back(); // Close the dialog -// }); +// // Close the dialog // -// setState(() {}); // Refresh the UI +// // Refresh the UI// Refresh the UI // }, // child: Text("Confirm"), // ), // TextButton( // onPressed: () { -// Get.back(); // Close the dialog +// Navigator.of(context).pop(); // Close the dialog // }, // child: Text("Cancel"), // ), @@ -1019,6 +297,7 @@ Widget _buildInfoRow(String label, String value, double fontSize) { // // // +// // @override // Widget build(BuildContext context) { // return Scaffold( @@ -1118,6 +397,7 @@ Widget _buildInfoRow(String label, String value, double fontSize) { // itemCount: widget.placedOrderList?.orderItem.length ?? 0, // itemBuilder: (context, index) { // final orderItem = widget.placedOrderList!.orderItem[index]; +// // final imageUrl = orderItem.image.isNotEmpty == true ? orderItem.image[0].url : null; // return orderItem != null // ? Card( // margin: const EdgeInsets.symmetric(vertical: 5.0), @@ -1129,11 +409,30 @@ Widget _buildInfoRow(String label, String value, double fontSize) { // child: Row( // children: [ // Image.asset( -// "assets/images/product.png", // Add the image URL here +// "assets/images/new_product.jpeg", +// // "assets/images/product.png", // Add the image URL here // height: 50, // width: 50, // fit: BoxFit.cover, // ), +// +// +// // imageUrl != null && imageUrl.isNotEmpty && imageUrl.startsWith('http') // Check if it's a network URL/ Check if it's a network URL +// // ? CachedNetworkImage( +// // imageUrl: imageUrl, +// // height: 50, +// // width: 50, +// // fit: BoxFit.cover, +// // placeholder: (context, url) => const CircularProgressIndicator(), // Optional placeholder +// // errorWidget: (context, url, error) => const Icon(Icons.error), // Optional error widget +// // ) +// // : Image.asset( +// // //imageUrl!, +// // 'assets/images/no_image_available.jpg', // Placeholder image when URL is empty +// // height: 50, +// // width: 50, +// // fit: BoxFit.cover, +// // ), // const SizedBox(width: 10), // Expanded( // child: Column( @@ -1190,9 +489,9 @@ Widget _buildInfoRow(String label, String value, double fontSize) { // ), // ), // ), -// _buildRow("Name:", "VAIBHAV", Get.width * 0.04), -// _buildRow("Email:", "vaibhav.gurjar20001@gmail.com", Get.width * 0.04), -// _buildRow("Mobile Number:", "7779797976", Get.width * 0.04), +// _buildRow("Name:", " Roshan Garg", Get.width * 0.04), +// _buildRow("Email:", "roshangarg28@gmail.com", Get.width * 0.04), +// _buildRow("Mobile Number:", "8876785448", Get.width * 0.04), // // // ], @@ -1448,3 +747,724 @@ Widget _buildInfoRow(String label, String value, double fontSize) { // // // +// // import 'package:auto_size_text/auto_size_text.dart'; +// // import 'package:cheminova/controller/get_order_placed_controller.dart'; +// // import 'package:cheminova/controller/rd_get_order_controller.dart'; +// // import 'package:cheminova/models/oder_place_model.dart'; +// // import 'package:cheminova/models/order_item_model.dart'; +// // import 'package:cheminova/models/place_order_list_model.dart'; +// // import 'package:cheminova/models/rd_get_order_model.dart'; +// // import 'package:cheminova/models/rd_order_item_model.dart'; +// // import 'package:cheminova/models/rd_placed_order_model.dart'; +// // import 'package:cheminova/screens/rd%20orders/partial_processing_dialog_screen.dart'; +// // +// // import 'package:flutter/cupertino.dart'; +// // import 'package:flutter/material.dart'; +// // import 'package:flutter_svg/svg.dart'; +// // import 'package:get/get.dart'; +// // import 'package:google_fonts/google_fonts.dart'; +// // import 'package:intl/intl.dart'; +// // import 'package:shared_preferences/shared_preferences.dart'; +// // +// // import '../../controller/cart_controller.dart'; +// // import '../../controller/rd_processing_order_controller.dart'; +// // import '../../models/product_model1.dart'; +// // import '../../utils/show_snackbar.dart'; +// // +// // class RdOrderDetailScreen extends StatefulWidget { +// // //final Product? productModel; +// // // PlacedOrderList and PlacedOrderModel are optional parameters passed to this screen +// // PlacedOrdersResponse? placedOrderList; +// // // PlacedOrderModel? placedOrderModel; +// // // Constructor for initializing the screen with placed order details +// // RdOrderDetailScreen({super.key,this.placedOrderList}); +// // +// // @override +// // State createState() => +// // _RdOrderDetailScreenState(); +// // } +// // +// // +// // class _RdOrderDetailScreenState +// // extends State { +// // // Controllers for managing cart and placed orders +// // +// // final GetProductRDController _getPlacedOrderController = Get.put(GetProductRDController()); +// // final RDOrderPlacedController controller = Get.put(RDOrderPlacedController()); +// // String? orderId; +// // final List statusOptions = [ +// // "new", +// // "pending", +// // "processing", +// // "dispatched", +// // "cancelled", +// // "delivered", +// // ]; +// // +// // +// // List _statusList = ["new", "processing", "partial processing", "cancelled"]; // Default status list +// // +// // // Define different status lists for different categories +// // final Map> statusLists = { +// // "new": ["new", "processing", "partial processing", "cancelled"], +// // "pending": ["pending", "processing", "dispatched", "cancelled"], +// // "dispatched": ["dispatched", "delivered", "returned", "cancelled"], +// // "delivered": ["delivered", "returned", "cancelled"], +// // }; +// // String selectedStatus = "new"; +// // String _groupValue = "cheque"; +// // // Function to format date from the API to a more readable format +// // +// // +// // // This function updates the dropdown list dynamically based on category selection +// // void updateStatusList(String category) { +// // setState(() { +// // _statusList = statusLists[category]!; // Update status list based on the selected category +// // selectedStatus = _statusList.first; // Set the default selection to the first item +// // }); +// // } +// // +// // String formatDate(String apiDate) { +// // +// // DateTime parsedDate = DateTime.parse(apiDate); +// // +// // String formattedDate = DateFormat('dd-MMM-yyyy').format(parsedDate); +// // +// // return formattedDate; +// // } +// // // Function to capitalize the first letter of a string +// // String capitalizeFirstLetter(String text) { +// // if (text.isEmpty) return text; +// // return text[0].toUpperCase() + text.substring(1).toLowerCase(); +// // } +// // +// // +// // void _onPaymentModeChanged(String? value) { +// // setState(() { +// // _groupValue = value!; +// // }); +// // _saveSelectedPaymentMode(); +// // } +// // +// // +// // void _saveSelectedPaymentMode() async { +// // SharedPreferences prefs = await SharedPreferences.getInstance(); +// // await prefs.setString('selectedPaymentMode', _groupValue); +// // } +// // +// // void _loadSelectedPaymentMode() async { +// // SharedPreferences prefs = await SharedPreferences.getInstance(); +// // setState(() { +// // _groupValue = prefs.getString('selectedPaymentMode') ?? 'cheque'; +// // }); +// // } +// // // Function to collect unique order IDs and corresponding order details +// // Future adduni()async { +// // final Set uniqueOrderIds = {}; +// // final List uniqueOrders = []; +// // // Loop through placed orders and add unique orders to the list +// // for (var order in _getPlacedOrderController.productRDList) { +// // if (uniqueOrderIds.add(order.uniqueId)) { +// // uniqueOrders.add(order); +// // } +// // } +// // final order = uniqueOrders[0]; +// // +// // // Combine product names, categories, and quantities into strings +// // final productNames = order.orderItem +// // .map((item) => (item.name)) +// // .join(', '); +// // final categotyName = order.orderItem +// // .map((item) => (item.categoryName)) +// // .join(', '); +// // final quantity = order.orderItem +// // .map((item) => (item.quantity)) +// // .join(', '); +// // } +// // @override +// // void initState() { +// // // TODO: implement initState +// // super.initState(); +// // selectedStatus= widget.placedOrderList?.status ?? 'new'; +// // // controller.fetchOrderItems(widget.placedOrderList!.id); +// // } +// // +// // void _showConfirmationDialog() { +// // String dialogTitle; +// // String dialogContent; +// // TextEditingController reasonController = TextEditingController(); +// // +// // // Set dialog title and content based on selected status +// // switch (selectedStatus) { +// // case "processing": +// // dialogTitle = "Update Order Status"; +// // dialogContent = "Are you sure you want to update the status to processing?"; +// // break; +// // case "partial processing": +// // dialogTitle = "Update to Partial Processing"; +// // dialogContent = "Are you sure you want to update the status to 'Partial Processing'?"; +// // break; +// // case "cancelled": +// // dialogTitle = "Cancellation Reason"; +// // dialogContent = "Please provide a reason for cancelling the order:"; +// // break; +// // default: +// // dialogTitle = "Update Order Status"; +// // dialogContent = "Are you sure you want to update the status to '$selectedStatus'?"; +// // break; +// // } +// // +// // showDialog( +// // context: context, +// // builder: (context) { +// // return AlertDialog( +// // title: Text(dialogTitle), +// // content: selectedStatus == "cancelled" +// // ? Column( +// // mainAxisSize: MainAxisSize.min, +// // children: [ +// // Text(dialogContent), +// // SizedBox(height: 10), +// // TextField( +// // controller: reasonController, +// // decoration: InputDecoration( +// // labelText: 'Cancellation Reason', +// // border: OutlineInputBorder(), +// // ), +// // ), +// // ], +// // ) +// // : Text(dialogContent), +// // actions: [ +// // TextButton( +// // onPressed: () async { +// // if (selectedStatus == "cancelled") { +// // // Ensure the reason is provided for cancellation +// // if (reasonController.text.isEmpty) { +// // showSnackbar("Please provide a reason for cancelling the order."); +// // return; // Exit early if reason is empty +// // } +// // +// // // Proceed with cancellation +// // await controller.CancleRDProduct(widget.placedOrderList!.id, reasonController.text); +// // +// // // Notify user about successful cancellation +// // showSnackbar("Order cancelled successfully"); +// // +// // // Update the status in your UI or backend to reflect the cancelled state +// // setState(() { +// // // Update the status in the local model/UI +// // }); +// // +// // // Close the dialog after a short delay +// // Future.delayed(Duration(seconds: 1), () { +// // Get.back(); // Close the dialog +// // }); +// // +// // return; // Exit here to prevent further processing +// // } +// // +// // if (selectedStatus == "partial processing") { +// // Get.to(() => PartialProcessingDialogScreen(productModel: widget.placedOrderList)); +// // return; +// // } +// // +// // // Create a map to track products by their IDs and aggregate quantities +// // Map orderItemMap = {}; +// // +// // // Populate the map with items and their quantities +// // for (var item in _getPlacedOrderController.productRDList) { +// // var productId = item.orderItem[0].productId; +// // +// // if (orderItemMap.containsKey(productId)) { +// // // If the product already exists, aggregate the quantity +// // var existingItem = orderItemMap[productId]!; // Get the existing item +// // existingItem.quantity = (existingItem.quantity ?? 0) + (item.orderItem[0].quantity ?? 0); +// // } else { +// // // If it's a new product, add it to the map +// // orderItemMap[productId] = RDOrderItem( +// // productId: productId, +// // sku: item.orderItem[0].sku, +// // name: item.orderItem[0].name, +// // categoryName: item.orderItem[0].categoryName, +// // brandName: item.orderItem[0].brandName, +// // price: item.orderItem[0].price, +// // gst: item.orderItem[0].gst, +// // hsnCode: item.orderItem[0].hsnCode, +// // description: item.orderItem[0].description, +// // image: [], // Handle images appropriately +// // quantity: item.orderItem[0].quantity??0, +// // remainingQuantity: item.orderItem[0].remainingQuantity??0, +// // processquantity: item.orderItem[0].processquantity??0, +// // ); +// // } +// // } +// // +// // // Convert the map to a list +// // List orderItems = orderItemMap.values.toList(); +// // +// // // Ensure the placed order contains the correct orderId and items +// // controller.placedOrder1.value = PlacedOrdersProcessing( +// // orderId: widget.placedOrderList!.id, +// // invoiceItems: orderItems, +// // ); +// // +// // // Debugging: Print the JSON payload +// // print(controller.placedOrder1.value.toJson()); +// // +// // await controller.placeRDOrder(); +// // +// // showSnackbar("Order processed and invoice created successfully"); +// // +// // Future.delayed(Duration(seconds: 1), () { +// // Get.back(); // Close the dialog +// // }); +// // +// // setState(() {}); // Refresh the UI +// // }, +// // child: Text("Confirm"), +// // ), +// // TextButton( +// // onPressed: () { +// // Get.back(); // Close the dialog +// // }, +// // child: Text("Cancel"), +// // ), +// // ], +// // ); +// // }, +// // ); +// // } +// // +// // +// // +// // +// // @override +// // Widget build(BuildContext context) { +// // return Scaffold( +// // extendBodyBehindAppBar: true, +// // appBar: AppBar( +// // backgroundColor: Colors.transparent, +// // elevation: 0, +// // leading: GestureDetector( +// // onTap: () {}, +// // child: Padding( +// // padding: const EdgeInsets.all(16.0), +// // child: SvgPicture.asset( +// // 'assets/svg/menu.svg', +// // ), +// // ), +// // ), +// // actions: [ +// // GestureDetector( +// // onTap: () => Get.back(), +// // child: Padding( +// // padding: const EdgeInsets.all(8.0), +// // child: SvgPicture.asset( +// // 'assets/svg/back_arrow.svg', +// // ), +// // ), +// // ), +// // ], +// // title: const Text( +// // "Order Detail", +// // ), +// // ), +// // body: Stack( +// // fit: StackFit.expand, +// // children: [ +// // Image.asset( +// // 'assets/images/image_1.png', +// // fit: BoxFit.cover, +// // ), +// // SafeArea( +// // child: SingleChildScrollView( +// // child: Column( +// // mainAxisSize: MainAxisSize.min, +// // mainAxisAlignment: MainAxisAlignment.start, +// // children: [ +// // SizedBox( +// // height: Get.height * 0.02, +// // ), +// // Card( +// // margin: const EdgeInsets.symmetric(horizontal: 18), +// // shape: RoundedRectangleBorder( +// // borderRadius: BorderRadius.circular(19), +// // side: const BorderSide(color: Color(0xFFFDFDFD)), +// // ), +// // color: const Color(0xFFB4D1E5).withOpacity(0.9), +// // child: Padding( +// // padding: const EdgeInsets.all(12.0), +// // child: Column( +// // mainAxisSize: MainAxisSize.min, +// // children: [ +// // +// // Card( +// // child: Column( +// // children: [ +// // SizedBox( +// // width: Get.width, +// // child: Padding( +// // padding: +// // const EdgeInsets.fromLTRB(8, 8, 8, 0), +// // child: Text( +// // "Order Summary", +// // style: GoogleFonts.roboto( +// // fontSize: Get.width * 0.05, +// // fontWeight: FontWeight.bold, +// // ), +// // ), +// // ), +// // ), +// // _buildRow("Order ID:", widget.placedOrderList!.uniqueId, Get.width * 0.04), +// // _buildRow("Order Date:", formatDate("${widget.placedOrderList!.createdAt}"), Get.width * 0.04), +// // _buildRow("Total Items:", "${widget.placedOrderList!.orderItem.length}", Get.width * 0.04), +// // _buildRow("Sub Total:", "₹ ${widget.placedOrderList!.subtotal}", Get.width * 0.04), +// // _buildRow("GST:", "₹ ${widget.placedOrderList!.gstTotal}", Get.width * 0.04), +// // _buildRow("Total Amount:", "₹ ${widget.placedOrderList!.grandTotal}", Get.width * 0.04), +// // +// // +// // ], +// // ), +// // ), +// // const SizedBox(height: 8), +// // Card( +// // child: SizedBox( +// // height: Get.height * 0.22, +// // child: Padding( +// // padding: EdgeInsets.all(Get.width * 0.02), +// // child: ListView.builder( +// // padding: EdgeInsets.zero, +// // itemCount: widget.placedOrderList?.orderItem.length ?? 0, +// // itemBuilder: (context, index) { +// // final orderItem = widget.placedOrderList!.orderItem[index]; +// // return orderItem != null +// // ? Card( +// // margin: const EdgeInsets.symmetric(vertical: 5.0), +// // shape: RoundedRectangleBorder( +// // borderRadius: BorderRadius.circular(10), +// // ), +// // child: Padding( +// // padding: const EdgeInsets.all(8.0), +// // child: Row( +// // children: [ +// // Image.asset( +// // "assets/images/product.png", // Add the image URL here +// // height: 50, +// // width: 50, +// // fit: BoxFit.cover, +// // ), +// // const SizedBox(width: 10), +// // Expanded( +// // child: Column( +// // crossAxisAlignment: CrossAxisAlignment.end, +// // children: [ +// // Text( +// // capitalizeFirstLetter(orderItem.name), +// // style: GoogleFonts.roboto( +// // fontSize: Get.width * 0.04, +// // fontWeight: FontWeight.bold, +// // ), +// // ), +// // Text( +// // "Quantity: ${orderItem.quantity}", +// // style: GoogleFonts.roboto( +// // fontSize: Get.width * 0.03, +// // ), +// // ), +// // Text("Price: ${orderItem.price}"), +// // Text("Subtotal : ${widget.placedOrderList!.subtotal}"), +// // Text("Gst : ${orderItem.gst}%"), +// // Text("GST : ${widget.placedOrderList!.gstTotal}"), +// // Text("Total Amount : ${widget.placedOrderList!.grandTotal}"), +// // ], +// // ), +// // ), +// // ], +// // ), +// // ), +// // ) +// // : const SizedBox.shrink(); +// // }, +// // ), +// // ), +// // ), +// // ), +// // const SizedBox(height: 8), +// // SizedBox( +// // height: Get.height* 0.19, +// // child: Card( +// // child: Column( +// // children: [ +// // SizedBox( +// // width: Get.width, +// // child: Padding( +// // padding: +// // const EdgeInsets.fromLTRB(8, 8, 8, 0), +// // child: Text( +// // "Customer Details", +// // style: GoogleFonts.roboto( +// // fontSize: Get.width * 0.05, +// // fontWeight: FontWeight.w500, +// // ), +// // ), +// // ), +// // ), +// // _buildRow("Name:", "VAIBHAV", Get.width * 0.04), +// // _buildRow("Email:", "vaibhav.gurjar20001@gmail.com", Get.width * 0.04), +// // _buildRow("Mobile Number:", "7779797976", Get.width * 0.04), +// // +// // +// // ], +// // ), +// // ), +// // ), +// // const SizedBox(height: 8), +// // Card( +// // child: Column( +// // children: [ +// // SizedBox( +// // width: Get.width, +// // child: Padding( +// // padding: +// // const EdgeInsets.fromLTRB(8, 8, 8, 0), +// // child: Text( +// // "Billing Information", +// // style: GoogleFonts.roboto( +// // fontSize: Get.width * 0.05, +// // fontWeight: FontWeight.w500, +// // ), +// // ), +// // ), +// // ), +// // _buildInfoRow("Address", widget.placedOrderList!.billTo, Get.width * 0.04) +// // +// // ], +// // ), +// // ), +// // const SizedBox(height: 8), +// // // Card for displaying shipping information +// // Card( +// // child: Column( +// // children: [ +// // SizedBox( +// // width: Get.width, +// // child: Padding( +// // padding: +// // const EdgeInsets.fromLTRB(8, 8, 8, 0), +// // child: Text( +// // "Shipping Information", +// // style: GoogleFonts.roboto( +// // fontSize: Get.width * 0.05, +// // fontWeight: FontWeight.w500, +// // ), +// // ), +// // ), +// // ), +// // _buildInfoRow("Address", widget.placedOrderList!.shipTo, Get.width * 0.04) +// // +// // +// // ], +// // ), +// // ), +// // const SizedBox(height: 8), +// // Card( +// // child: Column( +// // children: [ +// // SizedBox( +// // width: Get.width, +// // height: Get.height*0.05, +// // child: Padding( +// // padding: +// // const EdgeInsets.fromLTRB(8, 8, 8, 0), +// // child: Row( +// // children: [ +// // Text( +// // "Payment Mode : ", +// // style: GoogleFonts.roboto( +// // fontSize: Get.width * 0.04, +// // fontWeight: FontWeight.w500, +// // ), +// // ), +// // Text(capitalizeFirstLetter(widget.placedOrderList!.paymentMode)), +// // // Text("${widget.placedOrderList!.paymentMode}",maxLines: 4, +// // // overflow:TextOverflow.ellipsis,) +// // ], +// // ), +// // ), +// // ), +// // +// // +// // ], +// // ), +// // ), +// // const SizedBox(height: 8), +// // Card( +// // child: Column( +// // children: [ +// // SizedBox( +// // width: Get.width, +// // height: Get.height*0.05, +// // child: Padding( +// // padding: +// // const EdgeInsets.fromLTRB(8, 8, 8, 0), +// // child: Row( +// // children: [ +// // Text( +// // "Order Status :", +// // style: GoogleFonts.roboto( +// // fontSize: Get.width * 0.04, +// // fontWeight: FontWeight.w500, +// // ), +// // ), +// // SizedBox(width: Get.width*0.01,), +// // Text(capitalizeFirstLetter(selectedStatus)), +// // // Text("${widget.placedOrderList!.status}",maxLines: 4, +// // // overflow:TextOverflow.ellipsis,) +// // ], +// // ), +// // ), +// // ), +// // +// // +// // ], +// // ), +// // ), +// // const SizedBox(height: 8), +// // SizedBox( +// // height: Get.height * 0.05, +// // child: Row( +// // crossAxisAlignment: CrossAxisAlignment.center, +// // children: [ +// // const Text( +// // "Status: ", +// // style: TextStyle(fontWeight: FontWeight.bold), +// // ), +// // SizedBox(width: 10), // Space between label and dropdown +// // Expanded( +// // child: DropdownButtonFormField( +// // value: selectedStatus, +// // decoration: InputDecoration( +// // filled: true, +// // fillColor: Colors.white, // White background +// // contentPadding: EdgeInsets.symmetric( +// // vertical: 10, horizontal: 12), +// // border: OutlineInputBorder( +// // borderRadius: BorderRadius.circular(10), +// // borderSide: BorderSide( +// // color: Colors.grey, +// // width: 1, +// // ), +// // ), +// // ), +// // items: _statusList.map((String status) { +// // return DropdownMenuItem( +// // value: status, +// // child: Text(capitalizeFirstLetter(status)), +// // ); +// // }).toList(), +// // onChanged: (newValue) { +// // setState(() { +// // selectedStatus = newValue!; +// // }); +// // }, +// // ), +// // ), +// // ], +// // ), +// // ), +// // if (selectedStatus == "processing" || +// // selectedStatus == "partial processing" || +// // selectedStatus == "cancelled") +// // SizedBox( +// // width: Get.width * 0.4, +// // child: Padding( +// // padding: const EdgeInsets.all(8.0), +// // child: ElevatedButton( +// // onPressed: () { +// // // Show confirmation dialog +// // _showConfirmationDialog(); +// // }, +// // // Get.to(() => +// // // RdOrderDetailScreen( +// // // placedOrderList: uniqueOrders[index])), // Navigate to detail screen +// // style: ElevatedButton.styleFrom( +// // foregroundColor: Colors.white, +// // backgroundColor: const Color(0xFF004791), +// // shape: RoundedRectangleBorder( +// // borderRadius: BorderRadius.circular(10)), +// // ), +// // child: Text("Update Status", style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.w400)), +// // ), +// // ), +// // ) +// // +// // ], +// // ), +// // ), +// // ), +// // SizedBox(height: Get.height * 0.04), +// // +// // ], +// // ), +// // ), +// // ), +// // ], +// // ), +// // ); +// // } +// // } +// // Widget _buildRow(String label, String value, double fontSize) { +// // return SizedBox( +// // width: Get.width, +// // child: Padding( +// // padding: const EdgeInsets.fromLTRB(8, 8, 8, 0), +// // child: Row( +// // mainAxisAlignment: MainAxisAlignment.spaceBetween, +// // children: [ +// // Text( +// // label, +// // style: GoogleFonts.roboto( +// // fontSize: fontSize, +// // fontWeight: FontWeight.bold, +// // ), +// // ), +// // Text(value), +// // ], +// // ), +// // ), +// // ); +// // } +// // +// // Widget _buildInfoRow(String label, String value, double fontSize) { +// // return SizedBox( +// // width: Get.width, +// // child: Padding( +// // padding: const EdgeInsets.fromLTRB(8, 8, 8, 0), +// // child: Row( +// // children: [ +// // Text( +// // "$label ", +// // style: GoogleFonts.roboto( +// // fontSize: fontSize, +// // fontWeight: FontWeight.bold, +// // ), +// // ), +// // Expanded( +// // child: Text( +// // value, +// // maxLines: 4, +// // overflow: TextOverflow.ellipsis, +// // ), +// // ), +// // ], +// // ), +// // ), +// // ); +// // +// // } +// // +// // +// // +// // +// // diff --git a/lib/screens/rd orders/rd_order_details_update.dart b/lib/screens/rd orders/rd_order_details_update.dart index 6113403..6a89fb7 100644 --- a/lib/screens/rd orders/rd_order_details_update.dart +++ b/lib/screens/rd orders/rd_order_details_update.dart @@ -1,4 +1,5 @@ +import 'package:cached_network_image/cached_network_image.dart'; import 'package:cheminova/controller/rd_single_order_controller.dart'; import 'package:cheminova/models/rd_order_item_model.dart'; @@ -26,12 +27,14 @@ class RdOrderDetailUpdateScreen extends StatefulWidget { //final Product? productModel; // PlacedOrderList and PlacedOrderModel are optional parameters passed to this screen SingleGetOrderModel? placedOrderList; -final String orderId; +//final String orderId; //final int orderIndex; // New parameter to receive the index // PlacedOrderModel? placedOrderModel; // Constructor for initializing the screen with placed order details - RdOrderDetailUpdateScreen({super.key,this.placedOrderList,required this.orderId}); + RdOrderDetailUpdateScreen({super.key,this.placedOrderList, + //required this.orderId + }); @override State createState() => @@ -46,6 +49,7 @@ class _RdOrderDetailUpdateScreenState final RdSingleOrderController _getPlacedOrderController = Get.put(RdSingleOrderController()); final GetProductRDController _getProductRDController = Get.put(GetProductRDController()); final RDOrderPlacedController controller = Get.put(RDOrderPlacedController()); + bool isDialogClosed = false; // Flag to track if dialog is already closed String? orderId; @@ -226,6 +230,9 @@ class _RdOrderDetailUpdateScreenState actions: [ TextButton( onPressed: () async { + if (isDialogClosed) return; // Prevent reopening the dialog + isDialogClosed = true; // Mark dialog as closed + if (selectedStatus == "cancelled") { // Ensure the reason is provided for cancellation if (reasonController.text.isEmpty) { @@ -245,9 +252,9 @@ class _RdOrderDetailUpdateScreenState }); // Close the dialog after a short delay - Future.delayed(Duration(seconds: 1), () { - // Navigator.of(context).pop(); // Close the dialog - }); + // Future.delayed(Duration(seconds: 1), () { + // // Navigator.of(context).pop(); // Close the dialog + // }); return; // Exit here to prevent further processing } @@ -262,31 +269,33 @@ class _RdOrderDetailUpdateScreenState Map orderItemMap = {}; // Populate the map with items and their quantities - for (var item in _getProductRDController.productRDList) { - var productId = item.orderItem[0].productId; + for (var item in widget.placedOrderList!.orderItem) { + var productId = item.productId; if (orderItemMap.containsKey(productId)) { // If the product already exists, aggregate the quantity var existingItem = orderItemMap[productId]!; - existingItem.quantity = (existingItem.quantity ?? 0) + (item.orderItem[0].quantity ?? 0); - existingItem.remainingQuantity = (existingItem.remainingQuantity ?? 0) + (item.orderItem[0].remainingQuantity ?? 0); - existingItem.processquantity = (existingItem.processquantity ?? 0) + (item.orderItem[0].processquantity ?? 0); + // var existingItem = orderItemMap[productId]!; + existingItem.quantity = ((existingItem.quantity ?? 0) + (item.quantity ?? 0)); + // existingItem.quantity = (existingItem.quantity ?? 0) + (item.orderItem[0].quantity ?? 0); + // existingItem.remainingQuantity = (existingItem.remainingQuantity ?? 0) + (item.orderItem[0].remainingQuantity ?? 0); + // existingItem.processquantity = (existingItem.processquantity ?? 0) + (item.orderItem[0].processquantity ?? 0); } else { // If it's a new product, add it to the map orderItemMap[productId] = RDOrderItem( productId: productId, - sku: item.orderItem[0].sku, - name: item.orderItem[0].name, - categoryName: item.orderItem[0].categoryName, - brandName: item.orderItem[0].brandName, - price: item.orderItem[0].price, - gst: item.orderItem[0].gst.toInt(), - hsnCode: item.orderItem[0].hsnCode, - description: item.orderItem[0].description, + sku: item.sku, + name: item.name, + categoryName: item.categoryName, + brandName: item.brandName, + price: item.price, + gst: item.gst.toInt(), + hsnCode: item.hsnCode, + description: item.description, image: [], // Handle images appropriately - quantity: item.orderItem[0].quantity ?? 0, - remainingQuantity: item.orderItem[0].remainingQuantity ?? 0, - processquantity: item.orderItem[0].processquantity ?? 0, + quantity: item.quantity ?? 0, + remainingQuantity: item.remainingQuantity ?? 0, + processquantity: item.remainingQuantity ?? 0, ); } } @@ -309,7 +318,7 @@ class _RdOrderDetailUpdateScreenState showSnackbar("Order processed and invoice created successfully"); Get.to(RdOrderProcessingScreen()); - Navigator.of(context).pop(); + // Navigator.of(context).pop(); // Close the dialog after a short delay // Close the dialog @@ -458,6 +467,7 @@ class _RdOrderDetailUpdateScreenState itemCount: widget.placedOrderList!.orderItem!.length ?? 0, itemBuilder: (context, index) { final orderItem = widget.placedOrderList!.orderItem![index]; + final imageUrl = orderItem.image?.isNotEmpty == true ? orderItem.image![0].url : null; final subTotalProcesssItem = orderItem.price! * orderItem.quantity!.toInt(); final GstTotalAmounProcessItem = (orderItem.price! * orderItem.quantity!.toInt()) *(orderItem.gst!/100 ); final grandTotalProcessItem = subTotalProcesssItem + GstTotalAmounProcessItem; @@ -471,9 +481,27 @@ class _RdOrderDetailUpdateScreenState padding: const EdgeInsets.all(8.0), child: Row( children: [ - Image.asset( - "assets/images/new_product.jpeg", - // "assets/images/product.png", + // Image.asset( + // "assets/images/new_product.jpeg", + // // "assets/images/product.png", + // height: 50, + // width: 50, + // fit: BoxFit.cover, + // ), + + + imageUrl != null && imageUrl.isNotEmpty && imageUrl.startsWith('http') // Check if it's a network URL/ Check if it's a network URL + ? CachedNetworkImage( + imageUrl: imageUrl, + height: 50, + width: 50, + fit: BoxFit.cover, + placeholder: (context, url) => const CircularProgressIndicator(), // Optional placeholder + errorWidget: (context, url, error) => const Icon(Icons.error), // Optional error widget + ) + : Image.asset( + //imageUrl!, + 'assets/images/no_image_available.jpg', // Placeholder image when URL is empty height: 50, width: 50, fit: BoxFit.cover, diff --git a/lib/screens/rd orders/rd_order_screen.dart b/lib/screens/rd orders/rd_order_screen.dart index 4e65794..efd55ff 100644 --- a/lib/screens/rd orders/rd_order_screen.dart +++ b/lib/screens/rd orders/rd_order_screen.dart @@ -165,7 +165,7 @@ class _RdOrderScreenState extends State { // Navigate to the details screen with the fetched order Get.to(() => RdOrderDetailUpdateScreen( placedOrderList: singleOrder, - orderId: orderId, + // orderId: orderId, )); } else { // Handle the case where the single order could not be fetched @@ -224,7 +224,7 @@ class _RdOrderScreenState extends State { ), ), ], - title: const Text("RD Order"), + title: const Text("Retailer Order"), ), drawer: MyDrawer(), body: Stack( diff --git a/lib/screens/rd orders/rd_pending_deatils.dart b/lib/screens/rd orders/rd_pending_deatils.dart index c3ed434..db22325 100644 --- a/lib/screens/rd orders/rd_pending_deatils.dart +++ b/lib/screens/rd orders/rd_pending_deatils.dart @@ -1,4 +1,5 @@ import 'package:auto_size_text/auto_size_text.dart'; +import 'package:cached_network_image/cached_network_image.dart'; import 'package:cheminova/controller/get_order_placed_controller.dart'; import 'package:cheminova/controller/get_rd_pending_controller.dart'; import 'package:cheminova/controller/rd_get_order_controller.dart'; @@ -24,6 +25,7 @@ import 'package:shared_preferences/shared_preferences.dart'; import '../../controller/cart_controller.dart'; import '../../controller/get_single_invoice_controller.dart'; import '../../controller/rd_processing_order_controller.dart'; +import '../../controller/rd_single_order_controller.dart'; import '../../models/get_invoice_model.dart'; import '../../models/product_model1.dart'; import '../../models/rd_order_item_model.dart'; @@ -35,12 +37,14 @@ class RdOrderPendingScreenDetailScreen extends StatefulWidget { // PlacedOrderList and PlacedOrderModel are optional parameters passed to this screen final SingleGetOrderModel? placedOrderList; // GetRdPendingModel? productpendingModel; - final String orderId; + //final String orderId; // GetInvoiceModel? placeInvoiceList; // PlacedOrderModel? placedOrderModel; // Constructor for initializing the screen with placed order details - RdOrderPendingScreenDetailScreen({super.key,this.placedOrderList,required this.orderId}); + RdOrderPendingScreenDetailScreen({super.key,this.placedOrderList, + // required this.orderId + }); @override State createState() => @@ -52,11 +56,12 @@ class _RdOrderPendingScreenDetailScreenState extends State { // Controllers for managing cart and placed orders final CartController _cartController = Get.put(CartController()); + final RdSingleOrderController _getPlacedOrderController = Get.put(RdSingleOrderController()); final GetRdPendingController _getRdPendingController = Get.put(GetRdPendingController()); final GetSingleInvoiceController _getSingleInvoiceController = Get.put(GetSingleInvoiceController()); final GetProductRDController _getProductRDController = Get.put(GetProductRDController()); final RDOrderPlacedController controller = Get.put(RDOrderPlacedController()); - + bool isDialogClosed = false; // Flag to track if dialog is already closed final List statusOptions = [ "new", "pending", @@ -201,6 +206,9 @@ class _RdOrderPendingScreenDetailScreenState actions: [ TextButton( onPressed: () async { + if (isDialogClosed) return; // Prevent reopening the dialog + isDialogClosed = true; // Mark dialog as closed + { if (selectedStatus == "cancelled") { // Ensure the reason is provided for cancellation @@ -235,35 +243,47 @@ class _RdOrderPendingScreenDetailScreenState Map orderItemMap = {}; // Populate the map with items and their quantities - for (var item in _getProductRDController.productRDList) { - var productId = item.orderItem[0].productId; + for (var item in widget.placedOrderList!.orderItem) { + var productId = item.productId; - if (orderItemMap.containsKey(productId)) { - // If the product already exists, aggregate the quantity - var existingItem = orderItemMap[productId]!; - existingItem.quantity = (existingItem.quantity ?? 0) + (item.orderItem[0].quantity ?? 0); - existingItem.remainingQuantity = (existingItem.remainingQuantity ?? 0) + (item.orderItem[0].remainingQuantity ?? 0); - existingItem.processquantity = (existingItem.processquantity ?? 0) + (item.orderItem[0].processquantity ?? 0); - } else { + + if (item.remainingQuantity != null && item.remainingQuantity! > 0) { + if (orderItemMap.containsKey(productId)) { + // If the product already exists, aggregate the remaining quantity + var existingItem = orderItemMap[productId]!; + existingItem.quantity = (existingItem.quantity ?? 0) + (item.quantity ?? 0); + existingItem.remainingQuantity = (existingItem.remainingQuantity ?? 0) + (item.remainingQuantity ?? 0); + existingItem.processquantity = existingItem.remainingQuantity; // Process all remaining stock + } + + // if (orderItemMap.containsKey(productId)) { + // // If the product already exists, aggregate the quantity + // var existingItem = orderItemMap[productId]!; + // // var existingItem = orderItemMap[productId]!; + // existingItem.quantity = ((existingItem.quantity ?? 0) + (item.quantity ?? 0)); + // existingItem.quantity = (existingItem.quantity ?? 0) + (item.orderItem[0].quantity ?? 0); + // existingItem.remainingQuantity = (existingItem.remainingQuantity ?? 0) + (item.orderItem[0].remainingQuantity ?? 0); + // existingItem.processquantity = (existingItem.processquantity ?? 0) + (item.orderItem[0].processquantity ?? 0); + else { // If it's a new product, add it to the map orderItemMap[productId] = RDOrderItem( productId: productId, - sku: item.orderItem[0].sku, - name: item.orderItem[0].name, - categoryName: item.orderItem[0].categoryName, - brandName: item.orderItem[0].brandName, - price: item.orderItem[0].price, - gst: item.orderItem[0].gst.toInt(), - hsnCode: item.orderItem[0].hsnCode, - description: item.orderItem[0].description, + sku: item.sku, + name: item.name, + categoryName: item.categoryName, + brandName: item.brandName, + price: item.price, + gst: item.gst.toInt(), + hsnCode: item.hsnCode, + description: item.description, image: [], // Handle images appropriately - quantity: item.orderItem[0].quantity ?? 0, - remainingQuantity: item.orderItem[0].remainingQuantity ?? 0, - processquantity: item.orderItem[0].processquantity ?? 0, + quantity: item.quantity ?? 0, + remainingQuantity: item.remainingQuantity ?? 0, + processquantity: item.remainingQuantity ?? 0, ); } } - +} // Convert the map to a list List orderItems = orderItemMap.values.toList(); @@ -372,7 +392,7 @@ class _RdOrderPendingScreenDetailScreenState ), ], title: const Text( - "RDPending Order Details", + "RetailerPending Order Details", ), ), body: Stack( @@ -593,6 +613,7 @@ class _RdOrderPendingScreenDetailScreenState itemCount: order.orderItem!.length ?? 0, itemBuilder: (context, index) { final orderItem =order.orderItem![index]; + final imageUrl = orderItem.image?.isNotEmpty == true ? orderItem.image![0].url : null; final subTotal = orderItem.price * orderItem.quantity!.toInt(); final GstTotalAmount = (orderItem.price * orderItem.quantity!.toInt()) *(orderItem.gst/100 ); final grandTotal = subTotal + GstTotalAmount; @@ -606,9 +627,26 @@ class _RdOrderPendingScreenDetailScreenState padding: const EdgeInsets.all(8.0), child: Row( children: [ - Image.asset( - "assets/images/new_product.jpeg", - // "assets/images/product.png", + // Image.asset( + // "assets/images/new_product.jpeg", + // // "assets/images/product.png", + // height: 50, + // width: 50, + // fit: BoxFit.cover, + // ), + + imageUrl != null && imageUrl.isNotEmpty && imageUrl.startsWith('http') // Check if it's a network URL/ Check if it's a network URL + ? CachedNetworkImage( + imageUrl: imageUrl, + height: 50, + width: 50, + fit: BoxFit.cover, + placeholder: (context, url) => const CircularProgressIndicator(), // Optional placeholder + errorWidget: (context, url, error) => const Icon(Icons.error), // Optional error widget + ) + : Image.asset( + //imageUrl!, + 'assets/images/no_image_available.jpg', // Placeholder image when URL is empty height: 50, width: 50, fit: BoxFit.cover, @@ -690,6 +728,7 @@ class _RdOrderPendingScreenDetailScreenState .toList(); final orderItem = filteredItems[index]; + final imageUrl = orderItem.image?.isNotEmpty == true ? orderItem.image![0].url : null; final subTotalProcesssItem = orderItem.price! * orderItem.remainingQuantity!.toInt(); final GstTotalAmounProcessItem = (orderItem.price! * orderItem.remainingQuantity!.toInt()) *(orderItem.gst!/100 ); final grandTotalProcessItem = subTotalProcesssItem + GstTotalAmounProcessItem; @@ -703,12 +742,30 @@ class _RdOrderPendingScreenDetailScreenState padding: const EdgeInsets.all(8.0), child: Row( children: [ - Image.asset( + /* Image.asset( "assets/images/new_product.jpeg", // "assets/images/product.png", height: 50, width: 50, fit: BoxFit.cover, + ),*/ + + + imageUrl != null && imageUrl.isNotEmpty && imageUrl.startsWith('http') // Check if it's a network URL/ Check if it's a network URL + ? CachedNetworkImage( + imageUrl: imageUrl, + height: 50, + width: 50, + fit: BoxFit.cover, + placeholder: (context, url) => const CircularProgressIndicator(), // Optional placeholder + errorWidget: (context, url, error) => const Icon(Icons.error), // Optional error widget + ) + : Image.asset( + //imageUrl!, + 'assets/images/no_image_available.jpg', // Placeholder image when URL is empty + height: 50, + width: 50, + fit: BoxFit.cover, ), const SizedBox(width: 10), Expanded( diff --git a/lib/screens/rd orders/rd_pending_screen.dart b/lib/screens/rd orders/rd_pending_screen.dart index 91ad2e0..dc95e25 100644 --- a/lib/screens/rd orders/rd_pending_screen.dart +++ b/lib/screens/rd orders/rd_pending_screen.dart @@ -114,7 +114,7 @@ class _RdOrderPendingScreenState extends State { // Navigate to the details screen with the fetched order Get.to(() => RdOrderPendingScreenDetailScreen( placedOrderList: singleOrder, // Pass the single order instance - orderId: orderId, + // orderId: orderId, )); } else { @@ -171,7 +171,7 @@ class _RdOrderPendingScreenState extends State { ), ), ], - title: const Text("RD Pending Order"), + title: const Text("Retailer Pending Order"), ), drawer: MyDrawer(), body: Stack( diff --git a/lib/screens/rd orders/rd_processing_details.dart b/lib/screens/rd orders/rd_processing_details.dart index 219bf68..61642c3 100644 --- a/lib/screens/rd orders/rd_processing_details.dart +++ b/lib/screens/rd orders/rd_processing_details.dart @@ -123,8 +123,10 @@ class _RdOrderProcessingDetailScreenState extends State { ), ), ], - title: const Text("RD Processing Order"), + title: const Text("Retailer Processing Order"), ), drawer: MyDrawer(), body: Stack( diff --git a/lib/utils/common_api_service.dart b/lib/utils/common_api_service.dart index 393c373..2848224 100644 --- a/lib/utils/common_api_service.dart +++ b/lib/utils/common_api_service.dart @@ -5,7 +5,18 @@ import 'package:cheminova/utils/constants.dart'; import 'package:cheminova/utils/show_snackbar.dart'; import 'package:dio/dio.dart'; import 'package:shared_preferences/shared_preferences.dart'; + +import 'app_interceptor.dart'; + + +Dio createDio() { + final dio = Dio(); + dio.interceptors.add((AuthInterceptor())); + return dio; +} // Generic API service function that handles API requests with optional file uploads + + Future commonApiService({ required String url, required String method, @@ -18,7 +29,7 @@ Future commonApiService({ }) async { try { // Initialize Dio for making HTTP requests - Dio dio = Dio(); + Dio dio = createDio(); final Response response; print("body : $body"); diff --git a/lib/widgets/product_card.dart b/lib/widgets/product_card.dart index 9de1fda..41b75c9 100644 --- a/lib/widgets/product_card.dart +++ b/lib/widgets/product_card.dart @@ -1,8 +1,10 @@ +import 'package:cached_network_image/cached_network_image.dart'; import 'package:cheminova/controller/cart_controller.dart'; import 'package:cheminova/models/oder_place_model.dart'; import 'package:cheminova/models/order_item_model.dart'; import 'package:cheminova/models/place_order_list_model.dart'; import 'package:cheminova/models/product_model.dart'; +import 'package:cheminova/models/rd_get_order_model.dart'; import 'package:cheminova/screens/product/product_detail_screen.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -16,6 +18,7 @@ class ProductCard extends StatefulWidget { PlacedOrderModel? placedOrder; PlacedOrderList? placedOrderList; PlaceOrderItem1? placeorderItem; + PlacedOrdersResponse ? placeRDOrder; ProductModel? product; final bool isInCart; final bool isCheckout; @@ -30,6 +33,7 @@ class ProductCard extends StatefulWidget { this.placedOrder, this.placedOrderList, this.placeorderItem, + this.placeRDOrder, this.isInCart = false, this.isCheckout = false, this.isConfirmation = false, @@ -44,6 +48,7 @@ class _ProductCardState extends State { if (text.isEmpty) return text; return text[0].toUpperCase() + text.substring(1).toLowerCase(); } + String? imageurl; @override Widget build(BuildContext context) { @@ -53,155 +58,83 @@ class _ProductCardState extends State { // Get the current quantity of the product, either from the cart or the default value int currentQuantity = isProductInCart ? _cartController.cartList.firstWhere((p) => p.id == widget.productModel!.id).quantity - : widget.productModel!.quantity; - + : widget.productModel!.quantity ??1; + TextEditingController quantityController = + TextEditingController(text: currentQuantity.toString()); + imageurl = widget.productModel!.brand.images.isNotEmpty + ? widget.productModel!.brand.images[0].url + : 'assets/images/no_image_available.jpg'; // Use a fallback image URL or handle it accordingly return GestureDetector( // Navigate to the ProductDetailScreen on tap unless the product is in cart or checkout onTap: () => widget.isInCart || widget.isCheckout ? null : Get.to(() => ProductDetailScreen(productModel: widget.productModel)), - child: Card( - child: Row( - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: ClipRRect( - borderRadius: BorderRadius.circular(15.0), - child: Container( - height: Get.height * 0.15, - width: Get.width * 0.31, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage("assets/images/product.png"), - fit: BoxFit.cover, + child: SizedBox( + // height: Get.height * 0.21, + // width: Get.width *0.20, + child: Card( + child: Row( + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: ClipRRect( + borderRadius: BorderRadius.circular(15.0), + child: + Container( + height: Get.height * 0.18, + width: Get.width * 0.32, + decoration: BoxDecoration( + image: DecorationImage( + image: imageurl!.startsWith('http') + ? CachedNetworkImageProvider(imageurl!) as ImageProvider + : AssetImage(imageurl!), + fit: BoxFit.cover, + ), + ), + ), ), ), - ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 3.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Display the product name with the first letter capitalized - Text( - capitalizeFirstLetter(widget.productModel!.name), - style: GoogleFonts.roboto( - fontSize: 16, - fontWeight: FontWeight.w500, - ), - ), - // Display the category name of the product - Text( - capitalizeFirstLetter(widget.productModel!.category!.categoryName), - style: GoogleFonts.roboto( - fontSize: 14, - fontWeight: FontWeight.w400, - ), - ), - // Display the price of the product - Text( - "₹ ${widget.productModel!.price.toString()}", - style: GoogleFonts.roboto( - fontSize: 22, - fontWeight: FontWeight.w700, - ), - ), - if (showQuantity) + + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 0.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Display the product name with the first letter capitalized Text( - "Quantity: ${currentQuantity}", + capitalizeFirstLetter(widget.productModel!.name), style: GoogleFonts.roboto( - fontSize: 15, - fontWeight: FontWeight.w700, + fontSize: 16, + fontWeight: FontWeight.w500, ), ), - // Display quantity adjustment buttons and remove button if the product is in cart - if (!widget.isCheckout) - widget.isInCart - ? Row( + // Display the category name of the product + Text( + capitalizeFirstLetter(widget.productModel!.category!.categoryName), + style: GoogleFonts.roboto( + fontSize: 14, + fontWeight: FontWeight.w400, + ), + ), + // Display the price of the product + if (!widget.isCheckout) + widget.isInCart + ? + Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Container( - height: Get.height * 0.04, - width: Get.width * 0.21, - decoration: BoxDecoration( - color: const Color(0xFF004791), - borderRadius: BorderRadius.circular(10), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - SizedBox( - height: 24, - width: 24, - child: ElevatedButton( - onPressed: () { - _cartController.decreaseQuantity(widget.productModel!); - setState(() { - currentQuantity = _cartController - .cartList - .firstWhere((p) => p.id == widget.productModel!.id) - .quantity; - }); - }, - style: ElevatedButton.styleFrom( - padding: EdgeInsets.zero, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8.0), - ), - ), - child: Text( - '-', - style: GoogleFonts.roboto( - fontSize: 16, - fontWeight: FontWeight.w800, - ), - ), - ), - ), - Text( - "${currentQuantity}", - style: const TextStyle( - color: Colors.white, - fontSize: 16, - ), - ), - SizedBox( - height: 22, - width: 22, - child: ElevatedButton( - onPressed: () { - _cartController.increaseQuantity(widget.productModel!); - setState(() { - currentQuantity = _cartController - .cartList - .firstWhere((p) => p.id == widget.productModel!.id) - .quantity; - }); - }, - style: ElevatedButton.styleFrom( - padding: EdgeInsets.zero, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8.0), - ), - ), - child: Text( - '+', - style: GoogleFonts.roboto( - fontSize: 16, - fontWeight: FontWeight.w800, - ), - ), - ), - ), - ], + Text( + "₹ ${widget.productModel!.price.toString()}", + style: GoogleFonts.roboto( + fontSize: 20, + fontWeight: FontWeight.w700, ), ), - SizedBox( - width: 2.0, - ), + // SizedBox( + // width: 60, + // ), IconButton( onPressed: () { _cartController.removeFromCart(widget.productModel!); @@ -217,38 +150,462 @@ class _ProductCardState extends State { ), ], ) - : ElevatedButton( - onPressed: () { - if (isProductInCart) { - showSnackbar("Product already added to cart"); - } else { - _cartController.addToCart(widget.productModel!); - showSnackbar("Product successfully added to your cart"); - } - }, - style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: const Color(0xFF00784C), - padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 8), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(30), + :SizedBox(), + if (showQuantity) + SizedBox( + height: Get.height * 0.04, + child: Text( + "Quantity: ${currentQuantity}", + style: GoogleFonts.roboto( + color: Color(0xFF004791), + fontSize: 15, + fontWeight: FontWeight.w700, + ), ), ), - child: Text( - "Add To Cart", - style: GoogleFonts.roboto( - fontSize: 14, - fontWeight: FontWeight.w600, + // Display quantity adjustment buttons and remove button if the product is in cart + if (!widget.isCheckout) + widget.isInCart + ? + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + height: Get.height * 0.05, + width: Get.width * 0.40, + decoration: BoxDecoration( + color: const Color(0xFF004791), + borderRadius: BorderRadius.circular(10), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + SizedBox( + height: 25, + width: 25, + child: ElevatedButton( + onPressed: () { + _cartController.decreaseQuantity(widget.productModel!); + setState(() { + currentQuantity = _cartController + .cartList + .firstWhere((p) => p.id == widget.productModel!.id) + .quantity; + }); + }, + style: ElevatedButton.styleFrom( + padding: EdgeInsets.zero, + backgroundColor:Color(0xFF004791), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ), + ), + child: Text( + '-', + style: GoogleFonts.roboto( + color: Colors.white, + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + // Text( + // "${currentQuantity}", + // style: const TextStyle( + // color: Colors.white, + // fontSize: 16, + // ), + // Expanded( + // child: TextFormField( + // // decoration:InputDecoration( + // // border: InputBorder.none, + // // ), + // + // controller: quantityController, + // style: TextStyle(color: Color(0xFF004791),fontWeight: FontWeight.bold), + // keyboardType: TextInputType.number, + // + // textAlign: TextAlign.center, + // onFieldSubmitted: (value) { + // int enteredQuantity = int.tryParse(value) ?? currentQuantity; + // if (enteredQuantity <= 0) { + // showSnackbar("Quantity must be at least 1"); + // enteredQuantity = 1; + // } + // setState(() { + // currentQuantity = enteredQuantity; + // _cartController.updateQuantity( + // widget.productModel!, currentQuantity); + // }); + // }, + // decoration: const InputDecoration( + // + // contentPadding: EdgeInsets.only(left: 8.0,right: 8.0,bottom: 8.0), + // border: OutlineInputBorder( + // // + // ), + // ), + // ), + // ), + SizedBox(width: 5,), + Expanded( + child: TextFormField( + controller: quantityController, + style: const TextStyle( + color: Color(0xFF004791), + fontWeight: FontWeight.bold, + fontSize: 16, + ), + keyboardType: TextInputType.number, + textAlign: TextAlign.center, + onFieldSubmitted: (value) { + int enteredQuantity = int.tryParse(value) ?? currentQuantity; + if (enteredQuantity <= 0) { + showSnackbar("Quantity must be at least 1"); + enteredQuantity = 1; + } + setState(() { + currentQuantity = enteredQuantity; + _cartController.updateQuantity(widget.productModel!, currentQuantity); + }); + }, + decoration: InputDecoration( + labelText: "Enter Quantity", + labelStyle: const TextStyle( + color: Color(0xFF004791), + fontWeight: FontWeight.w600, + fontSize: 14, + ), + hintText: "", + hintStyle: const TextStyle( + color: Colors.grey, + fontWeight: FontWeight.w400, + fontSize: 14, + ), + filled: true, + fillColor: Colors.white, + contentPadding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 16.0), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: const BorderSide( + color: Color(0xFF004791), + width: 1.5, + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: const BorderSide( + color: Color(0xFF004791), + width: 2, + ), + ), + errorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: const BorderSide( + color: Colors.red, + width: 1.5, + ), + ), + focusedErrorBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: const BorderSide( + color: Colors.red, + width: 2, + ), + ), + ), + ), + ), + SizedBox(width: 5,), + SizedBox( + height: 25, + width: 25, + child: ElevatedButton( + onPressed: () { + _cartController.increaseQuantity(widget.productModel!); + setState(() { + currentQuantity = _cartController + .cartList + .firstWhere((p) => p.id == widget.productModel!.id) + .quantity; + }); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Color(0xFF004791), + padding: EdgeInsets.zero, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ), + ), + child: Text( + '+', + style: GoogleFonts.roboto( + color: Colors.white, + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ], + ), + ), + SizedBox( + width: 1.0, + ), + // IconButton( + // onPressed: () { + // _cartController.removeFromCart(widget.productModel!); + // showSnackbar("Product has been removed successfully!"); + // setState(() { + // currentQuantity = 1; + // }); + // }, + // icon: const Icon( + // Icons.delete_outline_rounded, + // color: Colors.red, + // ), + // ), + ], + ) + : ElevatedButton( + onPressed: () { + if (isProductInCart) { + showSnackbar("Product already added to cart"); + } else { + _cartController.addToCart(widget.productModel!); + showSnackbar("Product successfully added to your cart"); + } + }, + style: ElevatedButton.styleFrom( + foregroundColor: Colors.white, + backgroundColor: const Color(0xFF00784C), + padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 8), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + ), + ), + child: Text( + "Add To Cart", + style: GoogleFonts.roboto( + fontSize: 14, + fontWeight: FontWeight.w600, + ), ), ), - ), - ], + ], + ), ), ), - ), - ], + ], + ), ), ), ); } } + + + + + +// +// class ProductCard extends StatefulWidget { +// final Product? productModel; +// PlacedOrderModel? placedOrder; +// PlacedOrderList? placedOrderList; +// PlaceOrderItem1? placeorderItem; +// PlacedOrdersResponse ? placeRDOrder; +// ProductModel? product; +// final bool isInCart; +// final bool isCheckout; +// final bool isConfirmation; +// int? quantity; +// +// ProductCard({ +// super.key, +// this.product, +// this.quantity = 1, +// this.productModel, +// this.placedOrder, +// this.placedOrderList, +// this.placeorderItem, +// this.placeRDOrder, +// this.isInCart = false, +// this.isCheckout = false, +// this.isConfirmation = false, +// }); +// +// @override +// State createState() => _ProductCardState(); +// } +// +// class _ProductCardState extends State { +// final CartController _cartController = Get.put(CartController()); +// +// String capitalizeFirstLetter(String text) { +// if (text.isEmpty) return text; +// return text[0].toUpperCase() + text.substring(1).toLowerCase(); +// } +// +// @override +// Widget build(BuildContext context) { +// bool showQuantity = widget.isInCart || widget.isCheckout || widget.isConfirmation; +// bool isProductInCart = _cartController.cartList.any((p) => p.id == widget.productModel!.id); +// +// // Get the current quantity of the product +// int currentQuantity = isProductInCart +// ? _cartController.cartList.firstWhere((p) => p.id == widget.productModel!.id).quantity +// : widget.productModel!.quantity ?? 1; +// +// TextEditingController quantityController = +// TextEditingController(text: currentQuantity.toString()); +// +// return GestureDetector( +// onTap: () => widget.isInCart || widget.isCheckout +// ? null +// : Get.to(() => ProductDetailScreen(productModel: widget.productModel)), +// child: Card( +// child: Row( +// children: [ +// Padding( +// padding: const EdgeInsets.all(8.0), +// child: ClipRRect( +// borderRadius: BorderRadius.circular(15.0), +// child: Container( +// height: Get.height * 0.15, +// width: Get.width * 0.31, +// decoration: const BoxDecoration( +// image: DecorationImage( +// image: AssetImage("assets/images/product.png"), +// fit: BoxFit.cover, +// ), +// ), +// ), +// ), +// ), +// Expanded( +// child: Padding( +// padding: const EdgeInsets.symmetric(horizontal: 3.0), +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Text( +// capitalizeFirstLetter(widget.productModel!.name), +// style: GoogleFonts.roboto( +// fontSize: 16, +// fontWeight: FontWeight.w500, +// ), +// ), +// Text( +// capitalizeFirstLetter(widget.productModel!.category!.categoryName), +// style: GoogleFonts.roboto( +// fontSize: 14, +// fontWeight: FontWeight.w400, +// ), +// ), +// Text( +// "₹ ${widget.productModel!.price.toString()}", +// style: GoogleFonts.roboto( +// fontSize: 22, +// fontWeight: FontWeight.w700, +// ), +// ), +// if (showQuantity) +// Row( +// children: [ +// SizedBox( +// width: 50, +// child: TextFormField( +// controller: quantityController, +// keyboardType: TextInputType.number, +// textAlign: TextAlign.center, +// onFieldSubmitted: (value) { +// int enteredQuantity = int.tryParse(value) ?? currentQuantity; +// if (enteredQuantity <= 0) { +// showSnackbar("Quantity must be at least 1"); +// enteredQuantity = 1; +// } +// setState(() { +// currentQuantity = enteredQuantity; +// _cartController.updateQuantity( +// widget.productModel!, currentQuantity); +// }); +// }, +// decoration: const InputDecoration( +// contentPadding: EdgeInsets.all(8), +// border: OutlineInputBorder(), +// ), +// ), +// ), +// IconButton( +// onPressed: () { +// _cartController.decreaseQuantity(widget.productModel!); +// setState(() { +// currentQuantity = _cartController +// .cartList +// .firstWhere((p) => p.id == widget.productModel!.id) +// .quantity; +// quantityController.text = currentQuantity.toString(); +// }); +// }, +// icon: const Icon(Icons.remove), +// ), +// IconButton( +// onPressed: () { +// _cartController.increaseQuantity(widget.productModel!); +// setState(() { +// currentQuantity = _cartController +// .cartList +// .firstWhere((p) => p.id == widget.productModel!.id) +// .quantity; +// quantityController.text = currentQuantity.toString(); +// }); +// }, +// icon: const Icon(Icons.add), +// ), +// ], +// ), +// if (!widget.isCheckout) +// widget.isInCart +// ? Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// ElevatedButton( +// onPressed: () { +// _cartController.removeFromCart(widget.productModel!); +// showSnackbar("Product removed successfully!"); +// setState(() { +// currentQuantity = 1; +// quantityController.text = currentQuantity.toString(); +// }); +// }, +// style: ElevatedButton.styleFrom( +// backgroundColor: Colors.red, +// ), +// child: const Text("Remove"), +// ), +// ], +// ) +// : ElevatedButton( +// onPressed: () { +// if (isProductInCart) { +// showSnackbar("Product already added to cart"); +// } else { +// _cartController.addToCart(widget.productModel!); +// showSnackbar("Product added to cart successfully!"); +// } +// }, +// child: const Text("Add To Cart"), +// ), +// ], +// ), +// ), +// ), +// ], +// ), +// ), +// ); +// } +// } diff --git a/lib/widgets/product_card1.dart b/lib/widgets/product_card1.dart index f0119e4..ac76ff7 100644 --- a/lib/widgets/product_card1.dart +++ b/lib/widgets/product_card1.dart @@ -1,3 +1,4 @@ +import 'package:cached_network_image/cached_network_image.dart'; import 'package:cheminova/controller/cart_controller.dart'; import 'package:cheminova/controller/rd_get_order_controller.dart'; import 'package:cheminova/models/rd_get_order_model.dart'; @@ -5,6 +6,8 @@ import 'package:cheminova/models/rd_order_item_model.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:google_fonts/google_fonts.dart'; + +import '../utils/show_snackbar.dart'; class ProductCard1 extends StatefulWidget { final RDOrderItem productModel; // The specific product to be displayed int? quantity; @@ -24,16 +27,20 @@ class _ProductCard1State extends State { if (text.isEmpty) return text; return text[0].toUpperCase() + text.substring(1).toLowerCase(); } - + String? imageurl; @override Widget build(BuildContext context) { final CartController _cartController = Get.put(CartController()); - + TextEditingController quantityController = + TextEditingController(); // Current quantity the user wants to process int processQuantity = widget.productModel.processquantity ?? 1; // Total available quantity int availableQuantity = widget.productModel.remainingQuantity ?? 1; + imageurl = widget.productModel.image.isNotEmpty + ? widget.productModel.image[0].url + : 'assets/images/no_image_available.jpg'; return Card( child: Row( @@ -45,9 +52,12 @@ class _ProductCard1State extends State { child: Container( height: Get.height * 0.15, width: Get.width * 0.31, - decoration: const BoxDecoration( + decoration: BoxDecoration( image: DecorationImage( - image: AssetImage("assets/images/product.png"), + image: + imageurl!.startsWith('http') + ? CachedNetworkImageProvider(imageurl!) as ImageProvider + : AssetImage(imageurl!), fit: BoxFit.cover, ), ), @@ -158,6 +168,39 @@ class _ProductCard1State extends State { fontSize: 16, ), ), + + // Expanded( + // child: TextFormField( + // // decoration:InputDecoration( + // // border: InputBorder.none, + // // ), + // + // controller: quantityController, + // style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold), + // keyboardType: TextInputType.number, + // + // textAlign: TextAlign.center, + // onFieldSubmitted: (value) { + // int enteredQuantity = int.tryParse(value) ?? processQuantity; + // if (enteredQuantity <= 0) { + // showSnackbar("Quantity must be at least 1"); + // enteredQuantity = 1; + // } + // // setState(() { + // // // widget.productModel.processquantity = enteredQuantity; + // // // // _cartController.updateQuantity( + // // // // widget.productModel.processquantity!, processQuantity); + // // processQuantity = enteredQuantity; + // // widget.productModel.processquantity = processQuantity; + // // }); + // }, + // decoration: const InputDecoration( + // + // contentPadding: EdgeInsets.only(left: 8.0,right: 8.0,bottom: 8.0), + // // border: OutlineInputBorder(), + // ), + // ), + // ), // Increase quantity button SizedBox( height: 22, diff --git a/pubspec.yaml b/pubspec.yaml index 96dc2ac..9d1f0bf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 2.0.1+1 +version: 2.0.2+1 environment: sdk: ">=3.4.1 <4.0.0"