diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 4f76996c..ac9f195d 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1518,4 +1518,5 @@ const Map localizedValues = { "requestedDate": { "en": "Reqeusted Date", "ar": "التاريخ " }, "callDuration": { "en": "Call Duration", "ar": "مدة الاتصال" }, "alreadyRated": { "en": "This appointment has been previously evaluated.", "ar": "تم تقييم هذا الموعد مسبقاً" }, + "insuranceCompany": { "en": "Insurance Company", "ar": "شركة تأمين" }, }; diff --git a/lib/pages/medical/my_invoices/invoice_detail_page.dart b/lib/pages/medical/my_invoices/invoice_detail_page.dart index a8254cc6..768afdfc 100644 --- a/lib/pages/medical/my_invoices/invoice_detail_page.dart +++ b/lib/pages/medical/my_invoices/invoice_detail_page.dart @@ -2,204 +2,277 @@ 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/models/header_model.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/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/medical/doctor_card.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/new_design/doctor_header.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'; import 'package:diplomaticquarterapp/extensions/list_extension.dart'; -class InvoiceDetail extends StatelessWidget { +class InvoiceDetail extends StatefulWidget { final DoctorList doctor; final ListDentalAppointments listDentalAppointments; final DentalInvoiceDetailResponse dentalInvoiceDetailResponse; final BuildContext context; + InvoiceDetail(this.doctor, this.listDentalAppointments, + this.dentalInvoiceDetailResponse, this.context); + + @override + _InvoiceDetailState createState() => _InvoiceDetailState(); +} + +class _InvoiceDetailState extends State { dynamic totalServiceRate = 0; + dynamic totalDiscount = 0; + dynamic totalVAT = 0; + dynamic subTotal = 0; - dynamic grandTotal = 0; - InvoiceDetail(this.doctor, this.listDentalAppointments, this.dentalInvoiceDetailResponse, this.context); + dynamic grandTotal = 0; @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); generateInvoiceDetails(); return AppScaffold( - appBarTitle: TranslationBase.of(context).myInvoice, - isShowAppBar: true, - isShowDecPage: false, - showNewAppBar: true, - showNewAppBarTitle: true, - body: SingleChildScrollView( - child: Container( - child: Column( - children: [ - DoctorView(doctor: doctor, isLiveCareAppointment: false, isShowFlag: false), - Container( - 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( - topLeft: Radius.circular(8), - topRight: Radius.circular(8), - ), - ), - child: Table( - children: [ - TableRow(children: [ - Text(TranslationBase.of(context).description, textAlign: TextAlign.center, style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), - Text(TranslationBase.of(context).quantity, textAlign: TextAlign.center, style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), - Text(TranslationBase.of(context).price, textAlign: TextAlign.center, style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), - Text(TranslationBase.of(context).total, textAlign: TextAlign.center, style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), - ]), - ], + appBarTitle: widget.doctor.doctorTitle != null + ? widget.doctor.doctorTitle.toString() + : TranslationBase.of(context).dr + + " " + + widget.doctor.name.toString(), + isShowAppBar: true, + isShowDecPage: false, + showNewAppBar: true, + showNewAppBarTitle: true, + body: SingleChildScrollView( + child: Container( + child: Column( + children: [ + // DoctorView(doctor: doctor, isLiveCareAppointment: false, isShowFlag: false), + DoctorHeader( + headerModel: HeaderModel( + widget.doctor.name, + widget.doctor.doctorImageURL, + widget.doctor.speciality, + widget.doctor.clinicName, + widget.doctor.projectName, + DateUtil.convertStringToDate(widget.doctor.date), + null, + widget.doctor.nationalityFlagURL, + widget.doctor.doctorRate, + widget.doctor.actualDoctorRate, + widget.doctor.noOfPatientsRate, + projectViewModel.user.emailAddress), + onTap: () { + sendInvoiceEmail(); + }, ), - ), - 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: TranslationBase.of(context).patientShareTotal.toString() + " " + this.grandTotal.toString() + " " + TranslationBase.of(context).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(TranslationBase.of(context).discount, textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Text(this.totalDiscount.toString() + " " + TranslationBase.of(context).sar, - textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)), - ), - ]), - TableRow(children: [ - Container( - margin: EdgeInsets.only(top: 10.0), - child: Text( - TranslationBase.of(context).totalVAT.toString() + " (" + 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(num.tryParse(this.totalVAT.toString()).toStringAsFixed(2) + " " + TranslationBase.of(context).sar, - textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)), - ), - ]), - TableRow(children: [ - Container( - margin: EdgeInsets.only(top: 10.0), - child: Text(TranslationBase.of(context).total.toString() + ": ", textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: - Text(this.subTotal.toString() + " " + TranslationBase.of(context).sar, textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)), - ), - ]), - TableRow(children: [ - Container( - margin: EdgeInsets.only(top: 10.0), - child: Text(TranslationBase.of(context).paid.toString() + ": ", textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)), + Container( + child: Card( + elevation: 3.0, + shape: cardRadius(12), + margin: EdgeInsets.only( + left: 16, top: 8, right: 16, bottom: 16), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Table( + columnWidths: { + 0: FlexColumnWidth(2.0), + 1: FlexColumnWidth(1.5), + 2: FlexColumnWidth(1.5), + 3: FlexColumnWidth(1.5), + }, + children: fullData(context), ), + ], + ), + ), + ), + ), + Container( + width: double.infinity, + child: Card( + elevation: 3.0, + shape: cardRadius(12), + margin: EdgeInsets.only( + left: 16, top: 8, right: 16, bottom: 16), + child: Padding( + padding: const EdgeInsets.all(15.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ Container( - margin: EdgeInsets.only(top: 10.0, bottom: 10.0), - child: Text(this.grandTotal.toString() + " " + TranslationBase.of(context).sar, - textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)), + margin: EdgeInsets.only(bottom: 10.0), + child: Text(TranslationBase.of(context).cardDetail, + style: TextStyle( + color: Colors.black, + letterSpacing: -0.64, + fontSize: 18.0, + fontWeight: FontWeight.bold)), ), - ]), - ], + myRichText( + TranslationBase.of(context).insuranceCompany + + ": ", + widget.dentalInvoiceDetailResponse + .listEInvoiceForDental[0].companyName, + projectViewModel.isArabic), + myRichText( + TranslationBase.of(context).insuranceID + ": ", + widget + .dentalInvoiceDetailResponse + .listEInvoiceForDental[0] + .insuranceID != + null + ? widget.dentalInvoiceDetailResponse + .listEInvoiceForDental[0].insuranceID + : "N/A", + projectViewModel.isArabic), + ], + ), ), - ]), + ), ), - ), - Container( - margin: EdgeInsets.only(top: 3.0, left: 12.0, right: 12.0), - child: Divider( - color: Colors.grey[400], - thickness: 0.7, + Container( + width: double.infinity, + child: Card( + elevation: 3.0, + shape: cardRadius(12), + margin: EdgeInsets.only( + left: 16, top: 8, right: 16, bottom: 16), + child: Padding( + padding: const EdgeInsets.all(15.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Text( + TranslationBase.of(context).totalBalance, + style: TextStyle( + letterSpacing: -0.64, + color: Colors.black, + fontSize: 18.0, + fontWeight: FontWeight.bold)), + ), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 5), + child: Row( + children: [ + Expanded( + child: _getNormalText( + TranslationBase.of(context).discount), + ), + Expanded( + child: _getNormalText( + this.totalDiscount.toString() + + " " + + TranslationBase.of(context).sar, + isBold: true), + ) + ], + ), + ), + mDivider(Colors.grey[600]), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 5), + child: Row( + children: [ + Expanded( + child: _getNormalText( + TranslationBase.of(context) + .totalVAT + .toString() + + " (" + + widget + .dentalInvoiceDetailResponse + .listEInvoiceForDental[0] + .listConsultation[0] + .vATPercentage + .toString() + + "%): "), + ), + Expanded( + child: _getNormalText( + num.tryParse(this.totalVAT.toString()) + .toStringAsFixed(2) + + " " + + TranslationBase.of(context).sar, + isBold: true), + ) + ], + ), + ), + mDivider(Colors.grey[600]), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 5), + child: Row( + children: [ + Expanded( + child: _getNormalText( + TranslationBase.of(context).total), + ), + Expanded( + child: _getNormalText( + this.subTotal.toString() + + " " + + TranslationBase.of(context).sar, + isBold: true), + ) + ], + ), + ), + mDivider(Colors.grey[600]), + Container( + width: double.infinity, + padding: EdgeInsets.only(top: 10, bottom: 5), + child: Row( + children: [ + Expanded( + child: _getNormalText( + TranslationBase.of(context).paid), + ), + Expanded( + child: _getNormalText( + this.grandTotal.toString() + + " " + + TranslationBase.of(context).sar, + isBold: true), + ) + ], + ), + ), + ], + ), + ), + )), + SizedBox( + height: 100.0, ), - ), - 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(TranslationBase.of(context).dentalInsurance + ": ", 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(TranslationBase.of(context).insuranceID + ": ", 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 != null ? dentalInvoiceDetailResponse.listEInvoiceForDental[0].insuranceID : "N/A", textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold)), - ), - ]), - ]), - ), - SizedBox( - height: 100.0, - ), - ], - ), - ), - ), - bottomSheet: Container( - width: MediaQuery.of(context).size.width, - color: Theme.of(context).scaffoldBackgroundColor, - margin: EdgeInsets.only(left: 15.0, right: 15.0, top: 10.0, bottom: 20.0), - child: DefaultButton(TranslationBase.of(context).sendEmail, () { - showDialog( - context: context, - child: ConfirmSendEmailDialog( - email: projectViewModel.user.emailAddress, - onTapSendEmail: () { - sendInvoiceEmail(); - }, + ], ), - ); - }), - ), - ); + ), + )); } void generateInvoiceDetails() { @@ -211,8 +284,10 @@ class InvoiceDetail extends StatelessWidget { List listConsultations = new List(); - dentalInvoiceDetailResponse.listEInvoiceForDental[0].listConsultation.forEach((item) { - var i = listConsultations.indexWhere((x) => x.procedureID == item.procedureID); + widget.dentalInvoiceDetailResponse.listEInvoiceForDental[0].listConsultation + .forEach((item) { + var i = listConsultations + .indexWhere((x) => x.procedureID == item.procedureID); if (i <= -1) { listConsultations.add(item); } @@ -230,48 +305,92 @@ class InvoiceDetail extends StatelessWidget { } sendInvoiceEmail() { - GifLoaderDialogUtils.showMyDialog(context); + GifLoaderDialogUtils.showMyDialog(widget.context); MyInvoicesService myInvoicesService = new MyInvoicesService(); - myInvoicesService.sendDentalAppointmentInvoiceEmail(listDentalAppointments.projectID, listDentalAppointments.appointmentNo, context).then((res) { - GifLoaderDialogUtils.hideDialog(context); + myInvoicesService + .sendDentalAppointmentInvoiceEmail( + widget.listDentalAppointments.projectID, + widget.listDentalAppointments.appointmentNo, + widget.context) + .then((res) { + GifLoaderDialogUtils.hideDialog(widget.context); if (res['MessageStatus'] == 1) { - AppToast.showSuccessToast(message: TranslationBase.of(context).emailSentSuccessfully); + AppToast.showSuccessToast( + message: TranslationBase.of(widget.context).emailSentSuccessfully); } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { - GifLoaderDialogUtils.hideDialog(context); + GifLoaderDialogUtils.hideDialog(widget.context); print(err); AppToast.showErrorToast(message: err); - Navigator.of(context).pop(); + Navigator.of(widget.context).pop(); }); } List fullData(context) { List tableRow = []; - dentalInvoiceDetailResponse.listEInvoiceForDental[0].listConsultation.forEach((lab) { + + tableRow.add( + TableRow( + children: [ + Utils.tableColumnTitle(TranslationBase.of(context).description), + Utils.tableColumnTitle(TranslationBase.of(context).quantity), + Utils.tableColumnTitle(TranslationBase.of(context).price), + Utils.tableColumnTitle(TranslationBase.of(context).total), + ], + ), + ); + + // widget.dentalInvoiceDetailResponse.listEInvoiceForDental[0].listConsultation + // .forEach((lab) { + for (int i = 0; + i < + widget.dentalInvoiceDetailResponse.listEInvoiceForDental[0] + .listConsultation.length; + i++) { 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() + " " + TranslationBase.of(context).sar, textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontWeight: FontWeight.w400)), - ), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Text(lab.total.toString() + " " + TranslationBase.of(context).sar, textAlign: TextAlign.center, style: TextStyle(color: Colors.black, fontWeight: FontWeight.w400)), - ), + Utils.tableColumnValue( + '${widget.dentalInvoiceDetailResponse.listEInvoiceForDental[0].listConsultation[i].procedureName}', + isLast: i == + (widget.dentalInvoiceDetailResponse.listEInvoiceForDental[0] + .listConsultation.length - + 1)), + Utils.tableColumnValue( + '${widget.dentalInvoiceDetailResponse.listEInvoiceForDental[0].listConsultation[i].quantity}', + isLast: i == + (widget.dentalInvoiceDetailResponse.listEInvoiceForDental[0] + .listConsultation.length - + 1)), + Utils.tableColumnValue( + '${widget.dentalInvoiceDetailResponse.listEInvoiceForDental[0].listConsultation[i].price.toString() + " " + TranslationBase.of(context).sar}', + isLast: i == + (widget.dentalInvoiceDetailResponse.listEInvoiceForDental[0] + .listConsultation.length - + 1)), + Utils.tableColumnValue( + '${widget.dentalInvoiceDetailResponse.listEInvoiceForDental[0].listConsultation[i].total.toString() + " " + TranslationBase.of(context).sar}', + isLast: i == + (widget.dentalInvoiceDetailResponse.listEInvoiceForDental[0] + .listConsultation.length - + 1)), ]), ); - }); + } return tableRow; } + + _getNormalText(text, {bool isBold = false}) { + return Text( + text, + style: TextStyle( + fontSize: isBold ? 14 : 12, + letterSpacing: -0.5, + color: isBold ? Colors.black : Colors.grey[700], + fontWeight: FontWeight.w600, + ), + ); + } } diff --git a/lib/pages/medical/my_invoices/my_invoice_page.dart b/lib/pages/medical/my_invoices/my_invoice_page.dart index 174d6c1d..d13a0599 100644 --- a/lib/pages/medical/my_invoices/my_invoice_page.dart +++ b/lib/pages/medical/my_invoices/my_invoice_page.dart @@ -95,7 +95,8 @@ class _MyInvoicesState extends State { doctor.doctorImageURL = listDentalAppointments.doctorImageURL; doctor.projectID = listDentalAppointments.projectID; doctor.dayName = listDentalAppointments.invoiceNo; - doctor.clinicName = "InvoiceNo: " + listDentalAppointments.invoiceNo.toString(); + doctor.clinicName = listDentalAppointments.invoiceNo.toString(); + doctor.date = listDentalAppointments.appointmentDate; myInvoicesService.getDentalAppointmentInvoice(listDentalAppointments.projectID, listDentalAppointments.appointmentNo, context).then((res) { GifLoaderDialogUtils.hideDialog(context); diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 5fd6cc51..88e8e0e4 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -2306,6 +2306,8 @@ class TranslationBase { String get alreadyRated => localizedValues["alreadyRated"][locale.languageCode]; + String get insuranceCompany => localizedValues["insuranceCompany"][locale.languageCode]; + } class TranslationBaseDelegate extends LocalizationsDelegate {