import 'dart:convert'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:intl/intl.dart'; import 'package:toggle_switch/toggle_switch.dart'; import '../../constants.dart'; import '../../events/eventbus.dart'; import '../../events/events.dart'; import '../../generated/l10n.dart'; import '../../models/address.dart'; import '../../models/booking_date_time.dart'; import '../../models/booking_time.dart'; import '../../models/cart_info.dart'; import '../../models/cart_line_item.dart'; import '../../models/coupon.dart'; import '../../models/error_message.dart'; import '../../models/order.dart'; import '../../models/payment_platform.dart'; import '../../models/shipping_rate.dart'; import '../../models/text_value.dart'; import '../../routes.dart'; import '../../store/actions.dart'; import '../../store/store.dart'; import '../../utils/http_util.dart'; import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart'; import '../../utils/utils.dart'; import '../../widgets/general/sliding_up_panel.dart'; class MobileCheckout extends StatefulWidget { final Key key; final int businessId; const MobileCheckout(this.businessId, {this.key,}) : super(key: key); @override State createState() { return MobileCheckoutState(); } } class MobileCheckoutState extends State with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin { CartInfo cartInfo; Address shipAddress; bool canSubmit; List errorMessages; List bookingTimeList; List bookingDateTimeList; List paymentPlatforms; TextValue durationInTraffic; int selectedCoupon; double couponDiscountAmount = 0; List coupons; int peopleCount = 2; final TextEditingController remarkController = new TextEditingController(); String orderRemark = ''; int deliveryMethodIndex = 0; String deliveryMethod; List shippingRates = []; ShippingRate selectedShippingRate; List shippingMethodLabels = []; List shippingMethodIcons = []; GlobalKey _scaffoldKey = GlobalKey(); int bookingDateIndex; int bookingTimeIndex; int paymentPlatformIndex; GlobalKey slidingUpPanelKey = GlobalKey(); SlidingUpPanel slidingUpPanel; PanelController panelController = PanelController(); Widget panel; double subtotal; TextEditingController newCouponController = TextEditingController(); @override Widget build(BuildContext context) { super.build(context); store.dispatch(UpdateContext(context)); if (cartInfo == null ) { return new Scaffold( body: Center( child: SpinKitWave( color: Colors.lightBlueAccent, size: 40.0, ), ), ); } if (cartInfo.businessInfo.deliveryPickup == false && cartInfo.businessInfo.deliveryCanadaPost == false && cartInfo.businessInfo.deliveryStoreDelivery == false) { return Scaffold( body: Container( child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( S.of(context).no_delivery_method, ), RaisedButton( color: Theme.of(context).primaryColor, child: Text( S.of(context).ok, style: TextStyle( color: Colors.white, ), ), onPressed: () { Navigator.of(context).pop(); }, ), ], ), ), ), ); } WidgetsBinding.instance.addPostFrameCallback((timeStamp) { if(errorMessages.length > 0) { print('error: ${errorMessages.toString()}'); // _scaffoldKey.currentState.showSnackBar(errorSnackBar(errorMessages)); ScaffoldMessenger.of(context).showSnackBar(errorSnackBar(errorMessages)); } }); if (panel != null) { slidingUpPanel = SlidingUpPanel( key: slidingUpPanelKey, minHeight: 0.0, maxHeight: 400.0, backdropEnabled: true, backdropTapClosesPanel: false, isDraggable: false, controller: panelController, panel: panel, body: mainBody(), ); } Scaffold scaffold = Scaffold( key: _scaffoldKey, appBar: AppBar( leading: IconButton( icon: Icon(Icons.arrow_back_ios), onPressed: (){ Navigator.of(context).pop(); }, ), title: Text(S.of(context).confirm_order), backgroundColor: Theme.of(context).primaryColor, centerTitle: true, ), body: WillPopScope( child: slidingUpPanel, onWillPop: () async { if (panelController != null && panelController.isPanelOpen) { panelController.close(); return false; } return true; }, ), bottomNavigationBar: Container( padding: EdgeInsets.only(top: 0.0, bottom: 0.0, left: 0.0, right: 0.0), height: 55.0, // color: Colors.black87, child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( flex: 2, child: Container( height: 55.0, color: Colors.black87, alignment: Alignment.centerLeft, padding: EdgeInsets.only(top: 12.0, bottom: 12.0, left: 16.0, right: 16.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '\$${(cartInfo.totalPrice - couponDiscountAmount).toStringAsFixed(2)}', style: TextStyle( fontSize: 20.0, color: Colors.white, ), ), cartInfo.businessInfo.isPublic ? SizedBox.shrink() : Container( padding: EdgeInsets.only(top: 2.0, bottom: 2.0, left: 5.0, right: 5.0), width: 100.0, color: Colors.red, child: Text( S.of(context).under_renovation, style: TextStyle( color: Colors.white, fontSize: 10.0, ), maxLines: 3, softWrap: true, textAlign: TextAlign.center, ), ), ], ), ), ), Expanded( flex: 1, child: GestureDetector( child: Container( height: 55.0, color: canSubmit ? Colors.lightGreen : Colors.grey, child: Center( child: Text( S.of(context).pay_now, style: TextStyle( color: Colors.white, fontSize: 20.0, ), ), ), ), onTap: () { confirmOrder(); }, ), ), ], ), ), ); return scaffold; } String getShippingMethod(int index) { if (shippingMethodLabels[index] == S.of(context).delivery) { return 'store-delivery'; } else if (shippingMethodLabels[index] == S.of(context).pickup) { return 'pickup'; } else if (shippingMethodLabels[index] == S.of(context).canada_post) { return 'canada-post'; } return 'store-delivery'; } Widget mainBody() { return ListView.builder( itemCount: 6, addAutomaticKeepAlives: true, itemBuilder: (BuildContext context, int position) { var deliveryTimeInSeconds = cartInfo.businessInfo.shippingTime * 60 + (durationInTraffic != null ? durationInTraffic.value : 0); print('aaa: $deliveryTimeInSeconds'); DateTime now = DateTime.now(); var formatter = DateFormat('H:mm'); String deliveryAt = formatter.format(now.add(Duration(seconds: deliveryTimeInSeconds))); Widget peopleCountSelection = Container( padding: EdgeInsets.only(left: 0.0, right: 0.0, top: 0.0, bottom: 0.0), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( S.of(context).table_token(store.state.tableNumber), style: TextStyle( fontSize: 20.0, fontWeight: FontWeight.bold, ), ), Container( child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Container( margin: EdgeInsets.only(right: 10.0), child: Text(S.of(context).number_of_people), ), DropdownButton( value: peopleCount, items: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ].map((value) { return DropdownMenuItem( value: value, child: Text(value.toString()), ); }).toList(), onChanged: (newValue) { if (mounted) { setState(() { peopleCount = newValue; }); } }, hint: Text(S.of(context).number_of_people), isExpanded: false, ) ], ), ), ], ), ); ToggleSwitch toggleSwitch = ToggleSwitch( minWidth: 160.0, cornerRadius: 20, activeBgColor: [Colors.green], activeFgColor: Colors.white, inactiveBgColor: Colors.grey, inactiveFgColor: Colors.white, labels: shippingMethodLabels, icons: shippingMethodIcons, onToggle: (index) { selectedShippingRate = null; deliveryMethod = getShippingMethod(index); check(); }, initialLabelIndex: deliveryMethodIndex, ); switch (position) { case 0: if (cartInfo.businessInfo.deliveryPickup) { return Container( padding: EdgeInsets.only( top: 16.0, bottom: 16.0, left: 16.0, right: 16.0), decoration: BoxDecoration( border: Border( top: BorderSide( width: 10.0, color: Colors.black12, ), ), ), child: Container( alignment: Alignment.centerLeft, child: store.state.deviceId != null && store.state.deviceId.isNotEmpty ? ( store.state.tableNumber != null && store.state.tableNumber.isNotEmpty ? peopleCountSelection : SizedBox.shrink() ) : Center(child: toggleSwitch,), ), ); } else { return Container( child: SizedBox(), ); } break; case 1: if (store.state.deviceId != null && store.state.deviceId.isNotEmpty || store.state.tableNumber != null && store.state.tableNumber.isNotEmpty) { return SizedBox.shrink(); } if (deliveryMethod == 'pickup') { return Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0, bottom: 16.0), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( S.of(context).pickup_at, style: TextStyle( fontSize: 20.0, ), ), Container( margin: EdgeInsets.only(top: 10.0), child: Text( cartInfo.businessInfo.name, style: TextStyle( fontSize: 17.0, ), ), ), Container( margin: EdgeInsets.only(top: 5.0), child: Text( cartInfo.businessInfo.address.addressLine1, style: TextStyle( fontSize: 14.0, color: Colors.black45, ), ), ), Container( child: cartInfo.businessInfo.address.addressLine2 != null && cartInfo.businessInfo.address.addressLine2.length > 0 ? Text(cartInfo.businessInfo.address.addressLine2, style: TextStyle( fontSize: 14.0, color: Colors.black45, ), ) : SizedBox.shrink(), ), Container( child: Text( '${cartInfo.businessInfo.address.city}, ${cartInfo.businessInfo.address.state}, ${cartInfo.businessInfo.address.zip}', style: TextStyle( fontSize: 14.0, color: Colors.black45, ), ), ), Container( margin: EdgeInsets.only(top: 5.0), child: Text( 'Tel: ${cartInfo.businessInfo.phone}', style: TextStyle( fontSize: 15.0, color: Colors.black54, ) ), ) ], ), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 0.5, color: Colors.black12, ) ), ), ); } return GestureDetector( child: Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0, bottom: 16.0), child: Container( padding: EdgeInsets.only(bottom: 16.0), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 0.5, color: Colors.black12, ) ) ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( child: Text( shipAddress != null ? shipAddress.fullAddress : S.of(context).enter_delivery_address, style: TextStyle( fontSize: 16.0 ), maxLines: 2, overflow: TextOverflow.ellipsis, ), ), Container( padding: EdgeInsets.only(top: 6.0), child: Text( shipAddress != null ? shipAddress.contactName + ' ' + shipAddress.phone : '', style: TextStyle( fontSize: 14.0, color: Colors.black38, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ) ], ), ), Container( child: Icon( Icons.arrow_forward_ios, color: Colors.black38, size: 18.0, ), ) ], ), ), ), onTap: () { Routes.router.navigateTo(context, '/my-addresses/${cartInfo.businessInfo.id}', replace: true); }, ); break; case 2: if (deliveryMethod == 'pickup' || store.state.deviceId != null && store.state.deviceId.isNotEmpty || store.state.tableNumber != null && store.state.tableNumber.isNotEmpty) { return SizedBox.shrink(); } if (deliveryMethod == 'canada-post') { return GestureDetector( child: Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 0.0, bottom: 16.0), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Colors.black12, width: 10.0, ) ) ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( margin: EdgeInsets.only(right: 10.0), child: Text( S.of(context).canada_post_delivery, style: TextStyle( fontSize: 17.0, fontWeight: FontWeight.bold, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), Expanded( flex: 1, child: Container( alignment: Alignment.centerRight, child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( child: Container( margin: EdgeInsets.only(right: 5.0), alignment: Alignment.centerRight, child: Text( selectedShippingRate != null ? '${selectedShippingRate.name} \$${selectedShippingRate.price.toStringAsFixed(2)}' : S.of(context).please_select, style: TextStyle( fontSize: 15.0, color: Colors.black38, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), ), Container( child: Icon( Icons.arrow_forward_ios, color: Colors.black38, size: 18.0, ), ), ], ), ), ), ], ), ), onTap: () { onCanadaPostTapped(); }, ); } if (!cartInfo.businessInfo.instanceDelivery) { return Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 0.0, bottom: 16.0), child: Text(S.of(context).no_instance_delivery_desc), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Colors.black12, width: 10.0, ) ) ) ); } return GestureDetector( child: Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 0.0, bottom: 16.0), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Colors.black12, width: 10.0, ) ) ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( child: Text( bookingTimeList.length > 0 || bookingDateTimeList.length > 0 ? S.of(context).delivery_now : S.of(context).delivery_unavailable, style: TextStyle( fontSize: 17.0, fontWeight: FontWeight.bold, ), ), ), Container( child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( child: Text( bookingTimeList.length > 0 ? '${Utils.timestampToString(context, bookingTimeList[bookingTimeIndex].unixTime)}' : ((bookingTimeList.length == 0 && bookingDateTimeList.length == 0) ? '' : bookingDateTimeList[bookingDateIndex].viewDate + ' ' + (bookingDateTimeList[bookingDateIndex].bookTimes.length > 0 ? bookingDateTimeList[bookingDateIndex].bookTimes[bookingTimeIndex].viewTime : '')), ), ), Container( child: Icon( Icons.arrow_forward_ios, size: 18.0, color: Colors.grey, ), ), ], ), ), ], ), ), onTap: onDeliveryTap, ); case 3: return SizedBox.shrink(); // disable payment panel return Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0, bottom: 16.0), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 10.0, color: Colors.black12, ), ), ), child: GestureDetector( child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( child: Text( S.of(context).payment_method, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 17.0, ), ), ), Container( child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( child: Text( paymentPlatforms.length == 0 ? S.of(context).pay_on_deliery : PaymentPlatform.getPaymentPlatformName(context, paymentPlatforms[paymentPlatformIndex].code), ), ), Container( child: Icon( Icons.arrow_forward_ios, size: 18.0, color: Colors.grey, ), ) ], ), ), ], ), onTap: () { onPaymentMethodTapped(); }, ), ); break; case 4: Column column = Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [], ); column.children.add(Container( width: double.infinity, padding: EdgeInsets.only(bottom: 10.0), child: Text( cartInfo.businessInfo.name, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 16.0, fontWeight: FontWeight.bold, ), ), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Colors.black12, width: 0.5, ), ), ), ),); subtotal = 0.0; for (var i = 0; i < cartInfo.productList.length; i++) { subtotal += cartInfo.productList[i].totalPrice; column.children.add(lineItem(cartInfo.productList[i])); } column.children.add(GestureDetector( child: Container( margin: EdgeInsets.only(top: 8.0), padding: EdgeInsets.only(top: 16.0, bottom: 16.0), decoration: BoxDecoration( border: Border( top: BorderSide( width: 0.5, color: Colors.black12, ), bottom: BorderSide( width: 0.5, color: Colors.black12, ), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Container( child: Text( S.of(context).credit_coupon, style: TextStyle( fontSize: 16.0, fontWeight: FontWeight.bold, ), ), ), ), Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( child: Text( getSelectedCouponName(), style: TextStyle( color: Colors.grey, fontSize: 14.0, ), ), ), Container( child: Icon( Icons.arrow_forward_ios, color: Colors.black38, size: 18.0, ), ) ], ) ], ), ), onTap: () { onCouponsTapped(); }, )); column.children.add(Container( alignment: Alignment.centerRight, padding: EdgeInsets.only(top: 16.0, bottom: 16.0), child: Row( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( child: Text( S.of(context).subtotal, style: TextStyle( color: Colors.grey, ), ), ), Container( width: 100.0, alignment: Alignment.centerRight, child: Text( '${(subtotal - couponDiscountAmount).toStringAsFixed(2)}', style: TextStyle( fontSize: 16.0, fontWeight: FontWeight.bold, ), ), ), ], ), )); if (cartInfo.extraFeeList.length > 0) { for (var i = 0; i < cartInfo.extraFeeList.length; i++) { column.children.add(Container( padding: EdgeInsets.only(bottom: 16.0), alignment: Alignment.centerRight, child: Row( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( alignment: Alignment.centerRight, child: Text( S.of(context).extra_fee_token(cartInfo.extraFeeList[i].name, cartInfo.extraFeeList[i].rate), style: TextStyle( color: Colors.grey, ), ), ), Container( width: 100.0, alignment: Alignment.centerRight, child: Text( '${cartInfo.extraFeeList[i].price.toStringAsFixed(2)}' ), ), ], ), )); } } column.children.add(Container( alignment: Alignment.centerRight, padding: EdgeInsets.only(bottom: 16.0), child: Row( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( child: Text( S.of(context).total, style: TextStyle( color: Colors.grey, ), ), ), Container( width: 100.0, alignment: Alignment.centerRight, child: Text( '${(cartInfo.totalPrice - couponDiscountAmount).toStringAsFixed(2)}', style: TextStyle( fontSize: 19.0, fontWeight: FontWeight.bold, ), ), ), ], ), )); return Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0, bottom: 16.0), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Colors.black12, width: 10.0, ), ), ), child: column, ); break; case 5: return GestureDetector( child: Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0, bottom: 16.0), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Colors.black12, width: 160.0, ), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( child: Text( S.of(context).order_remark, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 17.0, ), ), ), Container( child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Container( width: 100.0, margin: EdgeInsets.only(right: 5.0), child: Text( orderRemark, maxLines: 1, style: TextStyle( fontSize: 12.0, color: Colors.black26, ), overflow: TextOverflow.ellipsis, ), ), Icon( Icons.arrow_forward_ios, color: Colors.grey, size: 18.0, ) ], ), ), ], ), ), onTap: () { onRemarkTapped(); }, ); break; default: return SizedBox(); } }, ); } Widget lineItem(CartLineItem cartLineItem) { return Container( padding: EdgeInsets.only(top: 16.0, bottom: 0.0), child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: EdgeInsets.all(5.0), child: Util.showImage('${cartLineItem.product.imagePath}', width: 40.0, height: 40.0, fit: BoxFit.fill, errorWidget: (context, url, error) => Icon(Icons.broken_image, size: 40.0, color: Colors.transparent,), ), ), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( child: Text( Utils.knownName(context, cartLineItem.name), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), Container( child: Text( cartLineItem.description, style: TextStyle( fontSize: 12.0, color: Colors.black38, ), overflow: TextOverflow.ellipsis, maxLines: 3, ), ) ], ), ), Container( alignment: Alignment.centerRight, margin: EdgeInsets.only(right: 10.0), child: Text( 'x${cartLineItem.quantity.round()}', ), ), Container( width: 60.0, alignment: Alignment.centerRight, child: Text( '${cartLineItem.totalPrice.toStringAsFixed(2)}', ), ), ], ), ); } @override void initState() { super.initState(); canSubmit = false; errorMessages = []; bookingTimeList = []; bookingDateTimeList = []; paymentPlatforms = []; bookingDateIndex = 0; bookingTimeIndex = 0; paymentPlatformIndex = 0; deliveryMethodIndex = 0; deliveryMethod = ''; panel = Container( child: SizedBox(), ); remarkController.addListener(remarkChangeListener); check(); } void check() { if (cartInfo != null) { Utils.showLoadingDialog(context); } CartInfo ci = Utils.getCartInfoByBusinessId(store.state.cartInfos, widget.businessId); HttpUtil.httpPost('v1/orders/check', (response) { if (cartInfo != null) { Navigator.of(context).pop(); } Utils.jsonPrettyPrint(response.data); if (mounted) { shippingMethodLabels.clear(); shippingMethodIcons.clear(); setState(() { cartInfo = CartInfo.fromJson(response.data['cart_info']); shipAddress = response.data['last_address'] != null ? Address.fromJson(response.data['last_address']) : null; canSubmit = response.data['can_submit']; errorMessages = (response.data['error_messages'] as List).map((e) => ErrorMessage.fromJson(e)).toList(); bookingTimeList = (response.data['booking_time_list'] as List).map((e) => BookingTime.fromJson(e)).toList(); bookingDateTimeList = (response.data['booking_date_time_list'] as List).map((e) => BookingDateTime.fromJson(e)).toList(); paymentPlatforms = (response.data['payment_platforms'] as List).map((e) => PaymentPlatform.fromJson(e)).toList(); durationInTraffic = response.data['duration_in_traffic'] != null ? TextValue.fromJson(response.data['duration_in_traffic']) : null; selectedCoupon = response.data['selected_coupon']; coupons = (response.data['coupons'] as List).map((e) => Coupon.fromJson(e)).toList(); deliveryMethod = response.data['delivery']; shippingRates = (response.data['shipping_rates'] as List).map((e) => ShippingRate.fromJson(e)).toList(); selectedShippingRate = (response.data['selected_shipping_rate'] as String).length > 0 ? ShippingRate.fromJson(json.decode(response.data['selected_shipping_rate'])) : null; int i = 0; if (cartInfo.businessInfo.deliveryStoreDelivery) { shippingMethodLabels.add(S.of(context).delivery); shippingMethodIcons.add(Icons.directions_car); if (deliveryMethod == 'store-delivery') { deliveryMethodIndex = i; } i++; } if (cartInfo.businessInfo.deliveryCanadaPost) { shippingMethodLabels.add(S.of(context).canada_post); shippingMethodIcons.add(Icons.local_shipping); if (deliveryMethod == 'canada-post') { deliveryMethodIndex = i; } i++; } if (cartInfo.businessInfo.deliveryPickup) { shippingMethodLabels.add(S.of(context).pickup); shippingMethodIcons.add(Icons.store); if (deliveryMethod == 'pickup') { deliveryMethodIndex = i; } i++; } }); } }, businessId: widget.businessId, body: { 'product_list': ci.productList.toString(), 'extra_data': ci.extraData, 'business_id': widget.businessId, 'pay_method': getPaymentMethod(), 'delivery': deliveryMethod, 'selected_coupon': selectedCoupon, 'selected_shipping_rate': selectedShippingRate != null ? selectedShippingRate.toString() : '', 'shipping_rates': shippingRates.toString(), 'device_id': store.state.deviceId != null ? store.state.deviceId : '', 'table_number': store.state.tableNumber != null ? store.state.tableNumber : '', }, isFormData: true, ).catchError((error) { if (cartInfo != null) { Navigator.of(context).pop(); } Utils.showMessageDialog(context, error, onOk: () { Navigator.of(context).pop(); Navigator.of(context).pop(); }); }); } int getPaymentMethod() { int method = 0; if (paymentPlatforms.length > 0 && paymentPlatformIndex < paymentPlatforms.length) { PaymentPlatform paymentPlatform = paymentPlatforms[paymentPlatformIndex]; if (paymentPlatform.method == Constants.PAYMENT_METHOD_PAY_ON_DELIVERY) { return 1; } } return method; } void afterBuild(Duration time) { if(errorMessages.length > 0) { print('error: ${errorMessages.toString()}'); // _scaffoldKey.currentState.showSnackBar(errorSnackBar(errorMessages)); ScaffoldMessenger.of(context).showSnackBar(errorSnackBar(errorMessages)); } } SnackBar errorSnackBar(List messages) { Column column = Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [], ); for (var i = 0; i < messages.length; i++) { column.children.add(Container( padding: EdgeInsets.only(left: 0.0, right: 0.0, top: 10.0, bottom: 0.0), child: Text( Utils.errorMsg2(context, messages[i].code, messages[i].string), ), )); } return SnackBar( content: Container( height: 60.0 * messages.length, child: column, ), action: SnackBarAction( label: S.of(context).ok, onPressed: () { // _scaffoldKey.currentState.hideCurrentSnackBar(); ScaffoldMessenger.of(context).hideCurrentSnackBar(); }, ), ); } Widget getBookingTimeWidget() { Widget widget; if (bookingTimeList.length > 0) { widget = Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, left: 16.0), child: Text( S.of(context).select_delivery_time, style: TextStyle( fontSize: 16.0, fontWeight: FontWeight.bold, ), ), ), Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, right: 16.0), child: FlatButton( child: Text(S.of(context).cancel), onPressed: () { panelController.close(); }, ), ) ], ), Expanded( child: ListView.builder( itemCount: bookingTimeList.length, itemBuilder: (BuildContext context, int position) { BookingTime bookingTime = bookingTimeList[position]; return GestureDetector( child: Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, bottom: 10.0, top: 10.0), child: Text( '${Utils.timestampToString(context, bookingTime.unixTime)}', ), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 0.3, color: Colors.black12, ) ) ), ), onTap: () { if (mounted) { setState(() { bookingDateIndex = 0; bookingTimeIndex = position; }); } panelController.close(); }, ); }, ), ) ], ); } else if (bookingDateTimeList.length > 0) { widget = Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, left: 16.0), child: Text( S.of(context).select_delivery_time, style: TextStyle( fontSize: 16.0, fontWeight: FontWeight.bold, ), ), ), Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, right: 16.0), child: FlatButton( child: Text(S.of(context).cancel), onPressed: () { panelController.close(); }, ), ) ], ), Expanded( child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Container( width: 150.0, color: new Color(0xFFF5F5F5), child: SizedBox.expand( child: ListView.builder( itemCount: bookingDateTimeList.length, itemBuilder: (BuildContext context, int position) { BookingDateTime bookingDateTime = bookingDateTimeList[position]; return GestureDetector( child: Container( color: bookingDateIndex == position ? Colors.white : Colors.transparent, padding: EdgeInsets.only(left: 10.0, right: 10.0, top: 10.0, bottom: 10.0), child: Center( child: Text( '${bookingDateTime.viewDate} (${Utils.getWeekDayName(context, bookingDateTime.unixTime, true)})', ), ), ), onTap: () { if (mounted) { setState(() { bookingDateIndex = position; panel = getBookingTimeWidget(); }); } }, ); }, ), ), ), Expanded( child: SizedBox.expand( child: ListView.builder( itemCount: bookingDateTimeList[bookingDateIndex].bookTimes.length, itemBuilder: (BuildContext context, int position) { BookingDateTime bookingDateTime = bookingDateTimeList[bookingDateIndex]; return GestureDetector( child: Container( padding: EdgeInsets.only(left: 12.0, right: 12.0, top: 12.0, bottom: 12.0), child: Text( bookingDateTime.bookTimes[position].viewTime, ), decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Colors.black12, width: 0.3, ), ), ), ), onTap: () { if (mounted) { setState(() { bookingTimeIndex = position; }); } panelController.close(); }, ); }, ), ), ), ], ), ) ], ); } else { widget = Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, left: 16.0), child: Text( S.of(context).select_delivery_time, style: TextStyle( fontSize: 16.0, fontWeight: FontWeight.bold, ), ), ), Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, right: 16.0), child: FlatButton( child: Text(S.of(context).close), onPressed: () { panelController.close(); }, ), ) ], ), Expanded( child: Container( padding: EdgeInsets.all(20.0), child: Center( child: Text( S.of(context).shipping_time_will_schedule, ), ), ), ) ], ); } return widget; } Widget getPaymentMethods() { Column widget = Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, left: 16.0), child: Text( S.of(context).select_a_payment_method, style: TextStyle( fontSize: 16.0, fontWeight: FontWeight.bold, ), ), ), Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, right: 16.0), child: FlatButton( child: Text(S.of(context).cancel), onPressed: () { panelController.close(); }, ), ) ], ), ], ); if (paymentPlatforms.length == 0) { widget.children.add(Center( child: Container( padding: EdgeInsets.all(16.0), child: Text( S.of(context).payment_method_not_set, ), ), )); } else { widget.children.add( Expanded( child:ListView.builder( itemCount: paymentPlatforms.length, itemBuilder: (BuildContext context, int position) { PaymentPlatform paymentPlatform = paymentPlatforms[position]; if (paymentPlatform.code == Constants.PAYMENT_METHOD_CODE_SQUARE && (paymentPlatform.squareAppId == null || paymentPlatform.squareAppId.isEmpty) && (paymentPlatform.squareAccessToken == null || paymentPlatform.squareAccessToken.isEmpty) && (paymentPlatform.squareLocationId == null || paymentPlatform.squareLocationId.isEmpty) ) { return SizedBox.shrink(); } if (paymentPlatform.code == Constants.PAYMENT_METHOD_CODE_CHASE && (paymentPlatform.xLogin == null || paymentPlatform.xLogin.isEmpty) && (paymentPlatform.transactionKey == null || paymentPlatform.transactionKey.isEmpty) && (paymentPlatform.responseKey == null || paymentPlatform.responseKey.isEmpty) ) { return SizedBox.shrink(); } Widget paymentWidget = GestureDetector( child: Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0, bottom: 16.0), decoration: paymentPlatformIndex == position ? BoxDecoration( border: Border( top: BorderSide( width: 3.0, color: Colors.lightBlue, ), bottom: BorderSide( width: 3.0, color: Colors.lightBlue, ), left: BorderSide( width: 3.0, color: Colors.lightBlue, ), right: BorderSide( width: 3.0, color: Colors.lightBlue, ), ), ) : BoxDecoration( border: Border( bottom: BorderSide( width: 0.3, color: Colors.black12, ), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( child: Util.showImage(paymentPlatform.icon, errorWidget: (context, url, error) => Icon(Icons.broken_image, size: 50.0, color: Colors.transparent,), fit: BoxFit.cover, width: 50.0, height: 50.0, ), ), Container( margin: EdgeInsets.only(left: 10.0), child: Text( PaymentPlatform.getPaymentPlatformName(context, paymentPlatform.code), style: TextStyle( fontSize: 18.0, fontWeight: FontWeight.bold, ), ), ), ], ), Container( child: Icon( Icons.check, size: 32.0, color: paymentPlatformIndex == position ? Colors.blue : Colors.grey, ), ), ], ), ), onTap: () { setState(() { paymentPlatformIndex = position; }); panelController.close(); }, ); return paymentWidget; } ), ), ); } return widget; } String getSelectedCouponName() { if (selectedCoupon == null) { if (coupons.length > 0) { return S .of(context) .please_select; } else { return S .of(context) .no_coupon_available; } } else if (selectedCoupon == 0) { return S.of(context).dont_use; } else { for (var i = 0; i < coupons.length; i++) { if (selectedCoupon == coupons[i].id) { if (coupons[i].isPercentage) { return S.of(context).percentage_discount_token2(couponDiscountAmount.toStringAsFixed(2), coupons[i].valueAmount); } else { return S.of(context).discount_amount_token(couponDiscountAmount.toStringAsFixed(2)); } } } return 'N/A'; } } Widget getCouponList() { Column widget = Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, left: 16.0), child: Text( S.of(context).pick_a_coupon, style: TextStyle( fontSize: 16.0, fontWeight: FontWeight.bold, ), ), ), Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, right: 16.0), child: FlatButton( child: Text(S.of(context).cancel), onPressed: () { panelController.close(); }, ), ) ], ), ], ); widget.children.add( Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0, bottom: 16.0), decoration: BoxDecoration( border: Border( bottom: BorderSide( width: 5.0, color: Colors.black26, ), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.end, mainAxisSize: MainAxisSize.min, children: [ Expanded( child: TextFormField( controller: newCouponController, keyboardType: TextInputType.number, decoration: InputDecoration( enabledBorder: UnderlineInputBorder( borderSide: BorderSide( color: Colors.black12, ), ), focusedBorder: UnderlineInputBorder( borderSide: BorderSide( color: Colors.blue, ) ), labelText: S.of(context).enter_coupon_code, ), validator: (String value) { return null; }, ), ), Container( margin: EdgeInsets.only(left: 5.0), child: RaisedButton( child: Text( S.of(context).get_coupon, ), onPressed: () { if (newCouponController.text.trim().isEmpty) { Fluttertoast.showToast( msg: S.of(context).please_enter_coupon_code, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, backgroundColor: Colors.black54, textColor: Colors.white, ); } else { _checkCouponCode(newCouponController.text.trim()); } }, ), ), ], ), ), ); if (paymentPlatforms.length == 0) { widget.children.add(Center( child: Container( padding: EdgeInsets.all(16.0), child: Text( S.of(context).no_coupon_available, ), ), )); } else { widget.children.add(Expanded( child: ListView.builder( itemCount: coupons.length + 1, itemBuilder: (BuildContext context, int position) { if (position == 0) { return GestureDetector( child: Container( decoration: selectedCoupon == 0 ? BoxDecoration( color: subtotal > cartInfo.businessInfo.minPrice ? Colors .transparent : Colors.black38, border: Border( top: BorderSide( width: 3.0, color: Colors.lightBlue, ), bottom: BorderSide( width: 3.0, color: Colors.lightBlue, ), left: BorderSide( width: 3.0, color: Colors.lightBlue, ), right: BorderSide( width: 3.0, color: Colors.lightBlue, ), ), ) : BoxDecoration( color: subtotal > cartInfo.businessInfo.minPrice ? Colors .transparent : Colors.black38, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0, bottom: 16.0), child: Text( S.of(context).dont_use, style: TextStyle( fontSize: 20.0, ), ), ), Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0, bottom: 16.0), child: Icon( Icons.check, size: 30.0, color: selectedCoupon == 0 ? Colors.lightBlue : Colors.black26, ), ), ], ), ), onTap: () { if (mounted) { setState(() { selectedCoupon = 0; couponDiscountAmount = 0; }); panelController.close(); } }, ); } else { Coupon coupon = coupons[position - 1]; return GestureDetector( child: Container( decoration: selectedCoupon == coupon.id ? BoxDecoration( color: subtotal > cartInfo.businessInfo.minPrice ? Colors .transparent : Colors.black38, border: Border( top: BorderSide( width: 3.0, color: Colors.lightBlue, ), bottom: BorderSide( width: 3.0, color: Colors.lightBlue, ), left: BorderSide( width: 3.0, color: Colors.lightBlue, ), right: BorderSide( width: 3.0, color: Colors.lightBlue, ), ), ) : BoxDecoration( color: subtotal > coupon.minAmount ? Colors .transparent : Colors.black26, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( padding: EdgeInsets.only( left: 16.0, top: 16.0, right: 16.0, bottom: 16.0), child: coupon.isPercentage ? Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: EdgeInsets.only(right: 5.0), child: Text( '${Utils.smartRound(coupon.valueAmount, 2)}', style: TextStyle( fontSize: 30.0, color: Colors.redAccent, ), ), ), Container( child: Text( S .of(context) .percent_discount, style: TextStyle( fontSize: 12.0, color: Colors.redAccent, ), ), ) ], ) : Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: EdgeInsets.only(right: 5.0), child: Text( '\$', style: TextStyle( fontSize: 12.0, color: Colors.redAccent, ), ), ), Container( child: Text( '${Utils.smartRound(coupon.valueAmount, 2)}', style: TextStyle( fontSize: 30.0, color: Colors.redAccent, ), ), ) ], ), ), Expanded( child: Container( child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Container( child: Text( '${coupon.description}', style: TextStyle( fontSize: 11.0, color: Colors.black45, ), ), ), Container( child: Text( coupon.expirationDate != null ? S.of(context).expiration_date_token( coupon.expirationDate) : S.of(context) .no_expiration, style: TextStyle( fontSize: 11.0, color: Colors.black26, ), ), ), Container( child: Text( coupon.minAmount > 0 ? S.of(context).min_order_amount_token( coupon.minAmount) : S.of(context) .no_restriction, style: TextStyle( fontSize: 11.0, color: Colors.black26, ), ), ) ], ), ), ), Container( padding: EdgeInsets.only( left: 16.0, top: 16.0, right: 16.0, bottom: 16.0), child: Icon( Icons.check, size: 30.0, color: selectedCoupon == coupon.id ? Colors.lightBlue : Colors.black26, ), ) ], ), ), onTap: () { if (subtotal > coupon.minAmount && mounted) { setState(() { selectedCoupon = coupon.id; if (coupon.isPercentage) { couponDiscountAmount = subtotal * coupon.valueAmount / 100.0; } else { couponDiscountAmount = coupon.valueAmount; } }); panelController.close(); } }, ); } }, ), ),); } return widget; } remarkChangeListener() { orderRemark = remarkController.text; } Widget remarkPanel() { Column quickInputs = Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [], ); if (cartInfo.businessInfo.quickInputs.length > 0) { Wrap w = Wrap( children: [], ); quickInputs.children.add(Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, bottom: 8.0), child: Text( S.of(context).quick_input, style: TextStyle( fontSize: 18.0, color: Colors.black54, ), ), )); for (int i = 0; i < cartInfo.businessInfo.quickInputs.length; i++) { String qi = cartInfo.businessInfo.quickInputs[i].value; w.children.add(FlatButton( child: Text( qi, style: TextStyle( fontSize: 14.0, color: Colors.black26, ), ), onPressed: () { orderRemark += ' ' + qi; remarkController.text = orderRemark; }, )); } quickInputs.children.add(Container( padding: EdgeInsets.only(left: 16.0, right: 16.0, bottom: 16.0), child: w, )); } Column widget = Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, left: 16.0), child: Text( S.of(context).order_remark, style: TextStyle( fontSize: 16.0, fontWeight: FontWeight.bold, ), ), ), ), Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, right: 16.0), child: FlatButton( child: Text(S.of(context).cancel), onPressed: () { panelController.close(); }, ), ), Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, right: 16.0), child: FlatButton( child: Text(S.of(context).save), onPressed: () { if (mounted) { setState(() { orderRemark = remarkController.text; }); } panelController.close(); }, ), ), ], ), Expanded( child: ListView( children: [ Container( padding: EdgeInsets.only(top: 0.0, bottom: 10.0, left: 16.0, right: 16.0), child: TextField( controller: remarkController, keyboardType: TextInputType.multiline, maxLines: 5, maxLength: 100, decoration: new InputDecoration( border: new OutlineInputBorder( borderRadius: const BorderRadius.all( const Radius.circular(12.0), ), ), filled: true, hintStyle: new TextStyle(color: Colors.grey[800]), hintText: S.of(context).type_your_order_remark, fillColor: Colors.white70, ), ), ), quickInputs, ], ), ), ], ); return widget; } Widget canadaPostPanel() { Column column = Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, left: 16.0), child: Text( S.of(context).choose_a_shipping_rate, style: TextStyle( fontSize: 16.0, fontWeight: FontWeight.bold, ), ), ), Container( padding: EdgeInsets.only(top: 16.0, bottom: 16.0, right: 16.0), child: FlatButton( child: Text(S.of(context).cancel), onPressed: () { panelController.close(); }, ), ) ], ), ], ); column.children.add(Expanded( child: ListView.builder( itemCount: shippingRates.length, itemBuilder: (BuildContext context, int position) { ShippingRate shippingRate = shippingRates[position]; return GestureDetector( child: Container( decoration: selectedShippingRate == shippingRate ? BoxDecoration( color: Colors.transparent, border: Border( top: BorderSide( width: 3.0, color: Colors.lightBlue, ), bottom: BorderSide( width: 3.0, color: Colors.lightBlue, ), left: BorderSide( width: 3.0, color: Colors.lightBlue, ), right: BorderSide( width: 3.0, color: Colors.lightBlue, ), ), ) : BoxDecoration( color: Colors.transparent, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( padding: EdgeInsets.only( left: 16.0, top: 16.0, right: 16.0, bottom: 16.0), child: Container( child: Text( shippingRate.name, style: TextStyle( fontSize: 20.0, ), ), ), ), Expanded( child: Container( alignment: Alignment.centerRight, child: Text( '${shippingRate.price.toStringAsFixed(2)}', style: TextStyle( fontSize: 16.0, color: Colors.black38, ), ), ), ), Container( padding: EdgeInsets.only( left: 16.0, top: 16.0, right: 16.0, bottom: 16.0), child: Icon( Icons.check, size: 30.0, color: selectedShippingRate == shippingRate ? Colors.lightBlue : Colors.black26, ), ) ], ), ), onTap: () { selectedShippingRate = shippingRate; panelController.close(); check(); }, ); } ), ),); return column; } void onDeliveryTap() { panelController.open(); setState(() { panel = getBookingTimeWidget(); }); } void onPaymentMethodTapped() { panelController.open(); setState(() { panel = getPaymentMethods(); }); } void onCouponsTapped() { panelController.open(); setState(() { panel = getCouponList(); }); } void onRemarkTapped() { panelController.open(); setState(() { panel = remarkPanel(); }); } void onCanadaPostTapped() { panelController.open(); setState(() { panel = canadaPostPanel(); }); } confirmOrder() { if (!canSubmit) { // _scaffoldKey.currentState.showSnackBar(errorSnackBar(errorMessages)); ScaffoldMessenger.of(context).showSnackBar(errorSnackBar(errorMessages)); } else { Utils.showSubmitDialog(context); HttpUtil.httpPost('v1/orders', (response) { Navigator.of(context).pop(); store.dispatch(UpdateCartInfo(Utils.removeCartInfoFromCartInfoList(store.state.cartInfos, cartInfo))); eventBus.fire(OnCartInfoUpdated()); Order order = Order.fromJson(response.data); PaymentPlatform paymentPlatform = paymentPlatforms[paymentPlatformIndex]; Routes.router.navigateTo(context, '/paynow/${order.id}', replace: true); }, businessId: widget.businessId, body: { 'cart_id': cartInfo.id, 'remark': orderRemark, 'booked_at': bookingTimeList.length > 0 ? bookingTimeList[bookingTimeIndex].unixTime : ( (bookingTimeList.length == 0 && bookingDateTimeList.length == 0) ? 0 : bookingDateTimeList[bookingDateIndex].bookTimes[bookingTimeIndex] .unixTime ), 'delivery': deliveryMethod, 'selected_coupon': selectedCoupon, 'delivery_method': deliveryMethod, 'coupon_discount_amount': couponDiscountAmount, 'device_id': store.state.deviceId != null ? store.state.deviceId : '', 'table_number': store.state.tableNumber != null ? store.state.tableNumber : '', 'people_count': peopleCount, }, isFormData: true, ).catchError((error) { Navigator.of(context).pop(); Utils.showMessageDialog(context, error, onOk: () { Navigator.of(context).pop(); Navigator.of(context).pop(); }); }); } } @override bool get wantKeepAlive => true; _checkCouponCode(String code) { Utils.showSubmitDialog(context); HttpUtil.httpGet('v1/check-coupon-code', queryParameters: { 'coupon_code': code, 'store_id': widget.businessId, }).then((data) { Navigator.of(context).pop(); if (mounted) { setState(() { newCouponController.text = ''; coupons = (data as List).map((e) => Coupon.fromJson(e)).toList(); panel = getCouponList(); }); } }).catchError((error) { Navigator.of(context).pop(); Utils.showMessageDialog(context, error); }); } }