import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:supplier_new/common/settings.dart'; import 'package:supplier_new/orders/edit_order_requests.dart'; import '../resources/tankers_model.dart'; import 'best_options.dart'; class AcceptOrderRequests extends StatefulWidget { var order; var status; AcceptOrderRequests({this.order, this.status}); @override State createState() => _AcceptOrderRequestsState(); } class _AcceptOrderRequestsState extends State { int advancePayable = 0; double totalFare = 0.0; final TextEditingController tankerPriceController = TextEditingController(); double platformFee = 0.0; double totalTaxes = 0.0; double subtotal = 0.0; double cgst = 0.0; double sgst = 0.0; double total = 0.0; @override void initState() { // TODO: implement initState super.initState(); tankerPriceController.addListener(() => setState(() {})); fetchTankers(); platformFee = 11; tankerPriceController.text = '${widget.order.quoted_amount}'; } List tankersList = []; bool isLoadingTankers = false; Future fetchTankers() async { setState(() { isLoadingTankers = true; }); try { final response = await AppSettings.getTankers(); final data = (jsonDecode(response)['data'] as List) .map((e)=> TankersModel.fromJson(e)) .toList(); tankersList = data; setState(() { isLoadingTankers = false; }); } catch(e){ print(e); setState(() { isLoadingTankers = false; }); } } double getDeliveryFee(){ if(tankersList.isEmpty) return 0; String orderCapacity = widget.order.capacity .replaceAll(",", "") .replaceAll("Litres","") .replaceAll("L","") .replaceAll(" ","") .trim(); var matched = tankersList.firstWhere( (t){ String tankerCap = t.capacity .replaceAll(",", "") .replaceAll("Litres","") .replaceAll("L","") .replaceAll(" ","") .trim(); return tankerCap == orderCapacity; }, orElse: ()=>TankersModel(), ); return double.tryParse( matched.delivery_fee.toString() ) ?? 0; } double calculateTransport(){ double distance = double.tryParse( widget.order.distanceInKm .toString() ) ?? 0; double deliveryFee = getDeliveryFee(); double qty = double.tryParse( widget.order.quantity .toString() ) ?? 1; return (distance * deliveryFee * qty); } @override Widget build(BuildContext context) { int tankerPrice = int.tryParse(tankerPriceController.text) ?? 0; int updatedQuantity=int.tryParse(widget.order.quantity) ?? 0; String updatedCapacity=widget.order.capacity; int bookingCharges = calculateTransport().round(); //int totalPrice = (tankerPrice * updatedQuantity) + bookingCharges; int advancePayable = bookingCharges; // //int amountToPayAfterDelivery=totalPrice-bookingCharges; double distance = double.tryParse( widget.order.distanceInKm.toString() ) ?? 0; double perKm = getDeliveryFee(); double transport = calculateTransport(); double actualPrice = double.tryParse( tankerPriceController.text ) ?? 0; double quantity = double.tryParse( widget.order.quantity.toString() ) ?? 1; double subtotal = actualPrice * quantity; double cgst = subtotal * 0.09; double sgst = subtotal * 0.09; double totalTaxes = cgst + sgst; double totalPrice = subtotal + transport + totalTaxes + platformFee; double amountToPayAfterDelivery = totalPrice - transport; return Scaffold( backgroundColor: Colors.white, extendBodyBehindAppBar: true, appBar: AppBar( backgroundColor: Colors.transparent, elevation: 0, scrolledUnderElevation: 0, title: Text( '', style: fontTextStyle(16, Color(0XFF2A2A2A), FontWeight.w600), ), iconTheme: IconThemeData(color: Color(0XFF2A2A2A)), actions: [ Row( children: [ Padding( padding: EdgeInsets.fromLTRB(0, 10, 10, 10), child: IconButton( icon: Image.asset( 'images/help_appbar.png', height: 20, width: 20, color: Color(0XFFFFFFFF), ), onPressed: () {}, ), ) ], ) ], leading: GestureDetector( onTap: () { Navigator.pop(context); }, child: Padding( padding: const EdgeInsets.fromLTRB(8, 8, 8, 8), // Add padding if needed child: Image.asset( 'images/backbutton_appbar.png', // Replace with your image path fit: BoxFit.contain, color: Color(0XFFFFFFFF), height: 24, width: 24, ), ), ), ), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ /// 🔹 Top Card with Image Stack( clipBehavior: Clip.none, children: [ /// 🔹 Background Image ClipRRect( borderRadius: const BorderRadius.only( bottomLeft: Radius.circular(0), bottomRight: Radius.circular(0), ), child: Image.asset( "images/building.png", height: 220, width: double.infinity, fit: BoxFit.cover, ), ), /// 🔹 Floating Info Card (half on image, half below) Positioned( bottom: -40, // pulls the card out by 40px left: 12, right: 12, child: Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black12, blurRadius: 6, offset: Offset(0, 3), ), ], ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4), decoration: BoxDecoration( color: Color(0XFFFFFFFF), borderRadius: BorderRadius.circular(4), border: Border.all( color: widget.status.statusColor, width: 0.5, ), ), child: Text(widget.status.status, style: fontTextStyle( 12, widget.status.statusColor, FontWeight.w500)), ), Text( widget.order.building_name, style: fontTextStyle( 20, const Color(0XFF2D2E30), FontWeight.w600), ), SizedBox(height: 4), Text( widget.order.displayAddress, style: fontTextStyle( 12, const Color(0XFF939495), FontWeight.w400), ), ], ), const Spacer(), Text( widget.order.distanceInKm.toString() + 'Km', style: fontTextStyle( 12, const Color(0XFF939495), FontWeight.w400), ), ], ), ), ), ], ), SizedBox( height: MediaQuery.of(context).size.height * .08, ), /// 🔹 Order Details Padding( padding: EdgeInsets.fromLTRB(16, 0, 16, 0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "ORDER DETAILS", style: fontTextStyle( 10, const Color(0XFF2D2E30), FontWeight.w600), ), SizedBox( height: MediaQuery.of(context).size.height * .011, ), _twoFields(tankerPriceController, "Tanker Price", 'images/price.png', false, null, null, null, null), /*_detailTwoRow( "Tanker Price", "₹${AppSettings.formDouble(widget.order.quoted_amount) ?? ''}", "images/financialsBottomIcon.png", "", "", ""),*/ _detailTwoRow( "Transport Charges", "₹ " + AppSettings.formDouble( transport.toString()), "images/advance.png", "", "", "", ), Padding( padding: EdgeInsets.only(left:4), child: Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ Image.asset( 'images/warning.png', fit: BoxFit.cover, width: 22, // Match the diameter of the CircleAvatar height: 22, ), SizedBox(width: MediaQuery.of(context).size.width * .020), Expanded( child: Text( "Transport charges are calculated based on distance ${distance.toStringAsFixed(2)} km and rate ₹${perKm.toStringAsFixed(0)} per km. Total transport charges are ₹${transport.toStringAsFixed(0)}.", softWrap:true, style: fontTextStyle( 11, Color(0XFF646566), FontWeight.w400), ), ), ], ) ), _detailTwoRow( "Water Type", "${widget.order.type_of_water}", "images/water.png", "Date of Delivery", "${widget.order.date}", "images/calendar_appbar.png", ), SizedBox( height: MediaQuery.of(context).size.height * .02, ), _detailTwoRow( "Capacity", "${widget.order.capacity}", "images/capacity.png", "Time of Delivery", "${widget.order.averageTime}", "images/time.png", ), SizedBox( height: MediaQuery.of(context).size.height * .02, ), _detailTwoRow( "Quantity", "${widget.order.quantity}", "images/quantity.png", "", "", "", ), ], ), ), SizedBox( height: MediaQuery.of(context).size.height * .008, ), /// 🔹 Additional Details /* Padding( padding: EdgeInsets.fromLTRB(16, 0, 16, 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "ADDITIONAL DETAILS", style: fontTextStyle( 10, const Color(0XFF2D2E30), FontWeight.w600), ), SizedBox( height: MediaQuery.of(context).size.height * .011, ), Text( "Lorem ipsum dolor sit amet, consectetur adipiscing elit, " "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. " "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut " "aliquip ex ea commodo consequat.", style: fontTextStyle( 12, const Color(0XFF646566), FontWeight.w400), ), ], )),*/ /// 🔹 Payment Summary /*Padding( padding: EdgeInsets.fromLTRB(16, 0, 16, 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "PAYMENT SUMMARY", style: fontTextStyle( 10, const Color(0XFF2D2E30), FontWeight.w600), ), SizedBox( height: MediaQuery.of(context).size.height * .011, ), _detailRow("Tanker Price", "₹${AppSettings.formDouble(widget.order.quoted_amount) ?? ''}"), SizedBox( height: MediaQuery.of(context).size.height * .004, ), _detailRow("Booking Charges", "₹ " + advance.toString()), SizedBox( height: MediaQuery.of(context).size.height * .004, ), _detailRow("Total Amount", "₹ " + totalFare.toString()), SizedBox( height: MediaQuery.of(context).size.height * .004, ), Divider( color: Color(0XFF646566), thickness: 0.3, ), SizedBox( height: MediaQuery.of(context).size.height * .004, ), _detailRow("Booking Charges Payable", '₹${AppSettings.formDouble(advancePayable.toString()) ?? ''}'), SizedBox( height: MediaQuery.of(context).size.height * .004, ), _detailRow("Amount to Pay (After Delivery)", '₹${AppSettings.formDouble(amountToPayAfterDelivery.toString()) ?? ''}'), ], ), ),*/ const SizedBox(height: 20), Padding( padding: EdgeInsets.fromLTRB(16, 0, 16, 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("UPDATED PAYMENT SUMMARY", style: fontTextStyle(12,Color(0XFF2D2E30),FontWeight.w600),), const SizedBox(height: 12), _summaryRow("Quantity", " $updatedQuantity"), _summaryRow("Capacity", "$updatedCapacity"), _summaryRow("Tanker Price", "₹ $tankerPrice"), _summaryRow("Transport Charges", "₹ $bookingCharges"), _summaryRow('Platform Fee', '₹${AppSettings.moneyConvertion(platformFee.toString())}'), _summaryRow('Taxes', '₹${AppSettings.moneyConvertion(totalTaxes.toString())}'), _summaryRow( "Total Price", "₹ ${AppSettings.formDouble(totalPrice.toString())}" ), const Divider(), _summaryRow( "Transport Charges", "₹ ${AppSettings.formDouble(transport.toString())}" ), _summaryRow("Amount to Pay (After Delivery)", "₹ $amountToPayAfterDelivery"), ], )), const SizedBox(height: 80), // space for bottom buttons ], ), ), /// 🔹 Bottom Action Buttons bottomNavigationBar: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( color: Color(0XFFFFFFFF), border: Border(top: BorderSide(color: Color(0XFFF5F6F6))), ), child: Row( children: [ /* Expanded( child: OutlinedButton( style: OutlinedButton.styleFrom( foregroundColor: Color(0XFF000000), backgroundColor: Color(0xFFF1F1F1), side: BorderSide(color: Color(0xFFF1F1F1)), padding: EdgeInsets.symmetric(vertical: 10), // uniform height ), onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (_) => EditOrderRequests( order: widget.order, advance: advance.toString(), status: widget.status, ), ), ); }, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset('images/edit.png', height: 20, width: 20), SizedBox(width: 4), Text( "Edit Order", style: fontTextStyle( 14, const Color(0XFF000000), FontWeight.w400), ), ], ), ), ), SizedBox(width: 8),*/ Expanded( child: OutlinedButton( style: OutlinedButton.styleFrom( foregroundColor: Color(0XFFE2483D), backgroundColor: Colors.white, side: BorderSide(color: Color(0XFFE2483D)), padding: EdgeInsets.symmetric(vertical: 10), ), onPressed: ()async { AppSettings.preLoaderDialog(context); bool isOnline = await AppSettings.internetConnectivity(); if (isOnline) { var payload = new Map(); payload["supplierId"] = AppSettings.supplierId; payload["amount"] = int.parse(tankerPriceController.text); payload["delivery_charges"] = calculateTransport().round(); payload["action"] = 'reject'; bool status = await AppSettings.acceptOrderRequests( payload, widget.order.dbId); try { if (status) { Navigator.of(context,rootNavigator: true).pop(); AppSettings.longSuccessToast("Order request rejected Successfully"); Navigator.pop(context, true); } else{ Navigator.of(context,rootNavigator: true).pop(); AppSettings.longFailedToast("reject of order request Failed"); } } catch (e) { Navigator.of(context,rootNavigator: true).pop(); print(e); } } else{ Navigator.of(context,rootNavigator: true).pop(); AppSettings.longFailedToast("Please Check internet"); } }, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset('images/cross.png', height: 20, width: 20), SizedBox(width: 4), Text( "Reject", style: fontTextStyle( 14, const Color(0XFF000000), FontWeight.w400), ), ], ), ), ), SizedBox(width: 8), Expanded( child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Color(0XFF0A9E04), foregroundColor: Color(0XFFFFFFFF), padding: EdgeInsets.symmetric(vertical: 10), ), onPressed: () async { AppSettings.preLoaderDialog(context); bool isOnline = await AppSettings.internetConnectivity(); if (isOnline) { var payload = new Map(); payload["supplierId"] = AppSettings.supplierId; payload["amount"] = int.parse(tankerPriceController.text); payload["delivery_charges"] = calculateTransport().round(); payload["action"] = 'accept'; bool status = await AppSettings.acceptOrderRequests( payload, widget.order.dbId); try { if (status) { Navigator.of(context,rootNavigator: true).pop(); Navigator.pop(context, true); } else{ Navigator.of(context,rootNavigator: true).pop(); AppSettings.longFailedToast("Accept of order request Failed"); } } catch (e) { Navigator.of(context,rootNavigator: true).pop(); print(e); } } else{ Navigator.of(context,rootNavigator: true).pop(); AppSettings.longFailedToast("Please Check internet"); } }, /*onPressed:(){ Navigator.push( context, MaterialPageRoute( builder:(_)=>TankerOptionsDemo() ) ); },*/ child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Image.asset('images/rite.png', height: 20, width: 20), SizedBox(width: 4), Text( "Accept", style: fontTextStyle( 14, const Color(0XFFFFFFFF), FontWeight.w400), ), ], ), ), ), ], )), ); } /// 🔹 Helper widget for rows Widget _detailRow(String title, String value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( title, style: fontTextStyle(12, const Color(0XFF646566), FontWeight.w400), ), Text( value, style: fontTextStyle(12, const Color(0XFF2D2E30), FontWeight.w500), ), ], ), ); } Widget _twoFields( TextEditingController? controller1, String? label1, String? path1, bool? readOnly1, TextEditingController? controller2, String? label2, String? path2, bool? readOnly2) { return Row( children: [ Expanded( child: _textField(controller1, label1, path1, readOnly1!), ), const SizedBox(width: 10), if (controller2 != null) Expanded( child: _textField(controller2, label2, path2, readOnly2!), ), ], ); } Widget _textField(TextEditingController? controller, String? label, String? path, bool readOnly) { return Container( margin: const EdgeInsets.only(bottom: 12), child: TextField( controller: controller, cursorColor: primaryColor, readOnly: readOnly, decoration: InputDecoration( counterText: '', filled: false, fillColor: Colors.white, prefixIcon: Padding( padding: const EdgeInsets.symmetric(horizontal: 6.0, vertical: 6.0), child: SizedBox( width: 18, height: 18, child: Image.asset( path!, fit: BoxFit.contain, color: Color(0XFFC3C4C4), ), ), ), prefixIconConstraints: BoxConstraints( minWidth: 24, minHeight: 24, ), suffixIcon: readOnly ? null : Padding( padding: const EdgeInsets.only(right: 8), child: Image.asset( 'images/edit.png', height: 18, width: 18, color: const Color(0XFFC3C4C4), ), ), suffixIconConstraints: BoxConstraints( minWidth: 24, minHeight: 24, ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(4.0), borderSide: BorderSide( color: Color(0XFFC3C4C4), width: 1, )), focusedBorder: !readOnly ? OutlineInputBorder( borderRadius: BorderRadius.circular(4.0), borderSide: BorderSide( color: Color(0XFF8270DB), width: 1, ), ) : OutlineInputBorder( borderRadius: BorderRadius.circular(4.0), borderSide: BorderSide( color: Color(0XFFC3C4C4), width: 1, ), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(4.0), borderSide: BorderSide(color: Color(0XFFC3C4C4)), ), labelText: label, labelStyle: fontTextStyle(12, Color(0XFF646566), FontWeight.w400), /* TextStyle(color: greyColor, fontWeight: FontWeight.bold //<-- SEE HERE ),*/ ), style: fontTextStyle(12, Color(0XFF343637), FontWeight.w500), ), ); } Widget _summaryRow(String title, String value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 6), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(title, style: fontTextStyle(12,Color(0XFF646566),FontWeight.w400),), Text(value, style: fontTextStyle(12,Color(0XFF2D2E30),FontWeight.w500),), ], ), ); } Widget _detailTwoRow( String title1, String value1, String path1, String title2, String value2, String path2, { EdgeInsetsGeometry padding = const EdgeInsets.symmetric(vertical: 6), }) { final titleStyle = fontTextStyle(12, Color(0XFF646566), FontWeight.w400); final valueStyle = fontTextStyle(12, Color(0XFF343637), FontWeight.w500); Widget _col(String t, String v, String path) { return Expanded( child: Padding( padding: const EdgeInsets.only(right: 8.0), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ if (path.isNotEmpty) Image.asset( path, fit: BoxFit.contain, height: 20, width: 20, color: const Color(0XFFC3C4C4), ), if (path.isNotEmpty) const SizedBox(width: 6), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(t, style: titleStyle, maxLines: 1, overflow: TextOverflow.ellipsis), Text(v, style: valueStyle, maxLines: 1, overflow: TextOverflow.ellipsis), ], ), ) ], ), ), ); } return Padding( padding: padding, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _col(title1, value1, path1), _col(title2, value2, path2), ], ), ); } }