|
|
|
|
@ -32,20 +32,18 @@ class PackagesCartPage extends StatefulWidget {
|
|
|
|
|
_PackagesCartPageState createState() => _PackagesCartPageState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _PackagesCartPageState extends State<PackagesCartPage>
|
|
|
|
|
with AfterLayoutMixin<PackagesCartPage>, SingleTickerProviderStateMixin {
|
|
|
|
|
class _PackagesCartPageState extends State<PackagesCartPage> with AfterLayoutMixin<PackagesCartPage>, SingleTickerProviderStateMixin {
|
|
|
|
|
getLanguageID() async {
|
|
|
|
|
languageID = await sharedPref.getString(APP_LANGUAGE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
double subtotal,tax, total;
|
|
|
|
|
double subtotal, tax, total;
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void initState() {
|
|
|
|
|
_agreeTerms = false;
|
|
|
|
|
_selectedPaymentMethod = null;
|
|
|
|
|
_animationController =
|
|
|
|
|
AnimationController(vsync: this, duration: Duration(seconds: 500));
|
|
|
|
|
_animationController = AnimationController(vsync: this, duration: Duration(seconds: 500));
|
|
|
|
|
super.initState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -69,22 +67,13 @@ class _PackagesCartPageState extends State<PackagesCartPage>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onPayNowClick() async {
|
|
|
|
|
await viewModel.service
|
|
|
|
|
.placeOrder(
|
|
|
|
|
context: context,
|
|
|
|
|
paymentParams: _selectedPaymentParams)
|
|
|
|
|
.then((orderId) {
|
|
|
|
|
await viewModel.service.placeOrder(context: context, paymentParams: _selectedPaymentParams).then((orderId) {
|
|
|
|
|
if (orderId.runtimeType == int) {
|
|
|
|
|
// result == order_id
|
|
|
|
|
var browser = MyInAppBrowser(
|
|
|
|
|
context: context,
|
|
|
|
|
onExitCallback: (data, isDone) => paymentClosed(
|
|
|
|
|
orderId: orderId, withStatus: isDone, data: data));
|
|
|
|
|
browser.openPackagesPaymentBrowser(
|
|
|
|
|
customer_id: viewModel.service.customer.id, order_id: orderId);
|
|
|
|
|
var browser = MyInAppBrowser(context: context, onExitCallback: (data, isDone) => paymentClosed(orderId: orderId, withStatus: isDone, data: data));
|
|
|
|
|
browser.openPackagesPaymentBrowser(customer_id: viewModel.service.customer.id, order_id: orderId);
|
|
|
|
|
} else {
|
|
|
|
|
utils.Utils.showErrorToast(
|
|
|
|
|
'Failed to place order, please try again later');
|
|
|
|
|
utils.Utils.showErrorToast('Failed to place order, please try again later');
|
|
|
|
|
}
|
|
|
|
|
}).catchError((error) {
|
|
|
|
|
utils.Utils.showErrorToast(error.toString());
|
|
|
|
|
@ -111,56 +100,48 @@ class _PackagesCartPageState extends State<PackagesCartPage>
|
|
|
|
|
isOfferPackages: true,
|
|
|
|
|
showOfferPackagesCart: false,
|
|
|
|
|
isShowDecPage: false,
|
|
|
|
|
showNewAppBar: true,
|
|
|
|
|
showNewAppBarTitle: true,
|
|
|
|
|
body: Column(
|
|
|
|
|
children: [
|
|
|
|
|
Expanded(
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: const EdgeInsets.all(5),
|
|
|
|
|
child: StaggeredGridView.countBuilder(
|
|
|
|
|
crossAxisCount: (_columnCount * _columnCount),
|
|
|
|
|
itemCount: viewModel.cartItemList.length,
|
|
|
|
|
itemBuilder: (BuildContext context, int index) {
|
|
|
|
|
var item = viewModel.cartItemList[index];
|
|
|
|
|
return Dismissible(
|
|
|
|
|
key: Key(index.toString()),
|
|
|
|
|
direction: DismissDirection.startToEnd,
|
|
|
|
|
background: _cartItemDeleteContainer(),
|
|
|
|
|
secondaryBackground: _cartItemDeleteContainer(),
|
|
|
|
|
confirmDismiss: (direction) async {
|
|
|
|
|
bool status = await viewModel.service
|
|
|
|
|
.deleteProductFromCart(item.id,
|
|
|
|
|
context: context, showLoading: false);
|
|
|
|
|
return status;
|
|
|
|
|
},
|
|
|
|
|
onDismissed: (direction) {
|
|
|
|
|
debugPrint('Index: $index');
|
|
|
|
|
viewModel.cartItemList.removeAt(index);
|
|
|
|
|
},
|
|
|
|
|
child: PackagesCartItemCard(
|
|
|
|
|
itemModel: item,
|
|
|
|
|
shouldStepperChangeApply: (apply, total) async {
|
|
|
|
|
var request = AddProductToCartRequestModel(
|
|
|
|
|
product_id: item.productId,
|
|
|
|
|
quantity: apply);
|
|
|
|
|
ResponseModel response = await viewModel
|
|
|
|
|
.service
|
|
|
|
|
.addProductToCart(request,
|
|
|
|
|
context: context, showLoading: false)
|
|
|
|
|
.catchError((error) {
|
|
|
|
|
utils.Utils.showErrorToast(error);
|
|
|
|
|
});
|
|
|
|
|
if(response.status){
|
|
|
|
|
fetchData();
|
|
|
|
|
}
|
|
|
|
|
return response.status ?? false;
|
|
|
|
|
},
|
|
|
|
|
));
|
|
|
|
|
},
|
|
|
|
|
staggeredTileBuilder: (int index) =>
|
|
|
|
|
StaggeredTile.fit(_columnCount),
|
|
|
|
|
mainAxisSpacing: 0,
|
|
|
|
|
crossAxisSpacing: 10,
|
|
|
|
|
)),
|
|
|
|
|
child: StaggeredGridView.countBuilder(
|
|
|
|
|
crossAxisCount: (_columnCount * _columnCount),
|
|
|
|
|
itemCount: viewModel.cartItemList.length,
|
|
|
|
|
itemBuilder: (BuildContext context, int index) {
|
|
|
|
|
var item = viewModel.cartItemList[index];
|
|
|
|
|
return Dismissible(
|
|
|
|
|
key: Key(index.toString()),
|
|
|
|
|
direction: DismissDirection.startToEnd,
|
|
|
|
|
background: _cartItemDeleteContainer(),
|
|
|
|
|
secondaryBackground: _cartItemDeleteContainer(),
|
|
|
|
|
confirmDismiss: (direction) async {
|
|
|
|
|
bool status = await viewModel.service.deleteProductFromCart(item.id, context: context, showLoading: false);
|
|
|
|
|
return status;
|
|
|
|
|
},
|
|
|
|
|
onDismissed: (direction) {
|
|
|
|
|
viewModel.cartItemList.removeAt(index);
|
|
|
|
|
},
|
|
|
|
|
child: PackagesCartItemCard(
|
|
|
|
|
itemModel: item,
|
|
|
|
|
viewModel: viewModel,
|
|
|
|
|
getCartItems: fetchData,
|
|
|
|
|
shouldStepperChangeApply: (apply, total) async {
|
|
|
|
|
var request = AddProductToCartRequestModel(product_id: item.productId, quantity: apply);
|
|
|
|
|
ResponseModel response = await viewModel.service.addProductToCart(request, context: context, showLoading: false).catchError((error) {
|
|
|
|
|
utils.Utils.showErrorToast(error);
|
|
|
|
|
});
|
|
|
|
|
if (response.status) {
|
|
|
|
|
fetchData();
|
|
|
|
|
}
|
|
|
|
|
return response.status ?? false;
|
|
|
|
|
},
|
|
|
|
|
));
|
|
|
|
|
},
|
|
|
|
|
staggeredTileBuilder: (int index) => StaggeredTile.fit(_columnCount),
|
|
|
|
|
mainAxisSpacing: 0,
|
|
|
|
|
crossAxisSpacing: 10,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
Container(
|
|
|
|
|
height: 0.25,
|
|
|
|
|
@ -170,8 +151,7 @@ class _PackagesCartPageState extends State<PackagesCartPage>
|
|
|
|
|
color: Colors.white,
|
|
|
|
|
child: Column(
|
|
|
|
|
children: [
|
|
|
|
|
Texts(TranslationBase.of(context).selectPaymentOption,
|
|
|
|
|
fontSize: 10, fontWeight: FontWeight.bold),
|
|
|
|
|
Texts(TranslationBase.of(context).selectPaymentOption, fontSize: 10, fontWeight: FontWeight.bold),
|
|
|
|
|
Container(
|
|
|
|
|
height: 0.25,
|
|
|
|
|
width: 100,
|
|
|
|
|
@ -184,11 +164,7 @@ class _PackagesCartPageState extends State<PackagesCartPage>
|
|
|
|
|
height: 0.25,
|
|
|
|
|
color: Colors.grey[300],
|
|
|
|
|
),
|
|
|
|
|
Container(
|
|
|
|
|
height: 40,
|
|
|
|
|
child: _termsAndCondition(context,
|
|
|
|
|
onSelected: onTermsClick,
|
|
|
|
|
onInfoClick: onTermsInfoClick)),
|
|
|
|
|
Container(height: 40, child: _termsAndCondition(context, onSelected: onTermsClick, onInfoClick: onTermsInfoClick)),
|
|
|
|
|
Container(
|
|
|
|
|
height: 0.25,
|
|
|
|
|
color: Colors.grey[300],
|
|
|
|
|
@ -204,7 +180,7 @@ class _PackagesCartPageState extends State<PackagesCartPage>
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fetchData() async {
|
|
|
|
|
await viewModel.service.cartItems(context: context).then((value){
|
|
|
|
|
await viewModel.service.cartItems(context: context).then((value) {
|
|
|
|
|
subtotal = value['subtotal'] ?? 0.0;
|
|
|
|
|
tax = value['tax'] ?? 0.0;
|
|
|
|
|
total = value['total'] ?? 0.0;
|
|
|
|
|
@ -213,15 +189,12 @@ class _PackagesCartPageState extends State<PackagesCartPage>
|
|
|
|
|
setState(() {});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
paymentClosed(
|
|
|
|
|
{@required int orderId, @required bool withStatus, dynamic data}) async {
|
|
|
|
|
paymentClosed({@required int orderId, @required bool withStatus, dynamic data}) async {
|
|
|
|
|
viewModel.service.getOrderById(orderId, context: context).then((value) {
|
|
|
|
|
var heading = withStatus ? "Success" : "Failed";
|
|
|
|
|
var title = withStatus ? "Your order has been placed successfully" : "Failed to place your order";
|
|
|
|
|
var title = withStatus ? "Your order has been placed successfully" : "Failed to place your order";
|
|
|
|
|
var subTitle = "Order# ${value.data.customOrderNumber}";
|
|
|
|
|
Navigator.of(context).pushReplacement(MaterialPageRoute(
|
|
|
|
|
builder: (context) => PackageOrderCompletedPage(
|
|
|
|
|
heading: heading, title: title, subTitle: subTitle)));
|
|
|
|
|
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => PackageOrderCompletedPage(heading: heading, title: title, subTitle: subTitle)));
|
|
|
|
|
}).catchError((error) {
|
|
|
|
|
debugPrint(error);
|
|
|
|
|
});
|
|
|
|
|
@ -231,7 +204,8 @@ class _PackagesCartPageState extends State<PackagesCartPage>
|
|
|
|
|
// /* Payment Footer Widgets */
|
|
|
|
|
// ---------------------------
|
|
|
|
|
String _selectedPaymentMethod;
|
|
|
|
|
Map<dynamic,dynamic> _selectedPaymentParams;
|
|
|
|
|
Map<dynamic, dynamic> _selectedPaymentParams;
|
|
|
|
|
|
|
|
|
|
Widget _paymentOptions(BuildContext context, Function(String) onSelected, {PackagesViewModel viewModel}) {
|
|
|
|
|
double height = 30;
|
|
|
|
|
|
|
|
|
|
@ -247,18 +221,17 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
borderRadius: BorderRadius.all(Radius.circular(5)),
|
|
|
|
|
border: Border.all(
|
|
|
|
|
color: isSelected ? Colors.green : Colors.grey,
|
|
|
|
|
width: isSelected ? 1 : 0.5)),
|
|
|
|
|
border: Border.all(color: isSelected ? Colors.green : Colors.grey, width: isSelected ? 1 : 0.5)),
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: const EdgeInsets.all(4),
|
|
|
|
|
child: Image.asset('assets/images/new-design/$imageName'),
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<String> selectTamaraPaymentOption() async{
|
|
|
|
|
|
|
|
|
|
Future<String> selectTamaraPaymentOption() async {
|
|
|
|
|
final tamara_options = await viewModel.service.getTamaraOptions(context: context, showLoading: true);
|
|
|
|
|
final selected = await SingleSelectionDialog<TamaraPaymentOption>(tamara_options, icon: Image.asset('assets/images/new-design/tamara.png'), title: TranslationBase.of(context).tamaraInstPlan).show(context);
|
|
|
|
|
final selected =
|
|
|
|
|
await SingleSelectionDialog<TamaraPaymentOption>(tamara_options, icon: Image.asset('assets/images/new-design/tamara.png'), title: TranslationBase.of(context).tamaraInstPlan).show(context);
|
|
|
|
|
return selected.name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -272,9 +245,9 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa
|
|
|
|
|
children: [
|
|
|
|
|
InkWell(
|
|
|
|
|
child: buttonContent(_selectedPaymentMethod == "tamara", 'tamara.png'),
|
|
|
|
|
onTap: () async{
|
|
|
|
|
onTap: () async {
|
|
|
|
|
final tamara_option = await selectTamaraPaymentOption();
|
|
|
|
|
_selectedPaymentParams = {"channel" : "Web", "payment_method_system_name" : "Payments.Tamara", "payment_option" : tamara_option};
|
|
|
|
|
_selectedPaymentParams = {"channel": "Web", "payment_method_system_name": "Payments.Tamara", "payment_option": tamara_option};
|
|
|
|
|
onSelected("tamara");
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
@ -284,7 +257,7 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa
|
|
|
|
|
InkWell(
|
|
|
|
|
child: buttonContent(_selectedPaymentMethod == "mada", 'mada.png'),
|
|
|
|
|
onTap: () {
|
|
|
|
|
_selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "MADA"};
|
|
|
|
|
_selectedPaymentParams = {"payment_method_system_name": "Payments.PayFort", "payment_option": "MADA"};
|
|
|
|
|
onSelected("mada");
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
@ -294,7 +267,7 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa
|
|
|
|
|
InkWell(
|
|
|
|
|
child: buttonContent(_selectedPaymentMethod == "visa", 'visa.png'),
|
|
|
|
|
onTap: () {
|
|
|
|
|
_selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "VISA"};
|
|
|
|
|
_selectedPaymentParams = {"payment_method_system_name": "Payments.PayFort", "payment_option": "VISA"};
|
|
|
|
|
onSelected("visa");
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
@ -304,7 +277,7 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa
|
|
|
|
|
InkWell(
|
|
|
|
|
child: buttonContent(_selectedPaymentMethod == "mastercard", 'mastercard.png'),
|
|
|
|
|
onTap: () {
|
|
|
|
|
_selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "MASTERCARD"};
|
|
|
|
|
_selectedPaymentParams = {"payment_method_system_name": "Payments.PayFort", "payment_option": "MASTERCARD"};
|
|
|
|
|
onSelected("mastercard");
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
@ -326,17 +299,15 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected, {Packa
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool _agreeTerms = false;
|
|
|
|
|
Widget _termsAndCondition(BuildContext context,
|
|
|
|
|
{@required Function(bool) onSelected, @required VoidCallback onInfoClick}) {
|
|
|
|
|
|
|
|
|
|
Widget _termsAndCondition(BuildContext context, {@required Function(bool) onSelected, @required VoidCallback onInfoClick}) {
|
|
|
|
|
return Padding(
|
|
|
|
|
padding: const EdgeInsets.all(5),
|
|
|
|
|
child: Row(
|
|
|
|
|
children: [
|
|
|
|
|
InkWell(
|
|
|
|
|
child: Icon(
|
|
|
|
|
_agreeTerms
|
|
|
|
|
? Icons.check_circle
|
|
|
|
|
: Icons.radio_button_unchecked_sharp,
|
|
|
|
|
_agreeTerms ? Icons.check_circle : Icons.radio_button_unchecked_sharp,
|
|
|
|
|
size: 20,
|
|
|
|
|
color: _agreeTerms ? Colors.green[600] : Colors.grey[400],
|
|
|
|
|
),
|
|
|
|
|
@ -386,18 +357,8 @@ Widget _payNow(BuildContext context, {double subtotal, double tax, double total,
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
Texts(
|
|
|
|
|
'${TranslationBase.of(context).subtotal}: $_subtotal ${TranslationBase.of(context).sar}',
|
|
|
|
|
heightFactor: 1.5,
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
color: Colors.grey,
|
|
|
|
|
fontSize: 8),
|
|
|
|
|
Texts(
|
|
|
|
|
'${TranslationBase.of(context).vat}: $_tax ${TranslationBase.of(context).sar}',
|
|
|
|
|
heightFactor: 1.5,
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
color: Colors.grey,
|
|
|
|
|
fontSize: 8),
|
|
|
|
|
Texts('${TranslationBase.of(context).subtotal}: $_subtotal ${TranslationBase.of(context).sar}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 8),
|
|
|
|
|
Texts('${TranslationBase.of(context).vat}: $_tax ${TranslationBase.of(context).sar}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 8),
|
|
|
|
|
Padding(
|
|
|
|
|
padding: const EdgeInsets.all(3),
|
|
|
|
|
child: Container(
|
|
|
|
|
@ -406,12 +367,7 @@ Widget _payNow(BuildContext context, {double subtotal, double tax, double total,
|
|
|
|
|
color: Colors.grey[300],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
Texts(
|
|
|
|
|
'${TranslationBase.of(context).total}: $_total ${TranslationBase.of(context).sar}',
|
|
|
|
|
heightFactor: 1.5,
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
color: Colors.black54,
|
|
|
|
|
fontSize: 15)
|
|
|
|
|
Texts('${TranslationBase.of(context).total}: $_total ${TranslationBase.of(context).sar}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.black54, fontSize: 15)
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
@ -425,10 +381,7 @@ Widget _payNow(BuildContext context, {double subtotal, double tax, double total,
|
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
|
),
|
|
|
|
|
padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0),
|
|
|
|
|
shape: RoundedRectangleBorder(
|
|
|
|
|
borderRadius: BorderRadius.circular(5),
|
|
|
|
|
side: BorderSide(
|
|
|
|
|
color: Theme.of(context).primaryColor, width: 0.5)),
|
|
|
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5), side: BorderSide(color: Theme.of(context).primaryColor, width: 0.5)),
|
|
|
|
|
color: Theme.of(context).primaryColor,
|
|
|
|
|
onPressed: isPayNowAQctive ? onPayNowClick : null,
|
|
|
|
|
),
|
|
|
|
|
|