Files
flutter_wisetronic/lib/widgets/mobile/mobile_checkout.dart
2021-08-31 13:28:33 -04:00

2248 lines
80 KiB
Dart

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<StatefulWidget> createState() {
return MobileCheckoutState();
}
}
class MobileCheckoutState extends State<MobileCheckout> with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin {
CartInfo cartInfo;
Address shipAddress;
bool canSubmit;
List<ErrorMessage> errorMessages;
List<BookingTime> bookingTimeList;
List<BookingDateTime> bookingDateTimeList;
List<PaymentPlatform> paymentPlatforms;
TextValue durationInTraffic;
int selectedCoupon;
double couponDiscountAmount = 0;
List<Coupon> coupons;
int peopleCount = 2;
final TextEditingController remarkController = new TextEditingController();
String orderRemark = '';
int deliveryMethodIndex = 0;
String deliveryMethod;
List<ShippingRate> shippingRates = [];
ShippingRate selectedShippingRate;
List<String> shippingMethodLabels = [];
List<IconData> shippingMethodIcons = [];
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
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: <Widget>[
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: <Widget>[
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<int>(
value: peopleCount,
items: <int>[
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
].map((value) {
return DropdownMenuItem<int>(
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: <Widget>[
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: <Widget>[
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[],
);
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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
Container(
child: Text(
S.of(context).order_remark,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 17.0,
),
),
),
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
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: <Widget>[
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: <Widget>[
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<ErrorMessage> messages) {
Column column = Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[],
);
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: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
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: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
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: <Widget>[
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: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
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: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
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: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
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: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
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: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
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: <Widget>[
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: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
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: <Widget>[
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);
});
}
}