Merge branch 'development' of https://gitlab.com/Cloud_Solution/diplomatic-quarter into fix-bugs
commit
b59ca8dedd
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="56.51" height="31.024" viewBox="0 0 56.51 31.024">
|
||||
<g id="liveCare_logo_icon_white" transform="translate(-30.848 -483.404)">
|
||||
<path id="Subtraction_64" data-name="Subtraction 64" d="M811.541,968.522h-4.912a6.163,6.163,0,0,1-2.422-.493,6.3,6.3,0,0,1-3.326-3.322,6.123,6.123,0,0,1-.492-2.414V943.726a6.134,6.134,0,0,1,.492-2.42,6.294,6.294,0,0,1,3.321-3.318,6.138,6.138,0,0,1,2.415-.49h23.025a6.137,6.137,0,0,1,2.42.492,6.291,6.291,0,0,1,3.318,3.322,6.146,6.146,0,0,1,.491,2.415v4.578a5.135,5.135,0,0,0,0,9.609v4.366a6.161,6.161,0,0,1-.484,2.423,6.279,6.279,0,0,1-3.314,3.326,6.138,6.138,0,0,1-2.419.492h-5.383a16.214,16.214,0,0,0,1.754-1.74,1.622,1.622,0,0,0,.358-1.281,23.673,23.673,0,0,0,3.34-6.283,22.887,22.887,0,0,0,.909-3.31,16.559,16.559,0,0,0,.317-3.107,10.971,10.971,0,0,0-.49-3.594,4.693,4.693,0,0,0-1.415-2.113,6.726,6.726,0,0,0-2.252-1.177c-.887-.3-1.911-.533-3-.781h0l-.007-.011a1.676,1.676,0,0,0-1.5-.951,1.7,1.7,0,1,0,0,3.4,1.636,1.636,0,0,0,1-.375l.04.015.011,0,.027.006c1.083.25,1.938.446,2.648.677a4.637,4.637,0,0,1,1.688.861,2.889,2.889,0,0,1,.875,1.486,9.923,9.923,0,0,1,.251,2.558,14.326,14.326,0,0,1-.292,2.753,20.686,20.686,0,0,1-.83,2.96,23.036,23.036,0,0,1-1.294,2.939,20.4,20.4,0,0,1-1.688,2.689,1.624,1.624,0,0,0-1.12.542,11.511,11.511,0,0,1-2.422,2.162,5.57,5.57,0,0,1-6.528.009,11.419,11.419,0,0,1-2.42-2.151,1.625,1.625,0,0,0-1.118-.542,20.374,20.374,0,0,1-1.692-2.7,23.179,23.179,0,0,1-1.3-2.945,20.645,20.645,0,0,1-.832-2.964A14.367,14.367,0,0,1,807,952.8a10.047,10.047,0,0,1,.248-2.559,2.876,2.876,0,0,1,.872-1.486,4.6,4.6,0,0,1,1.689-.861c.718-.232,1.622-.439,2.668-.678l.024-.005.006,0,.016-.014a1.68,1.68,0,0,0,1.022.377,1.7,1.7,0,1,0,0-3.4,1.651,1.651,0,0,0-.9.269,1.848,1.848,0,0,0-.617.681l0,0-.022.005c-4.457,1.028-7.146,1.649-7.146,7.674a16.585,16.585,0,0,0,.318,3.11,22.827,22.827,0,0,0,.914,3.316,23.494,23.494,0,0,0,3.365,6.294,1.612,1.612,0,0,0,.359,1.28,16.389,16.389,0,0,0,1.734,1.72h0Zm2.975-17.665a.923.923,0,0,0-.928.88V959a.918.918,0,0,0,.927.877h7.157A.923.923,0,0,0,822.6,959v-7.251a.887.887,0,0,0-.282-.625.975.975,0,0,0-.654-.265Zm41.339,14.421h-2.52a2.17,2.17,0,0,1-1.127-.327l-10.483-6.616a1.036,1.036,0,0,1-.485-.873V956.8a5.128,5.128,0,0,0,0-7.39v-1.163a1.037,1.037,0,0,1,.485-.873l10.483-6.616a2.075,2.075,0,0,1,1.127-.327h2.521a1.038,1.038,0,0,1,1.042,1.03V964.25a1.019,1.019,0,0,1-.3.728,1.042,1.042,0,0,1-.739.3Zm-38.73-6.877-1.683-.007-.532,0h-.005l0-1.741c0-.3.147-.536.35-.55l.917,0c.2-.013.35-.245.35-.552l0-.4c0-.3-.152-.545-.354-.558l-.916,0c-.2-.014-.35-.247-.35-.553l0-1.734h2.235c.2,0,.362.218.371.516l0,1.41c.009.3.166.518.373.518l.466,0c.2,0,.359-.221.369-.526V952.84c.009-.3.171-.528.377-.528h1.54a.932.932,0,0,0,.7-.439l0,2.171c0,.31-.144.545-.344.558l-.916,0c-.2,0-.362.219-.371.521l0,.47c.009.3.163.521.369.521l.911,0c.2.013.352.242.352.544l0,1.739-2.267-.005c-.2,0-.342-.2-.351-.511l0-1.414c0-.305-.148-.536-.352-.549l-.516,0c-.2.013-.343.238-.343.548l0,1.407C817.495,958.177,817.332,958.4,817.125,958.4Z" transform="translate(-769.54 -454.094)" fill="#fff"/>
|
||||
<path id="Path_663" data-name="Path 663" d="M971.268,998.3a2.982,2.982,0,1,1-2.982,2.982h0A2.982,2.982,0,0,1,971.268,998.3Z" transform="translate(-903.129 -502.474)" fill="#fff"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
@ -0,0 +1,147 @@
|
||||
|
||||
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';
|
||||
|
||||
|
||||
class RRTService extends BaseService{
|
||||
|
||||
}
|
||||
class _RRTServiceData{
|
||||
List<PrescriptionsOrder> pendingOrders = [];
|
||||
List<PrescriptionsOrder> completedOrders = [];
|
||||
ServicePrice servicePrice;
|
||||
}
|
||||
|
||||
class RRTViewModel extends BaseViewModel{
|
||||
var _service = RRTService();
|
||||
var _pharmacy_service = locator<PharmacyModuleService>();
|
||||
var _pharmacy_address_service = locator<PharmacyAddressService>();
|
||||
|
||||
_RRTServiceData rrtServiceData = _RRTServiceData();
|
||||
|
||||
Future<_RRTServiceData> loadRequiredData() async{
|
||||
await getServicePrice();
|
||||
await getAllOrders();
|
||||
return rrtServiceData;
|
||||
}
|
||||
|
||||
Future<int> createOrder(Map<String, dynamic> 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 requestNo;
|
||||
}
|
||||
|
||||
// Service ID: 4 == RRT
|
||||
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"] == 5){
|
||||
if(json["Status"] == 1){ // Pending
|
||||
rrtServiceData.pendingOrders.clear();
|
||||
rrtServiceData.pendingOrders.add(PrescriptionsOrder.fromJson(json));
|
||||
}else if (json["Status"] == 3){ // Completed
|
||||
rrtServiceData.completedOrders.clear();
|
||||
rrtServiceData.completedOrders.add(PrescriptionsOrder.fromJson(json));
|
||||
}
|
||||
}
|
||||
return Future.error("404");
|
||||
});
|
||||
}
|
||||
}, onFailure: (error, statusCode){
|
||||
AppToast.showErrorToast(message: error);
|
||||
});
|
||||
return rrtServiceData;
|
||||
}
|
||||
|
||||
|
||||
Future getOrderDetails() async{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Future getAllQuestions() async{
|
||||
dynamic response_;
|
||||
await _service.baseAppClient.post(GET_ALL_RRT_QUESTIONS, body: {}, onSuccess: (response, statusCode){
|
||||
response_ = response;
|
||||
}, onFailure: (error, statusCode){
|
||||
AppToast.showErrorToast(message: error);
|
||||
});
|
||||
return response_;
|
||||
}
|
||||
|
||||
|
||||
Future<ServicePrice> getServicePrice() async{
|
||||
Map<String,dynamic> 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){
|
||||
AppToast.showErrorToast(message: error);
|
||||
});
|
||||
return servicePrice;
|
||||
}
|
||||
|
||||
Future<bool> 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){
|
||||
AppToast.showErrorToast(message: error);
|
||||
success = false;
|
||||
});
|
||||
return Future.value(success);
|
||||
}
|
||||
|
||||
Future getCancelReasons(){
|
||||
}
|
||||
|
||||
Future<List<Addresses>> 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);
|
||||
}
|
||||
}
|
||||
@ -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<String, dynamic> toJson() {
|
||||
var map = <String, dynamic>{};
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
class CovidTestProceduresResponse {
|
||||
String procedureID;
|
||||
String procedureName;
|
||||
String procedureNameN;
|
||||
int projectID;
|
||||
String setupID;
|
||||
|
||||
CovidTestProceduresResponse(
|
||||
{this.procedureID,
|
||||
this.procedureName,
|
||||
this.procedureNameN,
|
||||
this.projectID,
|
||||
this.setupID});
|
||||
|
||||
CovidTestProceduresResponse.fromJson(Map<String, dynamic> json) {
|
||||
procedureID = json['ProcedureID'];
|
||||
procedureName = json['ProcedureName'];
|
||||
procedureNameN = json['ProcedureNameN'];
|
||||
projectID = json['ProjectID'];
|
||||
setupID = json['SetupID'];
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
data['ProcedureID'] = this.procedureID;
|
||||
data['ProcedureName'] = this.procedureName;
|
||||
data['ProcedureNameN'] = this.procedureNameN;
|
||||
data['ProjectID'] = this.projectID;
|
||||
data['SetupID'] = this.setupID;
|
||||
return data;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,489 @@
|
||||
class DentalInvoiceDetailResponse {
|
||||
List<ListEInvoiceForDental> listEInvoiceForDental;
|
||||
|
||||
DentalInvoiceDetailResponse({this.listEInvoiceForDental});
|
||||
|
||||
DentalInvoiceDetailResponse.fromJson(Map<String, dynamic> json) {
|
||||
if (json['List_eInvoiceForDental'] != null) {
|
||||
listEInvoiceForDental = new List<ListEInvoiceForDental>();
|
||||
json['List_eInvoiceForDental'].forEach((v) {
|
||||
listEInvoiceForDental.add(new ListEInvoiceForDental.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
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> 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<String, dynamic> 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<ListConsultation>();
|
||||
json['listConsultation'].forEach((v) {
|
||||
listConsultation.add(new ListConsultation.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
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<String, dynamic> 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<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,100 @@
|
||||
class GetDentalAppointmentsResponse {
|
||||
List<ListDentalAppointments> listDentalAppointments;
|
||||
|
||||
GetDentalAppointmentsResponse({this.listDentalAppointments});
|
||||
|
||||
GetDentalAppointmentsResponse.fromJson(Map<String, dynamic> json) {
|
||||
if (json['List_DentalAppointments'] != null) {
|
||||
listDentalAppointments = new List<ListDentalAppointments>();
|
||||
json['List_DentalAppointments'].forEach((v) {
|
||||
listDentalAppointments.add(new ListDentalAppointments.fromJson(v));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
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<String, dynamic> 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<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -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<String, dynamic> toJson() {
|
||||
var map = <String, dynamic>{};
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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<StatefulWidget> createState() => DoctorPostPreImagesPageState();
|
||||
}
|
||||
|
||||
class DoctorPostPreImagesPageState extends State<DoctorPostPreImagesPage>{
|
||||
|
||||
@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<DoctorPostPreImagesContent>{
|
||||
|
||||
@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),
|
||||
);
|
||||
},)
|
||||
],
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@ -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)),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
}
|
||||
@ -0,0 +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<PrescriptionsOrder> orders;
|
||||
|
||||
const RRTLogPage({this.orders});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => RRTLogPageState();
|
||||
|
||||
}
|
||||
class RRTLogPageState extends State<RRTLogPage>{
|
||||
|
||||
RRTViewModel viewModel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return BaseView<RRTViewModel>(
|
||||
onModelReady: (vm) => viewModel = vm,
|
||||
builder: (ctx, vm, widgetState){
|
||||
return ListView.builder(
|
||||
itemCount: widget.orders.length,
|
||||
itemBuilder: (ctx, idx) {
|
||||
var order = widget.orders[idx];
|
||||
return RRTLogListItem(order, onCancel: deleteOrder);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
deleteOrder(PrescriptionsOrder order) async {
|
||||
GifLoaderDialogUtils.showMyDialog(context);
|
||||
var success = await viewModel.cancelOrder(order);
|
||||
GifLoaderDialogUtils.hideDialog(context);
|
||||
if(success)
|
||||
setState(() {
|
||||
widget.orders.remove(order);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,108 @@
|
||||
|
||||
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';
|
||||
|
||||
class RRTMainScreen extends StatefulWidget{
|
||||
@override
|
||||
State<StatefulWidget> createState() => RRTMainScreenState();
|
||||
}
|
||||
|
||||
class RRTMainScreenState extends State<RRTMainScreen> with SingleTickerProviderStateMixin{
|
||||
|
||||
int currentIndex = 0;
|
||||
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: localize.rapidResponseTeam,
|
||||
isShowAppBar: true,
|
||||
body: BaseView<RRTViewModel>(
|
||||
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(
|
||||
margin: EdgeInsets.all(15),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(10)),
|
||||
child: TabBar(
|
||||
onTap: onPageChanged,
|
||||
indicatorWeight: 3,
|
||||
indicatorColor: Color(0xFFc5272d),
|
||||
isScrollable: false,
|
||||
controller: tabController,
|
||||
indicatorSize: TabBarIndicatorSize.label,
|
||||
tabs: [
|
||||
Tab(
|
||||
child: Text(localize.rapidResponseTeam, style: TextStyle(color: Theme.of(context).appBarTheme.color),),
|
||||
),
|
||||
Tab(
|
||||
child: Text(localize.orderLog, style: TextStyle(color: Theme.of(context).appBarTheme.color),),
|
||||
),
|
||||
]
|
||||
),
|
||||
);
|
||||
|
||||
Widget contentPager() => PageView(
|
||||
onPageChanged: onPageChanged,
|
||||
controller: pageController,
|
||||
children: [
|
||||
RRTRequestPage(servicePrice: viewModel.rrtServiceData.servicePrice, pendingOrders: viewModel.rrtServiceData.pendingOrders),
|
||||
RRTLogPage(orders: viewModel.rrtServiceData.completedOrders),
|
||||
],
|
||||
);
|
||||
|
||||
void onPageChanged(int index) {
|
||||
pageController.animateToPage(index, duration: Duration(milliseconds: 200), curve: Curves.easeInOut);
|
||||
tabController.animateTo(index);
|
||||
}
|
||||
}
|
||||
@ -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),),
|
||||
|
||||
);
|
||||
}
|
||||
@ -0,0 +1,252 @@
|
||||
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<StatefulWidget> createState() => RRTRequestPickupAddressPageState();
|
||||
|
||||
}
|
||||
class RRTRequestPickupAddressPageState extends State<RRTRequestPickupAddressPage> with SingleTickerProviderStateMixin{
|
||||
bool acceptTerms = false;
|
||||
|
||||
bool mapIdle = true;
|
||||
Completer<GoogleMapController> mapController = Completer();
|
||||
CameraPosition mapCameraPosition = CameraPosition(
|
||||
target: LatLng(24.7114693, 46.67469582),
|
||||
zoom: 14.4746,
|
||||
);
|
||||
|
||||
|
||||
List<Addresses> myAddresses = [];
|
||||
Addresses selectedAddress;
|
||||
StreamController<int> addressStreamController = StreamController();
|
||||
Stream<int> addressStream;
|
||||
StreamController<int> addressLoadingStreamController = StreamController();
|
||||
Stream<int> 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) {
|
||||
localize = TranslationBase.of(context);
|
||||
ProjectViewModel projectViewModel = Provider.of(context);
|
||||
|
||||
addressStreamController.sink.add(0);
|
||||
|
||||
return BaseView<RRTViewModel>(
|
||||
onModelReady: (vm){
|
||||
viewModel = vm;
|
||||
loadAddresses();
|
||||
},
|
||||
builder: (ctx, vm, widget) => AppScaffold(
|
||||
appBarTitle: localize.pickupLocation,
|
||||
isShowAppBar: true,
|
||||
body: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
StreamBuilder<Object>(
|
||||
stream: addressStream,
|
||||
builder: (context, snapshot) {
|
||||
return selectAddressField();
|
||||
}
|
||||
),
|
||||
StreamBuilder<Object>(
|
||||
stream: addressLoadingStream,
|
||||
builder: (context, snapshot) {
|
||||
return snapshot.hasData ? LinearProgressIndicator(backgroundColor: Colors.transparent) : Container(height: 4,);
|
||||
}
|
||||
),
|
||||
Expanded(
|
||||
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()
|
||||
],
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Widget centerTargetPoint(){
|
||||
double size = mapIdle ? 20 : 30;
|
||||
double margin = mapIdle ? 3 : 10;
|
||||
return Center(
|
||||
child: Container(
|
||||
width: size, height: size,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(20), border: Border.all(width: 2, color: Theme.of(context).appBarTheme.color)
|
||||
),
|
||||
child: Container(
|
||||
margin: EdgeInsets.all(margin),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).appBarTheme.color,
|
||||
borderRadius: BorderRadius.circular(20))
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget selectAddressField(){
|
||||
var text = selectedAddress == null ? localize.selectAddress : selectedAddress.toString();
|
||||
return Container(
|
||||
margin: EdgeInsets.all(10),
|
||||
height: 50,
|
||||
child: MaterialButton(
|
||||
height: 50, color: Colors.white,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10) ),
|
||||
onPressed: openAddressSelectDialog,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(child: Text(text, style: TextStyle(color: Colors.grey, fontSize: 13, letterSpacing: 1))),
|
||||
Icon(Icons.keyboard_arrow_down, size: 20, color: Colors.grey,)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget continueButton(){
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: MaterialButton(
|
||||
height: 50,
|
||||
color: Theme.of(context).appBarTheme.color,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10) ),
|
||||
onPressed: () =>
|
||||
Navigator.push(
|
||||
context,
|
||||
FadePage(page: RRTPlaceOrderPage(selectedAddress: selectedAddress, servicePrice: widget.servicePrice,))
|
||||
),
|
||||
child: Text(localize.continues, style: TextStyle(color: Colors.white, fontSize: 15, letterSpacing: 1),),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
openAddressSelectDialog(){
|
||||
showMaterialResponsiveDialog(
|
||||
hideButtons: true,
|
||||
context: context,
|
||||
title: localize.selectAddress,
|
||||
child: ListView.separated(
|
||||
shrinkWrap: true,
|
||||
padding: EdgeInsets.all(10),
|
||||
itemCount: myAddresses.length,
|
||||
itemBuilder: (ctx,idx) {
|
||||
var itm = myAddresses[idx];
|
||||
return ListTile(
|
||||
title: Text(itm.toString()),
|
||||
onTap: (){
|
||||
setState(() {
|
||||
selectedAddress = itm;
|
||||
Navigator.pop(context);
|
||||
if(itm.latLong != null && itm.latLong.isNotEmpty && itm.latLong.split(',').length > 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');
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
separatorBuilder: (ctx,idx) => 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);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,195 @@
|
||||
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/ErService/rapid-response-team/rrt-main-screen.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/uitl/utils.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<RRTViewModel>(
|
||||
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<String, dynamic> 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: '',
|
||||
confirmMessage: localize.rrtOrderSuccessMessage,
|
||||
okText: localize.ok,
|
||||
okFunction: (){
|
||||
AlertDialogBox.closeAlertDialog(_context);
|
||||
gotoRRTRoot();
|
||||
}
|
||||
).showAlertDialog(_context);
|
||||
}
|
||||
}else{
|
||||
AppToast.showErrorToast(message: 'Invalid location selected');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gotoRRTRoot(){
|
||||
Navigator.popUntil(_context, (route) => Utils.route(route, equalsTo: ErOptions));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,239 @@
|
||||
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';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class RRTRequestPage extends StatefulWidget{
|
||||
|
||||
final List<PrescriptionsOrder> pendingOrders;
|
||||
final ServicePrice servicePrice;
|
||||
|
||||
RRTRequestPage({this.pendingOrders, this.servicePrice});
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => RRTRequestPageState();
|
||||
|
||||
}
|
||||
class RRTRequestPageState extends State<RRTRequestPage>{
|
||||
bool acceptTerms = false;
|
||||
|
||||
TranslationBase localize;
|
||||
RRTViewModel viewModel;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
localize = TranslationBase.of(context);
|
||||
return BaseView<RRTViewModel>(
|
||||
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)
|
||||
),
|
||||
|
||||
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);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
Widget serviceDescription(BuildContext context) =>
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Text(
|
||||
localize.rrtDDetails,
|
||||
textAlign: TextAlign.justify,
|
||||
style: TextStyle(color: Theme.of(context).appBarTheme.color, fontSize: 15, height: 1.5, fontWeight: FontWeight.w300),
|
||||
),
|
||||
);
|
||||
|
||||
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(localize.approximateServiceFee, style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.w500, letterSpacing: 1))),
|
||||
),
|
||||
|
||||
pricingRow(label: localize.amountBeforeTax, value: '$amount ${localize.sar}'),
|
||||
Container(height: 0.5, color: Theme.of(context).appBarTheme.color),
|
||||
|
||||
pricingRow(label: localize.taxAmount, value: '$vat ${localize.sar}'),
|
||||
Container(height: 0.5, color: Theme.of(context).appBarTheme.color),
|
||||
|
||||
pricingRow(label: localize.totalAmountPayable, value: '$total ${localize.sar}', labelBold: true),
|
||||
Container(height: 0.5, color: Theme.of(context).appBarTheme.color),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget pricingRow({@required String label, @required String value, bool labelBold = false, bool valueBold = false}){
|
||||
return
|
||||
Container(
|
||||
height: 40, margin: EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(label, style: TextStyle(fontSize: 13, color: Theme.of(context).appBarTheme.color, fontWeight: labelBold ? FontWeight.bold : FontWeight.normal)),
|
||||
Spacer(),
|
||||
Container(height: 40, color: Theme.of(context).appBarTheme.color, width: 0.5,),
|
||||
Container(
|
||||
alignment: Alignment.center,
|
||||
width: MediaQuery.of(context).size.width * 0.25,
|
||||
child: Text(value, style: TextStyle(fontSize: 13, color: Theme.of(context).appBarTheme.color, fontWeight: valueBold ? FontWeight.bold : FontWeight.normal))
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Widget acceptPolicy(){
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Checkbox(value: acceptTerms, onChanged: (v){
|
||||
setState(() => acceptTerms = v);
|
||||
}),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
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(localize.clickHere, style: TextStyle(fontSize: 12, color: Colors.blue, fontWeight: FontWeight.w400)),
|
||||
onPressed: (){
|
||||
Navigator.push(
|
||||
context,
|
||||
FadePage(
|
||||
page: RRTAgreementPage()));
|
||||
}
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget paymentOptions()=> Container(
|
||||
height: 30,
|
||||
alignment: Alignment.center,
|
||||
child: Image.asset("assets/payment_options/payment_options.png", fit: BoxFit.fill,)
|
||||
);
|
||||
|
||||
Widget actionButtons(){
|
||||
return Container(
|
||||
margin: EdgeInsets.all(15),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: MaterialButton(
|
||||
height: 50,
|
||||
color: Theme.of(context).appBarTheme.color,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10) ),
|
||||
onPressed: () { },
|
||||
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(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);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
import 'package:diplomaticquarterapp/core/model/feedback/COC_items.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/data_display/text.dart';
|
||||
import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
|
||||
|
||||
class FeedbackDetails extends StatelessWidget {
|
||||
final COCItem items;
|
||||
|
||||
FeedbackDetails({
|
||||
@required this.items,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppScaffold(
|
||||
isShowAppBar: true,
|
||||
appBarTitle: TranslationBase.of(context).feedbackTitle,
|
||||
body: Container(
|
||||
margin: EdgeInsets.all(5),
|
||||
padding: EdgeInsets.all(5),
|
||||
color: Colors.white,
|
||||
child: Table(
|
||||
border: TableBorder.all(),
|
||||
columnWidths: const <int, TableColumnWidth>{
|
||||
0: IntrinsicColumnWidth(),
|
||||
1: FlexColumnWidth(),
|
||||
2: FixedColumnWidth(64),
|
||||
},
|
||||
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
||||
children: <TableRow>[
|
||||
TableRow(
|
||||
children: [
|
||||
getColumnText(TranslationBase.of(context).feedbackTitle),
|
||||
getColumnText(items.cOCTitle)
|
||||
],
|
||||
),
|
||||
TableRow(
|
||||
children: [
|
||||
getColumnText(TranslationBase.of(context).complaint),
|
||||
getColumnText(items.cOCID)
|
||||
],
|
||||
),
|
||||
TableRow(
|
||||
children: [
|
||||
getColumnText(TranslationBase.of(context).date),
|
||||
getColumnText(items.date)
|
||||
],
|
||||
),
|
||||
TableRow(
|
||||
children: [
|
||||
getColumnText(TranslationBase.of(context).type),
|
||||
getColumnText(items.formType)
|
||||
],
|
||||
)
|
||||
])));
|
||||
}
|
||||
|
||||
Widget getColumnText(value) {
|
||||
return Container(child: Texts(value), padding: EdgeInsets.all(5));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,339 @@
|
||||
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';
|
||||
|
||||
class InvoiceDetail extends StatelessWidget {
|
||||
final DoctorList doctor;
|
||||
final ListDentalAppointments listDentalAppointments;
|
||||
final DentalInvoiceDetailResponse dentalInvoiceDetailResponse;
|
||||
final BuildContext context;
|
||||
|
||||
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: 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("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<TableRow> fullData(context) {
|
||||
List<TableRow> 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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,256 @@
|
||||
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';
|
||||
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<MyInvoices> {
|
||||
bool isDataLoaded = false;
|
||||
GetDentalAppointmentsResponse getDentalAppointmentsResponse;
|
||||
DentalInvoiceDetailResponse dentalInvoiceDetailResponse;
|
||||
|
||||
@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: true,
|
||||
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) {
|
||||
GifLoaderDialogUtils.showMyDialog(context);
|
||||
MyInvoicesService myInvoicesService = new MyInvoicesService();
|
||||
|
||||
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();
|
||||
|
||||
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() {
|
||||
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);
|
||||
} else {
|
||||
AppToast.showErrorToast(message: res['ErrorEndUserMessage']);
|
||||
}
|
||||
isDataLoaded = true;
|
||||
});
|
||||
}).catchError((err) {
|
||||
GifLoaderDialogUtils.hideDialog(context);
|
||||
print(err);
|
||||
AppToast.showErrorToast(message: err);
|
||||
Navigator.of(context).pop();
|
||||
});
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue