From ef6ef970bbbac5ae3902a04309379c0ad04510bf Mon Sep 17 00:00:00 2001 From: saritabirare Date: Tue, 15 Oct 2024 10:28:22 +0530 Subject: [PATCH] 1) annaucement api integration done --- lib/controller/annaucement_controller.dart | 27 + lib/controller/annaucement_service.dart | 26 + .../get_single_invoice_Service.dart | 66 +- .../get_single_invoice_controller.dart | 63 +- lib/controller/rd_get_single_service.dart | 116 ++- lib/controller/rd_processing_service.dart | 4 +- .../rd_single_order_controller.dart | 137 ++- lib/models/annauncement_model.dart | 28 + lib/models/get_invoice_model.dart | 351 +++---- lib/models/rd_order_item_model.dart | 4 +- lib/models/single_get_order_model.dart | 123 +-- lib/screens/annauncement/annauncement.dart | 105 ++ lib/screens/home_screen.dart | 13 +- .../rd orders/partial_pending_dialog.dart | 22 +- .../partial_processing_dialog_screen.dart | 284 ++--- .../rd_cancelled_details_screen.dart | 48 +- .../rd orders/rd_cancelled_screen.dart | 16 +- .../rd_delivered_details_screen.dart | 11 +- .../rd_dispatched_details_screen.dart | 8 +- .../rd orders/rd_order_details_screen.dart | 8 +- .../rd orders/rd_order_details_update.dart | 756 ++++++++++++++ lib/screens/rd orders/rd_order_screen.dart | 372 +++++-- lib/screens/rd orders/rd_pending_deatils.dart | 87 +- lib/screens/rd orders/rd_pending_screen.dart | 86 +- .../rd orders/rd_processing_details.dart | 981 +++++++++--------- .../rd orders/rd_processing_screen.dart | 74 +- lib/utils/api_urls.dart | 5 + 27 files changed, 2660 insertions(+), 1161 deletions(-) create mode 100644 lib/controller/annaucement_controller.dart create mode 100644 lib/controller/annaucement_service.dart create mode 100644 lib/models/annauncement_model.dart create mode 100644 lib/screens/annauncement/annauncement.dart create mode 100644 lib/screens/rd orders/rd_order_details_update.dart diff --git a/lib/controller/annaucement_controller.dart b/lib/controller/annaucement_controller.dart new file mode 100644 index 0000000..6b928f3 --- /dev/null +++ b/lib/controller/annaucement_controller.dart @@ -0,0 +1,27 @@ +import 'package:get/get.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import '../models/annauncement_model.dart'; +import 'annaucement_service.dart'; + +class AnnouncementController extends GetxController { + final AnnouncementService _announcementService = AnnouncementService(); + var announcements = [].obs; + var isLoading = true.obs; + var errorMessage = ''.obs; + + Future fetchAnnouncements() async { + isLoading.value = true; + try { + SharedPreferences prefs = await SharedPreferences.getInstance(); + String? token = prefs.getString('token'); + final List? fetchedAnnouncements = + await _announcementService.fetchAnnouncements(token!); + announcements.assignAll(fetchedAnnouncements as Iterable); + } catch (e) { + errorMessage.value = e.toString(); + } finally { + isLoading.value = false; + } + } +} diff --git a/lib/controller/annaucement_service.dart b/lib/controller/annaucement_service.dart new file mode 100644 index 0000000..7da95a1 --- /dev/null +++ b/lib/controller/annaucement_service.dart @@ -0,0 +1,26 @@ +import 'package:cheminova/utils/api_urls.dart'; +import 'package:dio/dio.dart'; + +import '../models/annauncement_model.dart'; + +class AnnouncementService { + final Dio _dio = Dio(); + + Future> fetchAnnouncements(String token) async { + final String url = ApiUrls.AnnaouncementUrl; + try { + _dio.options.headers['Authorization'] = 'Bearer $token'; + final Response response = await _dio.get(url); + + if (response.statusCode == 200) { + + List data = response.data; + return data.map((announcement) => AnnouncementModel.fromJson(announcement)).toList(); + } else { + throw Exception('Failed to load announcements'); + } + } catch (e) { + throw Exception('Error occurred while fetching announcements: $e'); + } + } +} diff --git a/lib/controller/get_single_invoice_Service.dart b/lib/controller/get_single_invoice_Service.dart index fa2530b..a939cd6 100644 --- a/lib/controller/get_single_invoice_Service.dart +++ b/lib/controller/get_single_invoice_Service.dart @@ -1,33 +1,59 @@ import 'package:dio/dio.dart'; import '../models/get_invoice_model.dart'; -import '../utils/api_urls.dart'; import '../utils/common_api_service.dart'; +import '../utils/show_snackbar.dart'; + +class GetSingleInvoiceService { + Dio _dio = Dio(); -class GetSingleInvoiceService{ - final Dio _dio = Dio(); Future fetchInvoice(String token, String invoiceId) async { - final url = 'https://api.cnapp.co.in/api/pd-get-invoices/$invoiceId'; - try { - final response = await _dio.get( - url, - options: Options( - headers: { - 'Authorization': 'Bearer $token', - }, - ) + // Ensure the base URL and orderId are concatenated properly + String url = "/api/pd-get-invoices/$invoiceId"; + + final response = await commonApiService( + method: "GET", + url: url, + additionalHeaders: { + 'Authorization': 'Bearer $token', // Correctly pass the token as 'Bearer ' + }, + fromJson: (json) { + // Pass the entire JSON response to the fromJson method of GetInvoiceModel + return GetInvoiceModel.fromJson(json as Map); + }, ); - if (response.statusCode == 200) { - return GetInvoiceModel.fromJson(response.data); - } else { - throw Exception('Failed to load invoice'); - } + return response; // Return the fetched invoice if successful } catch (e) { - print(e); // Handle error here - return null; + // Show a snackbar with the error message + showSnackbar(e.toString()); + return null; // Return null to indicate an error occurred } } -} \ No newline at end of file + +// Future fetchInvoice(String token, String invoiceId) async { + // try { + // final response = await _dio.get( + // 'https://api.cnapp.co.in/api/pd-get-invoices/$invoiceId', + // options: Options( + // headers: { + // 'Authorization': 'Bearer $token', + // }, + // ), + // ); + // + // // Check if the response data is not null and status code is 200 + // if (response.statusCode == 200 && response.data != null) { + // return GetInvoiceModel.fromJson(response.data); // Parse the response + // } else { + // print('Invoice not found or server error'); + // return null; // Return null if data is not as expected + // } + // } catch (e) { + // print('Error fetching invoice: $e'); + // return null; // Return null if there is an error + // } + // } +} diff --git a/lib/controller/get_single_invoice_controller.dart b/lib/controller/get_single_invoice_controller.dart index 69f696e..b7354c6 100644 --- a/lib/controller/get_single_invoice_controller.dart +++ b/lib/controller/get_single_invoice_controller.dart @@ -1,7 +1,10 @@ +import 'package:cheminova/controller/rd_processing_invoice_service.dart'; import 'package:cheminova/models/get_invoice_model.dart'; import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import '../models/rd_processing_invoice_model.dart'; +import '../utils/show_snackbar.dart'; import 'get_single_invoice_Service.dart'; class GetSingleInvoiceController extends GetxController { @@ -24,15 +27,63 @@ class GetSingleInvoiceController extends GetxController { try { SharedPreferences prefs = await SharedPreferences.getInstance(); String? token = prefs.getString('token'); - invoice.value = (await GetSingleInvoiceService().fetchInvoice(token!,invoiceId)) - as List; - if (invoice.value == null) { - errorMessage.value = 'Invoice not found'; + final List? allOrders = await RdProcessingInvoiceService().getRDProcessingProduct(token!); + + // Check if the token is null or empty + if (token == null || token.isEmpty) { + errorMessage.value = 'Token not found'; // Handle token not being available + return; } - } catch (e) { - errorMessage.value = e.toString(); // Set the error message + + + + + if (allOrders == null || allOrders.isEmpty) { + print("No orders found."); + showSnackbar("No orders found."); + return; + } + + // Display the number of fetched orders + print("Fetched ${allOrders.length} orders."); + + // Get the ID of the first order and convert it to a String + final String firstOrderId = allOrders[0].id.toString(); // Convert to String + print("First order ID: $firstOrderId"); // Debugging: Log the order ID + + // Fetch the single order using the first order ID + final GetInvoiceModel? result = await GetSingleInvoiceService().fetchInvoice(token, firstOrderId); + + // Check if the result is not null + if (result != null) { + // Here, you should add the single order to your observable list + invoice.clear(); // Clear the previous data if necessary + invoice.add(result); // Add the single order to the list + } else { + // If the result is null, you can clear the list + invoice.clear(); + } + + // For debugging, log the fetched orders count + print("Fetched orders count: ${invoice.length}"); + } + + // Attempt to fetch the invoice + // final fetchedInvoice = await GetSingleInvoiceService().fetchInvoice(token, invoiceId); + + // Check if the fetchedInvoice is null before accessing it + // if (fetchedInvoice != null) { + // invoice.value = fetchedInvoice as List; // Assign the fetched invoice to the observable + // } else { + // errorMessage.value = 'Invoice not found'; // Handle the case where the invoice could not be fetched + // } + // } + catch (e) { + errorMessage.value = 'Error fetching invoice: $e'; // Set the error message with more context } finally { isLoading.value = false; // Set loading state to false } } + + } diff --git a/lib/controller/rd_get_single_service.dart b/lib/controller/rd_get_single_service.dart index 7158a88..6b2dd3d 100644 --- a/lib/controller/rd_get_single_service.dart +++ b/lib/controller/rd_get_single_service.dart @@ -1,73 +1,77 @@ -import 'dart:convert'; + import 'package:cheminova/models/single_get_order_model.dart'; import 'package:dio/dio.dart'; -import '../models/rd_get_order_model.dart'; -import '../utils/api_urls.dart'; import '../utils/common_api_service.dart'; import '../utils/show_snackbar.dart'; -class GetSingleProductService{ - // Future getSingleOrder(String token,String orderId) async { - // try { - // // Ensure the base URL and orderId are concatenated properly - // String url = "/api/pd-get-single-place-order/$orderId"; - // - // final response = await commonApiService( - // method: "GET", - // url: url, - // additionalHeaders: { - // 'Authorization': 'Bearer $token', // Correctly pass the token as 'Bearer ' - // }, - // fromJson: (json) { - // // Check if the JSON response contains the 'singleOrder' key - // if (json['singleOrder'] != null) { - // // Convert the JSON response to a SingleGetOrderModel - // return SingleGetOrderModel.fromJson(json['singleOrder'] as Map); - // } else { - // // Handle the case when the order is not found - // throw Exception("Order not found in response."); - // } - // }, - // ); - // - // return response; // Return the fetched order if successful - // } catch (e) { - // // Show a snackbar with the error message - // showSnackbar(e.toString()); - // return null; // Return null to indicate an error occurred - // } - // } - - - -Future GetsingleOrder(String token,String orderId) async { +class GetSingleProductService { + Future getSingleOrder(String token,String orderId) async { try { - final response = await Dio().get( - 'https://api.cnapp.co.in/api/pd-get-single-place-order/$orderId', + // Ensure the base URL and orderId are concatenated properly + String url = "/api/pd-get-single-place-order/$orderId"; - options: Options( - headers: { - 'Authorization': 'Bearer $token', - }, - ), + final response = await commonApiService( + method: "GET", + url: url, + additionalHeaders: { + 'Authorization': 'Bearer $token', // Correctly pass the token as 'Bearer ' + }, + fromJson: (json) { + // Check if the JSON response contains the 'singleOrder' key + if (json['singleOrder'] != null) { + // Convert the JSON response to a SingleGetOrderModel + return SingleGetOrderModel.fromJson(json['singleOrder'] as Map); + } else { + // Handle the case when the order is not found + throw Exception("Order not found in response."); + } + }, ); - - if (response.statusCode == 200) { - final data = response.data['singleOrder']; - jsonDecode(data); - return SingleGetOrderModel.fromJson(data); - } else { - print('Failed to load order'); - return null; - } + return response; // Return the fetched order if successful } catch (e) { - print('Error: $e'); - return null; + // Show a snackbar with the error message + showSnackbar(e.toString()); + return null; // Return null to indicate an error occurred } } + // + // Future fetchSingleOrder(String token, + // String orderId) async { + // final String url = 'https://api.cnapp.co.in/api/pd-get-single-place-order/$orderId'; + // + // try { + // Response response = await Dio().get( + // url, + // options: Options( + // headers: { + // 'Authorization': 'Bearer $token', + // 'Content-Type': 'application/json', + // }, + // ), + // ); + // + // if (response.statusCode == 200 && response.data != null) { + // // Check if 'singleOrder' is present in the response + // final singleOrderData = response.data['singleOrder']; + // + // if (singleOrderData != null) { + // return SingleGetOrderModel.fromJson(singleOrderData); + // } else { + // print('No single order data found in response.'); + // return null; + // } + // } else { + // print('Failed to load order data: ${response.statusCode}'); + // return null; + // } + // } catch (e) { + // print('Error fetching order data: $e'); + // return null; + // } + // } } \ No newline at end of file diff --git a/lib/controller/rd_processing_service.dart b/lib/controller/rd_processing_service.dart index 39d1e32..1760b35 100644 --- a/lib/controller/rd_processing_service.dart +++ b/lib/controller/rd_processing_service.dart @@ -30,7 +30,9 @@ class RDOrderPlacedService { if (response.statusCode != 200) { throw Exception('Failed to RD place order'); } - + else if(response.statusCode != 200 && response.statusCode == 400){ + showSnackbar("stock not Available"); + } } Future RDOrderCancel(String token, String orderId, String reason) async { diff --git a/lib/controller/rd_single_order_controller.dart b/lib/controller/rd_single_order_controller.dart index 041d3a2..d31b3ba 100644 --- a/lib/controller/rd_single_order_controller.dart +++ b/lib/controller/rd_single_order_controller.dart @@ -1,52 +1,115 @@ import 'dart:convert'; +import 'package:cheminova/controller/rd_get_order_service.dart'; import 'package:cheminova/controller/rd_get_single_service.dart'; import 'package:cheminova/models/single_get_order_model.dart'; import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import '../models/rd_get_order_model.dart'; import '../utils/show_snackbar.dart'; class RdSingleOrderController extends GetxController { var isLoading = true.obs; // Tracks the loading state var productRDOrderSingleList = [].obs; // List of products + // + Future fetchAllOrdersAndSingleOrder() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + String? token = prefs.getString('token'); - Future fetchRDSingleOrderProduct(String id) async { - try { - SharedPreferences prefs = await SharedPreferences.getInstance(); - String? token = prefs.getString('token'); + final List? allOrders = await GetProductRDService().getRDProducts(token!); - // Check if the token exists before proceeding - if (token == null || token.isEmpty) { - print("Token is missing"); - throw Exception("Token is missing"); - } - - print("Login token: $token"); - isLoading(true); // Start loading - - // Check if the list has any elements - if (productRDOrderSingleList.isEmpty) { - print("No orders found."); - showSnackbar("No orders found."); - return; // Early exit if no orders are available - } - - // Fetch the product using the API call, passing the token - final response = await GetSingleProductService().GetsingleOrder(token, id); - - if (response != null) { - // Assign the fetched products to the observable list (uncomment this if needed) - // productRDOrderSingleList.assignAll(response); - print("Fetched order details: $response"); - } else { - print("Response is null"); - showSnackbar("Response is null"); - } - } catch (e) { - // Print the error for debugging - print("Error: $e"); - showSnackbar("Error: $e"); - } finally { - isLoading(false); // End loading + if (allOrders == null || allOrders.isEmpty) { + print("No orders found."); + showSnackbar("No orders found."); + return; } + + // Display the number of fetched orders + print("Fetched ${allOrders.length} orders."); + + // Get the ID of the first order and convert it to a String + final String firstOrderId = allOrders[0].id.toString(); // Convert to String + print("First order ID: $firstOrderId"); // Debugging: Log the order ID + + // Fetch the single order using the first order ID + final SingleGetOrderModel? result = await GetSingleProductService().getSingleOrder(token!, firstOrderId); + + // Check if the result is not null + if (result != null) { + // Here, you should add the single order to your observable list + productRDOrderSingleList.clear(); // Clear the previous data if necessary + productRDOrderSingleList.add(result); // Add the single order to the list + } else { + // If the result is null, you can clear the list + productRDOrderSingleList.clear(); + } + + // For debugging, log the fetched orders count + print("Fetched orders count: ${productRDOrderSingleList.length}"); } + + + + // + // Future fetchAllOrdersAndSingleOrder() async { + // try { + // // Fetch all orders from your API + // SharedPreferences prefs = await SharedPreferences.getInstance(); + // String? token = prefs.getString('token'); + // final response = await GetProductRDService().getRDProducts(token!); // Adjust as per your API + // + // if (response != null && response.isNotEmpty) { + // productRDOrderSingleList.value = jsonDecode(response.toString()); // Assuming response is a List of orders + // } else { + // productRDOrderSingleList; + // } + // } catch (e) { + // print('Error fetching orders: $e'); + // productRDOrderSingleList; // Ensure the list is empty on error + // } + // } + + } + + // Future fetchAllOrdersAndSingleOrder(String id) async { + // SharedPreferences prefs = await SharedPreferences.getInstance(); + // String? token = prefs.getString('token'); + // + // final List? allOrders = await GetProductRDService().getRDProducts(token!); + // + // if (allOrders == null || allOrders.isEmpty) { + // print("No orders found."); + // showSnackbar("No orders found."); + // return; + // } + // + // // Display the number of fetched orders + // print("Fetched ${allOrders.length} orders."); + // + // // Fetch the single order using the provided selectedOrderId + // String orderIdToFetch = allOrders[0].id.toString(); // Use provided ID or first order ID + // print("Fetching order ID: $orderIdToFetch"); // Debugging: Log the order ID + // + // final result = (await GetSingleProductService().getSingleOrder(token, orderIdToFetch)) ; + // + // // Check if the result is not null + // if (result != null) { + // // Here, you should add the single order to your observable list + // productRDOrderSingleList.clear(); // Clear the previous data if necessary + // productRDOrderSingleList.add(result); // Add the single order to the list + // } else { + // // If the result is null, you can clear the list + // productRDOrderSingleList.clear(); + // } + // + // // For debugging, log the fetched orders count + // print("Fetched orders count: ${productRDOrderSingleList.length}"); + // } + + + + + + + + diff --git a/lib/models/annauncement_model.dart b/lib/models/annauncement_model.dart new file mode 100644 index 0000000..0ab22d6 --- /dev/null +++ b/lib/models/annauncement_model.dart @@ -0,0 +1,28 @@ +class AnnouncementModel { + final String id; + final String uniqueId; + final List sentTo; + final String message; + final DateTime createdAt; + final DateTime updatedAt; + + AnnouncementModel({ + required this.id, + required this.uniqueId, + required this.sentTo, + required this.message, + required this.createdAt, + required this.updatedAt, + }); + + factory AnnouncementModel.fromJson(Map json) { + return AnnouncementModel( + id: json['_id']??"", + uniqueId: json['uniqueId']??"", + sentTo: List.from(json['sentTo']), + message: json['message']??"", + createdAt: DateTime.parse(json['createdAt']), + updatedAt: DateTime.parse(json['updatedAt']), + ); + } +} diff --git a/lib/models/get_invoice_model.dart b/lib/models/get_invoice_model.dart index 3bb1c8a..f25560e 100644 --- a/lib/models/get_invoice_model.dart +++ b/lib/models/get_invoice_model.dart @@ -1,243 +1,244 @@ class GetInvoiceModel { - CourierStatusTimeline courierStatusTimeline; - String id; - String invoiceId; - OrderId orderId; - List items; - int subtotal; - double gstTotal; - double invoiceAmount; - String courierStatus; - int v; + CourierStatusTimeline? courierStatusTimeline; + String? id; + String? invoiceId; + OrderId? orderId; + List? items; + int? subtotal; + double? gstTotal; + double? invoiceAmount; + String? courierStatus; + int? v; GetInvoiceModel({ - required this.courierStatusTimeline, - required this.id, - required this.invoiceId, - required this.orderId, - required this.items, - required this.subtotal, - required this.gstTotal, - required this.invoiceAmount, - required this.courierStatus, - required this.v, + this.courierStatusTimeline, + this.id, + this.invoiceId, + this.orderId, + this.items, + this.subtotal, + this.gstTotal, + this.invoiceAmount, + this.courierStatus, + this.v, }); factory GetInvoiceModel.fromJson(Map json) { return GetInvoiceModel( - courierStatusTimeline: CourierStatusTimeline.fromJson( - json['courierstatus_timeline']), - id: json['_id'], - invoiceId: json['invoiceId'], - orderId: OrderId.fromJson(json['orderId']), - items: List.from(json['items'].map((item) => Item.fromJson(item))), - subtotal: json['subtotal'], - gstTotal: json['gstTotal'].toDouble(), - invoiceAmount: json['invoiceAmount'].toDouble(), - courierStatus: json['courierStatus'], - v: json['__v'], + courierStatusTimeline: json['courierstatus_timeline'] != null + ? CourierStatusTimeline.fromJson(json['courierstatus_timeline']) + : null, + id: json['_id'].toString() ?? '', + invoiceId: json['invoiceId'].toString() ?? '', + orderId: json['orderId'] != null ? OrderId.fromJson(json['orderId']) : null, + items: (json['items'] as List?)?.map((item) => Item.fromJson(item)).toList() ?? [], + subtotal: json['subtotal']?? 0, + gstTotal: json['gstTotal']?.toDouble() ?? 0.0, + invoiceAmount: json['invoiceAmount']?.toDouble() ?? 0.0, + courierStatus: json['courierStatus'].toString() ?? 'processing', + v: json['__v'] ?? 0, ); } } class CourierStatusTimeline { - String processing; + String? processing; CourierStatusTimeline({ - required this.processing, + this.processing, }); factory CourierStatusTimeline.fromJson(Map json) { return CourierStatusTimeline( - processing: json['processing'], + processing: json['processing'] ?? '', ); } } class OrderId { - String id; - String paymentMode; - String shipTo; - String billTo; - List orderItems; - int subtotal; - double gstTotal; - double grandTotal; - String status; - List invoices; - AddedBy addedBy; - String pd; - bool isCancelled; - bool isDelivered; - String deliveredDate; - String statusUpdatedAt; - String uniqueId; - String createdAt; - String updatedAt; - int v; + String? id; + String? paymentMode; + String? shipTo; + String? billTo; + List? orderItems; + int? subtotal; + double? gstTotal; + double? grandTotal; + String? status; + List? invoices; + AddedBy? addedBy; + String? pd; + bool? isCancelled; + bool? isDelivered; + String? deliveredDate; + String? statusUpdatedAt; + String? uniqueId; + String? createdAt; + String? updatedAt; + int? v; OrderId({ - required this.id, - required this.paymentMode, - required this.shipTo, - required this.billTo, - required this.orderItems, - required this.subtotal, - required this.gstTotal, - required this.grandTotal, - required this.status, - required this.invoices, - required this.addedBy, - required this.pd, - required this.isCancelled, - required this.isDelivered, - required this.deliveredDate, - required this.statusUpdatedAt, - required this.uniqueId, - required this.createdAt, - required this.updatedAt, - required this.v, + this.id, + this.paymentMode, + this.shipTo, + this.billTo, + this.orderItems, + this.subtotal, + this.gstTotal, + this.grandTotal, + this.status, + this.invoices, + this.addedBy, + this.pd, + this.isCancelled, + this.isDelivered, + this.deliveredDate, + this.statusUpdatedAt, + this.uniqueId, + this.createdAt, + this.updatedAt, + this.v, }); factory OrderId.fromJson(Map json) { return OrderId( - id: json['_id'], - paymentMode: json['paymentMode'], - shipTo: json['shipTo'], - billTo: json['billTo'], - orderItems: List.from(json['orderItem'].map((item) => OrderItem.fromJson(item))), - subtotal: json['subtotal'], - gstTotal: json['gstTotal'].toDouble(), - grandTotal: json['grandTotal'].toDouble(), - status: json['status'], - invoices: List.from(json['invoices']), - addedBy: AddedBy.fromJson(json['addedBy']), - pd: json['pd'], - isCancelled: json['iscancelled'], - isDelivered: json['isDelivered'], - deliveredDate: json['DeliveredDate'] ?? '', - statusUpdatedAt: json['statusUpdatedAt'], - uniqueId: json['uniqueId'], - createdAt: json['createdAt'], - updatedAt: json['updatedAt'], - v: json['__v'], + id: json['_id'].toString() ?? '', + paymentMode: json['paymentMode'].toString() ?? '', + shipTo: json['shipTo'].toString() ?? '', + billTo: json['billTo'].toString() ?? '', + orderItems: (json['orderItem'] as List?)?.map((item) => OrderItem.fromJson(item)).toList() ?? [], + subtotal: json['subtotal'] ?? 0, + gstTotal: json['gstTotal']?.toDouble() ?? 0.0, + grandTotal: json['grandTotal']?.toDouble() ?? 0.0, + status: json['status'].toString()?? '', + invoices: List.from(json['invoices'] ?? []), + addedBy: json['addedBy'] != null ? AddedBy.fromJson(json['addedBy']) : null, + pd: json['pd'].toString() ?? '', + isCancelled: json['iscancelled'] ?? false, + isDelivered: json['isDelivered'] ?? false, + deliveredDate: json['DeliveredDate']?? '', + statusUpdatedAt: json['statusUpdatedAt'] ?? '', + uniqueId: json['uniqueId'].toString() ?? '', + createdAt: json['createdAt'] ?? '', + updatedAt: json['updatedAt'] ?? '', + v: json['__v'] ?? 0, ); } } class OrderItem { - String productId; - String sku; - String name; - String categoryName; - String brandName; - int price; - int gst; - int hsnCode; - String description; - List image; - int quantity; - int remainingQuantity; - String id; + String? productId; + String? sku; + String? name; + String? categoryName; + String? brandName; + int? price; + int? gst; + int? hsnCode; + String? description; + List? image; + int? quantity; + int? remainingQuantity; + String? id; OrderItem({ - required this.productId, - required this.sku, - required this.name, - required this.categoryName, - required this.brandName, - required this.price, - required this.gst, - required this.hsnCode, - required this.description, - required this.image, - required this.quantity, - required this.remainingQuantity, - required this.id, + this.productId, + this.sku, + this.name, + this.categoryName, + this.brandName, + this.price, + this.gst, + this.hsnCode, + this.description, + this.image, + this.quantity, + this.remainingQuantity, + this.id, }); factory OrderItem.fromJson(Map json) { return OrderItem( - productId: json['productId'], - sku: json['SKU'], - name: json['name'], - categoryName: json['categoryName'], - brandName: json['brandName'], - price: json['price'], - gst: json['GST'], - hsnCode: json['HSN_Code'], + productId: json['productId'].toString()?? '', + sku: json['SKU'].toString() ?? '', + name: json['name'].toString()?? '', + categoryName: json['categoryName'].toString() ?? '', + brandName: json['brandName'].toString() ?? '', + price: json['price'] ?? 0, + gst: json['GST'] ?? 0, + hsnCode: json['HSN_Code'] ?? 0, description: json['description'] ?? '', - image: List.from(json['image']), - quantity: json['quantity'], - remainingQuantity: json['remainingQuantity'], - id: json['_id'], + image: List.from(json['image'] ?? []), + quantity: json['quantity'] ?? 0, + remainingQuantity: json['remainingQuantity'] ?? 0, + id: json['_id'] ?? '', ); } } class Item { - String productId; - String sku; - String name; - String categoryName; - String brandName; - int price; - int gst; - int hsnCode; - int processQuantity; - String id; + String? productId; + String? sku; + String? name; + String? categoryName; + String? brandName; + int? price; + int? gst; + int? hsnCode; + int? processQuantity; + String? id; Item({ - required this.productId, - required this.sku, - required this.name, - required this.categoryName, - required this.brandName, - required this.price, - required this.gst, - required this.hsnCode, - required this.processQuantity, - required this.id, + this.productId, + this.sku, + this.name, + this.categoryName, + this.brandName, + this.price, + this.gst, + this.hsnCode, + this.processQuantity, + this.id, }); factory Item.fromJson(Map json) { return Item( - productId: json['productId'], - sku: json['SKU'], - name: json['name'], - categoryName: json['categoryName'], - brandName: json['brandName'], - price: json['price'], - gst: json['GST'], - hsnCode: json['HSN_Code'], - processQuantity: json['processquantity'], - id: json['_id'], + productId: json['productId'].toString() ?? '', + sku: json['SKU'].toString() ?? '', + name: json['name'].toString() ?? '', + categoryName: json['categoryName'].toString()?? '', + brandName: json['brandName'].toString() ?? '', + price: json['price'] ?? 0, + gst: json['GST'] ?? 0, + hsnCode: json['HSN_Code'] ?? 0, + processQuantity: json['processquantity'] ?? 0, + id: json['_id'] ?? '', ); } } class AddedBy { - String id; - String name; - String email; - String mobileNumber; + String? id; + String? name; + String? email; + String? mobileNumber; dynamic fcmToken; AddedBy({ - required this.id, - required this.name, - required this.email, - required this.mobileNumber, + this.id, + this.name, + this.email, + this.mobileNumber, this.fcmToken, }); factory AddedBy.fromJson(Map json) { return AddedBy( - id: json['_id'], - name: json['name'], - email: json['email'], - mobileNumber: json['mobile_number'], - fcmToken: json['fcm_token'], + id: json['_id'].toString() ?? '', + name: json['name'].toString() ?? '', + email: json['email'].toString()?? '', + mobileNumber: json['mobile_number']?? '', + fcmToken: json['fcm_token']??"789789798798", ); } } diff --git a/lib/models/rd_order_item_model.dart b/lib/models/rd_order_item_model.dart index 7e06acd..015b3ab 100644 --- a/lib/models/rd_order_item_model.dart +++ b/lib/models/rd_order_item_model.dart @@ -26,12 +26,12 @@ required this.image, this.quantity, this.remainingQuantity, - this.processquantity, + this.processquantity = 1, }); factory RDOrderItem.fromJson(Map json) { return RDOrderItem( - productId: json['productId'] ?? '', + productId: json['productId'].toString()?? '', sku: json['SKU'] ?? '', name: json['name'] ?? '', categoryName: json['categoryName'] ?? '', diff --git a/lib/models/single_get_order_model.dart b/lib/models/single_get_order_model.dart index e29ade4..7d50440 100644 --- a/lib/models/single_get_order_model.dart +++ b/lib/models/single_get_order_model.dart @@ -1,44 +1,46 @@ +import 'package:cheminova/models/rd_order_item_model.dart'; + class SingleGetOrderModel { final String id; - final String paymentMode; - final String shipTo; - final String billTo; - final List orderItem; - final double subtotal; - final double gstTotal; - final double grandTotal; - final String status; - final List invoices; - final AddedBy addedBy; - final String pd; - final bool isCancelled; - final bool isDelivered; - final String deliveredDate; - final DateTime statusUpdatedAt; - final String uniqueId; - final DateTime createdAt; - final DateTime updatedAt; + String? paymentMode; + String? shipTo; + String? billTo; + List? orderItem; + double? subtotal; + double? gstTotal; + double? grandTotal; + String? status; + List? invoices; + AddedBy? addedBy; + String? pd; + bool? isCancelled; + bool? isDelivered; + String? deliveredDate; + DateTime? statusUpdatedAt; + String? uniqueId; + DateTime? createdAt; + DateTime? updatedAt; SingleGetOrderModel({ required this.id, - required this.paymentMode, - required this.shipTo, - required this.billTo, - required this.orderItem, - required this.subtotal, - required this.gstTotal, - required this.grandTotal, - required this.status, - required this.invoices, - required this.addedBy, - required this.pd, - required this.isCancelled, - required this.isDelivered, - required this.deliveredDate, - required this.statusUpdatedAt, - required this.uniqueId, - required this.createdAt, - required this.updatedAt, + this.paymentMode, + this.shipTo, + this.billTo, + this.orderItem, + this.subtotal, + this.gstTotal, + this.grandTotal, + this.status, + this.invoices, + this.addedBy, + this.pd, + this.isCancelled, + this.isDelivered, + this.deliveredDate, + this.statusUpdatedAt, + this.uniqueId, + this.createdAt, + this.updatedAt, }); factory SingleGetOrderModel.fromJson(Map json) { @@ -48,7 +50,7 @@ class SingleGetOrderModel { shipTo: json['shipTo'] ?? '', billTo: json['billTo'] ?? '', orderItem: (json['orderItem'] as List?) - ?.map((item) => OrderItem.fromJson(item)) + ?.map((item) => RDOrderItem.fromJson(item)) .toList() ?? [], subtotal: (json['subtotal'] as num?)?.toDouble() ?? 0.0, @@ -74,27 +76,27 @@ class SingleGetOrderModel { 'paymentMode': paymentMode, 'shipTo': shipTo, 'billTo': billTo, - 'orderItem': orderItem.map((item) => item.toJson()).toList(), + 'orderItem': orderItem?.map((item) => item.toJson()).toList(), 'subtotal': subtotal, 'gstTotal': gstTotal, 'grandTotal': grandTotal, 'status': status, 'invoices': invoices, - 'addedBy': addedBy.toJson(), + 'addedBy': addedBy?.toJson(), 'pd': pd, 'iscancelled': isCancelled, 'isDelivered': isDelivered, 'DeliveredDate': deliveredDate, - 'statusUpdatedAt': statusUpdatedAt.toIso8601String(), + 'statusUpdatedAt': statusUpdatedAt?.toIso8601String(), 'uniqueId': uniqueId, - 'createdAt': createdAt.toIso8601String(), - 'updatedAt': updatedAt.toIso8601String(), + 'createdAt': createdAt?.toIso8601String(), + 'updatedAt': updatedAt?.toIso8601String(), }; } @override String toString() { - return 'SingleOrder(id: $id, paymentMode: $paymentMode, shipTo: $shipTo, billTo: $billTo, ' + return 'SingleGetOrderModel(id: $id, paymentMode: $paymentMode, shipTo: $shipTo, billTo: $billTo, ' 'orderItem: $orderItem, subtotal: $subtotal, gstTotal: $gstTotal, grandTotal: $grandTotal, ' 'status: $status, invoices: $invoices, addedBy: $addedBy, pd: $pd, ' 'isCancelled: $isCancelled, isDelivered: $isDelivered, deliveredDate: $deliveredDate, ' @@ -108,14 +110,15 @@ class OrderItem { final String name; final String categoryName; final String brandName; - final double price; - final double gst; - final String hsnCode; + final int price; // Use int for price + final int gst; // Use int for GST + final int hsnCode; // Use int for HSN Code final String description; - final List image; + final List image; // Assuming images are stored as a list of strings final int quantity; final int remainingQuantity; - final String id; + int? processQuantity; + final String id; // Use String for _id OrderItem({ required this.productId, @@ -130,6 +133,7 @@ class OrderItem { required this.image, required this.quantity, required this.remainingQuantity, + this.processQuantity = 1, required this.id, }); @@ -140,13 +144,14 @@ class OrderItem { name: json['name'] ?? '', categoryName: json['categoryName'] ?? '', brandName: json['brandName'] ?? '', - price: (json['price'] as num?)?.toDouble() ?? 0.0, - gst: (json['GST'] as num?)?.toDouble() ?? 0.0, - hsnCode: json['HSN_Code'] ?? '', + price: (json['price'] as num?)?.toInt() ?? 0, // Handle as num + gst: (json['GST'] as num?)?.toInt() ?? 0, // Handle as num + hsnCode: (json['HSN_Code'] as num?)?.toInt() ?? 0, // Handle as num description: json['description'] ?? '', - image: json['image'] ?? [], - quantity: json['quantity'] ?? 0, - remainingQuantity: json['remainingQuantity'] ?? 0, + image: List.from(json['image'] ?? []), + quantity: (json['quantity'] as num?)?.toInt() ?? 0, // Handle as num + remainingQuantity: (json['remainingQuantity'] as num?)?.toInt() ?? 0, // Handle as num + processQuantity: (json['processQuantity']as num?)?.toInt()??0, id: json['_id'] ?? '', ); } @@ -188,7 +193,7 @@ class AddedBy { final String addedBy; final String userType; final String kyc; - final String? fcmToken; + String? fcmToken; final DateTime createdAt; final DateTime updatedAt; final String mappedSC; @@ -224,7 +229,7 @@ class AddedBy { addedBy: json['addedBy'] ?? '', userType: json['userType'] ?? '', kyc: json['kyc'] ?? '', - fcmToken: json['fcm_token'], + fcmToken: json['fcm_token']?.toString(), // Handle null safely createdAt: DateTime.parse(json['createdAt'] ?? DateTime.now().toString()), updatedAt: DateTime.parse(json['updatedAt'] ?? DateTime.now().toString()), mappedSC: json['mappedSC'] ?? '', @@ -257,8 +262,8 @@ class AddedBy { String toString() { return 'AddedBy(id: $id, designation: $designation, name: $name, email: $email, ' 'mobileNumber: $mobileNumber, principalDistributor: $principalDistributor, ' - 'addedBy: $addedBy, userType: $userType, kyc: $kyc, fcmToken: $fcmToken, ' - 'createdAt: $createdAt, updatedAt: $updatedAt, mappedSC: $mappedSC, ' - 'uniqueId: $uniqueId, mappedTM: $mappedTM)'; + 'addedBy: $addedBy, userType: $userType, kyc: $kyc, ' + 'fcmToken: $fcmToken, createdAt: $createdAt, updatedAt: $updatedAt, ' + 'mappedSC: $mappedSC, uniqueId: $uniqueId, mappedTM: $mappedTM)'; } } diff --git a/lib/screens/annauncement/annauncement.dart b/lib/screens/annauncement/annauncement.dart new file mode 100644 index 0000000..2a15e31 --- /dev/null +++ b/lib/screens/annauncement/annauncement.dart @@ -0,0 +1,105 @@ +import 'package:cheminova/widgets/my_drawer.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:get/get.dart'; +import 'package:intl/intl.dart'; + +import '../../controller/annaucement_controller.dart'; +import '../../widgets/comman_background.dart'; +import '../../widgets/common_appbar.dart'; + +class AnnouncementScreen extends StatefulWidget { + AnnouncementScreen({super.key}); + + @override + State createState() => _AnnouncementScreenState(); +} + +class _AnnouncementScreenState extends State { + // Initialize the controller + final AnnouncementController _announcementController = Get.put(AnnouncementController()); + + + 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 + } + + + @override + Widget build(BuildContext context) { + // Fetch announcements when the screen is built + _announcementController.fetchAnnouncements(); + + return CommonBackground( + child: Scaffold( + backgroundColor: Colors.transparent, + appBar: CommonAppBar( + actions: [ + IconButton( + onPressed: () { + Navigator.pop(context); + }, + icon: SvgPicture.asset('assets/svg/back_arrow.svg'), + padding: const EdgeInsets.only(right: 20), + ), + ], + title: const Text( + 'Announcement', + style: TextStyle( + fontSize: 20, + color: Colors.black, + fontWeight: FontWeight.w400, + fontFamily: 'Anek', + ), + ), + backgroundColor: Colors.transparent, + elevation: 0, + ), + drawer: MyDrawer(), + body: Obx(() { + // Show loading indicator while fetching announcements + if (_announcementController.isLoading.value) { + return Center(child: CircularProgressIndicator()); + } + // Show error message if there was an error + if (_announcementController.errorMessage.isNotEmpty) { + return Center( + child: Text('Error: ${_announcementController.errorMessage}'), + ); + } + // Display the list of announcements + return ListView.builder( + itemCount: _announcementController.announcements.length, + itemBuilder: (context, index) { + + return Card( + child: ListTile( + //leading:Text(_announcementController.announcements[index].id), + title: Row( + children: [ + Text("Message :",style: TextStyle(fontWeight: FontWeight.bold),), + Text(_announcementController.announcements[index].message), + ], + ), + subtitle: Row( + children: [ + Text("UniqueID :" , style: TextStyle(fontWeight: FontWeight.bold),), + Text(_announcementController.announcements[index].uniqueId), + ], + ), + trailing: Text(formatDate(_announcementController.announcements[index].createdAt.toIso8601String())), + ), + ); + }, + ); + }), + ), + ); + } +} diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index 45b6ed2..6f3d14b 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -1,4 +1,5 @@ import 'package:cheminova/controller/home_controller.dart'; +import 'package:cheminova/screens/annauncement/annauncement.dart'; import 'package:cheminova/screens/inventory/inventory_management_screen.dart'; import 'package:cheminova/screens/kyc/kyc_screen.dart'; import 'package:cheminova/screens/notification/notification_screen.dart'; @@ -187,12 +188,12 @@ class _HomeScreenState extends State { () => RdOrderScreen(), ), ), - // HomeCard( - // title: 'Kyc', - // onTap: () => Get.to( - // () => KycRetailerInfoScreen(), - // ), - // ), + HomeCard( + title: 'Announcement', + onTap: () => Get.to( + () => AnnouncementScreen(), + ), + ), ], diff --git a/lib/screens/rd orders/partial_pending_dialog.dart b/lib/screens/rd orders/partial_pending_dialog.dart index 0733e0a..2e03f28 100644 --- a/lib/screens/rd orders/partial_pending_dialog.dart +++ b/lib/screens/rd orders/partial_pending_dialog.dart @@ -3,6 +3,7 @@ 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/order/checkout_screen.dart'; +import 'package:cheminova/screens/rd%20orders/rd_pending_screen.dart'; import 'package:cheminova/widgets/my_drawer.dart'; import 'package:cheminova/widgets/product_card.dart'; import 'package:cheminova/widgets/product_card1.dart'; @@ -16,12 +17,14 @@ import '../../controller/rd_processing_order_controller.dart'; import '../../models/get_rd_pennding_model.dart'; import '../../models/oder_place_model.dart'; import '../../models/product_model1.dart'; +import '../../models/single_get_order_model.dart'; import '../../utils/show_snackbar.dart'; class PartialPendingDialogScreen extends StatefulWidget { - // PlacedOrdersResponse? productModel; - GetRdPendingModel? productpendingModel; - PartialPendingDialogScreen({super.key, this.productpendingModel}); + // PlacedOrdersResponse? productModel; + //GetRdPendingModel? productpendingModel; + SingleGetOrderModel? placedOrderList; + PartialPendingDialogScreen({super.key, this.placedOrderList}); @override State createState() => _PartialPendingDialogScreenState(); @@ -38,7 +41,7 @@ class _PartialPendingDialogScreenState extends State _separateProcessingAndPendingItems(); } void _separateProcessingAndPendingItems() { - for (var item in widget.productpendingModel!.orderItem) { + for (var item in widget.placedOrderList!.orderItem!.toList()) { if (item.remainingQuantity! > 0) { // If remainingQuantity > 0, it is available for processing processingItems.add(item ); @@ -87,7 +90,7 @@ class _PartialPendingDialogScreenState extends State List orderItems = orderItemMap.values.toList(); controller.placedOrder1.value = PlacedOrdersProcessing( - orderId: widget.productpendingModel!.id, + orderId: widget.placedOrderList!.id, invoiceItems: orderItems, ); @@ -95,7 +98,8 @@ class _PartialPendingDialogScreenState extends State showSnackbar("Partial order processed successfully."); Future.delayed(const Duration(seconds: 1), () { - Navigator.of(context).pop(); + Get.to(RdOrderPendingScreen()); + //Navigator.of(context).pop(); }); setState(() {}); @@ -199,7 +203,7 @@ class _PartialPendingDialogScreenState extends State fontWeight: FontWeight.bold, ), ), - Text("₹ ${widget.productpendingModel!.subtotal ?? 0}"), + Text("₹ ${widget.placedOrderList!.subtotal ?? 0}"), ], ), Row( @@ -213,7 +217,7 @@ class _PartialPendingDialogScreenState extends State fontWeight: FontWeight.bold, ), ), - Text("₹ ${widget.productpendingModel!.gstTotal ?? 0}"), + Text("₹ ${widget.placedOrderList!.gstTotal ?? 0}"), ], ), Row( @@ -227,7 +231,7 @@ class _PartialPendingDialogScreenState extends State fontWeight: FontWeight.bold, ), ), - Text("₹ ${widget.productpendingModel!.grandTotal ?? 0}"), + Text("₹ ${widget.placedOrderList!.grandTotal ?? 0}"), ], ), ], diff --git a/lib/screens/rd orders/partial_processing_dialog_screen.dart b/lib/screens/rd orders/partial_processing_dialog_screen.dart index 371ac51..2fc4c61 100644 --- a/lib/screens/rd orders/partial_processing_dialog_screen.dart +++ b/lib/screens/rd orders/partial_processing_dialog_screen.dart @@ -17,6 +17,7 @@ import '../../controller/rd_processing_order_controller.dart'; import '../../models/get_rd_pennding_model.dart'; import '../../models/oder_place_model.dart'; import '../../models/product_model1.dart'; +import '../../models/single_get_order_model.dart'; import '../../utils/show_snackbar.dart'; // // class PartialProcessingDialogScreen extends StatefulWidget { @@ -279,8 +280,8 @@ import '../../utils/show_snackbar.dart'; class PartialProcessingDialogScreen extends StatefulWidget { final PlacedOrdersResponse? productModel; - - PartialProcessingDialogScreen({super.key, this.productModel}); + SingleGetOrderModel? placedOrderList; + PartialProcessingDialogScreen({super.key, this.placedOrderList,this.productModel}); @override State createState() => _PartialProcessingDialogScreenState(); @@ -301,13 +302,13 @@ class _PartialProcessingDialogScreenState extends State 0) { // If remainingQuantity > 0, it is available for processing - processingItems.add(item); + processingItems.add(item as RDOrderItem); } else { // If remainingQuantity == 0, it should go into pending - pendingItems.add(item); + pendingItems.add(item as RDOrderItem); } } } @@ -351,13 +352,14 @@ class _PartialProcessingDialogScreenState extends State orderItems = orderItemMap.values.toList(); controller.placedOrder1.value = PlacedOrdersProcessing( - orderId: widget.productModel!.id, + orderId: widget.placedOrderList!.id, invoiceItems: orderItems, ); await controller.placeRDOrder(); showSnackbar("Partial order processed successfully."); - Navigator.of(context).pop(); + Get.to(RdOrderPendingScreen()); + //Navigator.of(context).pop(); // Future.delayed(const Duration(seconds: 1), () { // Get.to(RdOrderPendingScreen()); // //Navigator.of(context).pop(); @@ -384,155 +386,155 @@ class _PartialProcessingDialogScreenState extends State Scaffold.of(context).openDrawer(), + appBar: AppBar( + backgroundColor: Colors.transparent, + elevation: 0, + leading: Builder( + builder: (context) { + return GestureDetector( + onTap: () => Scaffold.of(context).openDrawer(), + 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(16.0), + padding: const EdgeInsets.all(8.0), child: SvgPicture.asset( - 'assets/svg/menu.svg', + 'assets/svg/back_arrow.svg', ), ), - ); - }, - ), - actions: [ - GestureDetector( - onTap: () => Get.back(), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: SvgPicture.asset( - 'assets/svg/back_arrow.svg', - ), + ), + ], + title: const Center( + child: Text( + "Modify Product Availability", ), ), - ], - title: const Center( - child: Text( - "Modify Product Availability", - ), ), - ), - drawer: MyDrawer(), - body: Stack( - fit: StackFit.expand, - children: [ - Image.asset( - 'assets/images/image_1.png', - fit: BoxFit.cover, - ), - SafeArea( - child: Column( - children: [ - Expanded( - child: ListView( - children: [ - const SizedBox(height: 20), - 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( - crossAxisAlignment: CrossAxisAlignment.start, + drawer: MyDrawer(), + body: Stack( + fit: StackFit.expand, + children: [ + Image.asset( + 'assets/images/image_1.png', + fit: BoxFit.cover, + ), + SafeArea( + child: Column( + children: [ + Expanded( + child: ListView( children: [ - const Text( - "Processing Products", - style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + const SizedBox(height: 20), + 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( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + "Processing Products", + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + SizedBox( + height: Get.height * 0.6, + child: ListView.builder( + itemCount: processingItems.length, + itemBuilder: (context, index) { + final orderItem = processingItems[index]; + return ProductCard1(productModel: orderItem); + }, + ), + ), + const SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Subtotal ", + style: GoogleFonts.roboto( + fontSize: 15, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + Text("₹ ${widget.placedOrderList!.subtotal ?? 0}"), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "GST ", + style: GoogleFonts.roboto( + fontSize: 15, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + Text("₹ ${widget.placedOrderList!.gstTotal ?? 0}"), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Total Amount ", + style: GoogleFonts.roboto( + fontSize: 15, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + Text("₹ ${widget.placedOrderList!.grandTotal ?? 0}"), + ], + ), + ], + ), + ), ), + SizedBox(height: Get.height * 0.020), SizedBox( - height: Get.height * 0.6, - child: ListView.builder( - itemCount: processingItems.length, - itemBuilder: (context, index) { - final orderItem = processingItems[index]; - return ProductCard1(productModel: orderItem); - }, + width: Get.width * 0.3, + height: Get.height * 0.06, + child: ElevatedButton( + onPressed: _showPartialOrderDialog, // Show dialog when pressed + style: ElevatedButton.styleFrom( + foregroundColor: Colors.white, + backgroundColor: const Color(0xFF00784C), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + child: Text( + "Submit", + style: GoogleFonts.roboto( + fontSize: 16, + fontWeight: FontWeight.w600, + ), + ), ), ), - const SizedBox(height: 10), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Subtotal ", - style: GoogleFonts.roboto( - fontSize: 15, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - ), - Text("₹ ${widget.productModel!.subtotal ?? 0}"), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "GST ", - style: GoogleFonts.roboto( - fontSize: 15, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - ), - Text("₹ ${widget.productModel!.gstTotal ?? 0}"), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Total Amount ", - style: GoogleFonts.roboto( - fontSize: 15, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - ), - Text("₹ ${widget.productModel!.grandTotal ?? 0}"), - ], - ), - ], - ), - ), - ), - SizedBox(height: Get.height * 0.020), - SizedBox( - width: Get.width * 0.3, - height: Get.height * 0.06, - child: ElevatedButton( - onPressed: _showPartialOrderDialog, // Show dialog when pressed - style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: const Color(0xFF00784C), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), + ], ), ), - child: Text( - "Submit", - style: GoogleFonts.roboto( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - ), + ], ), - ], - ), - ), - ], - ), - )]) + )]) ); } } diff --git a/lib/screens/rd orders/rd_cancelled_details_screen.dart b/lib/screens/rd orders/rd_cancelled_details_screen.dart index fcb4248..efb2db6 100644 --- a/lib/screens/rd orders/rd_cancelled_details_screen.dart +++ b/lib/screens/rd orders/rd_cancelled_details_screen.dart @@ -572,7 +572,7 @@ class _RdCancelledDetailScreenState fontWeight: FontWeight.bold, ), ), - Text("${"VAIBHAV"}",maxLines: 4, + Text("${" Roshan Garg"}",maxLines: 4, overflow:TextOverflow.ellipsis,) , ], ) @@ -593,7 +593,7 @@ class _RdCancelledDetailScreenState fontWeight: FontWeight.bold, ), ), - Text("${"vaibhav.gurjar20001@gmail.com"}",maxLines: 4, + Text("${"roshangarg28@gmail.com"}",maxLines: 4, overflow:TextOverflow.ellipsis,) , ], ) @@ -614,7 +614,7 @@ class _RdCancelledDetailScreenState fontWeight: FontWeight.bold, ), ), - Text("${"7779797976"}",maxLines: 4, + Text("${"8876785448"}",maxLines: 4, overflow:TextOverflow.ellipsis,) , ], ) @@ -785,33 +785,33 @@ class _RdCancelledDetailScreenState children: [ const Text( "CancelledReason: ", - style: TextStyle(fontWeight: FontWeight.bold), + style: TextStyle(fontWeight: FontWeight.bold,), ), SizedBox(width: 10), // Space between label and dropdown - Text("${widget.placedOrderList!.orderCancelledReason}",maxLines: 4, + Text("${widget.placedOrderList!.orderCancelledReason}",maxLines: 4,style: TextStyle(color: Colors.red,fontSize: 15), overflow:TextOverflow.ellipsis,) ], ), ), - SizedBox( - width: Get.width * 0.4, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: ElevatedButton( - onPressed: (){}, - // 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( + // width: Get.width * 0.4, + // child: Padding( + // padding: const EdgeInsets.all(8.0), + // child: ElevatedButton( + // onPressed: (){}, + // // 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)), + // ), + // ), + // ) ], ), diff --git a/lib/screens/rd orders/rd_cancelled_screen.dart b/lib/screens/rd orders/rd_cancelled_screen.dart index 399e12f..fc8fa6d 100644 --- a/lib/screens/rd orders/rd_cancelled_screen.dart +++ b/lib/screens/rd orders/rd_cancelled_screen.dart @@ -196,14 +196,14 @@ class _RdCancelledScreenState extends State { SizedBox( height: Get.height * 0.6, child: Obx(() { - // if (_getRdProductController.productRDList.isEmpty) { - // return Center( - // child: Text( - // 'No Orders Found', - // style: GoogleFonts.roboto(fontSize: 14), - // ), - // ); - // } + if (_getRdProductController.productRDList.isEmpty) { + return Center( + child: Text( + 'No Orders Found', + style: GoogleFonts.roboto(fontSize: 14), + ), + ); + } final Set uniqueOrderIds = {}; final List uniqueOrders = []; diff --git a/lib/screens/rd orders/rd_delivered_details_screen.dart b/lib/screens/rd orders/rd_delivered_details_screen.dart index 96d044d..86b61ff 100644 --- a/lib/screens/rd orders/rd_delivered_details_screen.dart +++ b/lib/screens/rd orders/rd_delivered_details_screen.dart @@ -343,11 +343,12 @@ class _RdDeliveredDetailsScreenState // placedOrderList: uniqueOrders[index])), // Navigate to detail screen style: ElevatedButton.styleFrom( foregroundColor: Colors.white, - backgroundColor: Colors.orange, + backgroundColor: Colors.green, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), ), - child: Text(widget.placedOrderList!.courierStatus, style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.w400)), + child: Text(capitalizeFirstLetter( widget.placedOrderList!.courierStatus) + , style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.w400)), ), //Text("₹ ${widget.placedOrderList!.gstTotal}"), ], @@ -450,7 +451,7 @@ class _RdDeliveredDetailsScreenState fontWeight: FontWeight.bold, ), ), - Text("${"VAIBHAV"}",maxLines: 4, + Text("${"Roshan Garg"}",maxLines: 4, overflow:TextOverflow.ellipsis,) , ], ) @@ -471,7 +472,7 @@ class _RdDeliveredDetailsScreenState fontWeight: FontWeight.bold, ), ), - Text("${"vaibhav.gurjar20001@gmail.com"}",maxLines: 4, + Text("${"roshangarg28@gmail.com"}",maxLines: 4, overflow:TextOverflow.ellipsis,) , ], ) @@ -492,7 +493,7 @@ class _RdDeliveredDetailsScreenState fontWeight: FontWeight.bold, ), ), - Text("${"7779797976"}",maxLines: 4, + Text("${"8876785448"}",maxLines: 4, overflow:TextOverflow.ellipsis,) , ], ) diff --git a/lib/screens/rd orders/rd_dispatched_details_screen.dart b/lib/screens/rd orders/rd_dispatched_details_screen.dart index 936dfe0..a299c2a 100644 --- a/lib/screens/rd orders/rd_dispatched_details_screen.dart +++ b/lib/screens/rd orders/rd_dispatched_details_screen.dart @@ -500,7 +500,7 @@ class _RdDispatchedDetailsDetailScreenState // placedOrderList: uniqueOrders[index])), // Navigate to detail screen style: ElevatedButton.styleFrom( foregroundColor: Colors.white, - backgroundColor: Colors.orange, + backgroundColor: Colors.lightBlue, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), ), @@ -551,7 +551,7 @@ class _RdDispatchedDetailsDetailScreenState fontWeight: FontWeight.bold, ), ), - Text("${"VAIBHAV"}",maxLines: 4, + Text("${"Roshan Garg"}",maxLines: 4, overflow:TextOverflow.ellipsis,) , ], ) @@ -572,7 +572,7 @@ class _RdDispatchedDetailsDetailScreenState fontWeight: FontWeight.bold, ), ), - Text("${"vaibhav.gurjar20001@gmail.com"}",maxLines: 4, + Text("${"roshangarg28@gmail.com"}",maxLines: 4, overflow:TextOverflow.ellipsis,) , ], ) @@ -593,7 +593,7 @@ class _RdDispatchedDetailsDetailScreenState fontWeight: FontWeight.bold, ), ), - Text("${"7779797976"}",maxLines: 4, + Text("${"8876785448"}",maxLines: 4, overflow:TextOverflow.ellipsis,) , ], ) diff --git a/lib/screens/rd orders/rd_order_details_screen.dart b/lib/screens/rd orders/rd_order_details_screen.dart index 1ba3105..98151ee 100644 --- a/lib/screens/rd orders/rd_order_details_screen.dart +++ b/lib/screens/rd orders/rd_order_details_screen.dart @@ -217,7 +217,7 @@ class _RdOrderDetailScreenState } if (selectedStatus == "partial processing") { - Get.to(() => PartialProcessingDialogScreen(productModel: widget.placedOrderList)); + // Get.to(() => PartialProcessingDialogScreen(productModel: widget.placedOrderList)); return; } @@ -468,9 +468,9 @@ class _RdOrderDetailScreenState ), ), ), - _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), ], diff --git a/lib/screens/rd orders/rd_order_details_update.dart b/lib/screens/rd orders/rd_order_details_update.dart new file mode 100644 index 0000000..d1f79d9 --- /dev/null +++ b/lib/screens/rd orders/rd_order_details_update.dart @@ -0,0 +1,756 @@ + +import 'package:cheminova/controller/rd_single_order_controller.dart'; + +import 'package:cheminova/models/rd_order_item_model.dart'; +import 'package:cheminova/models/rd_placed_order_model.dart'; +import 'package:cheminova/models/single_get_order_model.dart'; +import 'package:cheminova/screens/rd%20orders/partial_processing_dialog_screen.dart'; +import 'package:cheminova/screens/rd%20orders/rd_cancelled_screen.dart'; +import 'package:cheminova/screens/rd%20orders/rd_processing_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_get_order_controller.dart'; +import '../../controller/rd_processing_order_controller.dart'; +import '../../models/product_model1.dart'; +import '../../utils/show_snackbar.dart'; + +class RdOrderDetailUpdateScreen extends StatefulWidget { + //final Product? productModel; + // PlacedOrderList and PlacedOrderModel are optional parameters passed to this screen + SingleGetOrderModel? placedOrderList; +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}); + + @override + State createState() => + _RdOrderDetailUpdateScreenState(); +} + + +class _RdOrderDetailUpdateScreenState + extends State { + // Controllers for managing cart and placed orders + + final RdSingleOrderController _getPlacedOrderController = Get.put(RdSingleOrderController()); + final GetProductRDController _getProductRDController = 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.productRDOrderSingleList) { + if (uniqueOrderIds.add(order!.uniqueId.toString())) { + 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(); + //getOrder1(); + selectedStatus= widget.placedOrderList!.status ?? 'new'; + // controller.fetchOrderItems(widget.placedOrderList!.id); + + // if (widget.orderId.isNotEmpty) { + // _getPlacedOrderController.fetchAllOrdersAndSingleOrder().then((_) { + // if (_getPlacedOrderController.productRDOrderSingleList.isNotEmpty) { + // // Update the UI with the fetched order data + // setState(() { + // var order = _getPlacedOrderController.productRDOrderSingleList.first; + // selectedStatus = order.status ?? 'new'; + // widget.placedOrderList = order; // Update the placed order details + // }); + // } + // }); + // } + } + + + + Future getOrder1() async { + final order = await _getPlacedOrderController.fetchAllOrdersAndSingleOrder(); + if (_getPlacedOrderController.productRDOrderSingleList.isEmpty) { + print("No orders found."); + } else { + print(" New Orders fetched successfully"); + } + setState(() { + + }); + + } + + 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"); + Get.to(RdCancelledScreen()); + // 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(placedOrderList: 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 _getProductRDController.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"); + Get.to(RdOrderProcessingScreen()); + + 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: [ + _buildOrderSummary(), + const SizedBox(height: 8), + _buildOrderItems(), + const SizedBox(height: 8), + _buildCustomerDetails(), + const SizedBox(height: 8), + _buildBillingInfo(), + const SizedBox(height: 8), + _buildShippingInfo(), + const SizedBox(height: 8), + _buildPaymentInfo(), + const SizedBox(height: 8), + _buildOrderStatus(), + const SizedBox(height: 8), + _buildStatusDropdown(), + _buildUpdateStatusButton(), + ], + ), + ), + ), + SizedBox(height: Get.height * 0.04), + ], + ), + ), + ), + ], + ), + ); + } + + Widget _buildOrderSummary() { + return 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 ?? "44564", 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), + ], + ), + ); + } + + Widget _buildOrderItems() { + return 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", + 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}"), + Text("Price: ₹${orderItem.price}"), + Text("GST: ${orderItem.gst}%"), + ], + ), + ), + ], + ), + ), + ) + : const SizedBox.shrink(); + }, + ), + ), + ), + ); + } + + Widget _buildCustomerDetails() { + return Card( + child: Column( + children: [ + _buildSectionTitle("Customer Details"), + _buildRow("Name:", widget.placedOrderList!.addedBy!.name, Get.width * 0.04), + _buildRow("Email:", widget.placedOrderList!.addedBy!.email, Get.width * 0.04), + _buildRow("Mobile Number:", widget.placedOrderList!.addedBy!.mobileNumber, Get.width * 0.04), + ], + ), + ); + } + + Widget _buildBillingInfo() { + return Card( + child: Column( + children: [ + _buildSectionTitle("Billing Information"), + _buildInfoRow("Address", widget.placedOrderList!.billTo.toString(), Get.width * 0.04), + ], + ), + ); + } + + Widget _buildShippingInfo() { + return Card( + child: Column( + children: [ + _buildSectionTitle("Shipping Information"), + _buildInfoRow("Address", widget.placedOrderList!.shipTo.toString(), Get.width * 0.04), + ], + ), + ); + } + + Widget _buildPaymentInfo() { + return Card( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + Text( + "Payment Mode: ", + style: GoogleFonts.roboto( + fontSize: Get.width * 0.04, + fontWeight: FontWeight.w500, + ), + ), + Text(capitalizeFirstLetter(widget.placedOrderList!.paymentMode.toString())), + ], + ), + ), + ); + } + + Widget _buildOrderStatus() { + return Card( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + children: [ + Text( + "Order Status: ", + style: GoogleFonts.roboto( + fontSize: Get.width * 0.04, + fontWeight: FontWeight.w500, + ), + ), + Text(capitalizeFirstLetter(selectedStatus)), + ], + ), + ), + ); + } + + Widget _buildStatusDropdown() { + return SizedBox( + height: Get.height * 0.05, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Text( + "Status: ", + style: TextStyle(fontWeight: FontWeight.bold), + ), + const SizedBox(width: 10), + Expanded( + child: DropdownButtonFormField( + value: selectedStatus, + decoration: InputDecoration( + filled: true, + fillColor: Colors.white, + contentPadding: const EdgeInsets.symmetric(vertical: 10, horizontal: 12), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: const 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!; + }); + }, + ), + ), + ], + ), + ); + } + + Widget _buildUpdateStatusButton() { + if (selectedStatus == "processing" || selectedStatus == "partial processing" || selectedStatus == "cancelled") { + return SizedBox( + width: Get.width * 0.4, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: ElevatedButton( + onPressed: _showConfirmationDialog, + 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), + ), + ), + ), + ); + } + return const SizedBox.shrink(); + } + + Widget _buildSectionTitle(String title) { + return SizedBox( + width: Get.width, + child: Padding( + padding: const EdgeInsets.fromLTRB(8, 8, 8, 0), + child: Text( + title, + style: GoogleFonts.roboto(fontSize: Get.width * 0.05, fontWeight: FontWeight.bold), + ), + ), + ); + } + + Widget _buildRow(String label, String value, double fontSize) { + return Padding( + padding: const EdgeInsets.fromLTRB(8, 2, 8, 2), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + label, + style: GoogleFonts.roboto(fontSize: fontSize), + ), + Text( + value, + style: GoogleFonts.roboto(fontSize: fontSize), + ), + ], + ), + ); + } + + Widget _buildInfoRow(String label, String value, double fontSize) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "$label: ", + style: GoogleFonts.roboto(fontSize: fontSize, fontWeight: FontWeight.w500), + ), + Expanded( + child: Text( + value, + style: GoogleFonts.roboto(fontSize: fontSize), + ), + ), + ], + ), + ); + } + +} +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_screen.dart b/lib/screens/rd orders/rd_order_screen.dart index e8a81e1..617755f 100644 --- a/lib/screens/rd orders/rd_order_screen.dart +++ b/lib/screens/rd orders/rd_order_screen.dart @@ -1,10 +1,10 @@ - import 'package:cheminova/controller/rd_get_order_controller.dart'; import 'package:cheminova/models/rd_get_order_model.dart'; import 'package:cheminova/screens/rd%20orders/rd_cancelled_screen.dart'; import 'package:cheminova/screens/rd%20orders/rd_delivered_screen.dart'; import 'package:cheminova/screens/rd%20orders/rd_dispatched_scree.dart'; import 'package:cheminova/screens/rd%20orders/rd_order_details_screen.dart'; +import 'package:cheminova/screens/rd%20orders/rd_order_details_update.dart'; import 'package:cheminova/screens/rd%20orders/rd_pending_screen.dart'; import 'package:cheminova/screens/rd%20orders/rd_processing_screen.dart'; import 'package:cheminova/widgets/input_field.dart'; @@ -14,16 +14,18 @@ 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/rd_get_single_service.dart'; import '../../controller/rd_single_order_controller.dart'; import '../../models/single_get_order_model.dart'; import '../order_management/order_management_detail_screen.dart'; class RdOrderScreen extends StatefulWidget { final PlacedOrdersResponse? getrdProduct; - SingleGetOrderModel? getSingleProduct; + SingleGetOrderModel? getSingleProduct; - RdOrderScreen({super.key, this.getrdProduct,this.getSingleProduct}); + RdOrderScreen({super.key, this.getrdProduct, this.getSingleProduct}); @override State createState() => _RdOrderScreenState(); @@ -31,27 +33,33 @@ class RdOrderScreen extends StatefulWidget { class _RdOrderScreenState extends State { final _searchController = TextEditingController(); - final List _filterList = [ "new", + final List _filterList = [ + "new", "pending", "processing", "dispatched", "cancelled", - "delivered",]; + "delivered", + ]; int _selectedIndex = 0; - final GetProductRDController _getRdProductController = Get.put(GetProductRDController()); - final RdSingleOrderController _getrdSingleOrderController = Get.put(RdSingleOrderController()); - final GlobalKey _refreshIndicatorKey = GlobalKey(); + final GetProductRDController _getRdProductController = + Get.put(GetProductRDController()); + final RdSingleOrderController _getrdSingleOrderController = + Get.put(RdSingleOrderController()); + final GlobalKey _refreshIndicatorKey = + GlobalKey(); @override void initState() { super.initState(); getOrder1(); - // getOrder3(_getrdSingleOrderController.productRDOrderSingleList[0].id); - + getOrder3(); + // getOrder3(_getrdSingleOrderController.productRDOrderSingleList[0].id); } Future _onRefresh() async { await getOrder1(); + await Future.delayed(Duration(seconds: 1)); } @@ -62,23 +70,12 @@ class _RdOrderScreenState extends State { } else { print(" New Orders fetched successfully"); } - } - Future getOrder3(String orderId) async { - if (orderId != null && orderId.isNotEmpty) { - await _getrdSingleOrderController.fetchRDSingleOrderProduct(orderId); - if (_getrdSingleOrderController.productRDOrderSingleList.isEmpty) { - print("No orders found."); - } else { - print("Single Order fetched successfully."); - } - } else { - print("Order ID is invalid."); - } + Future getOrder3() async { + //_getrdSingleOrderController.fetchAllOrdersAndSingleOrder(); } - String capitalizeFirstLetter(String text) { if (text.isEmpty) return text; return text[0].toUpperCase() + text.substring(1).toLowerCase(); @@ -86,7 +83,8 @@ class _RdOrderScreenState extends State { 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).toLocal(); // Convert to local time // Format the date and time according to your specified format String formattedDate = DateFormat('EEE MMM dd yyyy').format(parsedDate); @@ -95,6 +93,108 @@ class _RdOrderScreenState extends State { } + + + // void onOrderTap(int index) async { + // // Fetch orders and ensure you wait for it to complete + // await _getrdSingleOrderController.fetchAllOrdersAndSingleOrder(); + // + // // Log the length of the list to help with debugging + // print('Fetched orders count: ${_getrdSingleOrderController.productRDOrderSingleList.length}'); + // + // // Check if the productRDOrderSingleList is not empty + // if (_getrdSingleOrderController.productRDOrderSingleList.isNotEmpty) { + // // Ensure the index is within range + // if (index >= 0 && index < _getrdSingleOrderController.productRDOrderSingleList.length) { + // // Get the order ID from the list based on the index + // final orderId = _getrdSingleOrderController.productRDOrderSingleList[index].id; + // + // // Retrieve the token from SharedPreferences + // SharedPreferences prefs = await SharedPreferences.getInstance(); + // String? token = prefs.getString('token'); + // + // // Fetch the single order using the order ID + // final singleOrder = await GetSingleProductService().getSingleOrder(token!, orderId); + // + // // Check if the single order was fetched successfully + // if (singleOrder != null) { + // // Navigate to the details screen with the fetched order + // Get.to(() => RdOrderDetailUpdateScreen(placedOrderList: singleOrder, orderId: orderId,)); + // } else { + // // Handle the case where the single order could not be fetched + // Get.snackbar("Error", "Unable to fetch order details."); + // } + // } else { + // // Handle the case when the index is out of bounds + // Get.snackbar("Error", "Invalid order selection."); + // } + // } else { + // // Handle the case when the list is empty + // Get.snackbar("Error", "No orders available to display."); + // } + // } + + + void onOrderTap(int index) async { + try { + // Fetch orders and ensure you wait for it to complete + await _getRdProductController.fetchRDProduct(); + + // Log the count of fetched orders + print('Fetched orders count: ${_getRdProductController.productRDList.length}'); + + // Check if the productRDList is populated + if (_getRdProductController.productRDList.isNotEmpty) { + // Ensure the index is valid + if (index >= 0 && index < _getRdProductController.productRDList.length) { + // Get the order ID from the list based on the index + final orderId = _getRdProductController.productRDList[index].id; + + // Retrieve the token from SharedPreferences + SharedPreferences prefs = await SharedPreferences.getInstance(); + String? token = prefs.getString('token'); + + // Check if the token is not null + if (token != null) { + // Fetch the single order using the order ID, and avoid caching issues + final singleOrder = await GetSingleProductService().getSingleOrder(token, orderId); + + // Check if the single order was fetched successfully + if (singleOrder != null) { + // Navigate to the details screen with the fetched order + Get.to(() => RdOrderDetailUpdateScreen( + placedOrderList: singleOrder, + orderId: orderId, + )); + } else { + // Handle the case where the single order could not be fetched + Get.snackbar("Error", "Unable to fetch order details."); + } + } else { + // Handle the case where the token is null + Get.snackbar("Error", "User not authenticated."); + } + } else { + // Handle the case when the index is out of bounds + Get.snackbar("Error", "Invalid order selection."); + } + } else { + // Handle the case when the list is empty + Get.snackbar("Error", "No orders available to display."); + } + } catch (e) { + // Log any errors that occur during the process + print('Error in onOrderTap: $e'); + Get.snackbar("Error", "An unexpected error occurred."); + } + } + + + + + + + @override Widget build(BuildContext context) { return Scaffold( @@ -133,7 +233,8 @@ class _RdOrderScreenState extends State { SafeArea( child: SingleChildScrollView( child: Padding( - padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), + padding: EdgeInsets.only( + bottom: MediaQuery.of(context).viewInsets.bottom), child: RefreshIndicator( key: _refreshIndicatorKey, onRefresh: _onRefresh, @@ -167,47 +268,61 @@ class _RdOrderScreenState extends State { scrollDirection: Axis.horizontal, itemCount: _filterList.length, itemBuilder: (context, index) => Padding( - padding: const EdgeInsets.symmetric(horizontal: 4), + padding: const EdgeInsets.symmetric( + horizontal: 4), child: GestureDetector( onTap: () { setState(() { - _selectedIndex = index; // Update selected index + _selectedIndex = + index; // Update selected index }); // Navigate to different screens based on selected tab switch (_filterList[index]) { case "new": - // Get.to(YourScreen1()); // Navigate to "new" orders screen + // Get.to(YourScreen1()); // Navigate to "new" orders screen break; case "pending": - Get.to(RdOrderPendingScreen()); // Navigate to "pending" orders screen + Get.to( + RdOrderPendingScreen()); // Navigate to "pending" orders screen break; case "processing": - Get.to(RdOrderProcessingScreen()); // Navigate to "processing" orders screen + Get.to( + RdOrderProcessingScreen()); // Navigate to "processing" orders screen break; - // Add more cases for other statuses + // Add more cases for other statuses case "dispatched": - Get.to(RdDispatchedScreen()); // Navigate to dispatched orders + Get.to( + RdDispatchedScreen()); // Navigate to dispatched orders break; case "cancelled": - Get.to(RdCancelledScreen()); // Navigate to cancelled orders + Get.to( + RdCancelledScreen()); // Navigate to cancelled orders break; case "delivered": - Get.to(RdDeliveredScreen()); // Navigate to delivered orders + Get.to( + RdDeliveredScreen()); // Navigate to delivered orders break; default: - // Get.to(YourScreen1()); // Default screen + // Get.to(YourScreen1()); // Default screen } }, child: Chip( - label: Text(capitalizeFirstLetter( _filterList[index]) - , + label: Text( + capitalizeFirstLetter( + _filterList[index]), style: GoogleFonts.roboto( fontSize: 14, fontWeight: FontWeight.w500, - color: _selectedIndex == index ? Colors.white : Colors.black, // Change color when selected + color: _selectedIndex == index + ? Colors.white + : Colors + .black, // Change color when selected ), ), - backgroundColor: _selectedIndex == index ? const Color(0xFF004791) : Colors.grey[100], // Change color when selected + backgroundColor: _selectedIndex == index + ? const Color(0xFF004791) + : Colors.grey[ + 100], // Change color when selected ), ), ), @@ -216,19 +331,21 @@ class _RdOrderScreenState extends State { SizedBox( height: Get.height * 0.6, child: Obx(() { - // if (_getRdProductController.productRDList.isEmpty) { - // return Center( - // child: Text( - // 'No Orders Found', - // style: GoogleFonts.roboto(fontSize: 14), - // ), - // ); - // } + if (_getRdProductController.productRDList.isEmpty) { + return Center( + child: Text( + 'No Orders Found', + style: GoogleFonts.roboto(fontSize: 14), + ), + ); + } final Set uniqueOrderIds = {}; - final List uniqueOrders = []; + final List + uniqueOrders = []; - for (var order in _getRdProductController.productRDList) { + for (var order in _getRdProductController + .productRDList) { if (uniqueOrderIds.add(order.id)) { uniqueOrders.add(order); } @@ -252,47 +369,76 @@ class _RdOrderScreenState extends State { // Combine product names into a single string final productNames = order.orderItem - .map((item) => capitalizeFirstLetter(item.name)) + .map((item) => + capitalizeFirstLetter(item.name)) .join(', '); return Padding( - padding: const EdgeInsets.symmetric(vertical: 8), + padding: const EdgeInsets.symmetric( + vertical: 8), child: Card( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ Padding( - padding: const EdgeInsets.fromLTRB(16, 8, 8, 0), + padding: + const EdgeInsets.fromLTRB( + 16, 8, 8, 0), child: Row( - mainAxisAlignment: MainAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.start, children: [ - Text("Order ID: ", style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.bold)), + Text("Order ID: ", + style: + GoogleFonts.roboto( + fontSize: 14, + fontWeight: + FontWeight + .bold)), Text("${order.uniqueId}") ], ), ), Padding( - padding: const EdgeInsets.fromLTRB(16, 8, 8, 0), + padding: + const EdgeInsets.fromLTRB( + 16, 8, 8, 0), child: Row( - crossAxisAlignment: CrossAxisAlignment.start, // Aligns the Column to the top of the Text + crossAxisAlignment: + CrossAxisAlignment + .start, // Aligns the Column to the top of the Text children: [ Text( "Product Names: ", style: GoogleFonts.roboto( fontSize: 14, - fontWeight: FontWeight.bold, + fontWeight: + FontWeight.bold, ), ), Expanded( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, // Aligns text to the right within the Column + crossAxisAlignment: + CrossAxisAlignment + .start, // Aligns text to the right within the Column children: [ - const SizedBox(height: 4), // Adds a small space between the label and the product names - for (int i = 0; i < productNames.split(",").length; i++) + const SizedBox( + height: + 4), // Adds a small space between the label and the product names + for (int i = 0; + i < + productNames + .split( + ",") + .length; + i++) Text( '${i + 1}. ${productNames.split(",")[i].trim()}', // Adds index and trims whitespace - textAlign: TextAlign.left, // Aligns text to the right - style: GoogleFonts.roboto( + textAlign: TextAlign + .left, // Aligns text to the right + style: GoogleFonts + .roboto( fontSize: 14, ), ), @@ -302,61 +448,100 @@ class _RdOrderScreenState extends State { ], ), ), - Padding( - padding: const EdgeInsets.fromLTRB(16, 8, 8, 0), + padding: + const EdgeInsets.fromLTRB( + 16, 8, 8, 0), child: Row( - mainAxisAlignment: MainAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.start, children: [ - Text("Order Value: ", style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.bold)), + Text("Order Value: ", + style: + GoogleFonts.roboto( + fontSize: 14, + fontWeight: + FontWeight + .bold)), Text("${order.grandTotal}") ], ), ), Padding( - padding: const EdgeInsets.fromLTRB(16, 8, 8, 0), + padding: + const EdgeInsets.fromLTRB( + 16, 8, 8, 0), child: Row( - mainAxisAlignment: MainAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.start, children: [ - Text("Order Date: ", style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.bold)), - Text(formatDate("${order.createdAt}")) + Text("Order Date: ", + style: + GoogleFonts.roboto( + fontSize: 14, + fontWeight: + FontWeight + .bold)), + Text(formatDate( + "${order.createdAt}")) ], ), ), Padding( - padding: const EdgeInsets.fromLTRB(16, 8, 8, 8), + padding: + const EdgeInsets.fromLTRB( + 16, 8, 8, 8), child: Row( - mainAxisAlignment: MainAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.start, children: [ - Text("Status: ", style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.bold)), - Text(capitalizeFirstLetter("${order.status}")) + Text("Status: ", + style: + GoogleFonts.roboto( + fontSize: 14, + fontWeight: + FontWeight + .bold)), + Text(capitalizeFirstLetter( + "${order.status}")) ], ), ), SizedBox( width: Get.width * 0.4, child: Padding( - padding: const EdgeInsets.all(8.0), + padding: + const EdgeInsets.all(8.0), child: ElevatedButton( - onPressed: (){ - Get.to(() => RdOrderDetailScreen( - placedOrderList: _getRdProductController.productRDList[index])); - // getOrder3(_getRdProductController.productRDList[index].id).then((_) { - // // Navigate to the details screen only if the single order data is fetched - // - // }); + onPressed: () + async { + onOrderTap(index); }, - // => - // Get.to(() => - // RdOrderDetailScreen( - // placedOrderList: _getRdProductController.productRDList[index])), // Navigate to detail screen - style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: const Color(0xFF004791), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10)), + // => + // Get.to(() => + // RdOrderDetailScreen( + // placedOrderList: _getRdProductController.productRDList[index])), // Navigate to detail screen + style: ElevatedButton + .styleFrom( + foregroundColor: + Colors.white, + backgroundColor: + const Color( + 0xFF004791), + shape: + RoundedRectangleBorder( + borderRadius: + BorderRadius + .circular( + 10)), ), - child: Text("View Details", style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.w400)), + child: Text("View Details", + style: + GoogleFonts.roboto( + fontSize: 14, + fontWeight: + FontWeight + .w400)), ), ), ) @@ -383,4 +568,3 @@ class _RdOrderScreenState extends State { ); } } - diff --git a/lib/screens/rd orders/rd_pending_deatils.dart b/lib/screens/rd orders/rd_pending_deatils.dart index 77186cf..0cabc3f 100644 --- a/lib/screens/rd orders/rd_pending_deatils.dart +++ b/lib/screens/rd orders/rd_pending_deatils.dart @@ -7,8 +7,10 @@ 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/single_get_order_model.dart'; import 'package:cheminova/screens/rd%20orders/partial_pending_dialog.dart'; import 'package:cheminova/screens/rd%20orders/partial_processing_dialog_screen.dart'; +import 'package:cheminova/screens/rd%20orders/rd_processing_screen.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -19,7 +21,9 @@ import 'package:intl/intl.dart'; 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 '../../models/get_invoice_model.dart'; import '../../models/product_model1.dart'; import '../../models/rd_order_item_model.dart'; import '../../models/rd_placed_order_model.dart'; @@ -28,11 +32,14 @@ import '../../utils/show_snackbar.dart'; class RdOrderPendingScreenDetailScreen extends StatefulWidget { //final Product? productModel; // PlacedOrderList and PlacedOrderModel are optional parameters passed to this screen - GetRdPendingModel? placedOrderList; + SingleGetOrderModel? placedOrderList; + GetRdPendingModel? productpendingModel; + final String orderId; + GetInvoiceModel? placeInvoiceList; // PlacedOrderModel? placedOrderModel; // Constructor for initializing the screen with placed order details - RdOrderPendingScreenDetailScreen({super.key,this.placedOrderList}); + RdOrderPendingScreenDetailScreen({super.key,this.placedOrderList,required this.orderId,this.placeInvoiceList}); @override State createState() => @@ -44,8 +51,9 @@ class _RdOrderPendingScreenDetailScreenState extends State { // Controllers for managing cart and placed orders final CartController _cartController = Get.put(CartController()); - final GetRdPendingController _getPlacedOrderController = Get.put(GetRdPendingController()); - final GetProductRDController _getPlacedOrderController1 = Get.put(GetProductRDController()); + final GetRdPendingController _getRdPendingController = Get.put(GetRdPendingController()); + final GetSingleInvoiceController _getSingleInvoiceController = Get.put(GetSingleInvoiceController()); + final GetProductRDController _getProductRDController = Get.put(GetProductRDController()); final RDOrderPlacedController controller = Get.put(RDOrderPlacedController()); final List statusOptions = [ @@ -102,7 +110,7 @@ class _RdOrderPendingScreenDetailScreenState final Set uniqueOrderIds = {}; final List uniqueOrders = []; // Loop through placed orders and add unique orders to the list - for (var order in _getPlacedOrderController.productRDList) { + for (var order in _getRdPendingController.productRDList) { if (uniqueOrderIds.add(order.uniqueId)) { uniqueOrders.add(order); } @@ -124,10 +132,18 @@ class _RdOrderPendingScreenDetailScreenState void initState() { // TODO: implement initState super.initState(); + //getOrder1(); selectedStatus= widget.placedOrderList?.status ?? 'new'; } - + // Future getOrder1() async { + // await _getSingleInvoiceController.fetchInvoice(widget.placedOrderList!.id); + // if (_getSingleInvoiceController.invoice.isEmpty) { + // print("No orders found."); + // } else { + // print(" New Orders fetched successfully"); + // } + // } void _showConfirmationDialog() { String dialogTitle; @@ -204,7 +220,7 @@ class _RdOrderPendingScreenDetailScreenState } if (selectedStatus == "partial processing") { - Get.to(() => PartialPendingDialogScreen(productpendingModel: widget.placedOrderList)); + Get.to(() => PartialPendingDialogScreen(placedOrderList: widget.placedOrderList)); return; } @@ -212,7 +228,7 @@ class _RdOrderPendingScreenDetailScreenState Map orderItemMap = {}; // Populate the map with items and their quantities - for (var item in _getPlacedOrderController1.productRDList) { + for (var item in _getProductRDController.productRDList) { var productId = item.orderItem[0].productId; if (orderItemMap.containsKey(productId)) { @@ -257,9 +273,9 @@ class _RdOrderPendingScreenDetailScreenState await controller.placeRDOrder(); 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 @@ -290,7 +306,7 @@ class _RdOrderPendingScreenDetailScreenState @override Widget build(BuildContext context) { - int remainingQuantity = (widget.placedOrderList!.orderItem[0].quantity)! -(widget.placedOrderList!.orderItem[0].remainingQuantity!.toInt()); + int remainingQuantity = (widget.placedOrderList!.orderItem![0].quantity)! -(widget.placedOrderList!.orderItem![0].remainingQuantity!.toInt()); return Scaffold( extendBodyBehindAppBar: true, appBar: AppBar( @@ -381,7 +397,7 @@ class _RdOrderPendingScreenDetailScreenState fontWeight: FontWeight.bold, ), ), - Text(widget.placedOrderList!.uniqueId), + Text(widget.placedOrderList!.uniqueId.toString()), // Text(widget.placedOrderList!.uniqueId), ], ), @@ -404,7 +420,7 @@ class _RdOrderPendingScreenDetailScreenState ), SizedBox(height: 10), // Add spacing between the title and the list of items Column( - children: widget.placedOrderList!.orderItem.map((item) { + children: widget.placedOrderList!.orderItem!.map((item) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4.0), // Add some spacing between items @@ -537,7 +553,9 @@ class _RdOrderPendingScreenDetailScreenState shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), ), - child: Text(widget.placedOrderList!.status, style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.w400)), + child: Text("Processing"), + // Text(widget.placedOrderList!.status.toString()) + //Text(widget.placedOrderList!.status, style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.w400)), ), //Text("₹ ${widget.placedOrderList!.gstTotal}"), ], @@ -573,9 +591,9 @@ class _RdOrderPendingScreenDetailScreenState Expanded( child: ListView.builder( padding: EdgeInsets.zero, - itemCount: widget.placedOrderList?.orderItem.length ?? 0, + itemCount: widget.placedOrderList?.orderItem!.length ?? 0, itemBuilder: (context, index) { - final orderItem = widget.placedOrderList!.orderItem[index]; + final orderItem = widget.placedOrderList!.orderItem![index]; return orderItem != null ? Card( margin: const EdgeInsets.symmetric(vertical: 5.0), @@ -645,7 +663,7 @@ class _RdOrderPendingScreenDetailScreenState Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), // Adjust padding if needed child: Text( - "Order Itmes to processed", // Title text + "Order Items to be processed", // Title text style: GoogleFonts.roboto( fontSize: Get.width * 0.05, // Adjust font size as needed fontWeight: FontWeight.bold, @@ -655,11 +673,18 @@ class _RdOrderPendingScreenDetailScreenState Expanded( child: ListView.builder( padding: EdgeInsets.zero, - itemCount: widget.placedOrderList?.orderItem.length ?? 0, + itemCount: widget.placedOrderList?.orderItem + ?.where((item) => item.remainingQuantity! > 0) + .length ?? 0, itemBuilder: (context, index) { - final orderItem = widget.placedOrderList!.orderItem[index]; - return orderItem != null - ? Card( + // Filter items with non-zero quantities + final filteredItems = widget.placedOrderList!.orderItem! + .where((item) => item.remainingQuantity! > 0) + .toList(); + + final orderItem = filteredItems[index]; + + return Card( margin: const EdgeInsets.symmetric(vertical: 5.0), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), @@ -686,12 +711,7 @@ class _RdOrderPendingScreenDetailScreenState fontWeight: FontWeight.bold, ), ), - Text( - "Quantity: ${orderItem.remainingQuantity}", - style: GoogleFonts.roboto( - fontSize: Get.width * 0.03, - ), - ), + Text("Quantity: ${orderItem.remainingQuantity}"), Text("Price: ${orderItem.price}"), Text("Subtotal: ${widget.placedOrderList!.subtotal}"), Text("Gst: ${orderItem.gst}%"), @@ -703,8 +723,7 @@ class _RdOrderPendingScreenDetailScreenState ], ), ), - ) - : const SizedBox.shrink(); + ); }, ), ), @@ -713,6 +732,8 @@ class _RdOrderPendingScreenDetailScreenState ), ), ), + + const SizedBox(height: 8), SizedBox( height: Get.height* 0.19, @@ -748,7 +769,7 @@ class _RdOrderPendingScreenDetailScreenState fontWeight: FontWeight.bold, ), ), - Text("${"VAIBHAV"}",maxLines: 4, + Text("${"Roshan Garg"}",maxLines: 4, overflow:TextOverflow.ellipsis,) , ], ) @@ -769,7 +790,7 @@ class _RdOrderPendingScreenDetailScreenState fontWeight: FontWeight.bold, ), ), - Text("${"vaibhav.gurjar20001@gmail.com"}",maxLines: 4, + Text("${"roshangarg28@gmail.com"}",maxLines: 4, overflow:TextOverflow.ellipsis,) , ], ) @@ -790,7 +811,7 @@ class _RdOrderPendingScreenDetailScreenState fontWeight: FontWeight.bold, ), ), - Text("${"7779797976"}",maxLines: 4, + Text("${"8876785448"}",maxLines: 4, overflow:TextOverflow.ellipsis,) , ], ) @@ -909,7 +930,7 @@ class _RdOrderPendingScreenDetailScreenState fontWeight: FontWeight.w500, ), ), - Text(capitalizeFirstLetter(widget.placedOrderList!.paymentMode)), + Text(capitalizeFirstLetter(widget.placedOrderList!.paymentMode.toString())), // Text("${widget.placedOrderList!.paymentMode}",maxLines: 4, // overflow:TextOverflow.ellipsis,) ], diff --git a/lib/screens/rd orders/rd_pending_screen.dart b/lib/screens/rd orders/rd_pending_screen.dart index a026fa4..9a2f584 100644 --- a/lib/screens/rd orders/rd_pending_screen.dart +++ b/lib/screens/rd orders/rd_pending_screen.dart @@ -4,6 +4,7 @@ import 'package:cheminova/controller/rd_get_order_controller.dart'; import 'package:cheminova/models/get_rd_pennding_model.dart'; import 'package:cheminova/models/rd_get_order_model.dart'; import 'package:cheminova/screens/rd%20orders/rd_order_details_screen.dart'; +import 'package:cheminova/screens/rd%20orders/rd_order_details_update.dart'; import 'package:cheminova/screens/rd%20orders/rd_pending_deatils.dart'; import 'package:cheminova/widgets/input_field.dart'; import 'package:cheminova/widgets/my_drawer.dart'; @@ -12,7 +13,10 @@ 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/get_single_invoice_Service.dart'; +import '../../controller/rd_get_single_service.dart'; import '../order_management/order_management_detail_screen.dart'; class RdOrderPendingScreen extends StatefulWidget { @@ -33,7 +37,9 @@ class _RdOrderPendingScreenState extends State { "cancelled", "delivered",]; int _selectedIndex = 0; - final GetRdPendingController _getRdProductController = Get.put(GetRdPendingController()); + final GetRdPendingController _getRdPendingController = Get.put(GetRdPendingController()); + // final GetProductRDController _getRdProductController = + // Get.put(GetProductRDController()); final GlobalKey _refreshIndicatorKey = GlobalKey(); @override @@ -49,8 +55,8 @@ class _RdOrderPendingScreenState extends State { } Future getOrder1() async { - await _getRdProductController.getRDPendingProduct(); - if (_getRdProductController.productRDList.isEmpty) { + await _getRdPendingController.getRDPendingProduct(); + if (_getRdPendingController.productRDList.isEmpty) { print("No orders found."); } else { print("Orders fetched successfully"); @@ -71,6 +77,66 @@ class _RdOrderPendingScreenState extends State { return formattedDate; // Return the formatted date string } + + + void onOrderTap(int index) async { + try { + // Fetch orders and ensure you wait for it to complete + await _getRdPendingController.getRDPendingProduct(); + + // Log the count of fetched orders + print('Fetched orders count: ${_getRdPendingController.productRDList.length}'); + + // Check if the productRDList is populated + if (_getRdPendingController.productRDList.isNotEmpty) { + // Ensure the index is valid + if (index >= 0 && index < _getRdPendingController.productRDList.length) { + // Get the order ID from the list based on the index + final orderId = _getRdPendingController.productRDList[index].id; + + // Retrieve the token from SharedPreferences + SharedPreferences prefs = await SharedPreferences.getInstance(); + String? token = prefs.getString('token'); + + // Check if the token is not null + if (token != null) { + // Fetch the single order using the order ID, and avoid caching issues + final singleOrder = await GetSingleProductService().getSingleOrder(token, orderId); + final singleInvoice = await GetSingleInvoiceService().fetchInvoice(token, orderId); + // Check if the single order was fetched successfully + if (singleOrder != null) { + // Navigate to the details screen with the fetched order + Get.to(() => RdOrderPendingScreenDetailScreen( + placedOrderList: singleOrder, + orderId: orderId, + placeInvoiceList: singleInvoice, + + )); + } else { + // Handle the case where the single order could not be fetched + Get.snackbar("Error", "Unable to fetch order details."); + } + } else { + // Handle the case where the token is null + Get.snackbar("Error", "User not authenticated."); + } + } else { + // Handle the case when the index is out of bounds + Get.snackbar("Error", "Invalid order selection."); + } + } else { + // Handle the case when the list is empty + Get.snackbar("Error", "No orders available to display."); + } + } catch (e) { + // Log any errors that occur during the process + print('Error in onOrderTap: $e'); + Get.snackbar("Error", "An unexpected error occurred."); + } + } + + + @override Widget build(BuildContext context) { return Scaffold( @@ -141,7 +207,7 @@ class _RdOrderPendingScreenState extends State { SizedBox( height: Get.height * 0.6, child: Obx(() { - if (_getRdProductController.productRDList.isEmpty) { + if (_getRdPendingController.productRDList.isEmpty) { return Center( child: Text( 'No Orders Found', @@ -153,7 +219,7 @@ class _RdOrderPendingScreenState extends State { final Set uniqueOrderIds = {}; final List uniqueOrders = []; - for (var order in _getRdProductController.productRDList) { + for (var order in _getRdPendingController.productRDList) { if (uniqueOrderIds.add(order.id)) { uniqueOrders.add(order); } @@ -264,10 +330,12 @@ class _RdOrderPendingScreenState extends State { child: Padding( padding: const EdgeInsets.all(8.0), child: ElevatedButton( - onPressed: ()=> - Get.to(() => - RdOrderPendingScreenDetailScreen( - placedOrderList: uniqueOrders[index])), // Navigate to detail screen + onPressed: (){ + onOrderTap(index); + }, + // Get.to(() => + // RdOrderPendingScreenDetailScreen( + // placedOrderList: uniqueOrders[index])), // Navigate to detail screen style: ElevatedButton.styleFrom( foregroundColor: Colors.white, backgroundColor: const Color(0xFF004791), diff --git a/lib/screens/rd orders/rd_processing_details.dart b/lib/screens/rd orders/rd_processing_details.dart index 7dcab9b..36042bb 100644 --- a/lib/screens/rd orders/rd_processing_details.dart +++ b/lib/screens/rd orders/rd_processing_details.dart @@ -4,8 +4,10 @@ import 'package:get/get.dart'; import 'package:get/get_core/src/get_main.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:intl/intl.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import '../../controller/get_dispatch_controller.dart'; +import '../../controller/get_single_invoice_Service.dart'; import '../../controller/get_single_invoice_controller.dart'; import '../../controller/rd_get_order_controller.dart'; import '../../controller/rd_processing_invoice_controller.dart'; @@ -14,9 +16,10 @@ import '../../models/get_invoice_model.dart'; import '../../models/rd_processing_invoice_model.dart'; import '../../utils/show_snackbar.dart'; class RdOrderProcessingDetailScreen extends StatefulWidget { - InvoiceResponseModel? placedOrderList; + // InvoiceResponseModel? placedOrderList; GetInvoiceModel? placeInvoiceList; - RdOrderProcessingDetailScreen({super.key ,this.placedOrderList,this.placeInvoiceList}); + //final String? orderId; + RdOrderProcessingDetailScreen({super.key ,this.placeInvoiceList,}); @override State createState() => _RdOrderProcessingDetailScreenState(); @@ -29,7 +32,7 @@ class _RdOrderProcessingDetailScreenState extends State statusOptions = [ "new", "pending", @@ -60,10 +63,15 @@ class _RdOrderProcessingDetailScreenState extends State - // RdOrderDetailScreen( - // placedOrderList: uniqueOrders[index])), // Navigate to detail screen - style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, - backgroundColor: Colors.orange, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10)), + ElevatedButton( + onPressed: () {}, + // Get.to(() => + // RdOrderDetailScreen( + // placedOrderList: uniqueOrders[index])), // Navigate to detail screen + style: ElevatedButton.styleFrom( + foregroundColor: Colors.white, + backgroundColor: Colors.orange, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius + .circular(10)), + ), + child: + Text(widget.placeInvoiceList!.courierStatus.toString(), + style: GoogleFonts.roboto( + fontSize: 14, + fontWeight: FontWeight + .w400)), ), - child: - Text(widget.placedOrderList!.courierStatus, style: GoogleFonts.roboto(fontSize: 14, fontWeight: FontWeight.w400)), - ), - //Text("₹ ${widget.placedOrderList!.gstTotal}"), - ], + //Text("₹ ${widget.placedOrderList!.gstTotal}"), + ], + ), ), ), - ), - ], + ], + ), ), - ), - const SizedBox(height: 8), + const SizedBox(height: 8), - const SizedBox(height: 8), + const SizedBox(height: 8), + 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, + ), + ), + ), + ), + SizedBox( + width: Get.width, + //height: Get.height*0.09, + child: Padding( + padding: + const EdgeInsets.fromLTRB(8, 8, 8, 0), + child: Row( + children: [ + Text( + "Name: ", + style: GoogleFonts.roboto( + fontSize: Get.width * 0.04, + fontWeight: FontWeight.bold, + ), + ), + Text("${widget.placeInvoiceList!.orderId!.addedBy!.name}", maxLines: 4, + overflow: TextOverflow + .ellipsis,) + , + ], + ) + ), + ), + SizedBox( + width: Get.width, + // height: Get.height*0.09, + child: Padding( + padding: + const EdgeInsets.fromLTRB(8, 8, 8, 0), + child: Row( + children: [ + Text( + "Email: ", + style: GoogleFonts.roboto( + fontSize: Get.width * 0.04, + fontWeight: FontWeight.bold, + ), + ), + Text( + "${widget.placeInvoiceList!.orderId!.addedBy!.email}", + maxLines: 4, + overflow: TextOverflow + .ellipsis,) + , + ], + ) + ), + ), + SizedBox( + width: Get.width, + // height: Get.height*0.09, + child: Padding( + padding: + const EdgeInsets.fromLTRB(8, 8, 8, 0), + child: Row( + children: [ + Text( + "Mobile Number: ", + style: GoogleFonts.roboto( + fontSize: Get.width * 0.04, + fontWeight: FontWeight.bold, + ), + ), + Text( + "${widget.placeInvoiceList!.orderId!.addedBy!.mobileNumber}", maxLines: 4, + overflow: TextOverflow + .ellipsis,) + , + ], + ) + ), + ) - - const SizedBox(height: 8), - SizedBox( - height: Get.height* 0.19, - child: Card( + ], + ), + ), + ), + const SizedBox(height: 8), + Card( child: Column( children: [ SizedBox( @@ -389,7 +509,7 @@ class _RdOrderProcessingDetailScreenState extends State( - 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, + 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, ), ), ), - items: _statusList.map((String status) { - return DropdownMenuItem( - value: status, - child: Text(capitalizeFirstLetter(status)), - ); - }).toList(), - onChanged: (newValue) { - setState(() { - selectedStatus = newValue!; - }); - }, ), - ), - ], - ), - ), - SizedBox( - width: Get.width * 0.4, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: ElevatedButton( - onPressed: (){ - //_getDispatchController.RDProcessingToDispatchProduct(widget.placedOrderList!.invoiceId, widget.placedOrderList!., couriertrackingId) - _showDispatchDetailsDialog(); - }, - // 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( + width: Get.width, + height: Get.height * 0.06, + child: Padding( + padding: + const EdgeInsets.fromLTRB(8, 8, 8, 0), + child: Wrap( + crossAxisAlignment: WrapCrossAlignment + .start, + children: [ + Text( + "Address: ", + style: GoogleFonts.roboto( + fontSize: Get.width * 0.04, + fontWeight: FontWeight.bold, + ), + ), + Text( + "${widget.placeInvoiceList!.orderId!.shipTo}", + 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( + "Payment Mode : ", + style: GoogleFonts.roboto( + fontSize: Get.width * 0.04, + fontWeight: FontWeight.w500, + ), + ), + Text(capitalizeFirstLetter( + widget.placeInvoiceList!.orderId!.paymentMode.toString())), + // 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(widget.placedOrderList!.status)), + Text("${widget.placeInvoiceList!.courierStatus}", 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!; + }); + }, + ), + ), + ], + ), + ), + SizedBox( + width: Get.width * 0.4, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: ElevatedButton( + onPressed: () { + //_getDispatchController.RDProcessingToDispatchProduct(widget.placedOrderList!.invoiceId, widget.placedOrderList!., couriertrackingId) + _showDispatchDetailsDialog(); + }, + // 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), + SizedBox(height: Get.height * 0.04), - ], - ), + ], + + + )), ), - ), + ], ), ); diff --git a/lib/screens/rd orders/rd_processing_screen.dart b/lib/screens/rd orders/rd_processing_screen.dart index 905ad72..2faf4e5 100644 --- a/lib/screens/rd orders/rd_processing_screen.dart +++ b/lib/screens/rd orders/rd_processing_screen.dart @@ -1,4 +1,5 @@ +import 'package:cheminova/controller/get_single_invoice_controller.dart'; import 'package:cheminova/controller/rd_get_order_controller.dart'; import 'package:cheminova/controller/rd_processing_invoice_controller.dart'; import 'package:cheminova/models/rd_get_order_model.dart'; @@ -18,7 +19,9 @@ 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/get_single_invoice_Service.dart'; import '../order_management/order_management_detail_screen.dart'; class RdOrderProcessingScreen extends StatefulWidget { @@ -40,12 +43,14 @@ class _RdOrderProcessingScreenState extends State { "delivered",]; int _selectedIndex = 0; final GetRDProcessingInvoiceController _getRdProductController = Get.put(GetRDProcessingInvoiceController()); + final GetSingleInvoiceController _getSingleInvoiceController = Get.put(GetSingleInvoiceController()); final GlobalKey _refreshIndicatorKey = GlobalKey(); @override void initState() { super.initState(); getOrder1(); + } Future _onRefresh() async { @@ -65,6 +70,10 @@ class _RdOrderProcessingScreenState extends State { }); } + + + + String capitalizeFirstLetter(String text) { if (text.isEmpty) return text; return text[0].toUpperCase() + text.substring(1).toLowerCase(); @@ -80,7 +89,60 @@ class _RdOrderProcessingScreenState extends State { return formattedDate; // Return the formatted date string } - @override + + void onOrderTap(int index) async { + try { + // Fetch orders and ensure you wait for it to complete + await _getRdProductController.getRDProcessingInvoiceProduct(); + + // Log the count of fetched orders + print('Fetched orders count: ${_getRdProductController.productProcessingRDList.length}'); + + if (_getRdProductController.productProcessingRDList.isNotEmpty) { + // Ensure the index is valid + if (index >= 0 && index < _getRdProductController.productProcessingRDList.length) { + // Get the order ID from the list based on the index + final orderId = _getRdProductController.productProcessingRDList[index].id; + + // Retrieve the token from SharedPreferences + SharedPreferences prefs = await SharedPreferences.getInstance(); + String? token = prefs.getString('token'); + + // Check if the token is not null + if (token != null) { + // Fetch the single order using the order ID, and avoid caching issues + final singleOrder = await GetSingleInvoiceService().fetchInvoice(token, orderId); + + // Check if the single order was fetched successfully + if (singleOrder != null) { + // Navigate to the details screen with the fetched order + Get.to(() => RdOrderProcessingDetailScreen( + placeInvoiceList: singleOrder, + // orderId: orderId, + )); + } } else { + // Handle the case where the single order could not be fetched + Get.snackbar("Error", "Unable to fetch order details."); + } + } else { + // Handle the case where the token is null + Get.snackbar("Error", "User not authenticated."); + } + } else { + // Handle the case when the index is out of bounds + Get.snackbar("Error", "Invalid order selection."); + } + + } catch (e) { + // Log any errors that occur during the process + print('Error in onOrderTap: $e'); + Get.snackbar("Error", "An unexpected error occurred."); + } +} + + + +@override @override Widget build(BuildContext context) { return Scaffold( @@ -258,8 +320,14 @@ class _RdOrderProcessingScreenState extends State { child: Padding( padding: const EdgeInsets.all(8.0), child: ElevatedButton( - onPressed: () => - Get.to(() => RdOrderProcessingDetailScreen(placedOrderList: _getRdProductController.productProcessingRDList[index])), + onPressed: () async{ + //await _getSingleInvoiceController.fetchInvoice(widget.getrdProduct!.id); + onOrderTap(index); + // Now navigate to the details screen + //Get.to(() => RdOrderProcessingDetailScreen()); + }, + //=> + // Get.to(() => RdOrderProcessingDetailScreen(placedOrderList:_getRdProductController.productProcessingRDList[index])), style: ElevatedButton.styleFrom( foregroundColor: Colors.white, backgroundColor: const Color(0xFF004791), diff --git a/lib/utils/api_urls.dart b/lib/utils/api_urls.dart index ad96ade..8081fce 100644 --- a/lib/utils/api_urls.dart +++ b/lib/utils/api_urls.dart @@ -76,4 +76,9 @@ class ApiUrls { //============================== RD dispatched to Delivered Order Details ==============================// static const String RdDispatchtoDeliveredOrdergUrl = '/api/pd-invoice/delivered'; + + //============================== Annaouncement Details ==============================// + static const String AnnaouncementUrl = '${baseUrl}/api/announcement/PDs'; + + }