From 90b821a37d14d2fbf9e827851364da5afd625996 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Tue, 9 Nov 2021 12:43:36 +0300 Subject: [PATCH] Offers & packages UI completed --- lib/core/service/client/base_app_client.dart | 3 +- .../PackagesOffersServices.dart | 197 +++--- .../PackagesOffersViewModel.dart | 2 + .../BillAmount.dart | 7 - .../OfferAndPackagesCartPage.dart | 565 +++++++++--------- 5 files changed, 373 insertions(+), 401 deletions(-) diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 206c45c6..23558ed1 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -481,7 +481,7 @@ class BaseAppClient { simplePost( String fullUrl, { - Map body, + Map body, Map headers, Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, @@ -496,7 +496,6 @@ class BaseAppClient { body: json.encode(body), headers: headers, ); - final int statusCode = response.statusCode; print("statusCode :$statusCode"); if (await handleUnauthorized(statusCode, forUrl: fullUrl)) simplePost(fullUrl, onFailure: onFailure, onSuccess: onSuccess, body: body, headers: headers); diff --git a/lib/core/service/packages_offers/PackagesOffersServices.dart b/lib/core/service/packages_offers/PackagesOffersServices.dart index 238cb611..ae5396a7 100644 --- a/lib/core/service/packages_offers/PackagesOffersServices.dart +++ b/lib/core/service/packages_offers/PackagesOffersServices.dart @@ -4,6 +4,7 @@ import 'dart:developer'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/ResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/CreateCustomerRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; @@ -15,13 +16,11 @@ import 'package:diplomaticquarterapp/core/model/packages_offers/responses/Packag 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'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; -import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:flutter/cupertino.dart'; -var packagesAuthHeader = {'Authorization': ''}; +Map packagesAuthHeader = {}; class OffersAndPackagesServices extends BaseService { AuthenticatedUser patientUser; @@ -32,64 +31,52 @@ class OffersAndPackagesServices extends BaseService { List bestSellerList = List(); List bannersList = List(); List cartItemList = List(); + List _hospitals = List(); + List get hospitals => _hospitals; String cartItemCount = ""; PackagesCustomerResponseModel customer; - Future> getAllCategories( - OffersCategoriesRequestModel request) async { + Future> getAllCategories(OffersCategoriesRequestModel request) async { Future errorThrow; var url = EXA_CART_API_BASE_URL + PACKAGES_CATEGORIES; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, - onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['categories'].forEach((json) { categoryList.add(PackagesCategoriesResponseModel().fromJson(json)); }); } - }, - onFailure: (String error, int statusCode) {}, - queryParams: request.toFlatMap()); + }, onFailure: (String error, int statusCode) {}, queryParams: request.toFlatMap()); return categoryList; } - Future> getAllProducts( - {@required OffersProductsRequestModel request, - @required BuildContext context, - @required bool showLoading = true}) async { + Future> getAllProducts({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { Future errorThrow; request.sinceId = (productList.isNotEmpty) ? productList.last.id : 0; productList = List(); var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, - onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { productList.add(PackagesResponseModel().fromJson(json)); }); } - }, - onFailure: (String error, int statusCode) {}, - queryParams: request.toFlatMap()); + }, onFailure: (String error, int statusCode) {}, queryParams: request.toFlatMap()); return productList; } - Future> getTamaraOptions( - {@required BuildContext context, - @required bool showLoading = true}) async { - if (tamaraPaymentOptions != null && tamaraPaymentOptions.isNotEmpty) - return tamaraPaymentOptions; + 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) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['payment_option'].forEach((json) { @@ -103,14 +90,10 @@ class OffersAndPackagesServices extends BaseService { return tamaraPaymentOptions; } - Future> getLatestOffers( - {@required OffersProductsRequestModel request, - @required BuildContext context, - @required bool showLoading = true}) async { + Future> getLatestOffers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, - onSuccess: (dynamic stringResponse, int statusCode) { - latestOffersList.clear(); + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { + latestOffersList.clear(); if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { @@ -124,14 +107,10 @@ class OffersAndPackagesServices extends BaseService { return latestOffersList; } - Future> getBestSellers( - {@required OffersProductsRequestModel request, - @required BuildContext context, - @required bool showLoading = true}) async { + Future> getBestSellers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, - onSuccess: (dynamic stringResponse, int statusCode) { - bestSellerList.clear(); + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { + bestSellerList.clear(); if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { @@ -145,13 +124,9 @@ class OffersAndPackagesServices extends BaseService { return bestSellerList; } - Future> getBanners( - {@required OffersProductsRequestModel request, - @required BuildContext context, - @required bool showLoading = true}) async { + Future> getBanners({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, - onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { @@ -165,10 +140,7 @@ class OffersAndPackagesServices extends BaseService { return bannersList; } - Future loadOffersPackagesDataForMainPage( - {@required BuildContext context, - bool showLoading = true, - Function completion}) async { + Future loadOffersPackagesDataForMainPage({@required BuildContext context, bool showLoading = true, Function completion}) async { var finished = 0; var totalCalls = 2; @@ -190,30 +162,20 @@ class OffersAndPackagesServices extends BaseService { // Check and Create Customer if (patientUser != null) { - customer = - await getCurrentCustomer(context: context, showLoading: showLoading); + customer = await getCurrentCustomer(context: context, showLoading: showLoading); if (customer == null) { - createCustomer(PackagesCustomerRequestModel.fromUser(patientUser), - context: context); + createCustomer(PackagesCustomerRequestModel.fromUser(patientUser), context: context); } } // Performing Parallel Request on same time // # 1 - getBestSellers( - request: OffersProductsRequestModel(), - context: context, - showLoading: false) - .then((value) { + getBestSellers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value) { completedAll(); }); // # 2 - getLatestOffers( - request: OffersProductsRequestModel(), - context: context, - showLoading: false) - .then((value) { + getLatestOffers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value) { completedAll(); }); @@ -230,10 +192,7 @@ class OffersAndPackagesServices extends BaseService { // -------------------- // Create Customer // -------------------- - Future createCustomer(PackagesCustomerRequestModel request, - {@required BuildContext context, - bool showLoading = true, - Function(bool) completion}) async { + Future createCustomer(PackagesCustomerRequestModel request, {@required BuildContext context, bool showLoading = true, Function(bool) completion}) async { if (customer != null) return Future.value(customer); customer = null; @@ -241,9 +200,7 @@ class OffersAndPackagesServices extends BaseService { _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_CUSTOMER; - await baseAppClient - .simplePost(url, headers: packagesAuthHeader, body: request.json(), - onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode) { var jsonResponse = json.decode(stringResponse); var customerJson = jsonResponse['customers'].first; customer = PackagesCustomerResponseModel.fromJson(customerJson); @@ -258,16 +215,12 @@ class OffersAndPackagesServices extends BaseService { return errorThrow ?? customer; } - Future getCurrentCustomer( - {@required BuildContext context, bool showLoading = true}) async { + Future getCurrentCustomer({@required BuildContext context, bool showLoading = true}) async { if (customer != null) return Future.value(customer); _showLoading(context, showLoading); - var url = EXA_CART_API_BASE_URL + - PACKAGES_CUSTOMER + - "/username/${patientUser.patientID}"; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, - onSuccess: (dynamic stringResponse, int statusCode) { + var url = EXA_CART_API_BASE_URL + PACKAGES_CUSTOMER + "/username/${patientUser.patientID}"; + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { var jsonResponse = json.decode(stringResponse); var customerJson = jsonResponse['customers'].first; customer = PackagesCustomerResponseModel.fromJson(customerJson); @@ -282,17 +235,14 @@ class OffersAndPackagesServices extends BaseService { // -------------------- // Shopping Cart // -------------------- - Future> cartItems( - {@required BuildContext context, bool showLoading = true}) async { + Future> cartItems({@required BuildContext context, bool showLoading = true}) async { Future errorThrow; cartItemList.clear(); _showLoading(context, showLoading); - var url = - EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/${customer.id}'; + var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/${customer.id}'; Map jsonResponse; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, - onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); jsonResponse = json.decode(stringResponse); @@ -308,10 +258,7 @@ class OffersAndPackagesServices extends BaseService { return errorThrow ?? jsonResponse; } - Future> addProductToCart( - AddProductToCartRequestModel request, - {@required BuildContext context, - bool showLoading = true}) async { + Future> addProductToCart(AddProductToCartRequestModel request, {@required BuildContext context, bool showLoading = true}) async { Future errorThrow; ResponseModel response; @@ -319,38 +266,27 @@ class OffersAndPackagesServices extends BaseService { _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART; - await baseAppClient - .simplePost(url, headers: packagesAuthHeader, body: request.json(), - onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); var jsonResponse = json.decode(stringResponse); var jsonCartItem = jsonResponse["shopping_carts"][0]; - response = ResponseModel( - status: true, - data: PackagesCartItemsResponseModel.fromJson(jsonCartItem), - error: null); + response = ResponseModel(status: true, data: PackagesCartItemsResponseModel.fromJson(jsonCartItem), error: null); cartItemCount = (jsonResponse['count'] ?? 0).toString(); }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); - errorThrow = - Future.error(ResponseModel(status: true, data: null, error: error)); + errorThrow = Future.error(ResponseModel(status: true, data: null, error: error)); }); return errorThrow ?? response; } - Future updateProductToCart(int cartItemID, - {UpdateProductToCartRequestModel request, - @required BuildContext context, - bool showLoading = true}) async { + Future updateProductToCart(int cartItemID, {UpdateProductToCartRequestModel request, @required BuildContext context, bool showLoading = true}) async { Future errorThrow; _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID'; - await baseAppClient - .simplePut(url, headers: packagesAuthHeader, body: request.json(), - onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simplePut(url, headers: packagesAuthHeader, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); var jsonResponse = json.decode(stringResponse); @@ -363,16 +299,13 @@ class OffersAndPackagesServices extends BaseService { return errorThrow ?? bannersList; } - Future deleteProductFromCart(int cartItemID, - {@required BuildContext context, bool showLoading = true}) async { + Future deleteProductFromCart(int cartItemID, {@required BuildContext context, bool showLoading = true}) async { Future errorThrow; _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID'; - await baseAppClient.simpleDelete(url, headers: packagesAuthHeader, - onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleDelete(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); - // var jsonResponse = json.decode(stringResponse); }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); log(error); @@ -385,28 +318,23 @@ class OffersAndPackagesServices extends BaseService { // -------------------- // Place Order // -------------------- - Future placeOrder( - {@required Map paymentParams, - @required BuildContext context, - bool showLoading = true}) async { + Future placeOrder({@required Map paymentParams, @required int projectID, @required BuildContext context, bool showLoading = true}) async { Future errorThrow; Map jsonBody = { "customer_id": customer.id, - "billing_address": { - "email": patientUser.emailAddress, - "phone_number": patientUser.mobileNumber - }, + "project_id": projectID, + "billing_address": {"email": patientUser.emailAddress, "phone_number": patientUser.mobileNumber}, }; jsonBody.addAll(paymentParams); jsonBody = {'order': jsonBody}; + print(jsonBody); + int order_id; _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_ORDERS; - await baseAppClient.simplePost(url, - headers: packagesAuthHeader, - body: jsonBody, onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simplePost(url, headers: packagesAuthHeader, body: jsonBody, onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); var jsonResponse = json.decode(stringResponse); @@ -420,21 +348,18 @@ class OffersAndPackagesServices extends BaseService { return errorThrow ?? order_id; } - Future> getOrderById(int id, - {@required BuildContext context, bool showLoading = true}) async { + Future> getOrderById(int id, {@required BuildContext context, bool showLoading = true}) async { Future errorThrow; ResponseModel response; _showLoading(context, showLoading); var url = EXA_CART_API_BASE_URL + PACKAGES_ORDERS + '/$id'; - await baseAppClient.simpleGet(url, headers: packagesAuthHeader, - onSuccess: (dynamic stringResponse, int statusCode) { + await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) { _hideLoading(context, showLoading); var jsonResponse = json.decode(stringResponse); var jsonOrder = jsonResponse['orders'][0]; - response = ResponseModel( - status: true, data: PackagesOrderResponseModel.fromJson(jsonOrder)); + response = ResponseModel(status: true, data: PackagesOrderResponseModel.fromJson(jsonOrder)); }, onFailure: (String error, int statusCode) { _hideLoading(context, showLoading); errorThrow = Future.error(ResponseModel(status: false, error: error)); @@ -442,6 +367,26 @@ class OffersAndPackagesServices extends BaseService { return errorThrow ?? response; } + + Future getHospitals({bool isResBasedOnLoc = true}) async { + Map body = Map(); + body['Latitude'] = await this.sharedPref.getDouble(USER_LAT); + body['Longitude'] = await this.sharedPref.getDouble(USER_LONG); + body['IsOnlineCheckIn'] = isResBasedOnLoc; + body['PatientOutSA'] = 0; + + await baseAppClient.post(GET_PROJECT, + onSuccess: (dynamic response, int statusCode) { + _hospitals.clear(); + response['ListProject'].forEach((hospital) { + _hospitals.add(HospitalsModel.fromJson(hospital)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + } _showLoading(BuildContext context, bool flag) { diff --git a/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart b/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart index 1b68e9d7..af750eab 100644 --- a/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart +++ b/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; @@ -22,6 +23,7 @@ class PackagesViewModel extends BaseViewModel { List get bestSellerList => service.bestSellerList; List get bannersList => service.bannersList; List get cartItemList => service.cartItemList; + List get hospitals => service.hospitals; String _cartItemCount = ""; diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart index e571e4e8..bacc9c38 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart @@ -59,13 +59,6 @@ class _BillAmountState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // Text(TranslationBase.of(context).testFee, - // style: TextStyle( - // color: Colors.black, - // fontSize: 16.0, - // fontWeight: FontWeight.w600, - // letterSpacing: -0.64, - // )), Container( width: double.infinity, padding: EdgeInsets.only(top: 10, bottom: 3), diff --git a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart index e28110a8..4b42774b 100644 --- a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart +++ b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart @@ -1,19 +1,23 @@ 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/hospitals/hospitals_model.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/ToDoList/payment_method_select.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/theme/colors.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/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/radio_selection_dialog.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'; @@ -22,6 +26,9 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; dynamic languageID; const _columnCount = 1; +bool _agreeTerms = false; +String _selectedPaymentMethod; +Map _selectedPaymentParams; AnimationController _animationController; @@ -38,6 +45,8 @@ class _PackagesCartPageState extends State with AfterLayoutMix } double subtotal, tax, total; + int _selectedHospitalIndex = -1; + HospitalsModel _selectedHospital; @override void initState() { @@ -67,9 +76,8 @@ class _PackagesCartPageState extends State with AfterLayoutMix } onPayNowClick() async { - await viewModel.service.placeOrder(context: context, paymentParams: _selectedPaymentParams).then((orderId) { + await viewModel.service.placeOrder(context: context, projectID: _selectedHospital.iD, 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); } else { @@ -83,100 +91,248 @@ class _PackagesCartPageState extends State with AfterLayoutMix @override void afterFirstLayout(BuildContext context) { fetchData(); + viewModel.service.getHospitals(); } @override Widget build(BuildContext context) { return BaseView( - allowAny: true, - onModelReady: (model) => viewModel = model, - builder: (_, model, wi) { - return AppScaffold( - appBarTitle: TranslationBase.of(context).offerAndPackages, - isShowAppBar: true, - isPharmacy: false, - showPharmacyCart: false, - showHomeAppBarIcon: false, - isOfferPackages: true, - showOfferPackagesCart: false, - isShowDecPage: false, - showNewAppBar: true, - showNewAppBarTitle: true, - body: Column( - children: [ - Expanded( - 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, - color: Theme.of(context).primaryColor, - ), - Container( + allowAny: true, + onModelReady: (model) => viewModel = model, + builder: (_, model, wi) { + return AppScaffold( + appBarTitle: TranslationBase.of(context).offerAndPackages, + isShowAppBar: true, + isPharmacy: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isOfferPackages: true, + showOfferPackagesCart: false, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + body: viewModel.cartItemList.length > 0 + ? Column( + children: [ + Expanded( + 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, + color: Theme.of(context).primaryColor, + ), + ], + ) + : getNoDataWidget(context), + bottomSheet: viewModel.cartItemList.length > 0 + ? Container( + padding: EdgeInsets.all(21.0), + width: double.infinity, color: Colors.white, child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: [ - Texts(TranslationBase.of(context).selectPaymentOption, fontSize: 10, fontWeight: FontWeight.bold), Container( - height: 0.25, - width: 100, - color: Colors.grey[300], + margin: EdgeInsets.only(bottom: 12.0), + child: InkWell( + onTap: () => confirmSelectHospitalDialog(model.hospitals), + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 50, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), border: Border.all(color: CustomColors.devider), color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + getHospitalName(), + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.w600, + letterSpacing: -0.46, + ), + ), + Icon(Icons.arrow_drop_down), + ], + ), + ), + ), + ), + Container( + margin: EdgeInsets.fromLTRB(0.0, 0.0, 20.0, 0.0), + child: Text(TranslationBase.of(context).YouCanPayByTheFollowingOptions, style: TextStyle(fontSize: 14.0, fontWeight: FontWeight.w600)), + ), + Container( + width: MediaQuery.of(context).size.width * 0.75, + margin: EdgeInsets.fromLTRB(0.0, 8.0, 20.0, 5.0), + child: getPaymentMethods(), + ), + Container( + margin: EdgeInsets.only(top: 14.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + SizedBox( + height: 24.0, + width: 24.0, + child: Checkbox( + value: _agreeTerms, + onChanged: (v) { + setState(() => _agreeTerms = v); + }), + ), + Expanded( + child: Text( + TranslationBase.of(context).iAcceptTermsConditions, + style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: CustomColors.textColor, letterSpacing: -0.48), + ), + ), + ], + ), ), - _paymentOptions(context, (paymentMethod) { - setState(() => _selectedPaymentMethod = paymentMethod); - }, viewModel: viewModel), Container( - height: 0.25, - color: Colors.grey[300], + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 12, bottom: 3), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).patientShareToDo), + ), + Expanded( + child: _getNormalText(TranslationBase.of(context).sar + " " + (subtotal ?? 0.0).toStringAsFixed(2), isBold: true), + ) + ], + ), + ), + mDivider(Colors.grey[200]), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 3, bottom: 3), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).patientTaxToDo), + ), + Expanded( + child: _getNormalText(TranslationBase.of(context).sar + ' ' + (tax ?? 0.0).toStringAsFixed(2), isBold: true), + ) + ], + ), + ), + mDivider(Colors.grey[200]), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 3, bottom: 3), + child: Row( + children: [ + Expanded( + child: _getNormalText(TranslationBase.of(context).patientShareTotalToDo), + ), + Expanded( + child: _getNormalText(TranslationBase.of(context).sar + ' ' + (total ?? 0.0).toStringAsFixed(2), isBold: true, isTotal: true), + ) + ], + ), + ), + ], + ), ), - Container(height: 40, child: _termsAndCondition(context, onSelected: onTermsClick, onInfoClick: onTermsInfoClick)), Container( - height: 0.25, - color: Colors.grey[300], + padding: EdgeInsets.only(top: 21, bottom: 21), + child: DefaultButton( + TranslationBase.of(context).payNow, + (_agreeTerms && _selectedHospital != null) + ? () { + Navigator.push(context, FadePage(page: PaymentMethod(onSelectedMethod: (String metohd) { + setState(() {}); + }))).then((value) { + print(value); + if (value != null) { + _selectedPaymentMethod = value; + _selectedPaymentParams = {"payment_method_system_name": "Payments.PayFort", "payment_option": value}; + onPayNowClick(); + } + }); + } + : null, + color: CustomColors.green, + disabledColor: CustomColors.grey2, + ), ), - _payNow(context, subtotal: subtotal, tax: tax, total: total, onPayNowClick: onPayNowClick) ], ), ) - ], - ), - ); - }); + : SizedBox(), + ); + }, + ); + } + + void confirmSelectHospitalDialog(List hospitals) { + List list = [ + for (int i = 0; i < hospitals.length; i++) RadioSelectionDialogModel(hospitals[i].name + ' ${hospitals[i].distanceInKilometers} ' + TranslationBase.of(context).km, i), + ]; + showDialog( + context: context, + child: RadioSelectionDialog( + listData: list, + selectedIndex: _selectedHospitalIndex, + isScrollable: true, + onValueSelected: (index) { + _selectedHospitalIndex = index; + _selectedHospital = hospitals[index]; + setState(() {}); + }, + ), + ); + } + + String getHospitalName() { + if (_selectedHospital != null) + return _selectedHospital.name; + else + return TranslationBase.of(context).selectHospital; } fetchData() async { @@ -201,196 +357,73 @@ class _PackagesCartPageState extends State with AfterLayoutMix } } -// /* Payment Footer Widgets */ -// --------------------------- -String _selectedPaymentMethod; -Map _selectedPaymentParams; +// Widget _payNow(BuildContext context, {double subtotal, double tax, double total, @required VoidCallback onPayNowClick}) { +// bool isPayNowAQctive = (_agreeTerms && (_selectedPaymentMethod != null)); +// +// String _subtotal = (subtotal ?? 0.0).toStringAsFixed(2); +// String _tax = (tax ?? 0.0).toStringAsFixed(2); +// String _total = (total ?? 0).toStringAsFixed(2); +// +// return Padding( +// padding: const EdgeInsets.all(5), +// child: Container( +// child: Row( +// crossAxisAlignment: CrossAxisAlignment.end, +// children: [ +// Padding( +// padding: const EdgeInsets.all(5), +// 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), +// Padding( +// padding: const EdgeInsets.all(3), +// child: Container( +// height: 0.25, +// width: 120, +// 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) +// ], +// ), +// ), +// Expanded(child: Container()), +// RaisedButton( +// elevation: 0, +// child: Texts( +// TranslationBase.of(context).payNow, +// fontSize: 15, +// color: Colors.white, +// 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)), +// color: Theme.of(context).primaryColor, +// onPressed: isPayNowAQctive ? onPayNowClick : null, +// ), +// ], +// )), +// ); +// } -Widget _paymentOptions(BuildContext context, Function(String) onSelected, {PackagesViewModel viewModel}) { - double height = 30; - - Widget buttonContent(bool isSelected, String imageName) { - return Container( - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow( - color: isSelected ? Colors.green[50] : Colors.grey[200], - blurRadius: 1, - spreadRadius: 2, - ), - ], - borderRadius: BorderRadius.all(Radius.circular(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 selectTamaraPaymentOption() async { - final tamara_options = await viewModel.service.getTamaraOptions(context: context, showLoading: true); - final selected = - await SingleSelectionDialog(tamara_options, icon: Image.asset('assets/images/new-design/tamara.png'), title: TranslationBase.of(context).tamaraInstPlan).show(context); - return selected.name; - } - - return Padding( - padding: const EdgeInsets.all(5), - child: Container( - height: height, - color: Colors.transparent, - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - InkWell( - child: buttonContent(_selectedPaymentMethod == "tamara", 'tamara.png'), - onTap: () async { - final tamara_option = await selectTamaraPaymentOption(); - _selectedPaymentParams = {"channel": "Web", "payment_method_system_name": "Payments.Tamara", "payment_option": tamara_option}; - onSelected("tamara"); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: buttonContent(_selectedPaymentMethod == "mada", 'mada.png'), - onTap: () { - _selectedPaymentParams = {"payment_method_system_name": "Payments.PayFort", "payment_option": "MADA"}; - onSelected("mada"); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: buttonContent(_selectedPaymentMethod == "visa", 'visa.png'), - onTap: () { - _selectedPaymentParams = {"payment_method_system_name": "Payments.PayFort", "payment_option": "VISA"}; - onSelected("visa"); - }, - ), - SizedBox( - width: 5, - ), - InkWell( - child: buttonContent(_selectedPaymentMethod == "mastercard", 'mastercard.png'), - onTap: () { - _selectedPaymentParams = {"payment_method_system_name": "Payments.PayFort", "payment_option": "MASTERCARD"}; - onSelected("mastercard"); - }, - ), - // SizedBox( - // width: 5, - // ), - // InkWell( - // child: buttonContent( - // _selectedPaymentMethod == "installment", 'installment.png'), - // onTap: () { - // _selectedPaymentParams = {"payment_method_system_name" : "Payments.PayFort", "payment_option" : "INSTALLMENT"}; - // onSelected("installment"); - // }, - // ), - ], - ), +_getNormalText(text, {bool isBold = false, bool isTotal = false}) { + return Text( + text, + style: TextStyle( + fontSize: isBold + ? isTotal + ? 16 + : 12 + : 10, + letterSpacing: -0.5, + color: isBold ? Colors.black : Colors.grey[700], + fontWeight: FontWeight.w600, ), ); } -bool _agreeTerms = false; - -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, - size: 20, - color: _agreeTerms ? Colors.green[600] : Colors.grey[400], - ), - onTap: () { - onSelected(!_agreeTerms); - }, - ), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 8), - child: Texts( - TranslationBase.of(context).pharmacyServiceTermsCondition, - fontWeight: FontWeight.normal, - fontSize: 13, - ), - )), - InkWell( - child: Icon( - Icons.info, - size: 20, - color: Colors.grey[600], - ), - onTap: () { - onInfoClick(); - }, - ), - ], - ), - ); -} - -Widget _payNow(BuildContext context, {double subtotal, double tax, double total, @required VoidCallback onPayNowClick}) { - bool isPayNowAQctive = (_agreeTerms && (_selectedPaymentMethod != null)); - - String _subtotal = (subtotal ?? 0.0).toStringAsFixed(2); - String _tax = (tax ?? 0.0).toStringAsFixed(2); - String _total = (total ?? 0).toStringAsFixed(2); - - return Padding( - padding: const EdgeInsets.all(5), - child: Container( - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Padding( - padding: const EdgeInsets.all(5), - 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), - Padding( - padding: const EdgeInsets.all(3), - child: Container( - height: 0.25, - width: 120, - 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) - ], - ), - ), - Expanded(child: Container()), - RaisedButton( - elevation: 0, - child: Texts( - TranslationBase.of(context).payNow, - fontSize: 15, - color: Colors.white, - 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)), - color: Theme.of(context).primaryColor, - onPressed: isPayNowAQctive ? onPayNowClick : null, - ), - ], - )), - ); -} -// ------------------- - Widget _cartItemDeleteContainer() { _animationController.duration = Duration(milliseconds: 500); _animationController.repeat(reverse: true);