diff --git a/android/gradle.properties b/android/gradle.properties index 38c8d454..a5965ab8 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,4 +1,4 @@ org.gradle.jvmargs=-Xmx1536M android.enableR8=true android.useAndroidX=true -android.enableJetifier=true +android.enableJetifier=true \ No newline at end of file diff --git a/assets/images/svg/tamara.svg b/assets/images/svg/tamara.svg new file mode 100644 index 00000000..acc21074 --- /dev/null +++ b/assets/images/svg/tamara.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/lib/config/config.dart b/lib/config/config.dart index bbbacaa4..27d60972 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -14,6 +14,7 @@ const PACKAGES_PRODUCTS = '/api/products'; const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; +const PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara'; const BASE_URL = 'https://uat.hmgwebservices.com/'; // const BASE_URL = 'https://hmgwebservices.com/'; diff --git a/lib/core/model/packages_offers/responses/tamara_payment_option.dart b/lib/core/model/packages_offers/responses/tamara_payment_option.dart new file mode 100644 index 00000000..ad79f5f3 --- /dev/null +++ b/lib/core/model/packages_offers/responses/tamara_payment_option.dart @@ -0,0 +1,35 @@ +class TamaraPaymentOption { + String name; + double minLimit; + double maxLimit; + int id; + + String fullName() => '$name Months'; + + TamaraPaymentOption({ + this.name, + this.minLimit, + this.maxLimit, + this.id}); + + + @override + String toString() => fullName(); + + TamaraPaymentOption.fromJson(dynamic json) { + name = json["name"]; + minLimit = json["min_limit"]; + maxLimit = json["max_limit"]; + id = json["id"]; + } + + Map toJson() { + var map = {}; + map["name"] = name; + map["min_limit"] = minLimit; + map["max_limit"] = maxLimit; + map["id"] = id; + return map; + } + +} \ No newline at end of file diff --git a/lib/core/service/packages_offers/PackagesOffersServices.dart b/lib/core/service/packages_offers/PackagesOffersServices.dart index 46e042a4..17abdc05 100644 --- a/lib/core/service/packages_offers/PackagesOffersServices.dart +++ b/lib/core/service/packages_offers/PackagesOffersServices.dart @@ -13,6 +13,7 @@ import 'package:diplomaticquarterapp/core/model/packages_offers/responses/Packag import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/order_response_model.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/tamara_payment_option.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; @@ -26,6 +27,7 @@ class OffersAndPackagesServices extends BaseService { List categoryList = List(); List productList = List(); List latestOffersList = List(); + List tamaraPaymentOptions = List(); List bestSellerList = List(); List bannersList = List(); List cartItemList = List(); @@ -71,6 +73,25 @@ class OffersAndPackagesServices extends BaseService { return productList; } + Future> getTamaraOptions({@required BuildContext context, @required bool showLoading = true}) async { + if(tamaraPaymentOptions != null && tamaraPaymentOptions.isNotEmpty) + return tamaraPaymentOptions; + + var url = EXA_CART_API_BASE_URL + PACKAGES_TAMARA_OPT; + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { + if (statusCode == 200) { + var jsonResponse = json.decode(stringResponse); + jsonResponse['payment_option'].forEach((json) { + tamaraPaymentOptions.add(TamaraPaymentOption.fromJson(json)); + }); + } + }, onFailure: (String error, int statusCode) { + log(error); + }); + + return tamaraPaymentOptions; + } + Future> getLatestOffers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; @@ -313,20 +334,19 @@ class OffersAndPackagesServices extends BaseService { // -------------------- // Place Order // -------------------- - Future placeOrder({@required String paymentOption, @required BuildContext context, bool showLoading = true}) async{ + Future placeOrder({@required Map paymentParams, @required BuildContext context, bool showLoading = true}) async{ Future errorThrow; - var jsonBody = { + var jsonBody = { "order": { "customer_id" : customer.id, "billing_address": { "email": patientUser.emailAddress, "phone_number": patientUser.mobileNumber }, - "payment_method_system_name": "Payments.PayFort", - "payment_option": paymentOption } }; + jsonBody.addAll(paymentParams); int order_id; _showLoading(context, showLoading); diff --git a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart index f122381a..53b4895c 100644 --- a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart +++ b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart @@ -2,17 +2,18 @@ import 'package:after_layout/after_layout.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/ResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/tamara_payment_option.dart'; import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/packages_offers/PackageOrderCompletedPage.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; -import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesCartItemCard.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/single_selection_dialog.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -71,7 +72,7 @@ class _PackagesCartPageState extends State await viewModel.service .placeOrder( context: context, - paymentOption: _selectedPaymentMethod.toUpperCase()) + paymentParams: _selectedPaymentParams) .then((orderId) { if (orderId.runtimeType == int) { // result == order_id @@ -176,13 +177,9 @@ class _PackagesCartPageState extends State width: 100, color: Colors.grey[300], ), - Padding( - padding: const EdgeInsets.only(left: 12.0, right: 12.0), - // child: getPaymentMethods(), - child: _paymentOptions(context, (paymentMethod) { - setState(() => _selectedPaymentMethod = paymentMethod); - }), - ), + _paymentOptions(context, (paymentMethod) { + setState(() => _selectedPaymentMethod = paymentMethod); + }, viewModel: viewModel), Container( height: 0.25, color: Colors.grey[300], @@ -234,7 +231,8 @@ class _PackagesCartPageState extends State // /* Payment Footer Widgets */ // --------------------------- String _selectedPaymentMethod; -Widget _paymentOptions(BuildContext context, Function(String) onSelected) { +Map _selectedPaymentParams; +Widget _paymentOptions(BuildContext context, Function(String) onSelected, {PackagesViewModel viewModel}) { double height = 30; Widget buttonContent(bool isSelected, String imageName) { @@ -257,6 +255,12 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected) { child: Image.asset('assets/images/new-design/$imageName'), )); } + + Future selectTamaraPaymentOption() async{ + final tamara_options = await viewModel.service.getTamaraOptions(context: context, showLoading: true); + final selected = await SingleSelectionDialog(tamara_options, title: 'Select the tamara installment plan').show(context); + return selected.name; + } return Padding( padding: const EdgeInsets.all(5), @@ -266,9 +270,18 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected) { child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ + InkWell( + child: buttonContent(_selectedPaymentMethod == "tamara", 'mada.png'), + onTap: () async{ + final tamara_option = await selectTamaraPaymentOption(); + _selectedPaymentParams = {"channel" : "Web", "payment_method_system_name" : "Payments.Tamara", "payment_option" : tamara_option}; + onSelected("tamara"); + }, + ), InkWell( child: buttonContent(_selectedPaymentMethod == "mada", 'mada.png'), onTap: () { + _selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "MADA"}; onSelected("mada"); }, ), @@ -278,6 +291,7 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected) { InkWell( child: buttonContent(_selectedPaymentMethod == "visa", 'visa.png'), onTap: () { + _selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "VISA"}; onSelected("visa"); }, ), @@ -285,9 +299,9 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected) { width: 5, ), InkWell( - child: buttonContent( - _selectedPaymentMethod == "mastercard", 'mastercard.png'), + child: buttonContent(_selectedPaymentMethod == "mastercard", 'mastercard.png'), onTap: () { + _selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "MASTERCARD"}; onSelected("mastercard"); }, ), @@ -298,6 +312,7 @@ Widget _paymentOptions(BuildContext context, Function(String) onSelected) { child: buttonContent( _selectedPaymentMethod == "installment", 'installment.png'), onTap: () { + _selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "INSTALLMENT"}; onSelected("installment"); }, ), diff --git a/lib/widgets/others/app_scaffold_widget.dart b/lib/widgets/others/app_scaffold_widget.dart index 8729fe4a..11879f20 100644 --- a/lib/widgets/others/app_scaffold_widget.dart +++ b/lib/widgets/others/app_scaffold_widget.dart @@ -357,7 +357,7 @@ class AppBarWidgetState extends State { icon: Badge( position: BadgePosition.topStart(top: -15, start: -10), badgeContent: Text( - orderPreviewViewModel.cartResponse.quantityCount.toString() /*_badgeText*/, + _badgeText, style: TextStyle(fontSize: 9, color: Colors.white, fontWeight: FontWeight.normal), ), child: Icon(Icons.shopping_cart)), diff --git a/lib/widgets/single_selection_dialog.dart b/lib/widgets/single_selection_dialog.dart new file mode 100644 index 00000000..b8466b65 --- /dev/null +++ b/lib/widgets/single_selection_dialog.dart @@ -0,0 +1,127 @@ +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/tamara_payment_option.dart'; +import 'package:diplomaticquarterapp/theme/colors.dart'; +import 'package:diplomaticquarterapp/uitl/CalendarUtils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:flutter/material.dart'; +import 'package:jiffy/jiffy.dart'; +import 'package:manage_calendar_events/manage_calendar_events.dart'; +import 'package:permission_handler/permission_handler.dart'; + + +class SingleSelectionDialog extends StatefulWidget { + final List items; + final String title; + + SingleSelectionDialog(this.items, {Widget icon, @required this.title}); + + Future show(BuildContext context) async { + return showDialog( + context: context, + barrierDismissible: true, // user must tap button! + builder: (BuildContext context) { + return Dialog( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0.0)), + insetPadding: EdgeInsets.all(21), + child: this, + ); + }, + ); + } + + @override + _SingleSelectionDialogState createState() => _SingleSelectionDialogState(); +} + +class _SingleSelectionDialogState extends State { + int i = 0; + + @override + Widget build(BuildContext context) { + return Container( + //width: MediaQuery.of(context).size.width / 0.8, + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon( + Icons.notifications_active, + color: Color(0xff2B353E), + size: 50, + ), + IconButton( + icon: Icon(Icons.clear), + color: Color(0xff2B353E), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ), + mHeight(20), + Text( + widget.title, + style: TextStyle( + fontSize: 16, + color: Color(0xff2B353E), + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), + + Padding( + padding: const EdgeInsets.symmetric(vertical: 20), + child: optionList(widget.items), + ), + + mHeight(12), + DefaultButton( + TranslationBase.of(context).done, + () { + Navigator.pop(context, widget.items[i]); + }, + color: CustomColors.green, + ), + ], + ), + ); + } + + Widget optionList(List options){ + return ListView( + shrinkWrap: true, + children: List.generate(options.length, (index){ + + final opt = options[index]; + return Row( + children: [ + Radio( + value: index, + groupValue: i, + onChanged: (int value) { + setState(() { + i = value; + }); + }, + ), + Text( + opt.toString(), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + letterSpacing: -0.48, + ), + ), + ], + ); + }), + ); + } +}