From e4256d6874688d71eb01172ae5f60602ba8eb5c8 Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Thu, 5 Aug 2021 19:05:31 +0300 Subject: [PATCH 1/9] RRT in progress (Service implementations) --- lib/config/config.dart | 1 + lib/core/viewModels/er/rrt-view-model.dart | 73 ++++++++-- .../AmbulanceRequestIndexPages/Summary.dart | 2 +- lib/pages/ErService/ErOptions.dart | 2 +- .../rrt-pickup-address-page.dart | 133 +++++++++++++++--- .../rapid-response-team/rrt-request-page.dart | 16 +-- lib/uitl/translations_delegate_base.dart | 16 +-- lib/widgets/dialogs/selection-dailog.dart | 56 ++++++++ 8 files changed, 252 insertions(+), 47 deletions(-) create mode 100644 lib/widgets/dialogs/selection-dailog.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index f4d5ac91..d25dc616 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -125,6 +125,7 @@ const INSERT_ER_INERT_PRES_ORDER = /// ER RRT const GET_ALL_RC_TRANSPORTATION = 'rc/api/Transportation/getalltransportation'; const GET_ALL_RRT_QUESTIONS = 'Services/Patients.svc/REST/PatientER_RRT_GetAllQuestions'; +const GET_RRT_SERVICE_PRICE = 'Services/Patients.svc/REST/PatientE_RealRRT_GetServicePrice'; ///FindUs const GET_FINDUS_REQUEST = 'Services/Lists.svc/REST/Get_HMG_Locations'; diff --git a/lib/core/viewModels/er/rrt-view-model.dart b/lib/core/viewModels/er/rrt-view-model.dart index a0ce7d07..975b01a1 100644 --- a/lib/core/viewModels/er/rrt-view-model.dart +++ b/lib/core/viewModels/er/rrt-view-model.dart @@ -1,4 +1,6 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/prescriptions_order.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import '../base_view_model.dart'; @@ -7,42 +9,91 @@ import '../base_view_model.dart'; class RRTService extends BaseService{ } - +class _RRTServiceOrders{ + List pendingOrders = []; + List completedOrders = []; +} class RRTViewModel extends BaseViewModel{ var _service = RRTService(); + _RRTServiceOrders rrtOrders = _RRTServiceOrders(); - Future createRequest(){ - - return null; + Future getRequiredData() async{ + getServicePrice(); + getAllOrders(); } + Future createOrder(){ + var body = {"Latitude":24.828170776367188,"Longitude":46.63229029757938,"IdentificationNo":"2344670985","NationalityID":"JOR","CreatedBy":1231755,"OrderServiceID":5,"Notes":""}; + _service.baseAppClient.post(PATIENT_ER_INSERT_PRES_ORDER, body: body, onSuccess: (response, statusCode){ + print(response); + }, onFailure: (error, statusCode){ - Future getAllRequest(){ - + }); return null; } + // Service ID: 4 == RRT + Future<_RRTServiceOrders> getAllOrders() async{ + await _service.baseAppClient.post(GET_PRESCRIPTIONS_ALL_ORDERS, body: {}, onSuccess: (response, statusCode){ + var data = response["PatientER_GetPatientAllPresOrdersList"]; + if(data != null && data is List){ + data.forEach((json){ + if(json["ServiceID"] == 4){ + if(json["Status"] == 1){ // Pending + rrtOrders.pendingOrders.clear(); + rrtOrders.pendingOrders.add(PrescriptionsOrder.fromJson(json)); + }else if (json["Status"] == 3){ // Completed + rrtOrders.completedOrders.clear(); + rrtOrders.completedOrders.add(PrescriptionsOrder.fromJson(json)); + } + } + }); + } + }, onFailure: (error, statusCode){ + print(error); + }); + return rrtOrders; + } + - Future getRequestDetails(){ + Future getOrderDetails(){ return null; } Future getAllQuestions(){ - + _service.baseAppClient.post(GET_ALL_RRT_QUESTIONS, body: {}, onSuccess: (response, statusCode){ + print(response); + }, onFailure: (error, statusCode){ + print(error); + }); return null; } - Future getCancelReasons(){ + Future getServicePrice(){ + var body = {"IdentificationNo":user.patientIdentificationNo}; + _service.baseAppClient.post(GET_RRT_SERVICE_PRICE, body: body, onSuccess: (response, statusCode){ + print(response); + }, onFailure: (error, statusCode){ + print(error); + }); + return null; + } + Future cancelOrder(){ + var body = {"PresOrderID":"2318","PresOrderStatus":4,"EditedBy":3,"RejectionReason":""}; + _service.baseAppClient.post(PATIENT_ER_UPDATE_PRES_ORDER, body: body, onSuccess: (response, statusCode){ + print(response); + }, onFailure: (error, statusCode){ + print(error); + }); return null; } - Future cancelRequest(){ - return null; + Future getCancelReasons(){ } } \ No newline at end of file diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart index 4ddfaaa3..d6d4372e 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart @@ -31,7 +31,7 @@ class _SummaryState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts(TranslationBase.of(context).RRTSummary), + Texts(TranslationBase.of(context).rrtSummary), SizedBox(height: 5,), Container( width: double.infinity, diff --git a/lib/pages/ErService/ErOptions.dart b/lib/pages/ErService/ErOptions.dart index 05121f0f..d80d6566 100644 --- a/lib/pages/ErService/ErOptions.dart +++ b/lib/pages/ErService/ErOptions.dart @@ -116,7 +116,7 @@ class _ErOptionsState extends State { locked: rrtLocked, image: 'assets/images/new-design/AM.PNG', text: TranslationBase.of(context).rrtService, - subText: TranslationBase.of(context).RapidResponseTeam, + subText: TranslationBase.of(context).rapidResponseTeam, onTap:(){ Navigator.push( context, diff --git a/lib/pages/ErService/rapid-response-team/rrt-pickup-address-page.dart b/lib/pages/ErService/rapid-response-team/rrt-pickup-address-page.dart index 91e9cbd2..5b6bf6f6 100644 --- a/lib/pages/ErService/rapid-response-team/rrt-pickup-address-page.dart +++ b/lib/pages/ErService/rapid-response-team/rrt-pickup-address-page.dart @@ -3,9 +3,12 @@ import 'dart:async'; import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/RadioStringDialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_material_pickers/flutter_material_pickers.dart'; +import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; class RRTRequestPickupAddressPage extends StatefulWidget{ @@ -14,15 +17,26 @@ class RRTRequestPickupAddressPage extends StatefulWidget{ State createState() => RRTRequestPickupAddressPageState(); } -class RRTRequestPickupAddressPageState extends State{ +class RRTRequestPickupAddressPageState extends State with SingleTickerProviderStateMixin{ bool acceptTerms = false; - Completer mapController = Completer(); - static final CameraPosition mapCamera = CameraPosition( - target: LatLng(37.42796133580664, -122.085749655962), + bool mapIdle = true; + Completer mapController = Completer(); + CameraPosition mapCameraPosition = CameraPosition( + target: LatLng(24.7114693, 46.67469582), zoom: 14.4746, ); + + List myAdresses = ["One","Two","Three",]; + dynamic selectedAddress; + + @override + void initState(){ + super.initState(); + goToCurrentLocation(); + } + @override Widget build(BuildContext context) { return BaseView( @@ -37,15 +51,31 @@ class RRTRequestPickupAddressPageState extends State Container(height: 0.25, color: Colors.grey.withOpacity(0.7),) + ) + ); + } + + moveToLocation(LatLng location, {bool animate = true}) async{ + await Future.delayed(Duration(milliseconds: 200)); + mapCameraPosition = CameraPosition(target: location, zoom: 16.4746,); + if(animate) + (await mapController.future).animateCamera(CameraUpdate.newCameraPosition(mapCameraPosition),); + else + (await mapController.future).moveCamera(CameraUpdate.newCameraPosition(mapCameraPosition),); + } + + goToCurrentLocation() async{ + var location = await Geolocator.getLastKnownPosition(); + if(location == null){ + Geolocator.getCurrentPosition().then((value){ + moveToLocation(LatLng(value.latitude, value.longitude)); + }); + return; + } + + moveToLocation(LatLng(location.latitude, location.longitude), animate: false); + } } \ No newline at end of file diff --git a/lib/pages/ErService/rapid-response-team/rrt-request-page.dart b/lib/pages/ErService/rapid-response-team/rrt-request-page.dart index 9fb0a2f5..14a244d5 100644 --- a/lib/pages/ErService/rapid-response-team/rrt-request-page.dart +++ b/lib/pages/ErService/rapid-response-team/rrt-request-page.dart @@ -18,8 +18,8 @@ class RRTRequestPageState extends State{ @override Widget build(BuildContext context) { return BaseView( - onModelReady: (viewModel){ - + onModelReady: (viewModel) async{ + await viewModel.getRequiredData(); }, builder: (ctx, vm, widget) => Column( children: [ @@ -38,7 +38,7 @@ class RRTRequestPageState extends State{ Container( padding: EdgeInsets.only(top: 20, bottom: 5), alignment: Alignment.center, - child: Text(TranslationBase.of(context).YouCanPayByTheFollowingOptions, style: TextStyle(fontSize: 13, color: Theme.of(context).appBarTheme.color, fontWeight: FontWeight.w500), maxLines: 2) + child: Text(TranslationBase.of(context).youCanPayByTheFollowingOptions, style: TextStyle(fontSize: 13, color: Theme.of(context).appBarTheme.color, fontWeight: FontWeight.w500), maxLines: 2) ), paymentOptions(), @@ -56,7 +56,7 @@ class RRTRequestPageState extends State{ Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: Text( - TranslationBase.of(context).RRTDDetails, + TranslationBase.of(context).rrtDDetails, textAlign: TextAlign.justify, style: TextStyle(color: Theme.of(context).appBarTheme.color, fontSize: 15, height: 1.5, fontWeight: FontWeight.w300), ), @@ -70,16 +70,16 @@ class RRTRequestPageState extends State{ Container( height: 30, decoration: BoxDecoration(color: Theme.of(context).appBarTheme.color, borderRadius: BorderRadius.only(topLeft: radius, topRight: radius)), - child: Center(child: Text(TranslationBase.of(context).ApproximateServiceFee, style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500, letterSpacing: 1))), + child: Center(child: Text(TranslationBase.of(context).approximateServiceFee, style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500, letterSpacing: 1))), ), - pricingRow(label: TranslationBase.of(context).AmountBeforeTax, value: '500 SAR'), + pricingRow(label: TranslationBase.of(context).amountBeforeTax, value: '500 SAR'), Container(height: 0.5, color: Theme.of(context).appBarTheme.color), - pricingRow(label: TranslationBase.of(context).TaxAmount, value: '50 SAR'), + pricingRow(label: TranslationBase.of(context).taxAmount, value: '50 SAR'), Container(height: 0.5, color: Theme.of(context).appBarTheme.color), - pricingRow(label: TranslationBase.of(context).TotalAmountPayable, value: '550 SAR', labelBold: true), + pricingRow(label: TranslationBase.of(context).totalAmountPayable, value: '550 SAR', labelBold: true), Container(height: 0.5, color: Theme.of(context).appBarTheme.color), ], ); diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 6610a6af..9127f582 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -1158,15 +1158,15 @@ class TranslationBase { String get walker => localizedValues['walker'][locale.languageCode]; String get stretcher => localizedValues['stretcher'][locale.languageCode]; String get none => localizedValues['none'][locale.languageCode]; - String get RRTSummary => localizedValues['RRT-Summary'][locale.languageCode]; - String get RapidResponseTeam => localizedValues['Rapid-Response-Team'][locale.languageCode]; - String get RRTDDetails => localizedValues['RRTDDetails'][locale.languageCode]; - String get ApproximateServiceFee => localizedValues['ApproximateServiceFee'][locale.languageCode]; - String get AmountBeforeTax => localizedValues['AmountBeforeTax'][locale.languageCode]; - String get TaxAmount => localizedValues['TaxAmount'][locale.languageCode]; - String get TotalAmountPayable => localizedValues['TotalAmountPayable'][locale.languageCode]; + String get rrtSummary => localizedValues['RRT-Summary'][locale.languageCode]; + String get rapidResponseTeam => localizedValues['Rapid-Response-Team'][locale.languageCode]; + String get rrtDDetails => localizedValues['RRTDDetails'][locale.languageCode]; + String get approximateServiceFee => localizedValues['ApproximateServiceFee'][locale.languageCode]; + String get amountBeforeTax => localizedValues['AmountBeforeTax'][locale.languageCode]; + String get taxAmount => localizedValues['TaxAmount'][locale.languageCode]; + String get totalAmountPayable => localizedValues['TotalAmountPayable'][locale.languageCode]; String get iAcceptTermsConditions => localizedValues['iAcceptTermsConditions'][locale.languageCode]; - String get YouCanPayByTheFollowingOptions => localizedValues['YouCanPayByTheFollowingOptions'][locale.languageCode]; + String get youCanPayByTheFollowingOptions => localizedValues['YouCanPayByTheFollowingOptions'][locale.languageCode]; String get rrtService => localizedValues['rrtService'][locale.languageCode]; String get billAmount => localizedValues['bill-amount'][locale.languageCode]; String get transportMethod => diff --git a/lib/widgets/dialogs/selection-dailog.dart b/lib/widgets/dialogs/selection-dailog.dart new file mode 100644 index 00000000..a1f4c66d --- /dev/null +++ b/lib/widgets/dialogs/selection-dailog.dart @@ -0,0 +1,56 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class SelectionDialog extends StatefulWidget{ + @override + State createState() => SelectionDialogState(); + + String title; + List items; + show({@required String title, @required List items}){ + this.title = title; + } +} + +class SelectionDialogState extends State{ + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(15)), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(15), + child: Text(widget.title,), + ), + + Container(height: 0.5, color: Colors.grey,), + + ListView.separated( + padding: EdgeInsets.all(10), + itemCount: widget.items.length, + itemBuilder: (ctx,idx) => item(idx), + separatorBuilder: (ctx,idx) => Container(height: 0.25, color: Colors.grey.withOpacity(0.7),)) + ], + ), + ) + ], + ); + } + + Widget item(int idx){ + var model = widget.items[idx]; + return Container( + padding: EdgeInsets.all(10), + height: 20, + color: Colors.blue, + child: Text(model.toString()), + ); + } + +} \ No newline at end of file From bf303a7be065c257b065325dd2b297cbfbf9493d Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Tue, 10 Aug 2021 17:48:27 +0300 Subject: [PATCH 2/9] RRT Implementation --- lib/config/localized_values.dart | 21 ++ lib/core/model/pharmacies/Addresses.dart | 5 + .../prescriptions/prescriptions_order.dart | 16 ++ lib/core/service/client/base_app_client.dart | 1 + lib/core/viewModels/er/rrt-view-model.dart | 128 ++++++++---- lib/core/viewModels/project_view_model.dart | 7 +- lib/models/rrt/service_price.dart | 53 +++++ .../rrt-agreement-page.dart | 49 +++++ .../rapid-response-team/rrt-logs-page.dart | 96 +++------ .../rapid-response-team/rrt-main-screen.dart | 47 ++++- .../rrt-order-list-item.dart | 71 +++++++ .../rrt-pickup-address-page.dart | 171 +++++++++++----- .../rapid-response-team/rrt-place-order.dart | 191 ++++++++++++++++++ .../rapid-response-team/rrt-request-page.dart | 169 +++++++++++----- lib/pages/login/forgot-password.dart | 2 +- lib/pages/login/register.dart | 4 +- .../pharmacyAddress_service.dart | 14 +- lib/uitl/HMGNetworkConnectivity.dart | 2 +- lib/uitl/translations_delegate_base.dart | 6 + lib/uitl/utils.dart | 2 +- lib/widgets/dialogs/alert_dialog.dart | 19 +- 21 files changed, 834 insertions(+), 240 deletions(-) create mode 100644 lib/models/rrt/service_price.dart create mode 100644 lib/pages/ErService/rapid-response-team/rrt-agreement-page.dart create mode 100644 lib/pages/ErService/rapid-response-team/rrt-order-list-item.dart create mode 100644 lib/pages/ErService/rapid-response-team/rrt-place-order.dart diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 18790bd4..681e0b22 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1269,10 +1269,31 @@ const Map localizedValues = { "TaxAmount": {"en": "Tax Amount:", "ar": "Tax Amount:"}, "TotalAmountPayable": {"en": "Total Amount Payable:", "ar": "Total Amount Payable:"}, "iAcceptTermsConditions": {"en": "I Accept the Terms And Conditions", "ar": "You can pay by the following options:"}, + "somethingWentWrongTryLater": {"en": "Sorry something went wrong please try again later", "ar": "نعتذر لخدمتكم يرجى المحاولة لاحقا"}, "YouCanPayByTheFollowingOptions": {"en": "You can pay by the following options:", "ar": "I Accept the Terms And Conditions"}, "RRTDDetails": {"en": "The RRT service provides medical services urgent and stable cases, not life-threatening situation or extremities and the service includes providing medical care from a copmplete medical team at home", "ar": "The RRT service provides medical services urgent and stable cases, not life-threatening situation or extremities and the service includes providing medical care from a copmplete medical team at home"}, "Rapid-Response-Team": {"en": "Rapid Response Team", "ar": "فريق الاستجابة السريع"}, "rrtService": {"en": "RRT Service", "ar": "خدمة RRT"}, + "rrtUserAgreementTitle":{ + "en":"Communication via email, text messages and phone calls", + "ar":"الاتصال عبر البريد الإلكتروني، والرسائل النصية، والمكالمات الهاتفية" + }, + "rrtUserAgreementP1":{ + "en" : "I understand that the contact number or Email that I have provided on registration will be used for communication by HMG. I hereby agree to be notified by HMG through SMS, Email or any other method for appointments notifications, current HMG’s medical services, and any services introduced by the HMG in the future or any modifications made to the services offered by the HMG. And these messages may be submitted as evidence where the HMG has the right to use at any time whatsoever and as it sees fit.", + "ar" : "أدرك بأن رقم الهاتف أو البريد الإلكتروني الذي قدمته للمجموعة سيستخدم كوسيلة اتصال بيني وبينها، وأقر بموافقتي على قيام المجموعة بإخطاري عن طريق الرسائل القصيرة أو البريد الإلكتروني أو أي طريقة أخرى بالمواعيد وبأي خدمات طبية تقدمها المجموعة أو قد تطرحها المجموعة للجمهور في المستقبل أو أي تعديلات قد تطرأ على الخدمات المقدمة من قبل المجموعة. وتعتبر هذه الرسائل دليل إثبات يحق للمجموعة استخدامه في أي وقت تشاء. " + }, + "rrtUserAgreementP2":{ + "en":"I understand the risks of communicating by email and text messages, in particular the privacy risks. I understand that HMG cannot guarantee the security and confidentiality of email or text communication. HMG will not be responsible for messages that are not received or delivered due to technical failure, or for disclosure of confidential information unless caused by intentional misconduct.", + "ar":"أفھم مخاطر التواصل عبر البرید الإلکتروني والرسائل النصیة، خاصة مخاطر الخصوصیة، وادرك أن المجموعة لا يمكنها ضمان أمن وسرية البريد الإلكتروني أو الرسائل النصية ولن تكون المجموعة مسؤولة عن الرسائل التي لم يتم استلامها أو تسليمها بسبب الفشل التقني أو الكشف عن المعلومات السرية ما لم يكن سببها سوء سلوك متعمد." + }, + "rrtUserAgreementP3":{ + "en":'I hereby agree to receive emails, text messages, phone calls for appointments notifications, special promotions and new features or products introduced by HMG or any third party.', + "ar":"وافق على تلقي رسائل البريد الإلكتروني، والرسائل النصية، والمكالمات الهاتفية للإخطار بالمواعيد والعروض الترويجية والمميزات والمنتجات الجديدة الخاصة بالمجموعة أو اي طرف اخر." + }, + "rrtOrderSuccessMessage": { + "en": "The request has been sent successfully, You will be contacted soon.", + "ar": "تم ارسال الطلب بنجاح وسيتم الاتصال بك قريبا." + }, "bill-amount": {"en": "Bill Amount", "ar": "مبلغ الفاتورة"}, "transport-method": {"en": "Transportation Method", "ar": "طريقة النقل"}, "directions": {"en": "Directions", "ar": "الاتجاهات"}, diff --git a/lib/core/model/pharmacies/Addresses.dart b/lib/core/model/pharmacies/Addresses.dart index b00b1a17..40bcb778 100644 --- a/lib/core/model/pharmacies/Addresses.dart +++ b/lib/core/model/pharmacies/Addresses.dart @@ -86,4 +86,9 @@ class Addresses { return data; } + @override + String toString() { + return "${address1 ?? ""} ${address2 ?? ""}"; + } + } diff --git a/lib/core/model/prescriptions/prescriptions_order.dart b/lib/core/model/prescriptions/prescriptions_order.dart index fdcbf203..d3390d92 100644 --- a/lib/core/model/prescriptions/prescriptions_order.dart +++ b/lib/core/model/prescriptions/prescriptions_order.dart @@ -1,4 +1,7 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; class PrescriptionsOrder { int iD; @@ -32,6 +35,19 @@ class PrescriptionsOrder { dynamic projectDescription; dynamic projectDescriptionN; + String getNearestProjectDescription(){ + return isAppArabic ? nearestProjectDescriptionN : nearestProjectDescription; + } + String getStatusName(TranslationBase localize){ + if(status == 1) + return localize.pending; + else if(status == 3) + return localize.completed; + return '$status'; + } + + String getFormattedDateTime()=> DateUtil.getDateFormatted(pickupDateTime); + PrescriptionsOrder( {this.iD, this.patientID, diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 03f12df1..42dc2f4b 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -169,6 +169,7 @@ class BaseAppClient { } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) { onSuccess(parsed, statusCode); + debugPrint(parsed.toString()); } else if (parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']) { if (parsed['SameClinicApptList'] != null) { diff --git a/lib/core/viewModels/er/rrt-view-model.dart b/lib/core/viewModels/er/rrt-view-model.dart index 975b01a1..1289538d 100644 --- a/lib/core/viewModels/er/rrt-view-model.dart +++ b/lib/core/viewModels/er/rrt-view-model.dart @@ -1,7 +1,19 @@ +import 'dart:async'; +import 'dart:convert'; + import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; import 'package:diplomaticquarterapp/core/model/prescriptions/prescriptions_order.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/rrt/service_price.dart'; +import 'package:diplomaticquarterapp/services/pharmacy_services/pharmacyAddress_service.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:flutter/cupertino.dart'; import '../base_view_model.dart'; @@ -9,91 +21,127 @@ import '../base_view_model.dart'; class RRTService extends BaseService{ } -class _RRTServiceOrders{ +class _RRTServiceData{ List pendingOrders = []; List completedOrders = []; + ServicePrice servicePrice; } class RRTViewModel extends BaseViewModel{ var _service = RRTService(); - _RRTServiceOrders rrtOrders = _RRTServiceOrders(); - - Future getRequiredData() async{ - getServicePrice(); - getAllOrders(); + var _pharmacy_service = locator(); + var _pharmacy_address_service = locator(); + + _RRTServiceData rrtServiceData = _RRTServiceData(); + + Future<_RRTServiceData> loadRequiredData() async{ + await getServicePrice(); + await getAllOrders(); + return rrtServiceData; } - Future createOrder(){ - var body = {"Latitude":24.828170776367188,"Longitude":46.63229029757938,"IdentificationNo":"2344670985","NationalityID":"JOR","CreatedBy":1231755,"OrderServiceID":5,"Notes":""}; - _service.baseAppClient.post(PATIENT_ER_INSERT_PRES_ORDER, body: body, onSuccess: (response, statusCode){ - print(response); - }, onFailure: (error, statusCode){ + Future createOrder(Map body) async{ + body['IdentificationNo'] = user.patientIdentificationNo; + body['NationalityID'] = user.nationalityID; + body['CreatedBy'] = user.patientIdentificationType; + body['OrderServiceID'] = 5; + int requestNo; + await _service.baseAppClient.post(PATIENT_ER_INSERT_PRES_ORDER, body: body, onSuccess: (response, statusCode){ + requestNo = response['RequestNo']; + }, onFailure: (error, statusCode){ + AppToast.showErrorToast(message: error); }); - return null; + return requestNo; } // Service ID: 4 == RRT - Future<_RRTServiceOrders> getAllOrders() async{ + Future<_RRTServiceData> getAllOrders() async{ await _service.baseAppClient.post(GET_PRESCRIPTIONS_ALL_ORDERS, body: {}, onSuccess: (response, statusCode){ var data = response["PatientER_GetPatientAllPresOrdersList"]; if(data != null && data is List){ data.forEach((json){ - if(json["ServiceID"] == 4){ + if(json["ServiceID"] == 5){ if(json["Status"] == 1){ // Pending - rrtOrders.pendingOrders.clear(); - rrtOrders.pendingOrders.add(PrescriptionsOrder.fromJson(json)); + rrtServiceData.pendingOrders.clear(); + rrtServiceData.pendingOrders.add(PrescriptionsOrder.fromJson(json)); }else if (json["Status"] == 3){ // Completed - rrtOrders.completedOrders.clear(); - rrtOrders.completedOrders.add(PrescriptionsOrder.fromJson(json)); + rrtServiceData.completedOrders.clear(); + rrtServiceData.completedOrders.add(PrescriptionsOrder.fromJson(json)); } } + return Future.error("404"); }); } }, onFailure: (error, statusCode){ - print(error); + AppToast.showErrorToast(message: error); }); - return rrtOrders; + return rrtServiceData; } - Future getOrderDetails(){ - + Future getOrderDetails() async{ return null; } - Future getAllQuestions(){ - _service.baseAppClient.post(GET_ALL_RRT_QUESTIONS, body: {}, onSuccess: (response, statusCode){ - print(response); + Future getAllQuestions() async{ + dynamic response_; + await _service.baseAppClient.post(GET_ALL_RRT_QUESTIONS, body: {}, onSuccess: (response, statusCode){ + response_ = response; }, onFailure: (error, statusCode){ - print(error); + AppToast.showErrorToast(message: error); }); - return null; + return response_; } - Future getServicePrice(){ - var body = {"IdentificationNo":user.patientIdentificationNo}; - _service.baseAppClient.post(GET_RRT_SERVICE_PRICE, body: body, onSuccess: (response, statusCode){ - print(response); + Future getServicePrice() async{ + Map body = {"IdentificationNo":user.patientIdentificationNo}; + ServicePrice servicePrice; + await _service.baseAppClient.post(GET_RRT_SERVICE_PRICE, body: body, onSuccess: (response, statusCode){ + var data = response['PatientE_RealRRT_GetServicePriceList']; + if(data != null && data is List){ + var priceData = data.first; + if(priceData != null){ + servicePrice = ServicePrice.fromJson(priceData); + rrtServiceData.servicePrice = servicePrice; + } + } }, onFailure: (error, statusCode){ - print(error); + AppToast.showErrorToast(message: error); }); - return null; + return servicePrice; } - Future cancelOrder(){ - var body = {"PresOrderID":"2318","PresOrderStatus":4,"EditedBy":3,"RejectionReason":""}; - _service.baseAppClient.post(PATIENT_ER_UPDATE_PRES_ORDER, body: body, onSuccess: (response, statusCode){ - print(response); + Future cancelOrder(PrescriptionsOrder order, {String reason = ""}) async{ + var body = {"PresOrderID":order.iD, "PresOrderStatus":4,"EditedBy":3,"RejectionReason":reason}; + var success = false; + await _service.baseAppClient.post(PATIENT_ER_UPDATE_PRES_ORDER, body: body, onSuccess: (response, statusCode){ + success = true; }, onFailure: (error, statusCode){ - print(error); + AppToast.showErrorToast(message: error); + success = false; }); - return null; + return Future.value(success); } - Future getCancelReasons(){ } + + Future> getAddresses() async{ + Object error; + try{ + var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); + if(token == null) + await _pharmacy_service.generatePharmacyToken(); + + await _pharmacy_service.makeVerifyCustomer({'PatientID': user.patientID.toString()}); + await _pharmacy_address_service.getAddresses(); + return _pharmacy_address_service.addresses; + }catch(e){ + error = e; + } + Future.error(error); + } } \ No newline at end of file diff --git a/lib/core/viewModels/project_view_model.dart b/lib/core/viewModels/project_view_model.dart index 17ccb267..2e6d1f29 100644 --- a/lib/core/viewModels/project_view_model.dart +++ b/lib/core/viewModels/project_view_model.dart @@ -11,6 +11,7 @@ import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; +var isAppArabic = false; class ProjectViewModel extends BaseViewModel { // Platform Bridge PlatformBridge platformBridge() { @@ -69,19 +70,19 @@ class ProjectViewModel extends BaseViewModel { currentLanguage = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); _appLocale = Locale(currentLanguage); - _isArabic = currentLanguage == 'ar'; + isAppArabic = _isArabic = currentLanguage == 'ar'; notifyListeners(); } void changeLanguage(String lan) { if (lan != "en" && currentLanguage != lan) { _appLocale = Locale("ar"); - _isArabic = true; + isAppArabic = _isArabic = true; currentLanguage = 'ar'; sharedPref.setString(APP_LANGUAGE, 'ar'); } else if (lan != "ar" && currentLanguage != lan) { _appLocale = Locale("en"); - _isArabic = false; + isAppArabic = _isArabic = false; currentLanguage = 'en'; sharedPref.setString(APP_LANGUAGE, 'en'); } diff --git a/lib/models/rrt/service_price.dart b/lib/models/rrt/service_price.dart new file mode 100644 index 00000000..d206c986 --- /dev/null +++ b/lib/models/rrt/service_price.dart @@ -0,0 +1,53 @@ +class ServicePrice { + String currency; + double maxPrice; + double maxTotalPrice; + double maxVAT; + double minPrice; + double minTotalPrice; + double minVAT; + int price; + int totalPrice; + int vat; + + ServicePrice({ + this.currency, + this.maxPrice, + this.maxTotalPrice, + this.maxVAT, + this.minPrice, + this.minTotalPrice, + this.minVAT, + this.price, + this.totalPrice, + this.vat}); + + ServicePrice.fromJson(dynamic json) { + currency = json["Currency"]; + maxPrice = json["MaxPrice"]; + maxTotalPrice = json["MaxTotalPrice"]; + maxVAT = json["MaxVAT"]; + minPrice = json["MinPrice"]; + minTotalPrice = json["MinTotalPrice"]; + minVAT = json["MinVAT"]; + price = json["Price"]; + totalPrice = json["TotalPrice"]; + vat = json["VAT"]; + } + + Map toJson() { + var map = {}; + map["Currency"] = currency; + map["MaxPrice"] = maxPrice; + map["MaxTotalPrice"] = maxTotalPrice; + map["MaxVAT"] = maxVAT; + map["MinPrice"] = minPrice; + map["MinTotalPrice"] = minTotalPrice; + map["MinVAT"] = minVAT; + map["Price"] = price; + map["TotalPrice"] = totalPrice; + map["VAT"] = vat; + return map; + } + +} \ No newline at end of file diff --git a/lib/pages/ErService/rapid-response-team/rrt-agreement-page.dart b/lib/pages/ErService/rapid-response-team/rrt-agreement-page.dart new file mode 100644 index 00000000..c3048127 --- /dev/null +++ b/lib/pages/ErService/rapid-response-team/rrt-agreement-page.dart @@ -0,0 +1,49 @@ +import 'package:diplomaticquarterapp/pages/conference/clipped_video.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class RRTAgreementPage extends StatelessWidget{ + TranslationBase localize; + + @override + Widget build(BuildContext context) { + localize = TranslationBase.of(context); + + return AppScaffold( + appBarTitle: localize.userAgreement, + isShowAppBar: true, + showHomeAppBarIcon: false, + body: SingleChildScrollView( + padding: EdgeInsets.all(20), + child: Column( + children: [ + Text(localize.rrtUserAgreementTitle, style: TextStyle(color: Colors.black, fontWeight: FontWeight.w500, fontSize: 22), maxLines: 100, textAlign: TextAlign.center), + SizedBox(height: 20), + text(localize.rrtUserAgreementP1), + text(localize.rrtUserAgreementP2), + text(localize.rrtUserAgreementP3) + ], + ), + ) + ); + } + + Widget text(String string)=> Padding( + padding: const EdgeInsets.symmetric(vertical: 15), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + clipBehavior: Clip.hardEdge, + width: 10, height: 10, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(20), color: Colors.black) + ), + SizedBox(width: 20), + Expanded(child: Text(string, style: TextStyle(color: Colors.black87, fontSize: 18), maxLines: 100, textAlign: TextAlign.justify)), + ], + ), + ); + +} \ No newline at end of file diff --git a/lib/pages/ErService/rapid-response-team/rrt-logs-page.dart b/lib/pages/ErService/rapid-response-team/rrt-logs-page.dart index acfe13d8..59f11fb2 100644 --- a/lib/pages/ErService/rapid-response-team/rrt-logs-page.dart +++ b/lib/pages/ErService/rapid-response-team/rrt-logs-page.dart @@ -1,94 +1,54 @@ +import 'package:diplomaticquarterapp/core/model/prescriptions/prescriptions_order.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-order-list-item.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class RRTLogPage extends StatefulWidget{ + final List orders; + const RRTLogPage({this.orders}); + @override State createState() => RRTLogPageState(); } class RRTLogPageState extends State{ + + RRTViewModel viewModel; + @override Widget build(BuildContext context) { - return BaseView( - onModelReady: (viewModel){ - }, - builder: (ctx, vm, widget){ + return BaseView( + onModelReady: (vm) => viewModel = vm, + builder: (ctx, vm, widgetState){ return ListView.builder( - itemCount: 10, - itemBuilder: (ctx, idx) => RRTLogListItem() + itemCount: widget.orders.length, + itemBuilder: (ctx, idx) { + var order = widget.orders[idx]; + return RRTLogListItem(order, onCancel: deleteOrder); + } ); } ); } -} - - - -// ------------------------ -// List Item Widget -// ------------------------ - - -final _item_content_seperator = Container(height: 0.25, padding: EdgeInsets.all(10), color: Colors.grey.withOpacity(0.5)); - -class RRTLogListItem extends StatelessWidget{ - BuildContext _context; - @override - Widget build(BuildContext context) { - _context = context; - - return Container( - padding: EdgeInsets.all(15), margin: EdgeInsets.symmetric(horizontal: 15, vertical: 10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - boxShadow: [BoxShadow(color: Colors.grey.withOpacity(0.25), spreadRadius: 1, blurRadius: 3)] - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - _contentItem(label: "Request ID", value: "2318"), - _item_content_seperator, - _contentItem(label: "Status", value: "2318"), - _item_content_seperator, - _contentItem(label: "Pickup Date", value: "2318"), - _item_content_seperator, - _contentItem(label: "Location", value: "2318"), - _item_content_seperator, - SizedBox(height: 10), - FractionallySizedBox(child: cancelButton()) - ], - ), - ); - } - - Widget _contentItem({@required String label, String value}){ - return Container( - padding: EdgeInsets.symmetric(vertical: 10), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(label, style: TextStyle(color: Theme.of(_context).appBarTheme.color, fontSize: 9, letterSpacing: 1),), - SizedBox(height: 5,), - Text(value, style: TextStyle(color: Theme.of(_context).appBarTheme.color,fontWeight: FontWeight.bold, fontSize: 14),), - ], - ), - ); + deleteOrder(PrescriptionsOrder order) async { + GifLoaderDialogUtils.showMyDialog(context); + var success = await viewModel.cancelOrder(order); + GifLoaderDialogUtils.hideDialog(context); + if(success) + setState(() { + widget.orders.remove(order); + }); } - Widget cancelButton() => MaterialButton( - height: 45, - color: Color(0xFFc5272d), - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10) ), - onPressed: () { }, - child: Text("CANCEL", style: TextStyle(color: Colors.white, fontSize: 13),), - - ); } + diff --git a/lib/pages/ErService/rapid-response-team/rrt-main-screen.dart b/lib/pages/ErService/rapid-response-team/rrt-main-screen.dart index fe1c6a9d..905d0810 100644 --- a/lib/pages/ErService/rapid-response-team/rrt-main-screen.dart +++ b/lib/pages/ErService/rapid-response-team/rrt-main-screen.dart @@ -1,6 +1,9 @@ +import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-logs-page.dart'; import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-request-page.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -16,27 +19,55 @@ class RRTMainScreenState extends State with SingleTickerProvider TabController tabController; PageController pageController = PageController(initialPage: 0, keepPage: true); + RRTViewModel viewModel; + bool loadingData; + @override void initState() { super.initState(); tabController = TabController(length: 2, vsync: this); } + TranslationBase localize; @override Widget build(BuildContext context) { + localize = TranslationBase.of(context); return AppScaffold( - appBarTitle: 'Rapid Response Team', + appBarTitle: localize.rapidResponseTeam, isShowAppBar: true, - body: Column( + body: BaseView( + onModelReady: (vm) async { + viewModel = vm; + loadingData = true; + await vm.loadRequiredData().then((value){ + }).whenComplete(() => setState(() => loadingData = false)); + }, + builder: (ctx, vm, widget) => content(), + ) + ); + } + + Widget content(){ + if(loadingData == true){ + return Center(child: CircularProgressIndicator()); + // else if(viewModel.state == ViewState.Error) + + }else if(viewModel.rrtServiceData != null && viewModel.rrtServiceData.servicePrice != null){ + return Column( children: [ tabBar(), Expanded( child: contentPager() ) ], - ), - ); + ); + }else{ + return Container( + alignment: Alignment.center, + child: Text(localize.somethingWentWrongTryLater, style: TextStyle(color: Colors.red), maxLines: 5,), + ); + } } Widget tabBar() => Container( @@ -52,10 +83,10 @@ class RRTMainScreenState extends State with SingleTickerProvider indicatorSize: TabBarIndicatorSize.label, tabs: [ Tab( - child: Text("Rapid Response Team", style: TextStyle(color: Theme.of(context).appBarTheme.color),), + child: Text(localize.rapidResponseTeam, style: TextStyle(color: Theme.of(context).appBarTheme.color),), ), Tab( - child: Text("Order Log", style: TextStyle(color: Theme.of(context).appBarTheme.color),), + child: Text(localize.orderLog, style: TextStyle(color: Theme.of(context).appBarTheme.color),), ), ] ), @@ -65,8 +96,8 @@ class RRTMainScreenState extends State with SingleTickerProvider onPageChanged: onPageChanged, controller: pageController, children: [ - RRTRequestPage(), - RRTLogPage(), + RRTRequestPage(servicePrice: viewModel.rrtServiceData.servicePrice, pendingOrders: viewModel.rrtServiceData.pendingOrders), + RRTLogPage(orders: viewModel.rrtServiceData.completedOrders), ], ); diff --git a/lib/pages/ErService/rapid-response-team/rrt-order-list-item.dart b/lib/pages/ErService/rapid-response-team/rrt-order-list-item.dart new file mode 100644 index 00000000..ed6078ff --- /dev/null +++ b/lib/pages/ErService/rapid-response-team/rrt-order-list-item.dart @@ -0,0 +1,71 @@ + +import 'package:diplomaticquarterapp/core/model/prescriptions/prescriptions_order.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +final _item_content_seperator = Container(height: 0.25, padding: EdgeInsets.all(10), color: Colors.grey.withOpacity(0.5)); + +class RRTLogListItem extends StatelessWidget{ + final PrescriptionsOrder order; + final Function(PrescriptionsOrder) onCancel; + RRTLogListItem(this.order, {this.onCancel}); + + BuildContext _context; + + TranslationBase localize; + @override + Widget build(BuildContext context) { + _context = context; + localize = TranslationBase.of(context); + + return Container( + padding: EdgeInsets.all(15), margin: EdgeInsets.symmetric(horizontal: 15, vertical: 10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(15), + boxShadow: [BoxShadow(color: Colors.grey.withOpacity(0.25), spreadRadius: 1, blurRadius: 3)] + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + _contentItem(label: localize.reqId, value: order.iD.toString()), + _item_content_seperator, + _contentItem(label: localize.status, value: order.getStatusName(localize)), + _item_content_seperator, + _contentItem(label: localize.pickupDate, value: order.getFormattedDateTime()), + _item_content_seperator, + _contentItem(label: localize.location, value: order.getNearestProjectDescription()), + _item_content_seperator, + SizedBox(height: 10), + + if(onCancel != null) + FractionallySizedBox(child: cancelButton()) + ], + ), + ); + } + + Widget _contentItem({@required String label, String value}){ + return Container( + padding: EdgeInsets.symmetric(vertical: 10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(label, style: TextStyle(color: Theme.of(_context).appBarTheme.color, fontSize: 9, letterSpacing: 1),), + SizedBox(height: 5,), + Text(value, style: TextStyle(color: Theme.of(_context).appBarTheme.color,fontWeight: FontWeight.bold, fontSize: 14),), + ], + ), + ); + } + + Widget cancelButton() => MaterialButton( + height: 45, + color: Color(0xFFc5272d), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10) ), + onPressed: () => onCancel(order), + child: Text(localize.cancel, style: TextStyle(color: Colors.white, fontSize: 13),), + + ); +} diff --git a/lib/pages/ErService/rapid-response-team/rrt-pickup-address-page.dart b/lib/pages/ErService/rapid-response-team/rrt-pickup-address-page.dart index 5b6bf6f6..20acbbb4 100644 --- a/lib/pages/ErService/rapid-response-team/rrt-pickup-address-page.dart +++ b/lib/pages/ErService/rapid-response-team/rrt-pickup-address-page.dart @@ -1,18 +1,33 @@ import 'dart:async'; +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/rrt/service_price.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/RadioStringDialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_material_pickers/flutter_material_pickers.dart'; import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:google_maps_place_picker/google_maps_place_picker.dart'; +import 'package:provider/provider.dart'; + +import 'rrt-place-order.dart'; class RRTRequestPickupAddressPage extends StatefulWidget{ + final ServicePrice servicePrice; + RRTRequestPickupAddressPage({@required this.servicePrice}); + @override State createState() => RRTRequestPickupAddressPageState(); @@ -28,55 +43,95 @@ class RRTRequestPickupAddressPageState extends State myAdresses = ["One","Two","Three",]; - dynamic selectedAddress; - + List myAddresses = []; + Addresses selectedAddress; + StreamController addressStreamController = StreamController(); + Stream addressStream; + StreamController addressLoadingStreamController = StreamController(); + Stream addressLoadingStream; + @override void initState(){ super.initState(); goToCurrentLocation(); + addressStream = addressStreamController.stream; + addressLoadingStream = addressLoadingStreamController.stream; + } + + void loadAddresses() async{ + // GifLoaderDialogUtils.showMyDialog(context); + myAddresses = await viewModel.getAddresses(); + // GifLoaderDialogUtils.hideDialog(context); + + if(myAddresses.isNotEmpty) + setState(() {}); } + TranslationBase localize; + RRTViewModel viewModel; + @override Widget build(BuildContext context) { - return BaseView( - onModelReady: (viewModel){ + localize = TranslationBase.of(context); + ProjectViewModel projectViewModel = Provider.of(context); + + addressStreamController.sink.add(0); + return BaseView( + onModelReady: (vm){ + viewModel = vm; + loadAddresses(); }, builder: (ctx, vm, widget) => AppScaffold( - appBarTitle: TranslationBase.of(context).pickupLocation, + appBarTitle: localize.pickupLocation, isShowAppBar: true, body: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - selectAddress(), + StreamBuilder( + stream: addressStream, + builder: (context, snapshot) { + return selectAddressField(); + } + ), + StreamBuilder( + stream: addressLoadingStream, + builder: (context, snapshot) { + return snapshot.hasData ? LinearProgressIndicator(backgroundColor: Colors.transparent) : Container(height: 4,); + } + ), Expanded( - child: Stack( - children: [ - GoogleMap( - myLocationEnabled: true, - onTap: moveToLocation, - mapType: MapType.normal, - initialCameraPosition: mapCameraPosition, - onCameraIdle: (){ - mapIdle = true; - setState((){}); - }, - onCameraMove: (camPosition){ - mapCameraPosition = camPosition; - }, - onCameraMoveStarted: (){ - mapIdle = false; - setState((){}); - }, - onMapCreated: (controller){ - mapController.complete(controller); - }, - ), - - centerTargetPoint() - ], - ) + child: + PlacePicker( + apiKey: GOOGLE_API_KEY, + enableMyLocationButton: true, + automaticallyImplyAppBarLeading: false, + autocompleteOnTrailingWhitespace: true, + selectInitialPosition: true, + autocompleteLanguage: projectViewModel.currentLanguage, + enableMapTypeButton: true, + searchForInitialValue: false, + selectedPlaceWidgetBuilder: (_, selectedPlace, state, isSearchBarFocused) { + if(state == SearchingState.Idle){ + addressLoadingStreamController.sink.add(null); + if(selectedPlace != null){ + var loc = selectedPlace.geometry.location; + var address1 = selectedPlace.addressComponents.first.longName; + var address2 = ""; + if(selectedPlace.addressComponents.length > 1) + address2 = selectedPlace.addressComponents[1].longName; + + selectedAddress = Addresses(latLong: '${loc.lat},${loc.lng}', address1: address1, address2: address2); + addressStreamController.sink.add(0); + } + }else{ + addressLoadingStreamController.sink.add(0); + } + return Container(); + }, + initialPosition: LatLng(24.7114693, 46.67469582), + useCurrentLocation: false, + ), ), continueButton() ], @@ -104,23 +159,20 @@ class RRTRequestPickupAddressPageState extends State + Navigator.push( + context, + FadePage(page: RRTPlaceOrderPage(selectedAddress: selectedAddress, servicePrice: widget.servicePrice,)) + ), + child: Text(localize.continues, style: TextStyle(color: Colors.white, fontSize: 15, letterSpacing: 1),), ), ); } @@ -144,19 +200,26 @@ class RRTRequestPickupAddressPageState extends State 1){ + var cordinates = itm.latLong.split(','); + var latlng = LatLng(double.parse(cordinates.first), double.parse(cordinates.last)); + moveToLocation(latlng); + }else{ + AppToast.showErrorToast(message: 'Invalid address coordinates'); + } }); }, ); diff --git a/lib/pages/ErService/rapid-response-team/rrt-place-order.dart b/lib/pages/ErService/rapid-response-team/rrt-place-order.dart new file mode 100644 index 00000000..9cded48d --- /dev/null +++ b/lib/pages/ErService/rapid-response-team/rrt-place-order.dart @@ -0,0 +1,191 @@ +import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; +import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; +import 'package:diplomaticquarterapp/models/rrt/service_price.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/alert_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; + +class RRTPlaceOrderPage extends StatelessWidget{ + TranslationBase localize; + RRTViewModel viewModel; + Addresses selectedAddress; + final ServicePrice servicePrice; + + RRTPlaceOrderPage({@required this.selectedAddress, @required this.servicePrice}); + + TextEditingController noteController = TextEditingController(text: ''); + BuildContext _context; + @override + Widget build(BuildContext context) { + _context = context; + localize = TranslationBase.of(context); + var lat = selectedAddress.latLong.split(',').first; + var lng = selectedAddress.latLong.split(',').last; + + return BaseView( + onModelReady: (vm) => viewModel = vm, + builder: (ctx,vm,wState){ + return AppScaffold( + appBarTitle: localize.rapidResponseTeam, + isShowAppBar: true, + body: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Expanded( + child: SingleChildScrollView( + padding: EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text(localize.selectedLocation, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),), + + selectedAddressField(), + + AspectRatio( + aspectRatio: 3/1, + child: ClipRRect( + clipBehavior: Clip.hardEdge, + borderRadius: BorderRadius.circular(10), + child: Image.network( + "https://maps.googleapis.com/maps/api/staticmap?center=$lat,$lng &zoom=16&size=800x400&maptype=roadmap&markers=color:red%7C$lat,$lng&key=AIzaSyCyDbWUM9d_sBUGIE8PcuShzPaqO08NSC8", + fit: BoxFit.cover, + ), + ), + ), + + SizedBox(height: 10,), + + Container( + height: 70, + margin: EdgeInsets.symmetric(vertical: 5), + padding: EdgeInsets.symmetric(horizontal: 15, vertical: 10), + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(10), + boxShadow: [BoxShadow(blurRadius: 5, spreadRadius: 2, offset: Offset(2,2), color: Colors.grey.withOpacity(0.25))] + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(localize.totalAmountPayable, style: TextStyle(fontSize: 13),), + SizedBox(height: 5,), + Text("${servicePrice.totalPrice ?? '- - -'} ${localize.sar}" , style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),), + ], + ), + ), + + Container( + height: 70, + margin: EdgeInsets.symmetric(vertical: 5), + padding: EdgeInsets.symmetric(horizontal: 0, vertical: 10), + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(10), + boxShadow: [BoxShadow(blurRadius: 5, spreadRadius: 2, offset: Offset(2,2), color: Colors.grey.withOpacity(0.25))] + ), + child: TextField( + controller: noteController, + style: TextStyle(fontSize: 18.0), + decoration: InputDecoration( + filled: true, + fillColor: Colors.white, + labelText: localize.notes, + contentPadding: const EdgeInsets.only(left: 14.0, bottom: 8.0, top: 8.0), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.white), + borderRadius: BorderRadius.circular(10), + ), + enabledBorder: UnderlineInputBorder( + borderSide: BorderSide(color: Colors.white), + borderRadius: BorderRadius.circular(10), + ), + ) + ), + ), + ], + ), + ), + ), + submitButton(context) + ], + ) + ); + }, + ); + } + + + Widget selectedAddressField(){ + var address = "${selectedAddress.address1 ?? ''} ${selectedAddress.address2 ?? ''}"; + return Container( + margin: EdgeInsets.symmetric(vertical: 10), + child: Expanded( + child: MaterialButton( + height: 50, color: Colors.white, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10) ), + onPressed: (){}, + child: Row( + children: [ + Expanded(child: Text(address, style: TextStyle(color: Colors.black87, fontSize: 15, letterSpacing: 1))), + Icon(Icons.location_on_rounded, size: 30, color: Colors.black,) + ], + ), + ), + ), + ); + } + + + Widget submitButton(BuildContext context){ + return Padding( + padding: const EdgeInsets.all(15), + child: MaterialButton( + height: 50, + color: Theme.of(context).appBarTheme.color, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + onPressed: () => placeOrder(), + child: Text(localize.submit, style: TextStyle(color: Colors.white, fontSize: 15, letterSpacing: 1),), + ), + ); + } + + placeOrder() async{ + if(selectedAddress != null && selectedAddress.latLong != null && selectedAddress.latLong.isNotEmpty && selectedAddress.latLong.split(',').length > 1){ + GifLoaderDialogUtils.showMyDialog(_context); + + Map params = {}; + var cordinates = selectedAddress.latLong.split(','); + var latlng = LatLng(double.parse(cordinates.first), double.parse(cordinates.last)); + params['Latitude'] = latlng.latitude; + params['Longitude'] = latlng.longitude; + params['Notes'] = noteController.text; + var requestId = await viewModel.createOrder(params); + + GifLoaderDialogUtils.hideDialog(_context); + + if(requestId != null){ + AlertDialogBox( + context: _context, + title: '', + message: localize.rrtOrderSuccessMessage, + okText: localize.ok, + okFunction: (){ + + } + ).showAlertDialog(); + } + }else{ + AppToast.showErrorToast(message: 'Invalid location selected'); + } + + } + + gotoRRTRoot(){ + + } +} \ No newline at end of file diff --git a/lib/pages/ErService/rapid-response-team/rrt-request-page.dart b/lib/pages/ErService/rapid-response-team/rrt-request-page.dart index 14a244d5..4cbfeb4b 100644 --- a/lib/pages/ErService/rapid-response-team/rrt-request-page.dart +++ b/lib/pages/ErService/rapid-response-team/rrt-request-page.dart @@ -1,6 +1,13 @@ +import 'package:diplomaticquarterapp/core/model/prescriptions/prescriptions_order.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/models/rrt/service_price.dart'; +import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-agreement-page.dart'; +import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-order-list-item.dart'; import 'package:diplomaticquarterapp/pages/ErService/rapid-response-team/rrt-pickup-address-page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; @@ -8,47 +15,79 @@ import 'package:flutter/material.dart'; class RRTRequestPage extends StatefulWidget{ + final List pendingOrders; + final ServicePrice servicePrice; + + RRTRequestPage({this.pendingOrders, this.servicePrice}); + @override - State createState() => RRTRequestPageState(); + State createState() => RRTRequestPageState(); } class RRTRequestPageState extends State{ bool acceptTerms = false; + TranslationBase localize; + RRTViewModel viewModel; + @override Widget build(BuildContext context) { + localize = TranslationBase.of(context); return BaseView( - onModelReady: (viewModel) async{ - await viewModel.getRequiredData(); - }, - builder: (ctx, vm, widget) => Column( - children: [ - Expanded( - child: ListView( - padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15), - children: [ - serviceDescription(context), - SizedBox(height: 20), - priceTable(context), - - acceptPolicy(), - - Container(height: 0.5, color: Theme.of(context).appBarTheme.color),// Seperator - - Container( - padding: EdgeInsets.only(top: 20, bottom: 5), - alignment: Alignment.center, - child: Text(TranslationBase.of(context).youCanPayByTheFollowingOptions, style: TextStyle(fontSize: 13, color: Theme.of(context).appBarTheme.color, fontWeight: FontWeight.w500), maxLines: 2) - ), - - paymentOptions(), - ], + onModelReady: (vm){ + viewModel = vm; + }, + builder: (ctx, vm, widgetState){ + + if(widget.pendingOrders.isNotEmpty) + return currentOrderContent(); + else + return requestContent(); + + }, + ); + + } + + Widget requestContent(){ + return Column( + children: [ + Expanded( + child: ListView( + padding: EdgeInsets.symmetric(horizontal: 20, vertical: 15), + children: [ + serviceDescription(context), + SizedBox(height: 20), + priceTable(context), + + acceptPolicy(), + + Container(height: 0.5, color: Theme.of(context).appBarTheme.color),// Seperator + + Container( + padding: EdgeInsets.only(top: 20, bottom: 5), + alignment: Alignment.center, + child: Text(localize.youCanPayByTheFollowingOptions, style: TextStyle(fontSize: 13, color: Theme.of(context).appBarTheme.color, fontWeight: FontWeight.w500), maxLines: 2) ), - ), - actionButtons() - ], - ) + paymentOptions(), + ], + ), + ), + + actionButtons() + ], + ); + } + + Widget currentOrderContent(){ + var orders = widget.pendingOrders; + return ListView.builder( + itemCount: orders.length, + itemBuilder: (ctx, idx) { + var order = orders[idx]; + return RRTLogListItem(order, onCancel: deleteOrder); + } ); } @@ -56,7 +95,7 @@ class RRTRequestPageState extends State{ Padding( padding: const EdgeInsets.symmetric(horizontal: 10), child: Text( - TranslationBase.of(context).rrtDDetails, + localize.rrtDDetails, textAlign: TextAlign.justify, style: TextStyle(color: Theme.of(context).appBarTheme.color, fontSize: 15, height: 1.5, fontWeight: FontWeight.w300), ), @@ -64,22 +103,25 @@ class RRTRequestPageState extends State{ Widget priceTable(BuildContext context){ var radius = Radius.circular(8); + String amount = widget.servicePrice.price.toString(); + String vat = widget.servicePrice.vat.toString(); + String total = widget.servicePrice.totalPrice.toString(); return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Container( height: 30, decoration: BoxDecoration(color: Theme.of(context).appBarTheme.color, borderRadius: BorderRadius.only(topLeft: radius, topRight: radius)), - child: Center(child: Text(TranslationBase.of(context).approximateServiceFee, style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500, letterSpacing: 1))), + child: Center(child: Text(localize.approximateServiceFee, style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500, letterSpacing: 1))), ), - pricingRow(label: TranslationBase.of(context).amountBeforeTax, value: '500 SAR'), + pricingRow(label: localize.amountBeforeTax, value: '$amount ${localize.sar}'), Container(height: 0.5, color: Theme.of(context).appBarTheme.color), - pricingRow(label: TranslationBase.of(context).taxAmount, value: '50 SAR'), + pricingRow(label: localize.taxAmount, value: '$vat ${localize.sar}'), Container(height: 0.5, color: Theme.of(context).appBarTheme.color), - pricingRow(label: TranslationBase.of(context).totalAmountPayable, value: '550 SAR', labelBold: true), + pricingRow(label: localize.totalAmountPayable, value: '$total ${localize.sar}', labelBold: true), Container(height: 0.5, color: Theme.of(context).appBarTheme.color), ], ); @@ -115,15 +157,18 @@ class RRTRequestPageState extends State{ }), SizedBox(width: 10), Expanded( - child: Text(TranslationBase.of(context).iAcceptTermsConditions, style: TextStyle(fontSize: 13, color: Theme.of(context).appBarTheme.color), maxLines: 2) + child: Text(localize.iAcceptTermsConditions, style: TextStyle(fontSize: 13, color: Theme.of(context).appBarTheme.color), maxLines: 2) ), Container( alignment: Alignment.center, width: MediaQuery.of(context).size.width * 0.25, child: TextButton( - child: Text(TranslationBase.of(context).clickHere, style: TextStyle(fontSize: 12, color: Colors.blue, fontWeight: FontWeight.w400)), + child: Text(localize.clickHere, style: TextStyle(fontSize: 12, color: Colors.blue, fontWeight: FontWeight.w400)), onPressed: (){ - + Navigator.push( + context, + FadePage( + page: RRTAgreementPage())); } ), ) @@ -133,10 +178,10 @@ class RRTRequestPageState extends State{ } Widget paymentOptions()=> Container( - height: 30, - alignment: Alignment.center, - child: Image.asset("assets/payment_options/payment_options.png", fit: BoxFit.fill,) - ); + height: 30, + alignment: Alignment.center, + child: Image.asset("assets/payment_options/payment_options.png", fit: BoxFit.fill,) + ); Widget actionButtons(){ return Container( @@ -149,28 +194,46 @@ class RRTRequestPageState extends State{ color: Theme.of(context).appBarTheme.color, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10) ), onPressed: () { }, - child: Text(TranslationBase.of(context).cancel, style: TextStyle(color: Colors.white, fontSize: 13, letterSpacing: 1),), + child: Text(localize.cancel, style: TextStyle(color: Colors.white, fontSize: 13, letterSpacing: 1),), ), ), SizedBox(width: 20,), Expanded( child: MaterialButton( - height: 50, - color: Theme.of(context).appBarTheme.color, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10) ), - child: Text(TranslationBase.of(context).ok, style: TextStyle(color: Colors.white, fontSize: 13, letterSpacing: 1),), - onPressed: () { - Navigator.push( - context, - FadePage( - page: RRTRequestPickupAddressPage())); - }, + height: 50, + color: Theme.of(context).appBarTheme.color, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10) ), + child: Text(localize.ok, style: TextStyle(color: Colors.white, fontSize: 13, letterSpacing: 1),), + onPressed: () { + if(acceptTerms) + goToPickupAddress(); + else + AppToast.showErrorToast(message: localize.pleaseAcceptTerms); + } ), ) ], ), ); } + + goToPickupAddress()async{ + Navigator.push( + context, + FadePage(page: RRTRequestPickupAddressPage(servicePrice: widget.servicePrice,)) + ); + } + + + deleteOrder(PrescriptionsOrder order) async { + GifLoaderDialogUtils.showMyDialog(context); + var success = await viewModel.cancelOrder(order); + GifLoaderDialogUtils.hideDialog(context); + if(success) + setState(() { + widget.pendingOrders.remove(order); + }); + } } \ No newline at end of file diff --git a/lib/pages/login/forgot-password.dart b/lib/pages/login/forgot-password.dart index 0bc93081..30720401 100644 --- a/lib/pages/login/forgot-password.dart +++ b/lib/pages/login/forgot-password.dart @@ -144,7 +144,7 @@ class _ForgotPassword extends State { Navigator.of(context).pop(); AlertDialogBox( context: con, - confirmMessage: res['ReturnMessage'], + message: res['ReturnMessage'], okText: TranslationBase.of(con).ok, okFunction: () { AlertDialogBox.closeAlertDialog(con); diff --git a/lib/pages/login/register.dart b/lib/pages/login/register.dart index 1591d1d5..faac5fc8 100644 --- a/lib/pages/login/register.dart +++ b/lib/pages/login/register.dart @@ -256,7 +256,7 @@ class _Register extends State { // AppToast.showErrorToast(message: response['ErrorEndUserMessage']); AlertDialogBox( context: context, - confirmMessage: response['ErrorEndUserMessage'], + message: response['ErrorEndUserMessage'], okText: TranslationBase.of(context).ok, okFunction: () { AlertDialogBox.closeAlertDialog(context); @@ -276,7 +276,7 @@ class _Register extends State { //AppToast.showErrorToast(message: response); AlertDialogBox( context: context, - confirmMessage: response, + message: response, okText: TranslationBase.of(context).ok, okFunction: () { AlertDialogBox.closeAlertDialog(context); diff --git a/lib/services/pharmacy_services/pharmacyAddress_service.dart b/lib/services/pharmacy_services/pharmacyAddress_service.dart index 592359ca..7856a506 100644 --- a/lib/services/pharmacy_services/pharmacyAddress_service.dart +++ b/lib/services/pharmacy_services/pharmacyAddress_service.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; @@ -10,12 +12,14 @@ class PharmacyAddressService extends BaseService { CountryData country; int selectedAddressIndex = 0; - Future getAddresses() async { + Future> getAddresses() async { var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); Map queryParams = {'fields': 'addresses'}; hasError = false; Addresses selectedAddress; try { + var completer = Completer(); + await baseAppClient.getPharmacy("$GET_CUSTOMERS_ADDRESSES$customerId", onSuccess: (dynamic response, int statusCode) async { addresses.clear(); @@ -33,13 +37,19 @@ class PharmacyAddressService extends BaseService { addresses.add(address); index++; }); + completer.complete(); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, queryParams: queryParams); - } catch (error) { + + await completer.future; + + } catch (error){ throw error; } + + return addresses; } Future getCountries(String countryName) async { diff --git a/lib/uitl/HMGNetworkConnectivity.dart b/lib/uitl/HMGNetworkConnectivity.dart index c4044573..213f9b46 100644 --- a/lib/uitl/HMGNetworkConnectivity.dart +++ b/lib/uitl/HMGNetworkConnectivity.dart @@ -76,7 +76,7 @@ class HMGNetworkConnectivity { AlertDialogBox( context: context, okText: translator.ok, - confirmMessage: message, + message: message, okFunction: () { AlertDialogBox.closeAlertDialog(context); }).showAlertDialog(context); diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 9127f582..b37932f2 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -1166,8 +1166,14 @@ class TranslationBase { String get taxAmount => localizedValues['TaxAmount'][locale.languageCode]; String get totalAmountPayable => localizedValues['TotalAmountPayable'][locale.languageCode]; String get iAcceptTermsConditions => localizedValues['iAcceptTermsConditions'][locale.languageCode]; + String get somethingWentWrongTryLater => localizedValues['somethingWentWrongTryLater'][locale.languageCode]; String get youCanPayByTheFollowingOptions => localizedValues['YouCanPayByTheFollowingOptions'][locale.languageCode]; String get rrtService => localizedValues['rrtService'][locale.languageCode]; + String get rrtUserAgreementTitle => localizedValues['rrtUserAgreementTitle'][locale.languageCode]; + String get rrtUserAgreementP1 => localizedValues['rrtUserAgreementP1'][locale.languageCode]; + String get rrtUserAgreementP2 => localizedValues['rrtUserAgreementP2'][locale.languageCode]; + String get rrtUserAgreementP3 => localizedValues['rrtUserAgreementP3'][locale.languageCode]; + String get rrtOrderSuccessMessage => localizedValues['rrtOrderSuccessMessage'][locale.languageCode]; String get billAmount => localizedValues['bill-amount'][locale.languageCode]; String get transportMethod => localizedValues['transport-method'][locale.languageCode]; diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart index d73bf6e8..9759ef5c 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -501,7 +501,7 @@ class Utils { } else { AlertDialogBox( context: context, - confirmMessage: + message: "Please login with your account first to use this feature", okText: "OK", okFunction: () { diff --git a/lib/widgets/dialogs/alert_dialog.dart b/lib/widgets/dialogs/alert_dialog.dart index 81507326..be202fd9 100644 --- a/lib/widgets/dialogs/alert_dialog.dart +++ b/lib/widgets/dialogs/alert_dialog.dart @@ -5,24 +5,29 @@ import 'package:flutter/material.dart'; class AlertDialogBox { final BuildContext context; - final confirmMessage; + final title; + final message; final okText; final Function okFunction; AlertDialogBox( {@required this.context, - @required this.confirmMessage, + this.title, + @required this.message, @required this.okText, @required this.okFunction}); - showAlertDialog(BuildContext context) { + showAlertDialog({BuildContext context}) { Widget continueButton = - FlatButton(child: Text(this.okText), onPressed: this.okFunction); + FlatButton(child: Text(this.okText), onPressed: (){ + this.okFunction(); + closeAlertDialog(context); + }); // set up the AlertDialog AlertDialog alert = AlertDialog( - title: Text(TranslationBase.of(context).confirm), - content: Text(this.confirmMessage), + title: Text(title ?? TranslationBase.of(context).confirm), + content: Text(this.message), actions: [ continueButton, ], @@ -31,7 +36,7 @@ class AlertDialogBox { // show the dialog showDialog( barrierDismissible: false, - context: context, + context: this.context, builder: (BuildContext context) { return alert; }, From 10a147860c59a0a58b6be40e88560100f34eff7b Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Tue, 10 Aug 2021 18:10:18 +0300 Subject: [PATCH 3/9] no message --- .../ErService/rapid-response-team/rrt-place-order.dart | 10 +++++++--- lib/widgets/dialogs/alert_dialog.dart | 3 +-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/pages/ErService/rapid-response-team/rrt-place-order.dart b/lib/pages/ErService/rapid-response-team/rrt-place-order.dart index 9cded48d..c2d943ed 100644 --- a/lib/pages/ErService/rapid-response-team/rrt-place-order.dart +++ b/lib/pages/ErService/rapid-response-team/rrt-place-order.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/rrt-view-model.dart'; import 'package:diplomaticquarterapp/models/rrt/service_price.dart'; +import 'package:diplomaticquarterapp/pages/ErService/ErOptions.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; @@ -175,9 +176,10 @@ class RRTPlaceOrderPage extends StatelessWidget{ message: localize.rrtOrderSuccessMessage, okText: localize.ok, okFunction: (){ - + AlertDialogBox.closeAlertDialog(_context); + gotoRRTRoot(); } - ).showAlertDialog(); + ).showAlertDialog(_context); } }else{ AppToast.showErrorToast(message: 'Invalid location selected'); @@ -186,6 +188,8 @@ class RRTPlaceOrderPage extends StatelessWidget{ } gotoRRTRoot(){ - + Navigator.pushAndRemoveUntil( + _context, + MaterialPageRoute(builder: (context) => ErOptions(isAppbar: true)), (Route r) => false); } } \ No newline at end of file diff --git a/lib/widgets/dialogs/alert_dialog.dart b/lib/widgets/dialogs/alert_dialog.dart index be202fd9..5e0bbb35 100644 --- a/lib/widgets/dialogs/alert_dialog.dart +++ b/lib/widgets/dialogs/alert_dialog.dart @@ -17,11 +17,10 @@ class AlertDialogBox { @required this.okText, @required this.okFunction}); - showAlertDialog({BuildContext context}) { + showAlertDialog(BuildContext context) { Widget continueButton = FlatButton(child: Text(this.okText), onPressed: (){ this.okFunction(); - closeAlertDialog(context); }); // set up the AlertDialog From bd85854fa4eadc7959489be7ce838524df77b5c8 Mon Sep 17 00:00:00 2001 From: Sultan Khan Date: Wed, 11 Aug 2021 09:38:39 +0300 Subject: [PATCH 4/9] changes --- lib/config/config.dart | 2 +- .../Authentication/register_user_requet.dart | 15 +++++++++------ lib/pages/login/login.dart | 5 ----- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index f4c5e559..0c18ecbb 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -262,7 +262,7 @@ const IS_DENTAL_ALLOWED_BACKEND = false; const PATIENT_TYPE = 1; const PATIENT_TYPE_ID = 1; var DEVICE_TOKEN = ""; -var IS_VOICE_COMMAND_CLOSED = false; +var IS_VOICE_COMMAND_CLOSED = true; var IS_TEXT_COMPLETED = false; var DeviceTypeID = Platform.isIOS ? 1 : 2; const LANGUAGE_ID = 2; diff --git a/lib/models/Authentication/register_user_requet.dart b/lib/models/Authentication/register_user_requet.dart index 7758ce5b..12e59d0a 100644 --- a/lib/models/Authentication/register_user_requet.dart +++ b/lib/models/Authentication/register_user_requet.dart @@ -83,6 +83,7 @@ class Patientobject { String dateofBirth; int gender; String nationalityID; + String eHealthIDField; String dateofBirthN; String emailAddress; String sourceType; @@ -96,15 +97,16 @@ class Patientobject { this.mobileNumber, this.patientOutSA, this.firstName, - this.middleName, - this.lastName, - this.firstNameN, - this.middleNameN, - this.lastNameN, + this.middleName, + this.lastName, + this.firstNameN, + this.middleNameN, + this.lastNameN, this.strDateofBirth, this.dateofBirth, this.gender, this.nationalityID, + this.eHealthIDField, this.dateofBirthN, this.emailAddress, this.sourceType, @@ -127,6 +129,7 @@ class Patientobject { dateofBirth = json['DateofBirth']; gender = json['Gender']; nationalityID = json['NationalityID']; + eHealthIDField = json['eHealthIDField']; dateofBirthN = json['DateofBirthN']; emailAddress = json['EmailAddress']; sourceType = json['SourceType']; @@ -152,10 +155,10 @@ class Patientobject { data['DateofBirth'] = this.dateofBirth; data['Gender'] = this.gender; data['NationalityID'] = this.nationalityID; + data['eHealthIDField'] = this.eHealthIDField; data['DateofBirthN'] = this.dateofBirthN; data['EmailAddress'] = this.emailAddress; data['SourceType'] = this.sourceType; - data['PreferredLanguage'] = this.preferredLanguage; data['Marital'] = this.marital; return data; diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index c5da90d5..1c0fd13e 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -64,11 +64,6 @@ class _Login extends State { void initState() { // getDeviceToken(); super.initState(); - - if(BASE_URL.contains("uat.")){ - nationalIDorFile.text = "1231755"; - mobileNumberController.text = mobileNo = "537503378"; - } } getDeviceToken() async { From b1453b52e3c04af9cbeac9dedfefbba45eae62bf Mon Sep 17 00:00:00 2001 From: Sultan Khan Date: Wed, 11 Aug 2021 16:31:47 +0300 Subject: [PATCH 5/9] registration --- lib/pages/login/register-info.dart | 32 ++++++++++++++++--- .../authentication/auth_provider.dart | 1 + 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/lib/pages/login/register-info.dart b/lib/pages/login/register-info.dart index d28fea86..e1152032 100644 --- a/lib/pages/login/register-info.dart +++ b/lib/pages/login/register-info.dart @@ -2,8 +2,9 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_paitent_authentication_req.dart'; import 'package:diplomaticquarterapp/models/Authentication/register_info_response.dart'; -import 'package:diplomaticquarterapp/models/Authentication/register_user_requet.dart'; -import 'package:diplomaticquarterapp/pages/login/login-type.dart'; +import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; +import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_response.dart' + as checkActivation; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; @@ -20,6 +21,10 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:hijri/hijri_calendar.dart'; import 'package:intl/intl.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; +import 'package:provider/provider.dart'; class RegisterInfo extends StatefulWidget { @override @@ -45,6 +50,13 @@ class _RegisterInfo extends State { String email = ''; String location = '1'; + AuthenticatedUserObject authenticatedUserObject = + locator(); + + ProjectViewModel projectViewModel; + + AppointmentRateViewModel appointmentRateViewModel = + locator(); @override void initState() { @@ -56,6 +68,8 @@ class _RegisterInfo extends State { @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); + return AppScaffold( appBarTitle: TranslationBase.of(context).register, isShowAppBar: true, @@ -300,16 +314,17 @@ class _RegisterInfo extends State { } else { + result = checkActivation.CheckActivationCode.fromJson(result), result.list.isFamily = false, sharedPref.setObject(USER_PROFILE, result.list), this.sharedPref.setObject(MAIN_USER, result.list), sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID), sharedPref.setString(TOKEN, result.authenticationTokenID), - Navigator.of(context).pushNamed(HOME) + this.setUser(result), } }) .catchError((err) { - GifLoaderDialogUtils.hideDialog(context); + // GifLoaderDialogUtils.hideDialog(context); ConfirmDialog dialog = new ConfirmDialog( context: context, confirmMessage: err, @@ -321,6 +336,15 @@ class _RegisterInfo extends State { }); } + setUser(result) async { + await authenticatedUserObject.getUser(getUser: true); + authenticatedUserObject.isLogin = true; + appointmentRateViewModel.isLogin = true; + projectViewModel.isLogin = true; + authenticatedUserObject.user = result.list; + Navigator.of(context).pushNamed(HOME); + } + getRegisterInfo() async { var data = RegisterInfoResponse.fromJson(await sharedPref.getObject(NHIC_DATA)); diff --git a/lib/services/authentication/auth_provider.dart b/lib/services/authentication/auth_provider.dart index 926ee2bc..dcc5599b 100644 --- a/lib/services/authentication/auth_provider.dart +++ b/lib/services/authentication/auth_provider.dart @@ -328,6 +328,7 @@ class AuthProvider with ChangeNotifier { request['LanguageID'] = LANGUAGE_ID; var requestN = RegisterUserRequest.fromJson(request); requestN.patientOutSA = requestN.patientobject.patientOutSA; + await sharedPref.remove(USER_PROFILE); // request.tokenID = ''; dynamic localRes; try { From a32501f3dc36eb9cd3a725b1ca3cf6f9979a2687 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Wed, 11 Aug 2021 17:29:52 +0300 Subject: [PATCH 6/9] My invoices implementation continued --- assets/images/medical/Invoice.png | Bin 0 -> 1748 bytes assets/images/new-design/ViewDetailsIco.png | Bin 0 -> 1314 bytes lib/config/config.dart | 5 +- lib/config/localized_values.dart | 8 + .../GetDentalAppointmentsResponse.dart | 100 ++++++++ lib/pages/BookAppointment/BookConfirm.dart | 2 +- .../BookAppointment/widgets/DoctorView.dart | 8 +- .../widgets/AppointmentActions.dart | 4 +- .../my_invoices/invoice_detail_page.dart | 51 ++++ .../medical/my_invoices/my_invoice_page.dart | 234 ++++++++++++++++++ .../my_invoice_services.dart | 53 ++++ lib/uitl/translations_delegate_base.dart | 6 + lib/uitl/utils.dart | 12 + 13 files changed, 476 insertions(+), 7 deletions(-) create mode 100644 assets/images/medical/Invoice.png create mode 100644 assets/images/new-design/ViewDetailsIco.png create mode 100644 lib/models/MyInvoices/GetDentalAppointmentsResponse.dart create mode 100644 lib/pages/medical/my_invoices/invoice_detail_page.dart create mode 100644 lib/pages/medical/my_invoices/my_invoice_page.dart create mode 100644 lib/services/my_invoice_service/my_invoice_services.dart diff --git a/assets/images/medical/Invoice.png b/assets/images/medical/Invoice.png new file mode 100644 index 0000000000000000000000000000000000000000..1e3b6f250398cd114afa63e6b05e842ca4eaacd6 GIT binary patch literal 1748 zcmb_d={wsC8Vwb$+(c_@VvB0H#au*eV;RAZkXuC)%fzHn)o??jxUrPd+9K5|9aOcA zB~i82Ry9?rmb9@{Bd#cJsaje~ZIhc)`{;a{KVUw*=RD_mpL3q`>3y&Hc)7zMnh+2O z1jBo{5)SzM_xVBo0HdZ0eGf?HH-fths9vbO00PP1#Jf8CCde$agIKqvRBLux)N&!~Q_7_Ad$V4%@X7XFWb* zVJQ(Nq&b6|Uv@-M6)AF&OQd7JhY#K17f=b^&J^^k)cMMv()E6d z)t&_d+N{WM4C37XcTuwJ4Q)5C;QKbK)}_2hxw*qnhf=a*inG5(vK+6}zsxPhjj_`Q zD(_B2#l+V{P_C~M-ytT}JE7GZ>X&Qa*8F(DAN@`B0z`zHcu0r~*7{^`ytrKuYs5{2 zQ)G5kM*Z%)@NJw+mz53z1y}GHbQ50HX@rc2jP5>?1*kFZK)R9f^({ii@7qWs?V3$n-<>+`4uJaVeGkVIn;D(c5@HJQLd;*UmHQ z@Fsooa|}M;nI{)aHc$Y_Mx~-iw7xSUptti#K;MZLEhzqoz%K^CE4T`5wg|*my=+eYHZ-;5Ot6F9ZI&03gz!f4AUg8#^+rUQ{? zsr#?IFx5?>N#E@4GwW8at2;7?3}dM?R(u>c>XmA9Iu4N1X0{u_f_qi%>lqE*N(L(Uu85QZ}WXylJl20 z8`Y#X8T(forjGUWTYS_WRSmFT`s41Ojk>&R9F1n#PtsEY_(vKdQy|iKp~QFNYFINP9igYD3B->?kP#5)=WfQ^N%t282Xa^eh@7cT`ob{rm3%EMwq_HSF! zxQu~jOgKXt#a1usJaNi+yRhX^qZ)%-oFtttFt~MM%H=6S%GyI;J~WvoR0$ibWs1Qg z+&d+ZAx%PQLlRBvT^{H8ZfrHY3w3bxk;Ucpa)5)yY)}rJdmL#)`2N2@csDQCdY7|l F{{bntGY9|x literal 0 HcmV?d00001 diff --git a/assets/images/new-design/ViewDetailsIco.png b/assets/images/new-design/ViewDetailsIco.png new file mode 100644 index 0000000000000000000000000000000000000000..cd58bddb8718ec93d9343daf41a7e8500639b297 GIT binary patch literal 1314 zcmV+-1>O3IP)mg5$ZTqG7` z2jKi7>&{q?yAtPQWk`PC=*f=6xnV*rGVDE-%k-%nY@0?Nz;a4};P-utA9Q3zvLts; zat0Iarcls%%W?Bj4iAN7z?G0;AT3?99GAR$OSSB-T@FZk$2N^n&)XET2LPoA^irz> zT3NEt1AtPW*rt(f_G2KVZ5lZZkxQpluuWq$5~OV!Cjcz;7$7((34A{rysK>*E2=}q zSndKw&c2nfjrH39YX|FdAE3HfRy}pr9|qPza*%yh<%%O`r!khBQ*B5jJ=ojB>eMTE zuvb+%?LL6f+NdbwJD{bP3eu5@m&9Ibko(z1)dmG>;MkaWaGCyoJpR-e?*6)_a{3_0 z)E=hb6B;@6kOtXk|3k9t?WVX?hdfBxU7HT1 zsv4d=gF{D$mCo9~vyJT=i@G5v$at3HZfS=cn#|(K@#mDzxx4;LJ0QV1rhtj{QLzBy;`4$pf0>V z_r8`{O&_l)rKa)AUp4@e=)Hd7%2n|YdK!|tqjXY#e)ly>uUS|+{UXZw%VOWav8OTm z=5*5A+)EYm$jO(*=gyCdxc%)F?BCfD-LrE2d+e5$#cxkM`+TB%(DGlZkePvpU6J7Y z+AS@KJ*vZzPqg%hzPQU_I`j{FPV%gN(Rd4XKnWxkapgF6PW<_Evri!UUl4vZfT>qhNA7%bz#6uZ7 z8cJe-F3Pl|fTR=wui|!G|9M35k$#=0@0wN5O&EL(Sp@4{zt*Zg;ws$lVAXKX) zx%4IN%8&{>naBmdN_kf<*c(r=`+h-dH>wrQu`8E(xjNsWpn)d!mpWF|TPv==o8jQ0 z9W}6t;G}dG+Gjc9$R@PzEv~F8a`cs0?fT0Et$C71rca86X$!Kn%q@|n=snxe1?CCB YfA3QFMu-0^N&o-=07*qoM6N<$g0RShVgLXD literal 0 HcmV?d00001 diff --git a/lib/config/config.dart b/lib/config/config.dart index f8bca863..acdc5c40 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -13,7 +13,7 @@ const PACKAGES_CUSTOMER = '/api/customers'; const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; const PACKAGES_ORDERS = '/api/orders'; -//const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; const BASE_URL = 'https://hmgwebservices.com/'; // Pharmacy UAT URLs @@ -605,6 +605,9 @@ const FILTERED_PRODUCTS = 'products?categoryids='; const GET_DOCTOR_LIST_CALCULATION = "Services/Doctors.svc/REST/GetCallculationDoctors"; +const GET_ALL_APPOINTMENTS_FOR_DENTAL_CLINIC = + "Services/Patients.svc/REST/GetDentalAppointments"; + class AppGlobal { static var context; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 1feb206a..cdcbb2fb 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -2101,4 +2101,12 @@ const Map localizedValues = { "ar": "تتيح لك هذه الخدمة إجراء استشارة عبر مكالمة فيديو مباشرة مع الطبيب من أي مكان وفي أي وقت" }, + "my-invoice": { + "en": "My Invoice", + "ar": "فواتيري" + }, + "invoice-list": { + "en": "Invoices List", + "ar": "فائمة الفواتير" + }, }; diff --git a/lib/models/MyInvoices/GetDentalAppointmentsResponse.dart b/lib/models/MyInvoices/GetDentalAppointmentsResponse.dart new file mode 100644 index 00000000..a5a43cef --- /dev/null +++ b/lib/models/MyInvoices/GetDentalAppointmentsResponse.dart @@ -0,0 +1,100 @@ +class GetDentalAppointmentsResponse { + List listDentalAppointments; + + GetDentalAppointmentsResponse({this.listDentalAppointments}); + + GetDentalAppointmentsResponse.fromJson(Map json) { + if (json['List_DentalAppointments'] != null) { + listDentalAppointments = new List(); + json['List_DentalAppointments'].forEach((v) { + listDentalAppointments.add(new ListDentalAppointments.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.listDentalAppointments != null) { + data['List_DentalAppointments'] = + this.listDentalAppointments.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class ListDentalAppointments { + String setupId; + int projectID; + int patientID; + int appointmentNo; + String appointmentDate; + dynamic appointmentDateN; + int clinicID; + int doctorID; + int invoiceNo; + int status; + String arrivedOn; + String doctorName; + dynamic doctorNameN; + String clinicName; + String doctorImageURL; + String projectName; + + ListDentalAppointments( + {this.setupId, + this.projectID, + this.patientID, + this.appointmentNo, + this.appointmentDate, + this.appointmentDateN, + this.clinicID, + this.doctorID, + this.invoiceNo, + this.status, + this.arrivedOn, + this.doctorName, + this.doctorNameN, + this.clinicName, + this.doctorImageURL, + this.projectName}); + + ListDentalAppointments.fromJson(Map json) { + setupId = json['SetupId']; + projectID = json['ProjectID']; + patientID = json['PatientID']; + appointmentNo = json['AppointmentNo']; + appointmentDate = json['AppointmentDate']; + appointmentDateN = json['AppointmentDateN']; + clinicID = json['ClinicID']; + doctorID = json['DoctorID']; + invoiceNo = json['InvoiceNo']; + status = json['Status']; + arrivedOn = json['ArrivedOn']; + doctorName = json['DoctorName']; + doctorNameN = json['DoctorNameN']; + clinicName = json['ClinicName']; + doctorImageURL = json['DoctorImageURL']; + projectName = json['ProjectName']; + } + + Map toJson() { + final Map data = new Map(); + data['SetupId'] = this.setupId; + data['ProjectID'] = this.projectID; + data['PatientID'] = this.patientID; + data['AppointmentNo'] = this.appointmentNo; + data['AppointmentDate'] = this.appointmentDate; + data['AppointmentDateN'] = this.appointmentDateN; + data['ClinicID'] = this.clinicID; + data['DoctorID'] = this.doctorID; + data['InvoiceNo'] = this.invoiceNo; + data['Status'] = this.status; + data['ArrivedOn'] = this.arrivedOn; + data['DoctorName'] = this.doctorName; + data['DoctorNameN'] = this.doctorNameN; + data['ClinicName'] = this.clinicName; + data['DoctorImageURL'] = this.doctorImageURL; + data['ProjectName'] = this.projectName; + return data; + } +} diff --git a/lib/pages/BookAppointment/BookConfirm.dart b/lib/pages/BookAppointment/BookConfirm.dart index 966dc4d4..fe9113cb 100644 --- a/lib/pages/BookAppointment/BookConfirm.dart +++ b/lib/pages/BookAppointment/BookConfirm.dart @@ -544,7 +544,7 @@ class _BookConfirmState extends State { navigateToBookSuccess(context, docObject, widget.patientShareResponse); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); - AppToast.showErrorToast(message: err); + // AppToast.showErrorToast(message: err); navigateToHome(context); print(err); }); diff --git a/lib/pages/BookAppointment/widgets/DoctorView.dart b/lib/pages/BookAppointment/widgets/DoctorView.dart index bb6fccab..7cdf7ed0 100644 --- a/lib/pages/BookAppointment/widgets/DoctorView.dart +++ b/lib/pages/BookAppointment/widgets/DoctorView.dart @@ -13,13 +13,15 @@ import '../DoctorProfile.dart'; class DoctorView extends StatelessWidget { final DoctorList doctor; bool isLiveCareAppointment; + bool isShowFlag; - DoctorView({@required this.doctor, @required this.isLiveCareAppointment}); + DoctorView({@required this.doctor, @required this.isLiveCareAppointment, this.isShowFlag = true}); @override Widget build(BuildContext context) { return InkWell( onTap: () { + if(isShowFlag) getDoctorsProfile(context, doctor); }, child: Card( @@ -113,10 +115,10 @@ class DoctorView extends StatelessWidget { filledIcon: Icons.star, emptyIcon: Icons.star, ), - Container( + isShowFlag ? Container( child: Image.network(this.doctor.nationalityFlagURL, width: 25.0, height: 25.0), - ), + ) : Container(), ], ), ], diff --git a/lib/pages/MyAppointments/widgets/AppointmentActions.dart b/lib/pages/MyAppointments/widgets/AppointmentActions.dart index 4658f83b..c37cf6ee 100644 --- a/lib/pages/MyAppointments/widgets/AppointmentActions.dart +++ b/lib/pages/MyAppointments/widgets/AppointmentActions.dart @@ -112,7 +112,7 @@ class _AppointmentActionsState extends State { e.title, color: Color(0xffB8382C), variant: "overline", - fontSize: SizeConfig.textMultiplier * 2.1, + fontSize: SizeConfig.textMultiplier * 1.8, ), ), Container( @@ -122,7 +122,7 @@ class _AppointmentActionsState extends State { e.subtitle, color: Colors.black, variant: "overline", - fontSize: SizeConfig.textMultiplier * 1.9, + fontSize: SizeConfig.textMultiplier * 1.6, ), ), ], diff --git a/lib/pages/medical/my_invoices/invoice_detail_page.dart b/lib/pages/medical/my_invoices/invoice_detail_page.dart new file mode 100644 index 00000000..33df8fc3 --- /dev/null +++ b/lib/pages/medical/my_invoices/invoice_detail_page.dart @@ -0,0 +1,51 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/MyInvoices/GetDentalAppointmentsResponse.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class InvoiceDetail extends StatelessWidget { + final DoctorList doctor; + final ListDentalAppointments listDentalAppointments; + + InvoiceDetail(this.doctor, this.listDentalAppointments); + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).myInvoice, + isShowAppBar: true, + isShowDecPage: false, + body: Container( + child: Column( + children: [ + DoctorView(doctor: doctor, isLiveCareAppointment: false, isShowFlag: false), + Container( + margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0), + padding: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0, bottom: 10.0), + decoration: BoxDecoration( + color: Colors.grey[800], + borderRadius: BorderRadius.only( + topLeft: Radius.circular(8), + topRight: Radius.circular(8), + ), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("Description", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + Text("Quantity", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + Text("Price", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + Text("Total", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + ], + ), + ), + ], + ), + )); + } +} diff --git a/lib/pages/medical/my_invoices/my_invoice_page.dart b/lib/pages/medical/my_invoices/my_invoice_page.dart new file mode 100644 index 00000000..898d374a --- /dev/null +++ b/lib/pages/medical/my_invoices/my_invoice_page.dart @@ -0,0 +1,234 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart' + as DoctorListResponse; +import 'package:diplomaticquarterapp/models/MyInvoices/GetDentalAppointmentsResponse.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_invoices/invoice_detail_page.dart'; +import 'package:diplomaticquarterapp/services/my_invoice_service/my_invoice_services.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class MyInvoices extends StatefulWidget { + @override + _MyInvoicesState createState() => _MyInvoicesState(); +} + +class _MyInvoicesState extends State { + bool isDataLoaded = false; + GetDentalAppointmentsResponse getDentalAppointmentsResponse; + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + getDentalAppointments(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).myInvoice, + isShowAppBar: true, + isShowDecPage: false, + body: Container( + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: isDataLoaded + ? Column( + children: [ + ...List.generate( + getDentalAppointmentsResponse + .listDentalAppointments.length, + (index) => InkWell( + onTap: () { + openInvoiceDetailsPage(getDentalAppointmentsResponse + .listDentalAppointments[index]); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: + BorderRadius.all(Radius.circular(8.0)), + ), + margin: EdgeInsets.all(10.0), + width: MediaQuery.of(context).size.width, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + child: Container( + margin: EdgeInsets.fromLTRB( + 20.0, 10.0, 20.0, 10.0), + child: ClipRRect( + borderRadius: + BorderRadius.circular(100.0), + child: Image.asset( + "assets/images/new-design/ViewDetailsIco.png", + fit: BoxFit.fill, + height: 60.0, + width: 60.0), + ), + ), + ), + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text("Appointment No: ", + style: TextStyle( + fontSize: 14.0, + color: Colors.black, + letterSpacing: 0.5)), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text("Appointment Date: ", + style: TextStyle( + fontSize: 14.0, + color: Colors.black, + letterSpacing: 0.5)), + ), + Container( + margin: EdgeInsets.only( + top: 10.0, bottom: 10.0), + child: Text("Clinic: ", + style: TextStyle( + fontSize: 14.0, + color: Colors.black, + letterSpacing: 0.5)), + ), + ], + ), + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text( + getDentalAppointmentsResponse + .listDentalAppointments[index] + .appointmentNo + .toString(), + style: TextStyle( + fontSize: 14.0, + color: Colors.black, + fontWeight: FontWeight.bold, + letterSpacing: 0.5)), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text( + DateUtil.getMonthDayYearDateFormatted( + DateUtil.convertStringToDate( + getDentalAppointmentsResponse + .listDentalAppointments[ + index] + .appointmentDate)), + style: TextStyle( + fontSize: 14.0, + color: Colors.black, + fontWeight: FontWeight.bold, + letterSpacing: 0.5)), + ), + Container( + margin: EdgeInsets.only( + top: 10.0, bottom: 10.0), + child: Text( + getDentalAppointmentsResponse + .listDentalAppointments[index] + .clinicName, + style: TextStyle( + fontSize: 14.0, + color: Colors.black, + fontWeight: FontWeight.bold, + letterSpacing: 0.5)), + ), + ], + ), + projectViewModel.isArabic + ? Container( + margin: EdgeInsets.only(left: 15.0), + child: Image.asset( + "assets/images/new-design/arrow_menu_black-ar.png", + fit: BoxFit.fill, + height: 20.0, + width: 12.0), + ) + : Container( + margin: EdgeInsets.only(right: 15.0), + child: Image.asset( + "assets/images/new-design/arrow_menu_black-en.png", + fit: BoxFit.fill, + height: 20.0, + width: 12.0), + ), + ], + ), + ), + ), + ), + ], + ) + : Container(), + ), + )); + } + + openInvoiceDetailsPage(ListDentalAppointments listDentalAppointments) { + DoctorListResponse.DoctorList doctor = new DoctorListResponse.DoctorList(); + + doctor.name = listDentalAppointments.doctorName; + doctor.projectName = listDentalAppointments.projectName; + doctor.date = listDentalAppointments.appointmentDate; + doctor.actualDoctorRate = 0; + doctor.doctorImageURL = listDentalAppointments.doctorImageURL; + doctor.dayName = listDentalAppointments.invoiceNo; + doctor.doctorTitle = "Dr."; + doctor.clinicName = "InvoiceNo: " + listDentalAppointments.invoiceNo.toString(); + + Navigator.push( + context, + FadePage( + page: InvoiceDetail( + doctor, + listDentalAppointments, + ))); + } + + getDentalAppointments() { + GifLoaderDialogUtils.showMyDialog(context); + MyInvoicesService myInvoicesService = new MyInvoicesService(); + + myInvoicesService.getAllDentalAppointments(12, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + setState(() { + if (res['MessageStatus'] == 1) { + getDentalAppointmentsResponse = + GetDentalAppointmentsResponse.fromJson(res); + print(getDentalAppointmentsResponse.listDentalAppointments.length); + print(getDentalAppointmentsResponse + .listDentalAppointments[0].appointmentNo); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + isDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err); + Navigator.of(context).pop(); + }); + } +} diff --git a/lib/services/my_invoice_service/my_invoice_services.dart b/lib/services/my_invoice_service/my_invoice_services.dart new file mode 100644 index 00000000..fc401c39 --- /dev/null +++ b/lib/services/my_invoice_service/my_invoice_services.dart @@ -0,0 +1,53 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/models/Request.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; + +class MyInvoicesService extends BaseService { + AppSharedPreferences sharedPref = AppSharedPreferences(); + AppGlobal appGlobal = new AppGlobal(); + + AuthenticatedUser authUser = new AuthenticatedUser(); + AuthProvider authProvider = new AuthProvider(); + + Future getAllDentalAppointments(int projectID, + context) async { + Map request; + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); + request = { + "LanguageID": languageID == 'ar' ? 1 : 2, + "IPAdress": "10.20.10.20", + "VersionID": req.VersionID, + "Channel": req.Channel, + "generalid": 'Cs2020@2016\$2958', + "PatientOutSA": authUser.outSA, + "DeviceTypeID": req.DeviceTypeID, + "SessionID": null, + "PatientID": authUser.patientID, + "License": true, + "IsRegistered": true, + "ProjectID": projectID, + "PatientTypeID":authUser.patientIdentificationType, + "PatientType":authUser.patientType, + "isDentalAllowedBackend": false + }; + + dynamic localRes; + + await baseAppClient.post(GET_ALL_APPOINTMENTS_FOR_DENTAL_CLINIC, + onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value( + localRes + ); + } + +} \ No newline at end of file diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 0a0e9b7c..bc88fea2 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -1673,6 +1673,12 @@ class TranslationBase { localizedValues["info-ereferral"][locale.languageCode]; String get erConsultation => localizedValues["er-consultation"][locale.languageCode]; + + String get myInvoice => + localizedValues["my-invoice"][locale.languageCode]; + + String get invoicesList => + localizedValues["invoice-list"][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart index 06aeca9d..5c7eecde 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -21,6 +21,7 @@ import 'package:diplomaticquarterapp/pages/medical/doctor/doctor_home_page.dart' import 'package:diplomaticquarterapp/pages/medical/eye/EyeMeasurementsPage.dart'; import 'package:diplomaticquarterapp/pages/medical/labs/labs_home_page.dart'; import 'package:diplomaticquarterapp/pages/medical/medical_profile_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_invoices/my_invoice_page.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers.dart'; import 'package:diplomaticquarterapp/pages/medical/patient_sick_leave_page.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; @@ -302,6 +303,17 @@ class Utils { isEnable: projectViewModel.havePrivilege(6)), )); + medical.add(InkWell( + onTap: () => + projectViewModel.havePrivilege(14) ? Navigator.push(context, FadePage(page: MyInvoices())) : null, + child: MedicalProfileItem( + title: TranslationBase.of(context).myInvoice, + imagePath: 'Invoice.png', + subTitle: TranslationBase.of(context).invoicesList, + isEnable: projectViewModel.havePrivilege(14), + ), + )); + medical.add(InkWell( onTap: () => projectViewModel.havePrivilege(14) ? Navigator.push(context, FadePage(page: EyeMeasurementsPage())) : null, From 6b7eaaafb912362f03012fbb13ebfa11aeaab32c Mon Sep 17 00:00:00 2001 From: Sultan Khan Date: Thu, 12 Aug 2021 14:02:38 +0300 Subject: [PATCH 7/9] fixes --- lib/config/config.dart | 4 ++-- lib/pages/landing/landing_page.dart | 17 +++++++++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/config/config.dart b/lib/config/config.dart index 1a309e96..b8782cf0 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -17,8 +17,8 @@ const BASE_URL = 'https://uat.hmgwebservices.com/'; //const BASE_URL = 'https://hmgwebservices.com/'; // Pharmacy UAT URLs -//const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; -//const PHARMACY_BASE_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; +// const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; +// const PHARMACY_BASE_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; // Pharmacy Production URLs const BASE_PHARMACY_URL = 'https://mdlaboratories.com/exacartapi/api/'; diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index df0af1f3..ab9982d3 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -41,9 +41,11 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import '../../locator.dart'; import '../../routes.dart'; import 'home_page.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; class LandingPage extends StatefulWidget { static LandingPage shared; @@ -70,6 +72,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { int currentTab = 0; PageController pageController; ProjectViewModel projectViewModel; + ToDoCountProviderModel model; var notificationCount = ''; var themeNotifier; @@ -101,10 +104,16 @@ class _LandingPageState extends State with WidgetsBindingObserver { setState(() { if (currentTab > 0 && tab == 2) pageController.jumpToPage(0); - else if (tab != 0) - pageController.jumpToPage(tab); - else { + else if (tab != 0) { + if (tab == 4 && model.count == 0) { + AppToast.showErrorToast( + message: TranslationBase.of(context).noBookedAppo); + } else { + pageController.jumpToPage(tab); + } + } else { IS_VOICE_COMMAND_CLOSED = false; + pageController.jumpToPage(tab); } currentTab = tab; @@ -471,7 +480,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { @override Widget build(BuildContext context) { projectViewModel = Provider.of(context); - + model = Provider.of(context); return Scaffold( appBar: AppBar( elevation: 0, From f442cc251c6a41b2d73b2d0dd76ccbec3c6f56c7 Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Thu, 12 Aug 2021 14:47:39 +0300 Subject: [PATCH 8/9] Pre Post Images Dental Doctor Profile --- lib/config/config.dart | 1 + lib/config/localized_values.dart | 1 + .../Appointments/DoctorListResponse.dart | 4 + lib/models/Appointments/DoctorProfile.dart | 4 + .../Appointments/doctor_pre_post_image.dart | 107 ++++++++++++++++ lib/pages/BookAppointment/DoctorProfile.dart | 50 +++++++- .../doctor_post_pre_images_page.dart | 121 ++++++++++++++++++ lib/pages/login/login.dart | 5 + .../appointment_services/GetDoctorsList.dart | 41 +++++- lib/uitl/translations_delegate_base.dart | 2 + 10 files changed, 329 insertions(+), 7 deletions(-) create mode 100644 lib/models/Appointments/doctor_pre_post_image.dart create mode 100644 lib/pages/BookAppointment/doctor_post_pre_images_page.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index 3aa66dd1..20c9b063 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -49,6 +49,7 @@ const WIFI_CREDENTIALS = const GET_MY_DOCTOR = 'Services/Doctors.svc/REST/GetPatientDoctorAppointmentResult'; const GET_DOCTOR_PROFILE = 'Services/Doctors.svc/REST/GetDocProfiles'; +const GET_DOCTOR_PRE_POST_IMAGES = 'Services/Doctors.svc/REST/GetDoctorPrePostImages'; const GET_DOCTOR_RATING_NOTES = 'Services/Doctors.svc/REST/dr_GetNotesDoctorRating'; const GET_DOCTOR_RATING_DETAILS = diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index e45af168..5cf126ef 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -59,6 +59,7 @@ const Map localizedValues = { 'logout': {'en': 'Logout', 'ar': 'تسجيل خروج'}, 'respirationRate': {'en': 'Respiration Rate', 'ar': 'معدل التنفس'}, 'bookAppo': {'en': 'Book Appointment', 'ar': 'حجز موعد'}, + 'beforeAfterImages': {'en': 'Before After Images', 'ar': 'قبل بعد الصور'}, 'searchBy': {'en': 'Search By:', 'ar': 'البحث عن طريق:'}, 'clinic': {'en': 'Clinic', 'ar': 'العيادة'}, 'hospital': {'en': 'Hospital', 'ar': 'المستشفى'}, diff --git a/lib/models/Appointments/DoctorListResponse.dart b/lib/models/Appointments/DoctorListResponse.dart index 4c7241c8..a038aaf4 100644 --- a/lib/models/Appointments/DoctorListResponse.dart +++ b/lib/models/Appointments/DoctorListResponse.dart @@ -21,6 +21,7 @@ class DoctorList { bool isDoctorAllowVedioCall; bool isDoctorDummy; bool isLiveCare; + bool isDoctorHasPrePostImages; String latitude; String longitude; String nationalityFlagURL; @@ -62,6 +63,7 @@ class DoctorList { this.isDoctorAllowVedioCall, this.isDoctorDummy, this.isLiveCare, + this.isDoctorHasPrePostImages, this.latitude, this.longitude, this.nationalityFlagURL, @@ -103,6 +105,7 @@ class DoctorList { isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; isDoctorDummy = json['IsDoctorDummy']; isLiveCare = json['IsLiveCare']; + isDoctorHasPrePostImages = json['IsDoctorHasPrePostImages']; latitude = json['Latitude']; longitude = json['Longitude']; nationalityFlagURL = json['NationalityFlagURL']; @@ -147,6 +150,7 @@ class DoctorList { data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall; data['IsDoctorDummy'] = this.isDoctorDummy; data['IsLiveCare'] = this.isLiveCare; + data['IsDoctorHasPrePostImages'] = this.isDoctorHasPrePostImages; data['Latitude'] = this.latitude; data['Longitude'] = this.longitude; data['NationalityFlagURL'] = this.nationalityFlagURL; diff --git a/lib/models/Appointments/DoctorProfile.dart b/lib/models/Appointments/DoctorProfile.dart index bfc8c189..9b2bc8e9 100644 --- a/lib/models/Appointments/DoctorProfile.dart +++ b/lib/models/Appointments/DoctorProfile.dart @@ -24,6 +24,7 @@ class DoctorProfileList { Null isRegistered; Null isDoctorDummy; bool isActive; + bool isDoctorHasPrePostImages; Null isDoctorAppointmentDisplayed; bool doctorClinicActive; Null isbookingAllowed; @@ -67,6 +68,7 @@ class DoctorProfileList { this.isRegistered, this.isDoctorDummy, this.isActive, + this.isDoctorHasPrePostImages, this.isDoctorAppointmentDisplayed, this.doctorClinicActive, this.isbookingAllowed, @@ -110,6 +112,7 @@ class DoctorProfileList { isRegistered = json['IsRegistered']; isDoctorDummy = json['IsDoctorDummy']; isActive = json['IsActive']; + isDoctorHasPrePostImages = json['IsDoctorHasPrePostImages']; isDoctorAppointmentDisplayed = json['IsDoctorAppointmentDisplayed']; doctorClinicActive = json['DoctorClinicActive']; isbookingAllowed = json['IsbookingAllowed']; @@ -155,6 +158,7 @@ class DoctorProfileList { data['IsRegistered'] = this.isRegistered; data['IsDoctorDummy'] = this.isDoctorDummy; data['IsActive'] = this.isActive; + data['IsDoctorHasPrePostImages'] = this.isDoctorHasPrePostImages; data['IsDoctorAppointmentDisplayed'] = this.isDoctorAppointmentDisplayed; data['DoctorClinicActive'] = this.doctorClinicActive; data['IsbookingAllowed'] = this.isbookingAllowed; diff --git a/lib/models/Appointments/doctor_pre_post_image.dart b/lib/models/Appointments/doctor_pre_post_image.dart new file mode 100644 index 00000000..cb68a472 --- /dev/null +++ b/lib/models/Appointments/doctor_pre_post_image.dart @@ -0,0 +1,107 @@ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:diplomaticquarterapp/uitl/utils.dart'; + +class DoctorPrePostImages { + DoctorPrePostImageModel pre; + DoctorPrePostImageModel post; + + Uint8List getPreBytes(){ + try{ + var b64 = pre.imageStr.replaceFirst('data:image/png;base64,', ''); + if(pre.imageStr != null && isBase64(b64)) + return Utils.dataFromBase64String(b64); + }catch(e){ + + } + return null; + } + + Uint8List getPostBytes(){ + try{ + var b64 = post.imageStr.replaceFirst('data:image/png;base64,', ''); + if(post.imageStr != null && isBase64(b64)) + return Utils.dataFromBase64String(b64); + }catch(e){ + + } + return null; + } + + bool isBase64(String str) { + RegExp _base64 = RegExp( + r'^(?:[A-Za-z0-9+\/]{4})*(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{4})$'); + return _base64.hasMatch(str); + } +} + +class DoctorPrePostImageModel { + String setupID; + int projectID; + int clinicId; + int doctorId; + int lineItemNo; + String imageStr; + int imageType; + String description; + dynamic isNewUpdated; + bool isActive; + String createdOn; + int createdBy; + dynamic editedOn; + dynamic editedBy; + + DoctorPrePostImageModel({ + this.setupID, + this.projectID, + this.clinicId, + this.doctorId, + this.lineItemNo, + this.imageStr, + this.imageType, + this.description, + this.isNewUpdated, + this.isActive, + this.createdOn, + this.createdBy, + this.editedOn, + this.editedBy}); + + DoctorPrePostImageModel.fromJson(dynamic json) { + setupID = json["SetupID"]; + projectID = json["ProjectID"]; + clinicId = json["ClinicId"]; + doctorId = json["DoctorId"]; + lineItemNo = json["LineItemNo"]; + imageStr = json["ImageStr"]; + imageType = json["ImageType"]; + description = json["Description"]; + isNewUpdated = json["IsNewUpdated"]; + isActive = json["IsActive"]; + createdOn = json["CreatedOn"]; + createdBy = json["CreatedBy"]; + editedOn = json["EditedOn"]; + editedBy = json["EditedBy"]; + } + + Map toJson() { + var map = {}; + map["SetupID"] = setupID; + map["ProjectID"] = projectID; + map["ClinicId"] = clinicId; + map["DoctorId"] = doctorId; + map["LineItemNo"] = lineItemNo; + map["ImageStr"] = imageStr; + map["ImageType"] = imageType; + map["Description"] = description; + map["IsNewUpdated"] = isNewUpdated; + map["IsActive"] = isActive; + map["CreatedOn"] = createdOn; + map["CreatedBy"] = createdBy; + map["EditedOn"] = editedOn; + map["EditedBy"] = editedBy; + return map; + } + +} \ No newline at end of file diff --git a/lib/pages/BookAppointment/DoctorProfile.dart b/lib/pages/BookAppointment/DoctorProfile.dart index fd89889f..949f2c44 100644 --- a/lib/pages/BookAppointment/DoctorProfile.dart +++ b/lib/pages/BookAppointment/DoctorProfile.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorRateDetails.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/doctor_post_pre_images_page.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart'; @@ -14,6 +15,7 @@ import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_material_pickers/flutter_material_pickers.dart'; import 'package:rating_bar/rating_bar.dart'; import 'BookConfirm.dart'; @@ -176,8 +178,15 @@ class _DoctorProfileState extends State )), ), ), + + if(widget.docProfileList.isDoctorHasPrePostImages == true) + Container( + height: 50, + alignment: Alignment.center, + child: prePostImagesButton(context) + ), + Container( - margin: EdgeInsets.only(top: 10.0), child: Divider( color: Colors.grey[500], ), @@ -225,6 +234,19 @@ class _DoctorProfileState extends State ); } + Widget prePostImagesButton(BuildContext context){ + return Padding( + padding: const EdgeInsets.all(10), + child: MaterialButton( + height: 50, + color: Theme.of(context).appBarTheme.color, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + onPressed: () => openDoctorPrePostImages(), + child: Text(TranslationBase.of(context).beforeAfterImages, style: TextStyle(color: Colors.white, fontSize: 15, letterSpacing: 1),), + ), + ); + } + getDoctorRatings() { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); @@ -265,6 +287,30 @@ class _DoctorProfileState extends State }); } + openDoctorPrePostImages(){ + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService().getDoctorPrePostImages(widget.docProfileList, context).then((images) { + GifLoaderDialogUtils.hideDialog(context); + showDialog( + context: context, barrierDismissible: true, + builder: (ctx){ + return DoctorPostPreImagesContent(doctorPrePostImages: images); + } + ); + // Navigator.push( + // context, + // FadePage( + // page: DoctorPostPreImagesPage(doctorPrePostImages: images,) + // ) + // ); + + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + void showRatingDialog(List doctorDetailsList) { showGeneralDialog( barrierColor: Colors.black.withOpacity(0.5), @@ -566,4 +612,6 @@ class _DoctorProfileState extends State selectedDate: DocAvailableAppointments.selectedDate, selectedTime: DocAvailableAppointments.selectedTime))); } + + } diff --git a/lib/pages/BookAppointment/doctor_post_pre_images_page.dart b/lib/pages/BookAppointment/doctor_post_pre_images_page.dart new file mode 100644 index 00000000..b97d58ac --- /dev/null +++ b/lib/pages/BookAppointment/doctor_post_pre_images_page.dart @@ -0,0 +1,121 @@ +import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart'; +import 'package:diplomaticquarterapp/models/Appointments/doctor_pre_post_image.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class DoctorPostPreImagesPage extends StatefulWidget{ + final DoctorPrePostImages doctorPrePostImages; + + const DoctorPostPreImagesPage({this.doctorPrePostImages}); + + @override + State createState() => DoctorPostPreImagesPageState(); +} + +class DoctorPostPreImagesPageState extends State{ + + @override + Widget build(BuildContext context) { + var images = widget.doctorPrePostImages; + return AppScaffold( + appBarTitle: TranslationBase.of(context).beforeAfterImages, + isShowAppBar: true, + isShowDecPage: false, + body: Padding( + padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 10), + child: Row( + children: [ + Expanded( + child: Column( + children: [ + Text("Before Image", style: TextStyle(color: Colors.black, fontSize: 17, fontWeight: FontWeight.bold, letterSpacing: 1),), + Image.memory(images.getPreBytes(), errorBuilder: (ctx,err, trace){ + return Container( + color: Colors.grey.withOpacity(0.25), + ); + },) + ], + ) + ), + Divider(color: Colors.grey.withOpacity(0.5)), + Expanded( + child: Column( + children: [ + Text("After Image", style: TextStyle(color: Colors.black, fontSize: 17, fontWeight: FontWeight.bold, letterSpacing: 1),), + Image.memory(images.getPostBytes(),errorBuilder: (ctx,err, trace){ + return Container( + color: Colors.grey.withOpacity(0.25), + ); + },) + ], + ) + ) + ], + ), + ) + ); + } + +} + + +class DoctorPostPreImagesContent extends StatefulWidget{ + final DoctorPrePostImages doctorPrePostImages; + + const DoctorPostPreImagesContent({this.doctorPrePostImages}); + + @override + DoctorPostPreImagesContentState createState() => DoctorPostPreImagesContentState(); +} + +class DoctorPostPreImagesContentState extends State{ + + @override + Widget build(BuildContext context) { + var images = widget.doctorPrePostImages; + return Material( + color: Colors.transparent, + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Expanded( + child: Column( + children: [ + Text("Before", style: TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.bold, letterSpacing: 1),), + SizedBox(height: 10,), + Image.memory(images.getPreBytes(), errorBuilder: (ctx,err, trace){ + return Container( + color: Colors.grey.withOpacity(0.25), + ); + },) + ], + ) + ), + Divider(color: Colors.grey.withOpacity(0.5)), + Expanded( + child: Column( + children: [ + Text("After", style: TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.bold, letterSpacing: 1),), + SizedBox(height: 10,), + Image.memory(images.getPostBytes(),errorBuilder: (ctx,err, trace){ + return Container( + color: Colors.grey.withOpacity(0.25), + ); + },) + ], + ) + ) + ], + ), + ], + ), + ), + ); + } + +} \ No newline at end of file diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index 1c0fd13e..c5da90d5 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -64,6 +64,11 @@ class _Login extends State { void initState() { // getDeviceToken(); super.initState(); + + if(BASE_URL.contains("uat.")){ + nationalIDorFile.text = "1231755"; + mobileNumberController.text = mobileNo = "537503378"; + } } getDeviceToken() async { diff --git a/lib/services/appointment_services/GetDoctorsList.dart b/lib/services/appointment_services/GetDoctorsList.dart index fb55d538..b97714ce 100644 --- a/lib/services/appointment_services/GetDoctorsList.dart +++ b/lib/services/appointment_services/GetDoctorsList.dart @@ -4,7 +4,9 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/DoctorProfile.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; +import 'package:diplomaticquarterapp/models/Appointments/doctor_pre_post_image.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/Request.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; @@ -157,7 +159,7 @@ class DoctorsListService extends BaseService { "VersionID": req.VersionID, "Channel": req.Channel, "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": authUser.outSA, + "PatientOutSA": authUser.outSA ?? false, "TokenID": "", "DeviceTypeID": req.DeviceTypeID, "SessionID": null, @@ -184,7 +186,7 @@ class DoctorsListService extends BaseService { Future getDoctorsRating(int docID, context) async { Map request; var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "LanguageID": languageID == 'ar' ? 1 : 2, @@ -207,13 +209,40 @@ class DoctorsListService extends BaseService { await baseAppClient.post(GET_DOCTOR_RATING_NOTES, onSuccess: (response, statusCode) async { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: request); + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); return Future.value(localRes); } + Future getDoctorPrePostImages(DoctorProfileList doctorProfile, context) async { + Map request; + request = { + "PatientOutSA": authUser.outSA ?? 0, + "isDentalAllowedBackend": false, + "DoctorID" : doctorProfile.doctorID, + "ClinicID":doctorProfile.clinicID, + "ProjectID":doctorProfile.projectID + }; + + var images = DoctorPrePostImages(); + await baseAppClient.post(GET_DOCTOR_PRE_POST_IMAGES, + onSuccess: (response, statusCode) async { + var list = response['DoctorPrePostImagesList']; + if (list is List && list.length > 0){ + list.forEach((j) { + var image = DoctorPrePostImageModel.fromJson(j); + if(image.imageType == 1) images.pre = image; + if(image.imageType == 2) images.post = image; + }); + } + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(images); + } + Future getDoctorsRatingDetails(int docID, context) async { Map request; var languageID = diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 795e9228..9ea40910 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -45,6 +45,8 @@ class TranslationBase { String get bookAppo => localizedValues['bookAppo'][locale.languageCode]; + String get beforeAfterImages => localizedValues['beforeAfterImages'][locale.languageCode]; + String get searchBy => localizedValues['searchBy'][locale.languageCode]; String get clinic => localizedValues['clinic'][locale.languageCode]; From e28fdaade1696713836364664ea86d4181644661 Mon Sep 17 00:00:00 2001 From: haroon amjad Date: Thu, 12 Aug 2021 14:49:09 +0300 Subject: [PATCH 9/9] Dental Invoices implementation completed --- lib/config/config.dart | 6 + .../DentalInvoiceDetailResponse.dart | 489 ++++++++++++++++++ .../my_invoices/invoice_detail_page.dart | 318 +++++++++++- .../medical/my_invoices/my_invoice_page.dart | 44 +- .../my_invoice_services.dart | 92 +++- 5 files changed, 911 insertions(+), 38 deletions(-) create mode 100644 lib/models/MyInvoices/DentalInvoiceDetailResponse.dart diff --git a/lib/config/config.dart b/lib/config/config.dart index acdc5c40..66937944 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -608,6 +608,12 @@ const GET_DOCTOR_LIST_CALCULATION = const GET_ALL_APPOINTMENTS_FOR_DENTAL_CLINIC = "Services/Patients.svc/REST/GetDentalAppointments"; +const GET_DENTAL_APPOINTMENT_INVOICE = + "Services/Patients.svc/REST/HIS_eInvoiceForDentalByAppointmentNo"; + +const SEND_DENTAL_APPOINTMENT_INVOICE_EMAIL = + "Services/Notifications.svc/REST/SendInvoiceForDental"; + class AppGlobal { static var context; diff --git a/lib/models/MyInvoices/DentalInvoiceDetailResponse.dart b/lib/models/MyInvoices/DentalInvoiceDetailResponse.dart new file mode 100644 index 00000000..83ef9f5a --- /dev/null +++ b/lib/models/MyInvoices/DentalInvoiceDetailResponse.dart @@ -0,0 +1,489 @@ +class DentalInvoiceDetailResponse { + List listEInvoiceForDental; + + DentalInvoiceDetailResponse({this.listEInvoiceForDental}); + + DentalInvoiceDetailResponse.fromJson(Map json) { + if (json['List_eInvoiceForDental'] != null) { + listEInvoiceForDental = new List(); + json['List_eInvoiceForDental'].forEach((v) { + listEInvoiceForDental.add(new ListEInvoiceForDental.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.listEInvoiceForDental != null) { + data['List_eInvoiceForDental'] = + this.listEInvoiceForDental.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class ListEInvoiceForDental { + int projectID; + int doctorID; + dynamic grandTotal; + dynamic quantity; + dynamic total; + dynamic discount; + dynamic subTotal; + int invoiceNo; + String createdOn; + dynamic procedureID; + dynamic procedureName; + dynamic procedureNameN; + dynamic procedurePrice; + dynamic patientShare; + dynamic companyShare; + dynamic totalPatientShare; + dynamic totalCompanyShare; + dynamic totalShare; + dynamic discountAmount; + dynamic vATPercentage; + dynamic patientVATAmount; + dynamic companyVATAmount; + dynamic totalVATAmount; + dynamic price; + int patientID; + String patientName; + dynamic patientNameN; + String nationalityID; + String doctorName; + dynamic doctorNameN; + int clinicID; + String clinicDescription; + dynamic clinicDescriptionN; + String appointmentDate; + int appointmentNo; + String insuranceID; + int companyID; + String companyName; + dynamic companyNameN; + String companyAddress; + dynamic companyAddressN; + String companyGroupAddress; + String groupName; + dynamic groupNameN; + String patientAddress; + String vATNo; + String paymentDate; + String projectName; + dynamic totalDiscount; + dynamic totalPatientShareWithQuantity; + String legalName; + dynamic legalNameN; + dynamic advanceAdjustment; + String doctorImageURL; + List listConsultation; + + ListEInvoiceForDental( + {this.projectID, + this.doctorID, + this.grandTotal, + this.quantity, + this.total, + this.discount, + this.subTotal, + this.invoiceNo, + this.createdOn, + this.procedureID, + this.procedureName, + this.procedureNameN, + this.procedurePrice, + this.patientShare, + this.companyShare, + this.totalPatientShare, + this.totalCompanyShare, + this.totalShare, + this.discountAmount, + this.vATPercentage, + this.patientVATAmount, + this.companyVATAmount, + this.totalVATAmount, + this.price, + this.patientID, + this.patientName, + this.patientNameN, + this.nationalityID, + this.doctorName, + this.doctorNameN, + this.clinicID, + this.clinicDescription, + this.clinicDescriptionN, + this.appointmentDate, + this.appointmentNo, + this.insuranceID, + this.companyID, + this.companyName, + this.companyNameN, + this.companyAddress, + this.companyAddressN, + this.companyGroupAddress, + this.groupName, + this.groupNameN, + this.patientAddress, + this.vATNo, + this.paymentDate, + this.projectName, + this.totalDiscount, + this.totalPatientShareWithQuantity, + this.legalName, + this.legalNameN, + this.advanceAdjustment, + this.doctorImageURL, + this.listConsultation}); + + ListEInvoiceForDental.fromJson(Map json) { + projectID = json['ProjectID']; + doctorID = json['DoctorID']; + grandTotal = json['GrandTotal']; + quantity = json['Quantity']; + total = json['Total']; + discount = json['Discount']; + subTotal = json['SubTotal']; + invoiceNo = json['InvoiceNo']; + createdOn = json['CreatedOn']; + procedureID = json['ProcedureID']; + procedureName = json['ProcedureName']; + procedureNameN = json['ProcedureNameN']; + procedurePrice = json['ProcedurePrice']; + patientShare = json['PatientShare']; + companyShare = json['CompanyShare']; + totalPatientShare = json['TotalPatientShare']; + totalCompanyShare = json['TotalCompanyShare']; + totalShare = json['TotalShare']; + discountAmount = json['DiscountAmount']; + vATPercentage = json['VATPercentage']; + patientVATAmount = json['PatientVATAmount']; + companyVATAmount = json['CompanyVATAmount']; + totalVATAmount = json['TotalVATAmount']; + price = json['Price']; + patientID = json['PatientID']; + patientName = json['PatientName']; + patientNameN = json['PatientNameN']; + nationalityID = json['NationalityID']; + doctorName = json['DoctorName']; + doctorNameN = json['DoctorNameN']; + clinicID = json['ClinicID']; + clinicDescription = json['ClinicDescription']; + clinicDescriptionN = json['ClinicDescriptionN']; + appointmentDate = json['AppointmentDate']; + appointmentNo = json['AppointmentNo']; + insuranceID = json['InsuranceID']; + companyID = json['CompanyID']; + companyName = json['CompanyName']; + companyNameN = json['CompanyNameN']; + companyAddress = json['CompanyAddress']; + companyAddressN = json['CompanyAddressN']; + companyGroupAddress = json['CompanyGroupAddress']; + groupName = json['GroupName']; + groupNameN = json['GroupNameN']; + patientAddress = json['PatientAddress']; + vATNo = json['VATNo']; + paymentDate = json['PaymentDate']; + projectName = json['ProjectName']; + totalDiscount = json['TotalDiscount']; + totalPatientShareWithQuantity = json['TotalPatientShareWithQuantity']; + legalName = json['LegalName']; + legalNameN = json['LegalNameN']; + advanceAdjustment = json['AdvanceAdjustment']; + doctorImageURL = json['DoctorImageURL']; + if (json['listConsultation'] != null) { + listConsultation = new List(); + json['listConsultation'].forEach((v) { + listConsultation.add(new ListConsultation.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['DoctorID'] = this.doctorID; + data['GrandTotal'] = this.grandTotal; + data['Quantity'] = this.quantity; + data['Total'] = this.total; + data['Discount'] = this.discount; + data['SubTotal'] = this.subTotal; + data['InvoiceNo'] = this.invoiceNo; + data['CreatedOn'] = this.createdOn; + data['ProcedureID'] = this.procedureID; + data['ProcedureName'] = this.procedureName; + data['ProcedureNameN'] = this.procedureNameN; + data['ProcedurePrice'] = this.procedurePrice; + data['PatientShare'] = this.patientShare; + data['CompanyShare'] = this.companyShare; + data['TotalPatientShare'] = this.totalPatientShare; + data['TotalCompanyShare'] = this.totalCompanyShare; + data['TotalShare'] = this.totalShare; + data['DiscountAmount'] = this.discountAmount; + data['VATPercentage'] = this.vATPercentage; + data['PatientVATAmount'] = this.patientVATAmount; + data['CompanyVATAmount'] = this.companyVATAmount; + data['TotalVATAmount'] = this.totalVATAmount; + data['Price'] = this.price; + data['PatientID'] = this.patientID; + data['PatientName'] = this.patientName; + data['PatientNameN'] = this.patientNameN; + data['NationalityID'] = this.nationalityID; + data['DoctorName'] = this.doctorName; + data['DoctorNameN'] = this.doctorNameN; + data['ClinicID'] = this.clinicID; + data['ClinicDescription'] = this.clinicDescription; + data['ClinicDescriptionN'] = this.clinicDescriptionN; + data['AppointmentDate'] = this.appointmentDate; + data['AppointmentNo'] = this.appointmentNo; + data['InsuranceID'] = this.insuranceID; + data['CompanyID'] = this.companyID; + data['CompanyName'] = this.companyName; + data['CompanyNameN'] = this.companyNameN; + data['CompanyAddress'] = this.companyAddress; + data['CompanyAddressN'] = this.companyAddressN; + data['CompanyGroupAddress'] = this.companyGroupAddress; + data['GroupName'] = this.groupName; + data['GroupNameN'] = this.groupNameN; + data['PatientAddress'] = this.patientAddress; + data['VATNo'] = this.vATNo; + data['PaymentDate'] = this.paymentDate; + data['ProjectName'] = this.projectName; + data['TotalDiscount'] = this.totalDiscount; + data['TotalPatientShareWithQuantity'] = this.totalPatientShareWithQuantity; + data['LegalName'] = this.legalName; + data['LegalNameN'] = this.legalNameN; + data['AdvanceAdjustment'] = this.advanceAdjustment; + data['DoctorImageURL'] = this.doctorImageURL; + if (this.listConsultation != null) { + data['listConsultation'] = + this.listConsultation.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class ListConsultation { + dynamic projectID; + dynamic doctorID; + dynamic grandTotal; + int quantity; + int total; + dynamic discount; + int subTotal; + dynamic invoiceNo; + dynamic createdOn; + String procedureID; + String procedureName; + dynamic procedureNameN; + dynamic procedurePrice; + int patientShare; + dynamic companyShare; + int totalPatientShare; + dynamic totalCompanyShare; + dynamic totalShare; + dynamic discountAmount; + int vATPercentage; + int patientVATAmount; + dynamic companyVATAmount; + dynamic totalVATAmount; + int price; + dynamic patientID; + dynamic patientName; + dynamic patientNameN; + dynamic nationalityID; + dynamic doctorName; + dynamic doctorNameN; + dynamic clinicID; + dynamic clinicDescription; + dynamic clinicDescriptionN; + dynamic appointmentDate; + dynamic appointmentNo; + dynamic insuranceID; + dynamic companyID; + dynamic companyName; + dynamic companyNameN; + dynamic companyAddress; + dynamic companyAddressN; + dynamic companyGroupAddress; + dynamic groupName; + dynamic groupNameN; + dynamic patientAddress; + String vATNo; + dynamic paymentDate; + dynamic projectName; + dynamic totalDiscount; + dynamic totalPatientShareWithQuantity; + dynamic legalName; + dynamic legalNameN; + int advanceAdjustment; + + ListConsultation( + {this.projectID, + this.doctorID, + this.grandTotal, + this.quantity, + this.total, + this.discount, + this.subTotal, + this.invoiceNo, + this.createdOn, + this.procedureID, + this.procedureName, + this.procedureNameN, + this.procedurePrice, + this.patientShare, + this.companyShare, + this.totalPatientShare, + this.totalCompanyShare, + this.totalShare, + this.discountAmount, + this.vATPercentage, + this.patientVATAmount, + this.companyVATAmount, + this.totalVATAmount, + this.price, + this.patientID, + this.patientName, + this.patientNameN, + this.nationalityID, + this.doctorName, + this.doctorNameN, + this.clinicID, + this.clinicDescription, + this.clinicDescriptionN, + this.appointmentDate, + this.appointmentNo, + this.insuranceID, + this.companyID, + this.companyName, + this.companyNameN, + this.companyAddress, + this.companyAddressN, + this.companyGroupAddress, + this.groupName, + this.groupNameN, + this.patientAddress, + this.vATNo, + this.paymentDate, + this.projectName, + this.totalDiscount, + this.totalPatientShareWithQuantity, + this.legalName, + this.legalNameN, + this.advanceAdjustment}); + + ListConsultation.fromJson(Map json) { + projectID = json['ProjectID']; + doctorID = json['DoctorID']; + grandTotal = json['GrandTotal']; + quantity = json['Quantity']; + total = json['Total']; + discount = json['Discount']; + subTotal = json['SubTotal']; + invoiceNo = json['InvoiceNo']; + createdOn = json['CreatedOn']; + procedureID = json['ProcedureID']; + procedureName = json['ProcedureName']; + procedureNameN = json['ProcedureNameN']; + procedurePrice = json['ProcedurePrice']; + patientShare = json['PatientShare']; + companyShare = json['CompanyShare']; + totalPatientShare = json['TotalPatientShare']; + totalCompanyShare = json['TotalCompanyShare']; + totalShare = json['TotalShare']; + discountAmount = json['DiscountAmount']; + vATPercentage = json['VATPercentage']; + patientVATAmount = json['PatientVATAmount']; + companyVATAmount = json['CompanyVATAmount']; + totalVATAmount = json['TotalVATAmount']; + price = json['Price']; + patientID = json['PatientID']; + patientName = json['PatientName']; + patientNameN = json['PatientNameN']; + nationalityID = json['NationalityID']; + doctorName = json['DoctorName']; + doctorNameN = json['DoctorNameN']; + clinicID = json['ClinicID']; + clinicDescription = json['ClinicDescription']; + clinicDescriptionN = json['ClinicDescriptionN']; + appointmentDate = json['AppointmentDate']; + appointmentNo = json['AppointmentNo']; + insuranceID = json['InsuranceID']; + companyID = json['CompanyID']; + companyName = json['CompanyName']; + companyNameN = json['CompanyNameN']; + companyAddress = json['CompanyAddress']; + companyAddressN = json['CompanyAddressN']; + companyGroupAddress = json['CompanyGroupAddress']; + groupName = json['GroupName']; + groupNameN = json['GroupNameN']; + patientAddress = json['PatientAddress']; + vATNo = json['VATNo']; + paymentDate = json['PaymentDate']; + projectName = json['ProjectName']; + totalDiscount = json['TotalDiscount']; + totalPatientShareWithQuantity = json['TotalPatientShareWithQuantity']; + legalName = json['LegalName']; + legalNameN = json['LegalNameN']; + advanceAdjustment = json['AdvanceAdjustment']; + } + + Map toJson() { + final Map data = new Map(); + data['ProjectID'] = this.projectID; + data['DoctorID'] = this.doctorID; + data['GrandTotal'] = this.grandTotal; + data['Quantity'] = this.quantity; + data['Total'] = this.total; + data['Discount'] = this.discount; + data['SubTotal'] = this.subTotal; + data['InvoiceNo'] = this.invoiceNo; + data['CreatedOn'] = this.createdOn; + data['ProcedureID'] = this.procedureID; + data['ProcedureName'] = this.procedureName; + data['ProcedureNameN'] = this.procedureNameN; + data['ProcedurePrice'] = this.procedurePrice; + data['PatientShare'] = this.patientShare; + data['CompanyShare'] = this.companyShare; + data['TotalPatientShare'] = this.totalPatientShare; + data['TotalCompanyShare'] = this.totalCompanyShare; + data['TotalShare'] = this.totalShare; + data['DiscountAmount'] = this.discountAmount; + data['VATPercentage'] = this.vATPercentage; + data['PatientVATAmount'] = this.patientVATAmount; + data['CompanyVATAmount'] = this.companyVATAmount; + data['TotalVATAmount'] = this.totalVATAmount; + data['Price'] = this.price; + data['PatientID'] = this.patientID; + data['PatientName'] = this.patientName; + data['PatientNameN'] = this.patientNameN; + data['NationalityID'] = this.nationalityID; + data['DoctorName'] = this.doctorName; + data['DoctorNameN'] = this.doctorNameN; + data['ClinicID'] = this.clinicID; + data['ClinicDescription'] = this.clinicDescription; + data['ClinicDescriptionN'] = this.clinicDescriptionN; + data['AppointmentDate'] = this.appointmentDate; + data['AppointmentNo'] = this.appointmentNo; + data['InsuranceID'] = this.insuranceID; + data['CompanyID'] = this.companyID; + data['CompanyName'] = this.companyName; + data['CompanyNameN'] = this.companyNameN; + data['CompanyAddress'] = this.companyAddress; + data['CompanyAddressN'] = this.companyAddressN; + data['CompanyGroupAddress'] = this.companyGroupAddress; + data['GroupName'] = this.groupName; + data['GroupNameN'] = this.groupNameN; + data['PatientAddress'] = this.patientAddress; + data['VATNo'] = this.vATNo; + data['PaymentDate'] = this.paymentDate; + data['ProjectName'] = this.projectName; + data['TotalDiscount'] = this.totalDiscount; + data['TotalPatientShareWithQuantity'] = this.totalPatientShareWithQuantity; + data['LegalName'] = this.legalName; + data['LegalNameN'] = this.legalNameN; + data['AdvanceAdjustment'] = this.advanceAdjustment; + return data; + } +} diff --git a/lib/pages/medical/my_invoices/invoice_detail_page.dart b/lib/pages/medical/my_invoices/invoice_detail_page.dart index 33df8fc3..3d62a661 100644 --- a/lib/pages/medical/my_invoices/invoice_detail_page.dart +++ b/lib/pages/medical/my_invoices/invoice_detail_page.dart @@ -1,8 +1,14 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; +import 'package:diplomaticquarterapp/models/MyInvoices/DentalInvoiceDetailResponse.dart'; import 'package:diplomaticquarterapp/models/MyInvoices/GetDentalAppointmentsResponse.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DoctorView.dart'; +import 'package:diplomaticquarterapp/services/my_invoice_service/my_invoice_services.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -10,23 +16,37 @@ import 'package:provider/provider.dart'; class InvoiceDetail extends StatelessWidget { final DoctorList doctor; final ListDentalAppointments listDentalAppointments; + final DentalInvoiceDetailResponse dentalInvoiceDetailResponse; + final BuildContext context; - InvoiceDetail(this.doctor, this.listDentalAppointments); + int totalServiceRate = 0; + int totalDiscount = 0; + int totalVAT = 0; + int subTotal = 0; + int grandTotal = 0; + + InvoiceDetail(this.doctor, this.listDentalAppointments, + this.dentalInvoiceDetailResponse, this.context); @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( - appBarTitle: TranslationBase.of(context).myInvoice, - isShowAppBar: true, - isShowDecPage: false, - body: Container( + appBarTitle: TranslationBase.of(context).myInvoice, + isShowAppBar: true, + isShowDecPage: false, + body: SingleChildScrollView( + child: Container( child: Column( children: [ - DoctorView(doctor: doctor, isLiveCareAppointment: false, isShowFlag: false), + DoctorView( + doctor: doctor, + isLiveCareAppointment: false, + isShowFlag: false), Container( - margin: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0), - padding: EdgeInsets.only(top: 10.0, left: 10.0, right: 10.0, bottom: 10.0), + margin: EdgeInsets.only(left: 10.0, right: 10.0), + padding: EdgeInsets.only( + top: 10.0, left: 10.0, right: 10.0, bottom: 10.0), decoration: BoxDecoration( color: Colors.grey[800], borderRadius: BorderRadius.only( @@ -34,18 +54,286 @@ class InvoiceDetail extends StatelessWidget { topRight: Radius.circular(8), ), ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + child: Table( children: [ - Text("Description", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), - Text("Quantity", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), - Text("Price", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), - Text("Total", style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), + TableRow(children: [ + Text("Description", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold)), + Text("Quantity", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold)), + Text("Price", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold)), + Text("Total", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold)), + ]), ], ), ), + Container( + margin: EdgeInsets.only(top: 0.0, left: 10.0, right: 10.0), + padding: EdgeInsets.only( + top: 10.0, left: 10.0, right: 10.0, bottom: 15.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(8), + bottomRight: Radius.circular(8), + )), + child: Table(children: fullData(context)), + ), + Container( + margin: EdgeInsets.only(top: 3.0, left: 12.0, right: 12.0), + child: Divider( + color: Colors.grey[400], + thickness: 0.7, + ), + ), + Container( + child: AppExpandableNotifier( + title: "Total Price: " + grandTotal.toString() + " SAR", + isExpand: true, + bodyWidget: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Table( + children: [ + TableRow(children: [ + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text("Discount: ", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text(totalDiscount.toString() + " SAR", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + ), + ]), + TableRow(children: [ + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text( + "VAT (" + + dentalInvoiceDetailResponse + .listEInvoiceForDental[0] + .listConsultation[0] + .vATPercentage + .toString() + + "%)", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text(totalVAT.toString() + " SAR", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + ), + ]), + TableRow(children: [ + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text("Total: ", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text(grandTotal.toString() + " SAR", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + ), + ]), + TableRow(children: [ + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text("Paid: ", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + ), + Container( + margin: + EdgeInsets.only(top: 10.0, bottom: 10.0), + child: Text(grandTotal.toString() + " SAR", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + ), + ]), + ], + ), + ]), + ), + ), + Container( + margin: EdgeInsets.only(top: 3.0, left: 12.0, right: 12.0), + child: Divider( + color: Colors.grey[400], + thickness: 0.7, + ), + ), + Container( + margin: EdgeInsets.only(top: 0.0, left: 10.0, right: 10.0), + padding: EdgeInsets.only( + top: 10.0, left: 10.0, right: 10.0, bottom: 15.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(8))), + child: Table(children: [ + TableRow(children: [ + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text("Insurance: ", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + ), + Container( + margin: EdgeInsets.only(top: 10.0, bottom: 5.0), + child: Text( + dentalInvoiceDetailResponse + .listEInvoiceForDental[0].companyName, + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + ), + ]), + TableRow(children: [ + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text("Insurance ID: ", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + ), + Container( + margin: EdgeInsets.only(top: 10.0, bottom: 10.0), + child: Text( + dentalInvoiceDetailResponse + .listEInvoiceForDental[0].insuranceID, + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold)), + ), + ]), + ]), + ), + SizedBox( + height: 100.0, + ), ], ), - )); + ), + ), + bottomSheet: Container( + width: MediaQuery.of(context).size.width, + height: 70.0, + margin: EdgeInsets.only(left: 15.0, right: 15.0, top: 10.0), + child: Button( + onTap: () { + sendInvoiceEmail(); + }, + label: TranslationBase.of(context).sendEmail, + backgroundColor: Colors.red[900], + ), + ), + ); + } + + sendInvoiceEmail() { + GifLoaderDialogUtils.showMyDialog(context); + MyInvoicesService myInvoicesService = new MyInvoicesService(); + + myInvoicesService + .sendDentalAppointmentInvoiceEmail( + 12, listDentalAppointments.appointmentNo, context) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + if (res['MessageStatus'] == 1) { + AppToast.showSuccessToast( + message: TranslationBase.of(context).emailSentSuccessfully); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err); + Navigator.of(context).pop(); + }); + } + + List fullData(context) { + List tableRow = []; + dentalInvoiceDetailResponse.listEInvoiceForDental[0].listConsultation + .forEach((lab) { + tableRow.add( + TableRow(children: [ + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text(lab.procedureName, + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, fontWeight: FontWeight.w400)), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text(lab.quantity.toString(), + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, fontWeight: FontWeight.w400)), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text(lab.price.toString() + " SAR", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, fontWeight: FontWeight.w400)), + ), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text(lab.total.toString() + " SAR", + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.black, fontWeight: FontWeight.w400)), + ), + ]), + ); + }); + return tableRow; } } diff --git a/lib/pages/medical/my_invoices/my_invoice_page.dart b/lib/pages/medical/my_invoices/my_invoice_page.dart index 898d374a..2af80adc 100644 --- a/lib/pages/medical/my_invoices/my_invoice_page.dart +++ b/lib/pages/medical/my_invoices/my_invoice_page.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart' as DoctorListResponse; +import 'package:diplomaticquarterapp/models/MyInvoices/DentalInvoiceDetailResponse.dart'; import 'package:diplomaticquarterapp/models/MyInvoices/GetDentalAppointmentsResponse.dart'; import 'package:diplomaticquarterapp/pages/medical/my_invoices/invoice_detail_page.dart'; import 'package:diplomaticquarterapp/services/my_invoice_service/my_invoice_services.dart'; @@ -21,6 +22,7 @@ class MyInvoices extends StatefulWidget { class _MyInvoicesState extends State { bool isDataLoaded = false; GetDentalAppointmentsResponse getDentalAppointmentsResponse; + DentalInvoiceDetailResponse dentalInvoiceDetailResponse; @override void initState() { @@ -36,7 +38,7 @@ class _MyInvoicesState extends State { return AppScaffold( appBarTitle: TranslationBase.of(context).myInvoice, isShowAppBar: true, - isShowDecPage: false, + isShowDecPage: true, body: Container( child: SingleChildScrollView( physics: BouncingScrollPhysics(), @@ -186,6 +188,9 @@ class _MyInvoicesState extends State { } openInvoiceDetailsPage(ListDentalAppointments listDentalAppointments) { + GifLoaderDialogUtils.showMyDialog(context); + MyInvoicesService myInvoicesService = new MyInvoicesService(); + DoctorListResponse.DoctorList doctor = new DoctorListResponse.DoctorList(); doctor.name = listDentalAppointments.doctorName; @@ -197,13 +202,33 @@ class _MyInvoicesState extends State { doctor.doctorTitle = "Dr."; doctor.clinicName = "InvoiceNo: " + listDentalAppointments.invoiceNo.toString(); - Navigator.push( - context, - FadePage( - page: InvoiceDetail( - doctor, - listDentalAppointments, - ))); + myInvoicesService.getDentalAppointmentInvoice(12, listDentalAppointments.appointmentNo, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + setState(() { + if (res['MessageStatus'] == 1) { + dentalInvoiceDetailResponse = + DentalInvoiceDetailResponse.fromJson(res); + print(dentalInvoiceDetailResponse.listEInvoiceForDental[0].listConsultation.length); + Navigator.push( + context, + FadePage( + page: InvoiceDetail( + doctor, + listDentalAppointments, + dentalInvoiceDetailResponse, + context + ))); + } else { + AppToast.showErrorToast(message: res['ErrorEndUserMessage']); + } + isDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + AppToast.showErrorToast(message: err.toString()); + Navigator.of(context).pop(); + }); } getDentalAppointments() { @@ -216,9 +241,6 @@ class _MyInvoicesState extends State { if (res['MessageStatus'] == 1) { getDentalAppointmentsResponse = GetDentalAppointmentsResponse.fromJson(res); - print(getDentalAppointmentsResponse.listDentalAppointments.length); - print(getDentalAppointmentsResponse - .listDentalAppointments[0].appointmentNo); } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } diff --git a/lib/services/my_invoice_service/my_invoice_services.dart b/lib/services/my_invoice_service/my_invoice_services.dart index fc401c39..69d3ea19 100644 --- a/lib/services/my_invoice_service/my_invoice_services.dart +++ b/lib/services/my_invoice_service/my_invoice_services.dart @@ -13,11 +13,10 @@ class MyInvoicesService extends BaseService { AuthenticatedUser authUser = new AuthenticatedUser(); AuthProvider authProvider = new AuthProvider(); - Future getAllDentalAppointments(int projectID, - context) async { + Future getAllDentalAppointments(int projectID, context) async { Map request; var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "LanguageID": languageID == 'ar' ? 1 : 2, @@ -32,22 +31,91 @@ class MyInvoicesService extends BaseService { "License": true, "IsRegistered": true, "ProjectID": projectID, - "PatientTypeID":authUser.patientIdentificationType, - "PatientType":authUser.patientType, + "PatientTypeID": authUser.patientIdentificationType, + "PatientType": authUser.patientType, "isDentalAllowedBackend": false }; dynamic localRes; await baseAppClient.post(GET_ALL_APPOINTMENTS_FOR_DENTAL_CLINIC, - onSuccess: (response, statusCode) async { - localRes = response; + onSuccess: (response, statusCode) async { + localRes = response; }, onFailure: (String error, int statusCode) { - throw error; + throw error; }, body: request); - return Future.value( - localRes - ); + return Future.value(localRes); + } + + Future getDentalAppointmentInvoice(int projectID, int appoNo, context) async { + Map request; + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); + request = { + "LanguageID": languageID == 'ar' ? 1 : 2, + "IPAdress": "10.20.10.20", + "VersionID": req.VersionID, + "Channel": req.Channel, + "generalid": 'Cs2020@2016\$2958', + "PatientOutSA": authUser.outSA, + "DeviceTypeID": req.DeviceTypeID, + "SessionID": null, + "PatientID": authUser.patientID, + "License": true, + "AppointmentNo": appoNo, + "IsRegistered": true, + "ProjectID": projectID, + "PatientTypeID": authUser.patientIdentificationType, + "PatientType": authUser.patientType, + "isDentalAllowedBackend": false + }; + + dynamic localRes; + + await baseAppClient.post(GET_DENTAL_APPOINTMENT_INVOICE, + onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + + Future sendDentalAppointmentInvoiceEmail(int projectID, int appoNo, context) async { + Map request; + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); + request = { + "LanguageID": languageID == 'ar' ? 1 : 2, + "IPAdress": "10.20.10.20", + "VersionID": req.VersionID, + "Channel": req.Channel, + "generalid": 'Cs2020@2016\$2958', + "PatientOutSA": authUser.outSA, + "DeviceTypeID": req.DeviceTypeID, + "SessionID": null, + "PatientID": authUser.patientID, + "License": true, + "AppointmentNo": appoNo, + "To": authUser.emailAddress, + "IsRegistered": true, + "ProjectID": projectID, + "PatientTypeID": authUser.patientIdentificationType, + "PatientType": authUser.patientType, + "isDentalAllowedBackend": false + }; + + dynamic localRes; + + await baseAppClient.post(SEND_DENTAL_APPOINTMENT_INVOICE_EMAIL, + onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); } -} \ No newline at end of file +}