diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index c869f0dc..aac9b8b5 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -4,13 +4,14 @@ class URLs { static const String appReleaseBuildNumber = "28"; // static const host1 = "https://atomsm.hmg.com"; // production url - // static const host1 = "https://atomsmdev.hmg.com"; // local DEV url - static const host1 = "https://atomsmuat.hmg.com"; // local UAT url + static const host1 = "https://atomsmdev.hmg.com"; // local DEV url + // static const host1 = "https://atomsmuat.hmg.com"; // local UAT url // static const host1 = "http://10.201.111.125:9495"; // temporary Server UAT url // static String _baseUrl = "$_host/mobile"; - static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis + // static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis + static final String _baseUrl = "$_host/v6/mobile"; // for asset delivery module // static final String _baseUrl = "$_host/mobile"; // host local UAT and for internal audit dev // static final String _baseUrl = "$_host/v3/mobile"; // v3 for production CM,PM,TM // static final String _baseUrl = "$_host/v5/mobile"; // v5 for data segregation @@ -391,4 +392,44 @@ class URLs { static get getLoanById => '$_baseUrl/Loan/GetLoanById'; static get addLoan => '$_baseUrl/Loan/AddLoan'; + + //Asset Delivery Module + //AssetDeliveryExternal/GetAssetDeliveryExternalById + static get getAssetDeliveryDetailsById => '$_baseUrl/AssetDeliveryExternal/GetAssetDeliveryExternalById'; + + static get getAssetDeliveryTableListById => '$_baseUrl/AssetDeliveryExternalDelivery/GetDeliveriesByMasterId'; + + static get addNewDelivery => '$_baseUrl/AssetDeliveryExternalDelivery/AddNewDelivery'; + + static get changeDeliveryStatusToCancel => '$_baseUrl/AssetDeliveryExternalDelivery/ChangeStatusDeliveryToCancel'; + + static get changeDeliveryStatus => '$_baseUrl/AssetDeliveryExternalDelivery/ChangeStatusDelivery'; + + static get getAssetDeliveryInspectionData => '$_baseUrl/AssetDeliveryExternalDeliveryInspection/GetAssetDeliveryExternalDeliveryInspectionByDeliveryId'; + + static get getOracleUserList => '$_baseUrl/AssetDeliveryExternal/GetEmployeesFromOracle'; + + static get getLineFromExternalPo => '$_baseUrl/AssetDeliveryExternalDeliveryInspection/GetLineFromExternalPo'; + static get getCostCenterListToLineDeliveryInspection => '$_baseUrl/AssetDeliveryExternalDeliveryInspection/GetCostCenterToLineDeliveryInspection'; + static get getCostCenterToPo => '$_baseUrl/AssetDeliveryExternalDeliveryInspection/GetCostCenterToPo'; + static get saveCostCenterToLineDeliveryInspection => '$_baseUrl/AssetDeliveryExternalDeliveryInspection/SaveCostCenterToLineDeliveryInspection'; + static get getDeliveryHistories => '$_baseUrl/AssetDeliveryExternalDelivery/GetDeliveryHistories'; + //Technical Inscption... + static get getLineFromTechnicalInspection => '$_baseUrl/AssetDeliveryExternalTechnicalInspection/GetLineFromDeliveryInspection'; + static get getTechnicalInspectionByDetailId => '$_baseUrl/AssetDeliveryExternalTechnicalInspection/GetTechnicalInspectionByDetailId'; + static get powerSupplyTypeLookUp => "$_baseUrl/Lookups/GetLookup?lookupEnum=527"; + static get saveTechnicalInspection => "$_baseUrl/AssetDeliveryExternalTechnicalInspection/SaveTechnicalInspection"; + static get getTechnicalInspectionParentData => "$_baseUrl/AssetDeliveryExternalTechnicalInspection/GetTechnicalInspectionItemByCostCenterId"; + static get getAssetFromInternalTechnicalInspection => "$_baseUrl/AssetDeliveryExternalTechnicalInspection/GetAssetFromInternal"; + static get getAssetDetailsByAssetId => "$_baseUrl/AssetDeliveryExternalTechnicalInspection/GetAssetByIdFromInternal"; + static get saveTechnicalInspectionAsset => "$_baseUrl/AssetDeliveryExternalTechnicalInspection/SaveTechnicalInspectionItem"; + static get getAttachments => "$_baseUrl/AssetDeliveryExternalDeliveryAttachment/GetAttachments"; + static get saveAttachments => "$_baseUrl/AssetDeliveryExternalDeliveryAttachment/Save"; + //End user Acceptance... + static get getEndUserAcceptanceCostCenter => "$_baseUrl/AssetDeliveryEndUserAcceptance/GetEndUserAcceptanceCostCenter"; + static get getCostCenterAssetList => "$_baseUrl/AssetDeliveryEndUserAcceptance/GetItemByCostCenter"; + static get saveEndUserFormData => "$_baseUrl/AssetDeliveryEndUserAcceptance/SaveMaster"; + static get saveEndUserAssetData => "$_baseUrl/AssetDeliveryEndUserAcceptance/SaveDetail"; + static get endUserStatusLookup => "$_baseUrl/Lookups/GetLookup?lookupEnum=534"; + static get endUserRejectionReasonLookup => "$_baseUrl/Lookups/GetLookup?lookupEnum=5007"; } diff --git a/lib/controllers/providers/api/devices_provider.dart b/lib/controllers/providers/api/devices_provider.dart index 3d031a61..ab196c11 100644 --- a/lib/controllers/providers/api/devices_provider.dart +++ b/lib/controllers/providers/api/devices_provider.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:developer'; import 'package:flutter/cupertino.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -10,6 +11,7 @@ import 'package:test_sa/models/device/asset_by_id_model.dart'; import 'package:test_sa/models/device/asset_search.dart'; import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/user.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/technical_inpection_asset_model.dart'; import '../../../models/device/asset.dart'; @@ -38,6 +40,7 @@ class AssetProvider extends ChangeNotifier { List _devices = []; List _searchDevices = []; + List technicalInspectionAsset= []; List get devices => _devices; @@ -99,6 +102,49 @@ class AssetProvider extends ChangeNotifier { return response.statusCode; } + Future getAssetsForAssetDelivery({DeviceSearch? search, bool isSearchBy = false, int? lineId}) async { + if (_loading == true) return -2; + _loading = true; + notifyListeners(); + late Response response; + try { + final Map body = { + "pageSize": isSearchBy ? searchPageItemNumber : pageItemNumber, + "pageNumber": isSearchBy ? (searchDevices.length / searchPageItemNumber).ceil() + 1 : devices.length ~/ pageItemNumber + 1, + + ///Uncommit this after testing... + "assetDeliveryExternalDetailId": lineId, + "assetName": search?.assetName, + + // "assetDeliveryExternalDetailId": 2, + // "assetName": "Treatment Center Intego - Dental Chair", + "assetNumber": search?.assetNo, + "model": search?.model, + "manufacturer": search?.manufacturer, + }; + response = await ApiManager.instance.post(URLs.getAssetFromInternalTechnicalInspection, body: body); + } catch (error) { + _loading = false; + _stateCode = -1; + notifyListeners(); + return -1; + } + _stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + List equipmentListJson = json.decode(response.body)["data"]; + var dList = equipmentListJson.map((asset) => TechnicalInspectionAssetBasicInfoModel.fromJson(asset)).toList() ?? []; + log('dlist ${dList.length}'); + + technicalInspectionAsset.addAll(dList); + nextPage = true; + } else { + nextPage = false; + } + _loading = false; + notifyListeners(); + return response.statusCode; + } + Future getAssetById(int assetId, AppLocalizations appLocalizations) async { late Response response; try { diff --git a/lib/extensions/enum_extensions.dart b/lib/extensions/enum_extensions.dart index c6d10640..747e2080 100644 --- a/lib/extensions/enum_extensions.dart +++ b/lib/extensions/enum_extensions.dart @@ -121,3 +121,7 @@ extension StringExtensionsRecurrentTaskInpesctionDataType on String { } } } +enum DropDownMatchType { + identifier, + name, +} diff --git a/lib/main.dart b/lib/main.dart index d4544472..ceff381d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -27,6 +27,11 @@ import 'package:test_sa/controllers/providers/api/status_drop_down/report/servic import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_repair_location_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_types_provider.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/cost_center_provider.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/end_user_rejection_reason_lookup_provider.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/end_user_status_lookup_provider.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/power_supply_type_provider.dart'; import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart'; import 'package:test_sa/modules/cm_module/cm_detail_provider.dart'; import 'package:test_sa/modules/cm_module/create_cm_request.dart'; @@ -316,6 +321,11 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider(create: (_) => LoanProvider()), ChangeNotifierProvider(create: (_) => LoanPeriodProvider()), ChangeNotifierProvider(create: (_) => MedicalDepartmentProvider()), + ChangeNotifierProvider(create: (_) => AssetDeliveryProvider()), + ChangeNotifierProvider(create: (_) => CostCenterProvider()), + ChangeNotifierProvider(create: (_) => PowerSupplyTypeProvider()), + ChangeNotifierProvider(create: (_) => EndUserStatusLookupProvider()), + ChangeNotifierProvider(create: (_) => EndUserRejectionReasonLookupProvider()), ], child: GestureDetector( onTap: () { diff --git a/lib/models/all_requests_and_count_model.dart b/lib/models/all_requests_and_count_model.dart index e980e164..95f19030 100644 --- a/lib/models/all_requests_and_count_model.dart +++ b/lib/models/all_requests_and_count_model.dart @@ -128,6 +128,8 @@ class RequestsDetails { String? date; String? siteTransferFrom; String? siteTransferTo; + String? poInternal; + String? poExternal; int? transactionType; int? numberOfAssets; int? numberOfSites; @@ -156,6 +158,8 @@ class RequestsDetails { this.code, this.siteTransferFrom, this.siteTransferTo, + this.poInternal, + this.poExternal, this.date, this.transactionType}); @@ -182,6 +186,8 @@ class RequestsDetails { assetTransferTo = json['assetTransferTo']; code = json['code']; date = json['date']; + poInternal = json['poInternal']; + poExternal = json['poExternal']; siteTransferFrom = json['siteTransferFrom']; siteTransferTo = json['siteTransferTo']; transactionType = json['transactionType']; diff --git a/lib/models/device/asset_search.dart b/lib/models/device/asset_search.dart index f311b208..1a70196b 100644 --- a/lib/models/device/asset_search.dart +++ b/lib/models/device/asset_search.dart @@ -1,6 +1,7 @@ import 'package:test_sa/models/lookup.dart'; class DeviceSearch { + DeviceSearch( {this.code, this.assetSerialNumber, diff --git a/lib/models/generic_attachment_model.dart b/lib/models/generic_attachment_model.dart index 1d3cd5ea..c0c2b4cf 100644 --- a/lib/models/generic_attachment_model.dart +++ b/lib/models/generic_attachment_model.dart @@ -8,7 +8,6 @@ class GenericAttachmentModel { String ?createdBy; String? originalName; GenericAttachmentModel.fromJson(Map json) { - print('created by here is ${json['createdBy']}'); id = json['id']; name = json['name']; createdBy = json['createdBy']; diff --git a/lib/models/new_models/dashboard_detail.dart b/lib/models/new_models/dashboard_detail.dart index 093019b2..7c39d4ce 100644 --- a/lib/models/new_models/dashboard_detail.dart +++ b/lib/models/new_models/dashboard_detail.dart @@ -55,6 +55,8 @@ class Data { String? assetNumber; String? requestTypeName; String? requestNo; + String? poInternal; + String? poExternal; int? transactionNo; int? numberOfSites; int? numberOfAssets; @@ -75,6 +77,8 @@ class Data { this.assetNumber, this.requestTypeName, this.requestNo, + this.poExternal, + this.poInternal, this.transactionNo}); Data.fromJson(Map json) { @@ -93,6 +97,8 @@ class Data { requestNo = json['requestNo']; rejectReason = json['rejectReason']; transactionNo = json['transactionNo']; + poInternal = json['poInternal']; + poExternal = json['poExternal']; nameOfType = json['nameOfType']; } diff --git a/lib/modules/asset_delivery_module/models/asset_delivery_data_model.dart b/lib/modules/asset_delivery_module/models/asset_delivery_data_model.dart new file mode 100644 index 00000000..08de3111 --- /dev/null +++ b/lib/modules/asset_delivery_module/models/asset_delivery_data_model.dart @@ -0,0 +1,383 @@ +import 'package:test_sa/models/lookup.dart'; + +class AssetDeliveryDataModel { + int? id; + bool? isHMG; + int? operatingUnitId; + String? operatingUnit; + String? clientName; + int? poNumberId; + int? poNumber; + SiteModel? site; + Lookup? paymentTerm; + num? paymentTermAmount; + num? deliveryAmount; + num? total; + num? totalInvoice; + String? edd; + double? warrentyPeriod; + + AssetDeliveryInternalMaster? assetDeliveryInternalMaster; + PurchaseOrderMaster? purchaseOrderMaster; + List? assetDeliveryExternalDetails; + List? assetDeliveryExternalDeliveries; + + AssetDeliveryDataModel(); + + AssetDeliveryDataModel.fromJson(Map json) { + id = json['id']; + isHMG = json['isHMG']; + operatingUnitId = json['operatingUnitId']; + clientName = json['clientName']; + operatingUnit = json['operatingUnit']; + poNumberId = json['poNumberId']; + poNumber = json['poNumber']; + total = json['total']; + totalInvoice = json['totalInvoice']; + edd = json['edd']; + deliveryAmount = json['deliveryAmount']; + site = json['site'] != null + ? SiteModel.fromJson(json['site']) + : null; + paymentTerm = json['paymentTerm'] != null + ? Lookup.fromJson(json['paymentTerm']) + : null; + paymentTermAmount = json['paymentTermAmount']; + warrentyPeriod = json['warrentyPeriod']; + + assetDeliveryInternalMaster = json['assetDeliveryInternalMaster'] != null + ? AssetDeliveryInternalMaster.fromJson(json['assetDeliveryInternalMaster']) + : null; + purchaseOrderMaster = json['purchaseOrderMaster'] != null + ? PurchaseOrderMaster.fromJson(json['purchaseOrderMaster']) + : null; + + if (json['assetDeliveryExternalDetails'] != null) { + assetDeliveryExternalDetails = []; + json['assetDeliveryExternalDetails'].forEach((v) { + assetDeliveryExternalDetails!.add(AssetDeliveryExternalDetail.fromJson(v)); + }); + } + + if (json['assetDeliveryExternalDeliveries'] != null) { + assetDeliveryExternalDeliveries = []; + json['assetDeliveryExternalDeliveries'].forEach((v) { + assetDeliveryExternalDeliveries!.add(AssetDeliveryTableModel.fromJson(v)); + }); + } + } + + Map toJson() { + final data = {}; + + data['id'] = id; + data['isHMG'] = isHMG; + data['operatingUnitId'] = operatingUnitId; + data['operatingUnit'] = operatingUnit; + data['clientName'] = clientName; + data['poNumberId'] = poNumberId; + data['poNumber'] = poNumber; + data['total'] = total; + data['edd'] = edd; + data['totalInvoice'] = totalInvoice; + data['deliveryAmount'] = deliveryAmount; + data['site'] = site; + data['paymentTermAmount'] = paymentTermAmount; + data['warrentyPeriod'] = warrentyPeriod; + + if (paymentTerm != null) data['paymentTerm'] = paymentTerm!.toJson(); + if (assetDeliveryInternalMaster != null) { + data['assetDeliveryInternalMaster'] = + assetDeliveryInternalMaster!.toJson(); + } + if (assetDeliveryExternalDetails != null) { + data['assetDeliveryExternalDetails'] = + assetDeliveryExternalDetails!.map((v) => v.toJson()).toList(); + } + if (assetDeliveryExternalDeliveries != null) { + data['assetDeliveryExternalDeliveries'] = + assetDeliveryExternalDeliveries!.map((v) => v.toJson()).toList(); + } + + return data; + } +} + + +class AssetDeliveryInternalMaster { + int? id; + int? operatingUnitId; + String? operatingUnit; + int? poNumberId; + int? poNumber; + String? supplier; + String? supplierSite; + String? type; + String? buyer; + num? total; + String? currency; + String? remark; + String? status; + String? paymentTerms; + double? warrantyPeriod; + String? assetDeliveryStatus; + String? statusDocument; + String? remarkDocument; + String? edd; + + AssetDeliveryInternalMaster(); + + AssetDeliveryInternalMaster.fromJson(Map json) { + id = json['id']; + operatingUnitId = json['operatingUnitId']; + operatingUnit = json['operatingUnit']; + poNumberId = json['poNumberId']; + poNumber = json['poNumber']; + supplier = json['supplier']; + supplierSite = json['supplierSite']; + type = json['type']; + buyer = json['buyer']; + total = json['total']; + currency = json['currency']; + remark = json['remark']; + status = json['status']; + paymentTerms = json['paymentTerms']; + warrantyPeriod = json['warrantyPeriod']; + assetDeliveryStatus = json['assetDeliveryStatus']; + statusDocument = json['statusDocument']; + remarkDocument = json['remarkDocument']; + edd = json['edd']; + } + + Map toJson() { + return { + 'id': id, + 'operatingUnitId': operatingUnitId, + 'operatingUnit': operatingUnit, + 'poNumberId': poNumberId, + 'poNumber': poNumber, + 'supplier': supplier, + 'supplierSite': supplierSite, + 'type': type, + 'buyer': buyer, + 'total': total, + 'currency': currency, + 'remark': remark, + 'status': status, + 'paymentTerms': paymentTerms, + 'warrantyPeriod': warrantyPeriod, + 'assetDeliveryStatus': assetDeliveryStatus, + 'statusDocument': statusDocument, + 'remarkDocument': remarkDocument, + 'edd': edd, + }; + } +} + +class AssetDeliveryExternalDetail { + int? id; + AssetDeliveryInternalDetail? assetDeliveryInternalDetail; + String? itemNumber; + String? lineType; + String? unitMeasure; + num? qtyOrdered; + num? qtyReceived; + num? qtyBilled; + num? qtyCancelled; + num? unitPrice; + num? unitPriceWithTax; + String? itemDescription; + + AssetDeliveryExternalDetail(); + + AssetDeliveryExternalDetail.fromJson(Map json) { + id = json['id']; + itemNumber = json['itemNumber']; + lineType = json['lineType']; + unitMeasure = json['unitMeasure']; + qtyOrdered = json['qtyOrdered']; + qtyReceived = json['qtyReceived']; + qtyBilled = json['qtyBilled']; + qtyCancelled = json['qtyCancelled']; + unitPrice = json['unitPrice']; + unitPriceWithTax = json['unitPriceWithTax']; + itemDescription = json['itemDescription']; + + assetDeliveryInternalDetail = + json['assetDeliveryInternalDetail'] != null + ? AssetDeliveryInternalDetail.fromJson( + json['assetDeliveryInternalDetail']) + : null; + } + + Map toJson() { + return { + 'id': id, + 'itemNumber': itemNumber, + 'lineType': lineType, + 'unitMeasure': unitMeasure, + 'qtyOrdered': qtyOrdered, + 'qtyReceived': qtyReceived, + 'qtyBilled': qtyBilled, + 'qtyCancelled': qtyCancelled, + 'unitPrice': unitPrice, + 'unitPriceWithTax': unitPriceWithTax, + 'itemDescription': itemDescription, + 'assetDeliveryInternalDetail': + assetDeliveryInternalDetail?.toJson(), + }; + } +} + +class AssetDeliveryInternalDetail { + int? id; + int? lineId; + String? itemNumber; + String? itemDescription; + String? unitMeasure; + num? qtyOrdered; + num? qtyReceived; + num? qtyBilled; + num? qtyCancelled; + num? unitPrice; + num? unitPriceWithTax; + String? itemCategory; + num? totalAssets; + num? childPerAsset; + + AssetDeliveryInternalDetail(); + + AssetDeliveryInternalDetail.fromJson(Map json) { + id = json['id']; + lineId = json['lineId']; + itemNumber = json['itemNumber']; + itemDescription = json['itemDescription']; + unitMeasure = json['unitMeasure']; + qtyOrdered = json['qtyOrdered']; + qtyReceived = json['qtyReceived']; + qtyBilled = json['qtyBilled']; + qtyCancelled = json['qtyCancelled']; + unitPrice = json['unitPrice']; + unitPriceWithTax = json['unitPriceWithTax']; + itemCategory = json['itemCategory']; + totalAssets = json['totalAssets']; + childPerAsset = json['childPerAsset']; + } + + Map toJson() { + return { + 'id': id, + 'lineId': lineId, + 'itemNumber': itemNumber, + 'itemDescription': itemDescription, + 'unitMeasure': unitMeasure, + 'qtyOrdered': qtyOrdered, + 'qtyReceived': qtyReceived, + 'qtyBilled': qtyBilled, + 'qtyCancelled': qtyCancelled, + 'unitPrice': unitPrice, + 'unitPriceWithTax': unitPriceWithTax, + 'itemCategory': itemCategory, + 'totalAssets': totalAssets, + 'childPerAsset': childPerAsset, + }; + } +} +class AssetDeliveryTableModel { + int? id; + Lookup? status; + String? number; + num? deliveryAmount; + num? invoiceAmount; + bool? isContainsTechnicalInspection; + + AssetDeliveryTableModel(); + + AssetDeliveryTableModel.fromJson(Map json) { + id = json['id']; + number = json['number']; + deliveryAmount = json['deliveryAmount']; + invoiceAmount = json['invoiceAmount']; + isContainsTechnicalInspection = json['isContainsTechnicalInspection']; + + status = json['status'] != null + ? Lookup.fromJson(json['status']) + : null; + } + + Map toJson() { + return { + 'id': id, + 'number': number, + 'deliveryAmount': deliveryAmount, + 'invoiceAmount': invoiceAmount, + 'isContainsTechnicalInspection': isContainsTechnicalInspection, + 'status': status?.toJson(), + }; + } +} + +class PurchaseOrderMaster { + int? id; + num? poNumber; + int? siteId; + String? siteName; + num? amount; + String? remarks; + String? statuss; + List? assetDeliveryPurchaseOrderDetails; + + PurchaseOrderMaster({ + this.id, + this.poNumber, + this.siteId, + this.siteName, + this.amount, + this.remarks, + this.statuss, + this.assetDeliveryPurchaseOrderDetails, + }); + + PurchaseOrderMaster.fromJson(Map json) { + id = json['id']; + poNumber = json['poNumber']; + siteId = json['siteId']; + siteName = json['siteName']; + amount = json['amount']; + remarks = json['remarks']; + statuss = json['statuss']; + + if (json['assetDeliveryPurchaseOrderDetails'] != null && + json['assetDeliveryPurchaseOrderDetails'] is List) { + assetDeliveryPurchaseOrderDetails = + (json['assetDeliveryPurchaseOrderDetails'] as List) + .map((e) => PurchaseOrderDetails.fromJson(e)) + .toList(); + } else { + assetDeliveryPurchaseOrderDetails = null; + } + } +} + +class SiteModel{ + int? id; + String? siteName; + + SiteModel({ + this.id, + this.siteName, + }); + + SiteModel.fromJson(Map json) { + id = json['id']; + siteName = json['siteName']; + } +} +///Check this model if required and whats the parm +class PurchaseOrderDetails { + // No fields provided in your JSON – placeholder + PurchaseOrderDetails(); + + PurchaseOrderDetails.fromJson(Map json); +} + diff --git a/lib/modules/asset_delivery_module/models/asset_inventory_model.dart b/lib/modules/asset_delivery_module/models/asset_inventory_model.dart deleted file mode 100644 index 4a4e6587..00000000 --- a/lib/modules/asset_delivery_module/models/asset_inventory_model.dart +++ /dev/null @@ -1,345 +0,0 @@ -import 'dart:developer'; - -import 'package:test_sa/models/new_models/building.dart'; -import 'package:test_sa/models/new_models/floor.dart'; -import 'package:test_sa/models/new_models/room_model.dart'; -import 'package:test_sa/models/new_models/site.dart'; -import 'package:test_sa/models/service_request/supplier_details.dart'; -import '../../../models/new_models/department.dart'; - -class AssetInventoryResponse { - num? totalRows; - num? count; - String? message; - String? title; - String? innerMessage; - num? responseCode; - bool? isSuccess; - List? assetList; - - AssetInventoryResponse({ - this.totalRows, - this.count, - this.message, - this.title, - this.innerMessage, - this.responseCode, - this.isSuccess, - this.assetList, - }); - - AssetInventoryResponse.fromJson(Map json) { - totalRows = json['totalRows']; - count = json['count']; - message = json['message']; - title = json['title']; - innerMessage = json['innerMessage']; - responseCode = json['responseCode']; - isSuccess = json['isSuccess']; - if (json['data'] != null) { - assetList = (json['data'] as List).map((item) => AssetInventoryModel.fromJson(item)).toList(); - } - } - - Map toJson() { - return { - 'totalRows': totalRows, - 'count': count, - 'message': message, - 'title': title, - 'innerMessage': innerMessage, - 'responseCode': responseCode, - 'isSuccess': isSuccess, - }; - } -} - -class AssetInventoryModel { - num? id; - num? assetId; - String? transactionDate; - String? assetNumber; - String? serialNo; - String? assetName; - num? assetNameId; - String? model; - String? manufacturer; - String? supplierName; - String? siteName; - String? buildingName; - String? floorName; - String? departmentName; - String? roomName; - num? statusId; - String? status; - num? statusValue; - num? statusByAdminId; - String? statusByAdmin; - num? statusByAdminValue; - bool? isNotRegistered; - num? sessionId; - num? assetImportId; - num? siteId; - num? supplierId; - num? buildingId; - num? floorId; - num? departmentId; - num? roomId; - String? newAssetNumber; - String? newSerialNo; - num? newAssetNameId; - String? newAssetNameText; - num? newModelId; - String? newModelName; - num? manufacturerId; - num? modelId; - num? newManufacturerId; - String? newManufacturerName; - num? newSupplierId; - String? newSupplierName; - String? photo; - String? photoOriginName; - String? remarks; - Site? site; - Building? building; - Floor? floor; - Department? department; - Rooms? room; - SupplierDetails? supplier; - List assetInventoryDetailAssetAttachments = []; - - AssetInventoryModel({ - this.id, - this.sessionId, - this.assetId, - this.transactionDate, - this.assetNumber, - this.assetNameId, - this.serialNo, - this.assetName, - this.model, - this.manufacturer, - this.supplierName, - this.siteName, - this.buildingName, - this.floorName, - this.departmentName, - this.roomName, - this.statusId, - this.status, - this.statusValue, - this.statusByAdminId, - this.statusByAdmin, - this.statusByAdminValue, - this.isNotRegistered, - this.assetImportId, - this.siteId, - this.buildingId, - this.floorId, - this.departmentId, - this.supplierId, - this.roomId, - this.newAssetNumber, - this.manufacturerId, - this.newSerialNo, - this.newAssetNameId, - this.newAssetNameText, - this.newModelId, - this.modelId, - this.newModelName, - this.newManufacturerId, - this.newManufacturerName, - this.newSupplierId, - this.newSupplierName, - this.photo, - this.photoOriginName, - this.remarks, - this.site, - this.department, - this.building, - this.floor, - this.room, - this.supplier, - this.assetInventoryDetailAssetAttachments = const [], - }); - - AssetInventoryModel.fromJson(Map json) { - id = json['id']; - assetId = json['assetId']; - transactionDate = json['transactionDate']; - assetNumber = json['assetNumber']; - assetNameId = json['assetNameId']; - serialNo = json['serialNo']; - assetName = json['assetName']; - model = json['model'] ?? json['modelName']; - manufacturer = json['manufacturer'] ?? json['manufacturerName']; - supplierName = json['supplierName']; - siteName = json['site'] ?? json['siteName']; - buildingName = json['building'] ?? json['buildingName']; - floorName = json['floor'] ?? json['floorName']; - departmentName = json['department'] ?? json['departmentName']; - roomName = json['room'] ?? json['roomName']; - statusId = json['statusId']; - status = json['status'] ?? json['classification']; - statusValue = json['statusValue']; - isNotRegistered = json['isNotRegistered']; - sessionId = json['sessionId']; - assetImportId = json['assetImportId']??json['id']; - siteId = json['siteId']; - buildingId = json['buildingId']; - floorId = json['floorId']; - supplierId = json['supplierId']; - departmentId = json['departmentId']; - roomId = json['roomId']; - modelId = json['modelId']; - photo = json['photo']; - photoOriginName = json['photoOriginName']; - remarks = json['remarks']; - if (json['assetTransferAttachments'] != null) { - assetInventoryDetailAssetAttachments = []; - json['assetInventoryDetailAssetAttachments'].forEach((v) { - assetInventoryDetailAssetAttachments.add(AssetInventoryDetailAssetAttachments.fromJson(v)); - }); - } - - //new data.. - // newAssetNumber = json['newAssetNumber'] ?? json['assetNumber']; - // manufacturerId = json['manufacturerId'] ?? json['manufacturerId']; - // newSerialNo = json['newSerialNo'] ?? json['serialNo']; - // newAssetNameId = json['newAssetNameId'] ?? json['assetNameId']; - // newAssetNameText = json['newAssetNameText'] ?? json['assetNameText']; - // newModelId = json['newModelId'] ?? json['modelId']; - // newModelName = json['newModelName'] ?? json['modelName']; - // newManufacturerId = json['newManufacturerId'] ?? json['manufacturerId']; - // newManufacturerName = json['newManufacturerName'] ?? json['manufacturerName']; - // newSupplierId = json['newSupplierId'] ?? json['supplierId']; - // newSupplierName = json['newSupplierName'] ?? json['supplierName']; - } - - Map toJson() { - return { - 'isNotRegistered': isNotRegistered, - 'sessionId': sessionId, - 'assetImportId': assetImportId, - 'transactionDate': transactionDate, - 'assetId': assetId, - 'siteId': siteId, - 'buildingId': buildingId, - 'floorId': floorId, - 'departmentId': departmentId, - 'roomId': roomId, - 'newSerialNo': newSerialNo, - 'newAssetNameId': newAssetNameId, - 'newAssetNameText': newAssetNameText, - 'newAssetNumber': newAssetNumber, - 'newModelId': newModelId, - 'newModelName': newModelName, - 'newManufacturerId': newManufacturerId, - 'newManufacturerName': newManufacturerName, - 'newSupplierId': newSupplierId, - 'newSupplierName': newSupplierName, - 'photo': photo, - 'remarks': remarks, - 'assetInventoryDetailAssetAttachments': assetInventoryDetailAssetAttachments != null - ? assetInventoryDetailAssetAttachments!.map((v) => v.toJson()).toList() - : [], - }; - } - - AssetInventoryModel mergeWith(AssetInventoryModel? other) { - if (other == null) return this; - - return AssetInventoryModel( - id: id ?? other.id, - assetId: assetId ?? other.assetId, - transactionDate: transactionDate ?? other.transactionDate, - assetNumber: assetNumber ?? other.assetNumber, - serialNo: serialNo ?? other.serialNo, - assetName: assetName ?? other.assetName, - assetNameId: assetNameId ?? other.assetNameId, - model: model ?? other.model, - manufacturer: manufacturer ?? other.manufacturer, - supplierName: supplierName ?? other.supplierName, - siteName: siteName ?? other.siteName, - buildingName: buildingName ?? other.buildingName, - floorName: floorName ?? other.floorName, - departmentName: departmentName ?? other.departmentName, - roomName: roomName ?? other.roomName, - statusId: statusId ?? other.statusId, - status: status ?? other.status, - statusValue: statusValue ?? other.statusValue, - statusByAdminId: statusByAdminId ?? other.statusByAdminId, - statusByAdmin: statusByAdmin ?? other.statusByAdmin, - statusByAdminValue: statusByAdminValue ?? other.statusByAdminValue, - isNotRegistered: isNotRegistered ?? other.isNotRegistered, - sessionId: sessionId ?? other.sessionId, - assetImportId: assetImportId ?? other.assetImportId, - siteId: siteId ?? other.siteId, - supplierId: supplierId ?? other.supplierId, - buildingId: buildingId ?? other.buildingId, - floorId: floorId ?? other.floorId, - departmentId: departmentId ?? other.departmentId, - roomId: roomId ?? other.roomId, - newAssetNumber: newAssetNumber ?? other.newAssetNumber, - newSerialNo: newSerialNo ?? other.newSerialNo, - newAssetNameId: newAssetNameId ?? other.newAssetNameId, - newAssetNameText: newAssetNameText ?? other.newAssetNameText, - newModelId: newModelId ?? other.newModelId, - newModelName: newModelName ?? other.newModelName, - manufacturerId: manufacturerId ?? other.manufacturerId, - modelId: modelId ?? other.modelId, - newManufacturerId: newManufacturerId ?? other.newManufacturerId, - newManufacturerName: newManufacturerName ?? other.newManufacturerName, - newSupplierId: newSupplierId ?? other.newSupplierId, - newSupplierName: newSupplierName ?? other.newSupplierName, - photo: photo ?? other.photo, - photoOriginName: photoOriginName ?? other.photoOriginName, - remarks: remarks ?? other.remarks, - site: site ?? other.site, - building: building ?? other.building, - floor: floor ?? other.floor, - department: department ?? other.department, - room: room ?? other.room, - supplier: supplier ?? other.supplier, - assetInventoryDetailAssetAttachments: assetInventoryDetailAssetAttachments??other.assetInventoryDetailAssetAttachments, - ); - } - - -} -class AssetInventoryDetailAssetAttachments { - AssetInventoryDetailAssetAttachments({ - this.id, - this.name, - this.originalName, - }); - - AssetInventoryDetailAssetAttachments.fromJson(dynamic json) { - id = json['id']; - name = json['name']; - originalName = json['originalName']; - } - - num? id; - String? name; - String? originalName; - - AssetInventoryDetailAssetAttachments copyWith({ - num? id, // Parameter is now nullable - String? name, // Parameter is now nullable - String? originalName, // Parameter is now nullable - }) => - AssetInventoryDetailAssetAttachments( - id: id ?? this.id, - name: name??this.name, - originalName: originalName??this.originalName, - ); - - Map toJson() { - final map = {}; - map['id'] = id; - map['name'] = name; - map['originalName'] = originalName; - return map; - } -} diff --git a/lib/modules/asset_delivery_module/models/cost_center_model.dart b/lib/modules/asset_delivery_module/models/cost_center_model.dart index d465b58d..4bbfe9aa 100644 --- a/lib/modules/asset_delivery_module/models/cost_center_model.dart +++ b/lib/modules/asset_delivery_module/models/cost_center_model.dart @@ -1,27 +1,62 @@ import 'package:test_sa/models/lookup.dart'; class CostCenterModel { + int? id; + int? assetDeliveryExternalDetailId; Lookup? costCenter; + String? acceptedBy; + String? costCenterName; + DateTime? acceptanceDate; + String? acceptedByEmail; + String? acceptedBySignature; double? quantity; CostCenterModel({ + this.id, + this.assetDeliveryExternalDetailId, this.costCenter, + this.acceptedBy, + this.costCenterName, + this.acceptanceDate, + this.acceptedByEmail, + this.acceptedBySignature, this.quantity, }); CostCenterModel.fromJson(Map json) { - costCenter = json['costCenter'] != null - ? Lookup.fromJson(json['costCenter']) - : null; - quantity = json['quantity']; + costCenterName = json['costCenter'] ?? json['costCenterName']; + acceptanceDate = json['acceptanceDate'] != null ? DateTime.tryParse(json['acceptanceDate']) : null; + acceptedBySignature = json['acceptedBySignature']; + acceptedByEmail = json['acceptedByEmail']; + quantity = json['qty'] ?? json['costCenterQty']; + acceptedBy = json['acceptedBy']; + costCenter = json['costCenter'] != null ? Lookup(name: json['costCenter']) : null; + id = json['id'] ?? json['costCenterId']; + assetDeliveryExternalDetailId = json['assetDeliveryExternalDetailId']; } Map toJson() { final Map data = {}; - if (costCenter != null) { - data['costCenter'] = costCenter!.toJson(); - } - data['quantity'] = quantity; + + data['id'] = id ?? 0; + data['qty'] = quantity; + // data['costCenter'] = costCenter; + // data['acceptedBy'] = acceptedBy; + // data['acceptanceDate'] = acceptanceDate; + // data['acceptedByEmail'] = acceptedByEmail; + // data['acceptedBySignature'] = acceptedBySignature; + data['costCenter'] = costCenterName; + return data; + } + + Map toEndUserAcceptanceFormJson() { + final Map data = {}; + data['assetDeliveryExternalDeliveryId'] = assetDeliveryExternalDetailId; + data['costCenterName'] = costCenterName; + data['acceptedBy'] = acceptedBy; + data['acceptanceDate'] = acceptanceDate?.toIso8601String(); + data['acceptedByEmail'] = acceptedByEmail; + data['acceptedBySignature'] = acceptedBySignature; return data; } } diff --git a/lib/modules/asset_delivery_module/models/delivery_inspection_form_model.dart b/lib/modules/asset_delivery_module/models/delivery_inspection_form_model.dart new file mode 100644 index 00000000..10b45d4f --- /dev/null +++ b/lib/modules/asset_delivery_module/models/delivery_inspection_form_model.dart @@ -0,0 +1,37 @@ +class DeliveryInspectionFormModel { + int? assetDeliveryExternalDeliveryId; + String? deliveryInspectionInspectedBy; + DateTime? deliveryInspectionInspectedDateFrom; + DateTime? deliveryInspectionInspectedDateTo; + num? totalTime; + String? deliveryInspectionApprovedBy; + + DeliveryInspectionFormModel({ + this.assetDeliveryExternalDeliveryId, + this.deliveryInspectionInspectedBy, + this.deliveryInspectionInspectedDateFrom, + this.deliveryInspectionInspectedDateTo, + this.totalTime, + this.deliveryInspectionApprovedBy, + }); + + DeliveryInspectionFormModel.fromJson(Map json) { + assetDeliveryExternalDeliveryId = json['assetDeliveryExternalDeliveryId']; + deliveryInspectionInspectedBy = json['deliveryInspectionInspectedBy']; + deliveryInspectionInspectedDateFrom = json['deliveryInspectionInspectedDateFrom']!=null?DateTime.tryParse(json['deliveryInspectionInspectedDateFrom']):null; + deliveryInspectionInspectedDateTo = json['deliveryInspectionInspectedDateTo']!=null?DateTime.tryParse(json['deliveryInspectionInspectedDateTo']):null; + totalTime = json['totalTime']; + deliveryInspectionApprovedBy = json['deliveryInspectionApprovedBy']; + } + + Map toJson() { + return { + 'assetDeliveryExternalDeliveryId': assetDeliveryExternalDeliveryId, + 'deliveryInspectionInspectedBy': deliveryInspectionInspectedBy, + 'deliveryInspectionInspectedDateFrom': deliveryInspectionInspectedDateFrom?.toIso8601String(), + 'deliveryInspectionInspectedDateTo': deliveryInspectionInspectedDateTo?.toIso8601String(), + 'totalTime': totalTime, + 'deliveryInspectionApprovedBy': deliveryInspectionApprovedBy, + }; + } +} diff --git a/lib/modules/asset_delivery_module/models/delivery_line_model.dart b/lib/modules/asset_delivery_module/models/delivery_line_model.dart new file mode 100644 index 00000000..d715c8c1 --- /dev/null +++ b/lib/modules/asset_delivery_module/models/delivery_line_model.dart @@ -0,0 +1,61 @@ +class DeliveryLineModel { + int? id; + int? assetDeliveryInternalDetailId; + String? itemNumber; + String? itemDescription; + num? qty; + num? remainingQty; + num? usingQtyInThisDelivery; + num? unitPrice; + num? total; + String? unitOfMeasure; + String? lineType; + String? itemCategory; + + DeliveryLineModel({ + this.id, + this.assetDeliveryInternalDetailId, + this.itemNumber, + this.itemDescription, + this.qty, + this.remainingQty, + this.usingQtyInThisDelivery, + this.unitPrice, + this.total, + this.unitOfMeasure, + this.lineType, + this.itemCategory, + }); + + DeliveryLineModel.fromJson(Map json) { + id = json['id']; + assetDeliveryInternalDetailId = json['assetDeliveryInternalDetailId']; + itemNumber = json['itemNumber']; + itemDescription = json['itemDescription']; + qty = json['qty']; + remainingQty = json['remainingQty']; + usingQtyInThisDelivery = json['usingQtyInThisDelivery']; + unitPrice = json['unitPrice']; + total = json['total']; + unitOfMeasure = json['unitOfMeasure']; + lineType = json['lineType']; + itemCategory = json['itemCategory']; + } + + Map toJson() { + return { + 'id': id, + 'assetDeliveryInternalDetailId': assetDeliveryInternalDetailId, + 'itemNumber': itemNumber, + 'itemDescription': itemDescription, + 'qty': qty, + 'remainingQty': remainingQty, + 'usingQtyInThisDelivery': usingQtyInThisDelivery, + 'unitPrice': unitPrice, + 'total': total, + 'unitOfMeasure': unitOfMeasure, + 'lineType': lineType, + 'itemCategory': itemCategory, + }; + } +} diff --git a/lib/modules/asset_delivery_module/models/end_user_asset_details_model.dart b/lib/modules/asset_delivery_module/models/end_user_asset_details_model.dart new file mode 100644 index 00000000..242cf70a --- /dev/null +++ b/lib/modules/asset_delivery_module/models/end_user_asset_details_model.dart @@ -0,0 +1,71 @@ +import 'package:test_sa/models/lookup.dart'; + +class EndUserAssetDetailsModel { + int? id; + int? typeId; + int? assetDeliveryExternalDeliveryId; + String? type; + String? itemNumber; + String? costCenterName; + Lookup? status; + Lookup? rejectionReason; + String? description; + double? receivedQty; + num? rejectedQty; + String? assetNumber; + String? serialNo; + String? assetType; + String? replacedAssetNo; + + EndUserAssetDetailsModel( + {this.costCenterName, + this.rejectedQty, + this.description, + this.id, + this.typeId, + this.status, + this.rejectionReason, + this.assetType, + this.assetNumber, + this.serialNo, + this.itemNumber, + this.type, + this.receivedQty, + this.replacedAssetNo, + this.assetDeliveryExternalDeliveryId}); + + EndUserAssetDetailsModel.fromJson(Map json) { + id = json['id']; + typeId = json['typeId']; + type = json['type']; + itemNumber = json['itemNumber']; + status = json['status'] != null ? Lookup.fromJson(json['status']) : null; + rejectionReason = json['rejectReason'] != null ? Lookup.fromJson(json['rejectReason']) : null; + description = json['description']; + receivedQty = json['receivedQty']; + rejectedQty = json['rejectedQty']; + assetNumber = json['assetNumber']; + serialNo = json['serialNo']; + assetType = json['assetType']; + replacedAssetNo = json['replacedAssetNo']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['assetDeliveryExternalDeliveryId'] = assetDeliveryExternalDeliveryId; + data['costCenterName'] = costCenterName; + data['typeId'] = typeId; + data['type'] = type; + data['itemNumber'] = itemNumber; + data['statusId'] = status?.id; + // data['status'] = status; + // data['rejectionReason'] = rejectionReason; + data['rejectReasonId'] = rejectionReason?.id; + data['description'] = description; + data['receivedQty'] = receivedQty; + data['rejectedQty'] = rejectedQty; + + return data; + } +} diff --git a/lib/modules/asset_delivery_module/models/history_model.dart b/lib/modules/asset_delivery_module/models/history_model.dart new file mode 100644 index 00000000..67fc4e11 --- /dev/null +++ b/lib/modules/asset_delivery_module/models/history_model.dart @@ -0,0 +1,34 @@ +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/models/new_models/work_order_detail_model.dart'; + +class AssetDeliveryHistoryModel { + WorkOrderAssignedEmployee? user; + Lookup? status; + DateTime? createdDate; + String ?timeDifference; + + AssetDeliveryHistoryModel({ + this.user, + this.status, + this.createdDate, + this.timeDifference, + }); + + AssetDeliveryHistoryModel.fromJson(Map json) { + user = json['user'] != null ? WorkOrderAssignedEmployee.fromJson(json['user']) : null; + status = json['status'] != null ? Lookup.fromJson(json['status']) : null; + createdDate = json['createdDate'] != null ? DateTime.tryParse(json['createdDate']) : null; + timeDifference = ''; + } + + Map toJson() { + final Map data = {}; + if (user != null) { + data['user'] = user!.toJson(); + } + if (status != null) { + data['status'] = status!.toJson(); + } + return data; + } +} diff --git a/lib/modules/asset_delivery_module/models/oracle_user_model.dart b/lib/modules/asset_delivery_module/models/oracle_user_model.dart new file mode 100644 index 00000000..90ed9ee3 --- /dev/null +++ b/lib/modules/asset_delivery_module/models/oracle_user_model.dart @@ -0,0 +1,26 @@ +class OracleUserModel { + String? employeeNumber; + String? fullName; + String? job; + String? employeeMobileNumber; + String? employeeExtensionNumber; + String? employeeEmail; + + OracleUserModel({ + this.employeeNumber, + this.fullName, + this.job, + this.employeeMobileNumber, + this.employeeExtensionNumber, + this.employeeEmail, + }); + + OracleUserModel.fromJson(Map json) { + employeeNumber = json['employeeNumber']; + fullName = json['fullName']; + job = json['job']; + employeeMobileNumber = json['employeeMobileNumber']; + employeeExtensionNumber = json['employeeExtensionNumber']; + employeeEmail = json['employeeEmail']; + } +} diff --git a/lib/modules/asset_delivery_module/models/session_model.dart b/lib/modules/asset_delivery_module/models/session_model.dart deleted file mode 100644 index 8de8503b..00000000 --- a/lib/modules/asset_delivery_module/models/session_model.dart +++ /dev/null @@ -1,234 +0,0 @@ -import 'package:test_sa/models/new_models/site.dart'; - -class SessionModel { - int? id; - String? createdDate; - String? sessionName; - int? sessionTypeId; - int? sessionTypeValue; - String? sessionTypeName; - int? statusId; - String? statusName; - String? startDate; - String? endDate; - List assetInventorySites = []; - List assetInventoryAssignedEmployee = []; - - SessionModel({ - this.id, - this.sessionName, - this.createdDate, - this.sessionTypeId, - this.sessionTypeValue, - this.sessionTypeName, - this.statusId, - this.statusName, - this.startDate, - this.endDate, - List? assetInventorySites, - List? assetInventoryAssignedEmployee, - }) { - this.assetInventorySites = assetInventorySites ?? []; - this.assetInventoryAssignedEmployee = assetInventoryAssignedEmployee ?? []; - } - - SessionModel.fromJson(Map json) { - id = json['id']; - sessionName = json['sessionName']; - sessionTypeId = json['sessionTypeId']; - sessionTypeValue = json['sessionTypeValue']; - sessionTypeName = json['sessionTypeName']; - statusId = json['statusId']; - createdDate = json['createdDate']; - statusName = json['statusName']; - startDate = json['startDate']; - endDate = json['endDate']; - - if (json['assetInventorySites'] != null) { - assetInventorySites = (json['assetInventorySites'] as List).map((e) => Site.fromJson(e)).toList(); - } - - if (json['assetInventoryAssignedEmployee'] != null) { - assetInventoryAssignedEmployee = (json['assetInventoryAssignedEmployee'] as List).map((e) => AssetInventoryAssignedEmployee.fromJson(e)).toList(); - } - } - - Map toJson() { - final map = {}; - map['id'] = id; - map['sessionName'] = sessionName; - map['sessionTypeId'] = sessionTypeId; - map['sessionTypeValue'] = sessionTypeValue; - map['sessionTypeName'] = sessionTypeName; - map['statusId'] = statusId; - map['statusName'] = statusName; - map['createdDate'] = createdDate; - map['startDate'] = startDate; - map['endDate'] = endDate; - map['assetInventorySites'] = assetInventorySites.map((e) => e.toJson()).toList(); - map['assetInventoryAssignedEmployee'] = assetInventoryAssignedEmployee.map((e) => e.toJson()).toList(); - return map; - } -} - -// class AssetInventorySite { -// int? siteId; -// String? siteName; -// List assetInventoryBuildings = []; -// -// AssetInventorySite({ -// this.siteId, -// this.siteName, -// List? assetInventoryBuildings, -// }) { -// this.assetInventoryBuildings = assetInventoryBuildings ?? []; -// } -// -// AssetInventorySite.fromJson(Map json) { -// siteId = json['siteId']; -// siteName = json['siteName']; -// -// if (json['assetInventoryBuildings'] != null) { -// assetInventoryBuildings = (json['assetInventoryBuildings'] as List).map((e) => AssetInventoryBuilding.fromJson(e)).toList(); -// } -// } -// -// Map toJson() { -// final map = {}; -// map['siteId'] = siteId; -// map['siteName'] = siteName; -// map['assetInventoryBuildings'] = assetInventoryBuildings.map((e) => e.toJson()).toList(); -// return map; -// } -// } -// -// class AssetInventoryBuilding { -// int? buildingId; -// String? buildingName; -// List assetInventoryFloors = []; -// -// AssetInventoryBuilding({ -// this.buildingId, -// this.buildingName, -// List? assetInventoryFloors, -// }) { -// this.assetInventoryFloors = assetInventoryFloors ?? []; -// } -// -// AssetInventoryBuilding.fromJson(Map json) { -// buildingId = json['buildingId']; -// buildingName = json['buildingName']; -// -// if (json['assetInventoryFloors'] != null) { -// assetInventoryFloors = (json['assetInventoryFloors'] as List).map((e) => AssetInventoryFloor.fromJson(e)).toList(); -// } -// } -// -// Map toJson() { -// final map = {}; -// map['buildingId'] = buildingId; -// map['buildingName'] = buildingName; -// map['assetInventoryFloors'] = assetInventoryFloors.map((e) => e.toJson()).toList(); -// return map; -// } -// } -// -// class AssetInventoryFloor { -// int? floorId; -// String? floorName; -// List assetInventoryDepartments = []; -// -// AssetInventoryFloor({ -// this.floorId, -// this.floorName, -// List? assetInventoryDepartments, -// }) { -// this.assetInventoryDepartments = assetInventoryDepartments ?? []; -// } -// -// AssetInventoryFloor.fromJson(Map json) { -// floorId = json['floorId']; -// floorName = json['floorName']; -// -// if (json['assetInventoryDepartments'] != null) { -// assetInventoryDepartments = (json['assetInventoryDepartments'] as List).map((e) => AssetInventoryDepartment.fromJson(e)).toList(); -// } -// } -// -// Map toJson() { -// final map = {}; -// map['floorId'] = floorId; -// map['floorName'] = floorName; -// map['assetInventoryDepartments'] = assetInventoryDepartments.map((e) => e.toJson()).toList(); -// return map; -// } -// } -// -// class AssetInventoryDepartment { -// int? departmentId; -// String? departmentName; -// List assetInventoryRooms = []; -// -// AssetInventoryDepartment({ -// this.departmentId, -// this.departmentName, -// List? assetInventoryRooms, -// }) { -// this.assetInventoryRooms = assetInventoryRooms ?? []; -// } -// -// AssetInventoryDepartment.fromJson(Map json) { -// departmentId = json['departmentId']; -// departmentName = json['departmentName']; -// -// if (json['assetInventoryRooms'] != null) { -// assetInventoryRooms = (json['assetInventoryRooms'] as List).map((e) => AssetInventoryRoom.fromJson(e)).toList(); -// } -// } -// -// Map toJson() { -// final map = {}; -// map['departmentId'] = departmentId; -// map['departmentName'] = departmentName; -// map['assetInventoryRooms'] = assetInventoryRooms.map((e) => e.toJson()).toList(); -// return map; -// } -// } -// -// class AssetInventoryRoom { -// int? roomId; -// String? roomName; -// -// AssetInventoryRoom({this.roomId, this.roomName}); -// -// AssetInventoryRoom.fromJson(Map json) { -// roomId = json['roomId']; -// roomName = json['roomName']; -// } -// -// Map toJson() { -// final map = {}; -// map['roomId'] = roomId; -// map['roomName'] = roomName; -// return map; -// } -// } - -class AssetInventoryAssignedEmployee { - String? assignedEngineerId; - String? assignedEngineerName; - - AssetInventoryAssignedEmployee({this.assignedEngineerId, this.assignedEngineerName}); - - AssetInventoryAssignedEmployee.fromJson(Map json) { - assignedEngineerId = json['assignedEngineerId']; - assignedEngineerName = json['assignedEngineerName']; - } - - Map toJson() { - final map = {}; - map['assignedEngineerId'] = assignedEngineerId; - map['assignedEngineerName'] = assignedEngineerName; - return map; - } -} diff --git a/lib/modules/asset_delivery_module/models/technical_inpection_asset_model.dart b/lib/modules/asset_delivery_module/models/technical_inpection_asset_model.dart new file mode 100644 index 00000000..7404b585 --- /dev/null +++ b/lib/modules/asset_delivery_module/models/technical_inpection_asset_model.dart @@ -0,0 +1,61 @@ +class TechnicalInspectionAssetBasicInfoModel { + int? id; + String? assetNumber; + String? assetType; + String? assetOrigin; + String? assetName; + String? model; + String? manufacturer; + String? site; + String? building; + String? floor; + String? department; + String? room; + + TechnicalInspectionAssetBasicInfoModel({ + this.id, + this.assetNumber, + this.assetType, + this.assetOrigin, + this.assetName, + this.model, + this.manufacturer, + this.site, + this.building, + this.floor, + this.department, + this.room, + }); + + TechnicalInspectionAssetBasicInfoModel.fromJson(Map json) { + id = json['id']; + assetNumber = json['assetNumber']; + assetType = json['assetType']; + assetOrigin = json['assetOrigin']; + assetName = json['assetName']; + model = json['model']; + manufacturer = json['manufacturer']; + site = json['site']; + building = json['building']; + floor = json['floor']; + department = json['department']; + room = json['room']; + } + + Map toJson() { + return { + 'id': id, + 'assetNumber': assetNumber, + 'assetType': assetType, + 'assetOrigin': assetOrigin, + 'assetName': assetName, + 'model': model, + 'manufacturer': manufacturer, + 'site': site, + 'building': building, + 'floor': floor, + 'department': department, + 'room': room, + }; + } +} diff --git a/lib/modules/asset_delivery_module/models/technical_inspection_asset_model.dart b/lib/modules/asset_delivery_module/models/technical_inspection_asset_model.dart new file mode 100644 index 00000000..64671b11 --- /dev/null +++ b/lib/modules/asset_delivery_module/models/technical_inspection_asset_model.dart @@ -0,0 +1,215 @@ +import 'dart:developer'; + +import 'package:test_sa/models/device/supplier.dart'; +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/models/new_models/building.dart'; +import 'package:test_sa/models/new_models/floor.dart'; +import 'package:test_sa/models/new_models/room_model.dart'; +import 'package:test_sa/models/new_models/site.dart'; + +import '../../../models/device/model_definition.dart'; +import '../../../models/new_models/department.dart'; + +class TechnicalInspectionAssetModel { + num? id; + num? tableItemId; + num? lineId; + num? assetDeliveryInternalDetailAssetId; + num? assetDeliveryInternalDetailAssetChildId; + num? costCenterId; + String? assetNumber; + String? status; + Lookup? assetOrigin; + Lookup? replacedAsset; + AssetModelDefination? modelDefinition; + Supplier? supplier; + Lookup? assetType; // Now nullable + Site? site; // Now nullable + Building? building; // Now nullable + Floor? floor; // Now nullable + Department? department; // Now nullable + Rooms? room; + String? serialNo; + String? systemId; + DateTime? installationDate; + List? childAssetList; + bool? flagphysicalInspection; + bool? flagFunctionPerformance; + bool? flagGroundingResistance; + bool? flagChassiss; + bool? flagLeadsLeakage; + bool? flagAlert; + + TechnicalInspectionAssetModel({ + this.id, + this.assetDeliveryInternalDetailAssetId, + this.assetDeliveryInternalDetailAssetChildId, + this.tableItemId, + this.status, + this.lineId, + this.costCenterId, + this.assetNumber, + this.assetOrigin, + this.assetType, + this.replacedAsset, + this.modelDefinition, + this.supplier, + this.site, + this.building, + this.floor, + this.department, + this.room, + this.serialNo, + this.systemId, + this.installationDate, + this.childAssetList, + this.flagphysicalInspection, + this.flagFunctionPerformance, + this.flagGroundingResistance, + this.flagChassiss, + this.flagLeadsLeakage, + this.flagAlert, + }); + + TechnicalInspectionAssetModel.fromJson(Map json) { + id = json['id']; + assetDeliveryInternalDetailAssetId = json['assetDeliveryInternalDetailAssetId']; + assetDeliveryInternalDetailAssetChildId = json['assetDeliveryInternalDetailAssetChildId']; + assetNumber = json['assetNumber']; + assetOrigin = json['assetOrigin'] != null ? Lookup.fromJson(json['assetOrigin']) : null; + replacedAsset = json['replacedAsset'] != null ? Lookup.fromJson(json['replacedAsset']) : null; + modelDefinition = json['modelDefinition'] != null ? AssetModelDefination.fromJson(json['modelDefinition']) : null; + supplier = json['supplier'] != null ? Supplier.fromJson(json['supplier']) : null; + assetType = json['assetType'] != null ? Lookup.fromJson(json['assetType']) : null; + site = json['site'] != null ? Site.fromJson(json['site']) : null; + building = json['building'] != null ? Building.fromJson(json['building']) : null; + floor = json['floor'] != null ? Floor.fromJson(json['floor']) : null; + department = json['department'] != null ? Department.fromJson(json['department']) : null; + room = json['room'] != null ? Rooms.fromJson(json['room']) : null; + serialNo = json['serialNo']; + systemId = json['systemId']; + installationDate = json['installationDate'] != null ? DateTime.tryParse(json['installationDate']) : null; + childAssetList = + json['assetDeliveryInternalDetailAssetChild'] != null ? (json['assetDeliveryInternalDetailAssetChild'] as List).map((e) => TechnicalInspectionAssetModel.fromJson(e)).toList() : []; + //Need to keep one parm from backend + // childAssetList = json['assetDeliveryExternalDeliveryLineTechnicalInspectionItemChild'] != null + // ? (json['assetDeliveryExternalDeliveryLineTechnicalInspectionItemChild'] as List).map((e) => TechnicalInspectionAssetModel.fromJson(e)).toList() + // : []; + flagphysicalInspection = json['flagphysicalInspection']; + flagFunctionPerformance = json['flagFunctionPerformance']; + flagGroundingResistance = json['flagGroundingResistance']; + flagChassiss = json['flagChassiss']; + flagLeadsLeakage = json['flagLeadsLeakage']; + flagAlert = json['flagAlert']; + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['assetDeliveryInternalDetailAssetId'] = assetDeliveryInternalDetailAssetId; + data['assetDeliveryExternalDeliveryId'] = tableItemId; + data['assetDeliveryExternalDetailId'] = lineId; + data['costCenterId'] = costCenterId; + data['assetNumber'] = assetNumber; + data['assetOriginId'] = assetOrigin?.id; + data['assetTypeId'] = assetType?.id; + data['replacedAssetId'] = replacedAsset?.id; + data['modelDefinitionId'] = modelDefinition?.modelDefinitionId; + data['supplierId'] = supplier?.id; + data['siteId'] = site?.id; + data['buildingId'] = building?.id; + data['floorId'] = floor?.id; + data['departmentId'] = department?.id; + data['roomId'] = room?.id; + data['serialNo'] = serialNo; + data['systemId'] = systemId; + data['installationDate'] = installationDate?.toIso8601String(); + data['assetDeliveryInternalDetailAssetChild'] = childAssetList?.map((e) => e.toChildJson()).toList(); + data['flagphysicalInspection'] = flagphysicalInspection; + data['flagFunctionPerformance'] = flagFunctionPerformance; + data['flagGroundingResistance'] = flagGroundingResistance; + data['flagChassiss'] = flagChassiss; + data['flagLeadsLeakage'] = flagLeadsLeakage; + data['flagAlert'] = flagAlert; + return data; + } + + Map toChildJson() { + final Map data = {}; + data['id'] = id; + data['assetDeliveryInternalDetailAssetChildId'] = assetDeliveryInternalDetailAssetChildId; + data['assetNumber'] = assetNumber; + data['assetOriginId'] = assetOrigin?.id; + data['assetTypeId'] = assetType?.id; + data['replacedAssetId'] = replacedAsset?.id; + data['modelDefinitionId'] = modelDefinition?.modelDefinitionId; + data['supplierId'] = supplier?.id; + data['siteId'] = site?.id; + data['buildingId'] = building?.id; + data['floorId'] = floor?.id; + data['departmentId'] = department?.id; + data['roomId'] = room?.id; + data['serialNo'] = serialNo; + data['systemId'] = systemId; + data['installationDate'] = installationDate?.toIso8601String(); + data['flagphysicalInspection'] = flagphysicalInspection; + data['flagFunctionPerformance'] = flagFunctionPerformance; + data['flagGroundingResistance'] = flagGroundingResistance; + data['flagChassiss'] = flagChassiss; + data['flagLeadsLeakage'] = flagLeadsLeakage; + data['flagAlert'] = flagAlert; + return data; + } +} + +class InspectionChecklistItem { + String? title; + String? value; + String? status; // "PASS" or "FAIL" + + InspectionChecklistItem({this.title, this.status, this.value}); + + InspectionChecklistItem.fromJson(Map json) { + title = json['title']; + value = json['value']; + status = json['status']; + } + + Map toJson() { + return { + 'title': title, + 'value': value, + 'status': status, + }; + } +} + +class AssetModelDefination { + int? modelDefinitionId; + String? assetName; + String? model; + String? manufacturer; + + AssetModelDefination({ + this.modelDefinitionId, + this.assetName, + this.model, + this.manufacturer, + }); + + AssetModelDefination.fromJson(Map json) { + modelDefinitionId = json['modelDefinitionId']; + assetName = json['assetName']; + model = json['model']; + manufacturer = json['manufacturer']; + } + + Map toJson() { + final Map data = {}; + data['modelDefinitionId'] = modelDefinitionId; + data['assetName'] = assetName; + data['model'] = model; + data['manufacturer'] = manufacturer; + return data; + } +} diff --git a/lib/modules/asset_delivery_module/models/technical_inspection_form_model.dart b/lib/modules/asset_delivery_module/models/technical_inspection_form_model.dart new file mode 100644 index 00000000..cbde7191 --- /dev/null +++ b/lib/modules/asset_delivery_module/models/technical_inspection_form_model.dart @@ -0,0 +1,53 @@ +import 'dart:developer'; + +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/cost_center_model.dart'; + +class TechnicalInspectionFormModel { + Lookup? powerSupplyType; + num? powerReading; + num? maxCurrent; + num? voltage; + num? frequency; + List? costCenters; + int? tableItemId; + int? lineId; + + TechnicalInspectionFormModel({ + this.powerSupplyType, + this.powerReading, + this.maxCurrent, + this.voltage, + this.frequency, + this.costCenters, + this.lineId, + this.tableItemId, + }); + + TechnicalInspectionFormModel.fromJson(Map json) { + powerSupplyType = json["powerSupplyType"] == null ? null : Lookup.fromJson(json["powerSupplyType"]); + powerReading = json['powerReading']; + maxCurrent = json['maxCurrent']; + voltage = json['voltage']; + frequency = json['frequency']; + if (json['costCenters'] != null) { + costCenters = []; + json['costCenters'].forEach((v) { + costCenters!.add(CostCenterModel.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = {}; + data['powerSupplyTypeId'] = powerSupplyType?.id; + data['assetDeliveryExternalDeliveryId'] = tableItemId; + data['assetDeliveryExternalDetailId'] = lineId; + data['powerReading'] = powerReading; + data['maxCurrent'] = maxCurrent; + data['voltage'] = voltage; + data['frequency'] = frequency; + // data['costCenters'] = costCenters != null ? costCenters!.map((v) => v.toJson()).toList() : []; + return data; + } +} diff --git a/lib/modules/asset_delivery_module/pages/asset_delivery_detail_page.dart b/lib/modules/asset_delivery_module/pages/asset_delivery_detail_page.dart deleted file mode 100644 index d0b4f264..00000000 --- a/lib/modules/asset_delivery_module/pages/asset_delivery_detail_page.dart +++ /dev/null @@ -1,105 +0,0 @@ - -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:test_sa/extensions/context_extension.dart'; -import 'package:test_sa/extensions/int_extensions.dart'; -import 'package:test_sa/extensions/string_extensions.dart'; -import 'package:test_sa/extensions/text_extensions.dart'; -import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/history_log_view.dart'; -import 'package:test_sa/modules/cm_module/cm_detail_provider.dart'; -import 'package:test_sa/modules/cx_module/chat/chat_provider.dart'; -import 'package:test_sa/new_views/app_style/app_color.dart'; -import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; - -class AssetDeliveryDetailPage extends StatefulWidget { - final int requestId; - - AssetDeliveryDetailPage({Key? key, required this.requestId}) : super(key: key); - - @override - _AssetDeliveryDetailPageState createState() { - return _AssetDeliveryDetailPageState(); - } -} - -class _AssetDeliveryDetailPageState extends State { - late CMDetailProvider _requestProvider; - - static const int moduleId = 1; - - @override - void initState() { - super.initState(); - WidgetsBinding.instance.addPostFrameCallback((_) { - Provider.of(context, listen: false).reset(); - getInitialData(); - }); - } - - Future getInitialData() async { - ///Replace with data ... - // _requestProvider = Provider.of(context, listen: false); - // await _requestProvider.getWorkOrderById(id: widget.requestId); - - } - - @override - void dispose() { - super.dispose(); - } - - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Theme.of(context).scaffoldBackgroundColor, - appBar: DefaultAppBar( - ///Title should be change with view change - title: 'Delivery Inspection'.addTranslation, - onBackPress: () { - Navigator.pop(context); - }, - ), - body: DefaultTabController( - length: 2, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 12.toScreenHeight), - decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.white10, borderRadius: BorderRadius.circular(10)), - child: TabBar( - //controller: _tabController, - padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth), - labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20, - unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20, - unselectedLabelStyle: AppTextStyles.bodyText, - labelStyle: AppTextStyles.bodyText, - indicatorPadding: EdgeInsets.zero, - indicatorSize: TabBarIndicatorSize.tab, - dividerColor: Colors.transparent, - indicator: BoxDecoration(color: context.isDark ? AppColor.neutral60 : AppColor.neutral110, borderRadius: BorderRadius.circular(7)), - onTap: (index) { - // setState(() {}); - }, - tabs: [ - Tab(text: context.translation.details, height: 57.toScreenHeight), - Tab(text: context.translation.historyLogs, height: 57.toScreenHeight), - ], - ), - ), - 12.height, - TabBarView( - children: [ - DeliveryInspectionFormView(), - const AssetDeliveryHistoryLogView(), - ], - ).expanded, - ], - ), - )); - } - -} diff --git a/lib/modules/asset_delivery_module/pages/asset_delivery_item_view.dart b/lib/modules/asset_delivery_module/pages/asset_delivery_item_view.dart index 99aafbf3..ff02233c 100644 --- a/lib/modules/asset_delivery_module/pages/asset_delivery_item_view.dart +++ b/lib/modules/asset_delivery_module/pages/asset_delivery_item_view.dart @@ -15,6 +15,7 @@ class AssetDeliveryItemView extends StatelessWidget { final Data? requestData; final RequestsDetails? requestDetails; final bool showShadow; + const AssetDeliveryItemView({Key? key, this.requestData, this.requestDetails, this.showShadow = true}) : super(key: key); @override @@ -23,27 +24,10 @@ class AssetDeliveryItemView extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // Row( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // StatusLabel( - // label: requestData!.statusName!, - // textColor: AppColor.getRequestStatusTextColorByName(context, requestData!.statusName!), - // backgroundColor: AppColor.getRequestStatusColorByName(context, requestData!.statusName!), - // ), - // 1.width.expanded, - // Text( - // requestData!.transactionDate?.toServiceRequestCardFormat ?? "", - // textAlign: TextAlign.end, - // style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50), - // ), - // ], - // ), 8.height, - 'Asset Delivery'.addTranslation.heading5(context), - infoWidget(label: 'Delivery Type'.addTranslation, value: '-', context: context), - infoWidget(label: 'No of Assets'.addTranslation, value: '-', context: context), - infoWidget(label: 'No of Sites'.addTranslation, value: '-', context: context), + (requestData?.typeTransaction ?? 'Asset Delivery').heading5(context), + infoWidget(label: 'PO Internal'.addTranslation, value: requestData?.poInternal ?? '-', context: context), + infoWidget(label: 'PO External'.addTranslation, value: requestData?.poExternal ?? '-', context: context), // infoWidget(label: 'No of Sites'.addTranslation, value: requestData?.numberOfSites != null ? requestData?.numberOfSites.toString() : '-', context: context), 8.height, Row( @@ -59,33 +43,21 @@ class AssetDeliveryItemView extends StatelessWidget { ), ], ).toShadowContainer(context, withShadow: showShadow).onPress(() async { - Navigator.of(context).push(MaterialPageRoute(builder: (_) => AssetInventoryPage(sessionId: requestData!.id!, moduleId: requestData!.transactionNo!))); + Navigator.of(context).push(MaterialPageRoute( + builder: (_) => AssetDeliveryPage( + requestId: requestData!.id!, + poInternal: requestData?.poInternal, + poExternal: requestData?.poExternal, + ))); }); } return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // Row( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // StatusLabel( - // label: requestDetails!.status!, - // textColor: AppColor.getRequestStatusTextColorByName(context, requestDetails?.status!), - // backgroundColor: AppColor.getRequestStatusColorByName(context, requestDetails?.status!), - // ), - // 1.width.expanded, - // Text( - // requestDetails!.date?.toServiceRequestCardFormat ?? "", - // textAlign: TextAlign.end, - // style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50), - // ), - // ], - // ), 8.height, - 'Asset Delivery'.addTranslation.heading5(context), - infoWidget(label: 'Delivery Type'.addTranslation, value: '-', context: context), - infoWidget(label: 'No of Assets'.addTranslation, value: '-', context: context), - infoWidget(label: 'No of Sites'.addTranslation, value: '-', context: context), + (requestDetails?.nameOfType ?? 'Asset Delivery').heading5(context), + infoWidget(label: 'PO Internal'.addTranslation, value: requestDetails?.poInternal ?? '-', context: context), + infoWidget(label: 'PO External'.addTranslation, value: requestDetails?.poExternal ?? '-', context: context), 8.height, Row( mainAxisSize: MainAxisSize.min, @@ -100,7 +72,12 @@ class AssetDeliveryItemView extends StatelessWidget { ), ], ).toShadowContainer(context, withShadow: showShadow).onPress(() async { - Navigator.of(context).push(MaterialPageRoute(builder: (_) => AssetDeliveryPage(requestId: requestDetails!.id!))); + Navigator.of(context).push(MaterialPageRoute( + builder: (_) => AssetDeliveryPage( + requestId: requestDetails!.id!, + poInternal: requestDetails?.poInternal, + poExternal: requestDetails?.poExternal, + ))); }); } diff --git a/lib/modules/asset_delivery_module/pages/asset_delivery_line_card_view.dart b/lib/modules/asset_delivery_module/pages/asset_delivery_line_card_view.dart index b8a22248..5337f457 100644 --- a/lib/modules/asset_delivery_module/pages/asset_delivery_line_card_view.dart +++ b/lib/modules/asset_delivery_module/pages/asset_delivery_line_card_view.dart @@ -1,22 +1,21 @@ import 'package:flutter/material.dart'; import 'package:test_sa/extensions/context_extension.dart'; -import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/delivery_line_model.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; class AssetDeliveryLineCard extends StatelessWidget { - ///Need to replace with Lines model. - AssetInventoryModel deliveryDetails; - ///if include in model skip this + DeliveryLineModel deliveryLineModel; bool isViewOnly; - VoidCallback ?editPress; + VoidCallback? editPress; + bool isTechnical; AssetDeliveryLineCard({ super.key, required this.isViewOnly, - required this.deliveryDetails, + required this.deliveryLineModel, + this.isTechnical = false, this.editPress, }); @@ -30,43 +29,55 @@ class AssetDeliveryLineCard extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - 'Item No: ${deliveryDetails.transactionDate?.toServiceRequestDetailsFormat ?? '-'}', + 'Item Category: ${deliveryLineModel.itemCategory ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), - if(!isViewOnly) - 'edit_icon'.toSvgAsset().onPress(() { - if(editPress!=null){ - editPress!(); - } - }), + if (!isViewOnly) + 'edit_icon'.toSvgAsset().onPress(() { + if (editPress != null) { + editPress!(); + } + }), ], ), Text( - 'Item Description: ${deliveryDetails.assetNumber ?? '-'}', + 'Item No: ${deliveryLineModel.itemNumber ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), Text( - 'Quantity: ${deliveryDetails.assetName ?? '-'}', + 'Item Description: ${deliveryLineModel.itemDescription ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), Text( - 'Remaining Quantity: ${deliveryDetails.assetName ?? '-'}', + 'Quantity: ${deliveryLineModel.qty ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), + + if(!isTechnical)...[ + Text( + 'Remaining Quantity: ${deliveryLineModel.remainingQty ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Quantity of this Delivery: ${deliveryLineModel.usingQtyInThisDelivery ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + ], + Text( - 'Quantity of this Delivery: ${deliveryDetails.assetName ?? '-'}', + 'Measure Unit: ${deliveryLineModel.unitOfMeasure ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), Text( - 'Marge Unit: ${deliveryDetails.assetName ?? '-'}', + 'Unit price: ${deliveryLineModel.unitPrice ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), Text( - 'Unit price: ${deliveryDetails.assetName ?? '-'}', + 'Line Type: ${deliveryLineModel.lineType ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), Text( - 'Total: ${deliveryDetails.assetName ?? '-'}', + 'Total: ${deliveryLineModel.total ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), ], diff --git a/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart b/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart index eba6ccd8..aad1d276 100644 --- a/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart +++ b/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart @@ -1,30 +1,31 @@ -import 'dart:developer'; - import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/models/new_models/site.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/asset_delivery_detail_page.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/asset_delivery_data_model.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/asset_delivery_table_card_view.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/change_status_bottomsheet.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart'; -import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart'; -import 'package:test_sa/modules/asset_inventory_module/models/session_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/history_log_view.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; -import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; +import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; -import 'package:test_sa/views/widgets/requests/request_status.dart'; class AssetDeliveryPage extends StatefulWidget { final int? requestId; + final String? poInternal; + final String? poExternal; const AssetDeliveryPage({ Key? key, this.requestId, + this.poInternal, + this.poExternal, }) : super(key: key); @override @@ -32,11 +33,28 @@ class AssetDeliveryPage extends StatefulWidget { } class _AssetDeliveryPageState extends State { + AssetDeliveryDataModel? dataModel; + AssetDeliveryProvider? assetDeliveryProvider; + @override void initState() { + assetDeliveryProvider = Provider.of(context, listen: false); + WidgetsBinding.instance.addPostFrameCallback((_) { + getDetailsById(); + }); super.initState(); } + Future getDetailsById() async { + final futures = [ + assetDeliveryProvider!.getAssetDeliveryDetailById(requestId: widget.requestId).then((value) => dataModel = value), + assetDeliveryProvider!.getAssetDeliveryTableListById(requestId: widget.requestId), + ]; + + await Future.wait(futures); + } + + @override @override Widget build(BuildContext context) { return Scaffold( @@ -47,17 +65,72 @@ class _AssetDeliveryPageState extends State { Navigator.pop(context); }, ), - body: widget.requestId == null - ? const NoDataFound() - : ListView( - padding: const EdgeInsets.all(12), - children: [ - requestDetailCard(context), - // const SizedBox(height: 12), - const Divider().defaultStyle(context), - assetDeliveryTableList(context), - ], - ).toShadowContainer(context, borderRadius: 20, padding: 0, margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 12)), + body: Consumer( + builder: (context, provider, child) { + final dataModel = provider.assetDeliveryDataModel; + if (provider.isLoading) { + return const CircularProgressIndicator(color: AppColor.primary10).center; + } + if (dataModel == null) { + return const NoDataFound().center; + } + return ListView( + padding: const EdgeInsets.all(12), + children: [ + requestDetailCard(context), + const Divider().defaultStyle(context), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Asset Delivery Table", + style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + Row( + children: [ + Container( + height: 24, + width: 24, + decoration: const BoxDecoration( + shape: BoxShape.circle, + color: AppColor.primary10, // or AppColor.blueStatus(context) + ), + alignment: Alignment.center, + child: const Icon( + Icons.add, + color: Colors.white, + size: 16, + ), + ), + 4.width, + Text( + "Add more", + style: AppTextStyles.bodyText.copyWith( + color: context.isDark ? AppColor.neutral30 : AppColor.neutral50, + decoration: TextDecoration.underline, + ), + ), + ], + ).onPress(() async { + await assetDeliveryProvider?.addNewDelivery(requestId: widget.requestId).then((status) async { + if (status) { + await assetDeliveryProvider?.getAssetDeliveryTableListById(requestId: widget.requestId); + } + }); + }), + ], + ), + 8.height, + assetDeliveryTableList(context: context, assetDeliveryProvider: provider), + ], + ).toShadowContainer( + context, + borderRadius: 20, + padding: 0, + margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + ); + }, + ), ); } @@ -67,183 +140,207 @@ class _AssetDeliveryPageState extends State { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + Text( + 'PO No. Internal'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + widget.poInternal ?? '-', + style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), + ), + 8.height, + Text( + 'Client Name'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + dataModel?.clientName ?? '-', + style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), + ), // Row( - // crossAxisAlignment: CrossAxisAlignment.start, - // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // mainAxisSize: MainAxisSize.min, // children: [ - // // - // StatusLabel( - // label: sessionModel.statusName, - // id: sessionModel.statusId, - // radius: 4, - // textColor: AppColor.getRequestStatusTextColorByName(context, sessionModel.statusName), - // backgroundColor: AppColor.getRequestStatusColorByName(context, sessionModel.statusName), - // // textColor: AppColor.green15, - // // backgroundColor: AppColor.greenStatus(context), + // Checkbox( + // value: dataModel!.isHMG, + // activeColor: AppColor.neutral120, + // materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + // visualDensity: const VisualDensity(horizontal: -4, vertical: -3), + // onChanged: (value) {}, // ), + // 8.width, // Text( - // sessionModel.createdDate!.toString().toServiceRequestCardFormat, - // textAlign: TextAlign.end, - // style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), - // ) + // 'HMG'.addTranslation, + // style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + // ), // ], // ), 8.height, - //neutral120 + if (dataModel?.isHMG == true) ...[ + Text( + 'Operation Units'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + dataModel?.operatingUnit ?? '-', + style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), + ), + ] else ...[ + Text( + 'Site'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + dataModel?.site?.siteName ?? '-', + style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), + ), + ], + 8.height, Text( - 'PO No. Internal'.addTranslation, + 'PO No.'.addTranslation, style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), ), 8.height, + //Need to verify this with backend ... + // widget.poInternal?? '-', Text( - 'PO8745623'.addTranslation, + dataModel?.isHMG == true + ? dataModel?.poNumber != null + ? dataModel!.poNumber.toString() + : '-' + : dataModel?.poNumber != null + ? dataModel!.poNumber.toString() + : '-', style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), 8.height, - Row( - mainAxisSize: MainAxisSize.min, - children: [ - Checkbox( - value: true, - activeColor: AppColor.neutral120, - materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - visualDensity: const VisualDensity(horizontal: -4, vertical: -3), - onChanged: (value) {}, - ), - 8.width, - Text( - 'HMS'.addTranslation, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), - ), - ], - ), - 8.height, Text( - 'Operation Units'.addTranslation, + 'Warranty Period'.addTranslation, style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), ), 8.height, Text( - '50'.addTranslation, + dataModel?.warrentyPeriod != null ? dataModel!.warrentyPeriod.toString() : '-', style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), 8.height, Text( - 'PO No.'.addTranslation, + 'Payment Term'.addTranslation, style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), ), 8.height, Text( - 'PO438'.addTranslation, + dataModel?.paymentTerm != null ? dataModel!.paymentTerm!.name.toString() : '-', style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), 8.height, + Text( - 'Warranty Period'.addTranslation, + 'Payment Terms Amount'.addTranslation, style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), ), 8.height, Text( - '1 Year'.addTranslation, + dataModel?.paymentTermAmount != null ? dataModel!.paymentTermAmount.toString() : '-', style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), 8.height, Text( - 'Payment Terms Amount'.addTranslation, + 'EDD (Estimated Delivery Date)'.addTranslation, style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), ), 8.height, Text( - '70%'.addTranslation, + dataModel?.edd != null ? dataModel!.edd!.toAssetDetailsFormat : '-', style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), 8.height, Text( - 'EDD (Estimated Delivery Date)'.addTranslation, + 'Total'.addTranslation, style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), ), 8.height, Text( - '25 December, 2025'.addTranslation, + dataModel?.total != null ? dataModel!.total.toString() : '-', style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), 8.height, Text( - 'Total'.addTranslation, + 'Total Invoice'.addTranslation, style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), ), 8.height, Text( - '4930'.addTranslation, + dataModel?.totalInvoice != null ? dataModel!.totalInvoice.toString() : '-', style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), ], ); } - Widget assetDeliveryTableList(BuildContext context) { - final assetDeliveryTableList = ['abc', 'def', 'ghi', 'fhg', 'hjhh']; - return Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "Asset Delivery Table", - style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), - ), - Container( - height: 24, - width: 24, - decoration: const BoxDecoration( - shape: BoxShape.circle, - color: AppColor.primary10, // or AppColor.blueStatus(context) - ), - alignment: Alignment.center, - child: const Icon( - Icons.add, - color: Colors.white, - size: 16, - ), - ).onPress(() { - //add entry into table. - }), - // AppFilledButton( - // label: '', - // maxWidth: true, - // textColor: AppColor.textColor(context), - // buttonColor: context.isDark ? AppColor.neutral60 : AppColor.white10, - // icon: Icon(Icons.add_circle, color: AppColor.blueStatus(context)), - // showIcon: true, - // onPressed: (){ - // - // }, - // ) - ], - ), - 8.height, - ListView.separated( - itemCount: assetDeliveryTableList.length, - separatorBuilder: (_, __) => 8.height, - padding: EdgeInsets.zero, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (listContext, itemIndex) { - return AssetDeliveryTableCard( - deliveryDetails: AssetInventoryModel(), - onCardTap: () { - ///TODO need to display bottomsheet to change status if new... - // if(status=='NEW') - // AssetDeliveryBottomSheet.changeStatusBottomSheet(context: context); - Navigator.of(context).push(MaterialPageRoute(builder: (_) => AssetDeliveryDetailPage(requestId: 13,))); - }, - onViewHistoryPress: () {}, - ); - }, - ), - ], - ); + Widget assetDeliveryTableList({required BuildContext context, required AssetDeliveryProvider assetDeliveryProvider}) { + List assetDeliveryTableList = assetDeliveryProvider.assetDeliveryTableList; + return assetDeliveryProvider.isDeliveryTableListLoading + ? SizedBox(height: 200.toScreenHeight, child: const CircularProgressIndicator(color: AppColor.primary10).center) + : assetDeliveryTableList.isEmpty + ? const NoDataFound().center + : ListView.separated( + itemCount: assetDeliveryTableList.length, + separatorBuilder: (_, __) => 8.height, + padding: EdgeInsets.zero, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (listContext, itemIndex) { + AssetDeliveryTableModel model = assetDeliveryTableList[itemIndex]; + return AssetDeliveryTableCard( + deliveryTableModel: model, + onCardTap: () { + //status new + if (model.status?.value == 1) { + AssetDeliveryBottomSheet.changeStatusBottomSheet( + context: context, + cancelStatusTap: () async { + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + await assetDeliveryProvider.changeDeliveryStatusToCancel(itemId: model.id).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context); + await assetDeliveryProvider.getAssetDeliveryTableListById(requestId: widget.requestId); + } + }); + }, + statusChangeTap: () async { + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + await assetDeliveryProvider.changeDeliveryStatus(itemId: model.id).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context); + await assetDeliveryProvider.getAssetDeliveryTableListById(requestId: widget.requestId); + } + }); + }); + } else { + Navigator.of(context).push(MaterialPageRoute( + builder: (_) => DeliveryInspectionFormView( + deliveryTableModel: model, + requestModel: dataModel, + ), + )); + } + }, + onViewHistoryTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AssetDeliveryHistoryLogView( + tableItemId: model.id, + ))); + }, + ); + }, + ); } } diff --git a/lib/modules/asset_delivery_module/pages/asset_delivery_table_card_view.dart b/lib/modules/asset_delivery_module/pages/asset_delivery_table_card_view.dart index bcbf9544..0d906d49 100644 --- a/lib/modules/asset_delivery_module/pages/asset_delivery_table_card_view.dart +++ b/lib/modules/asset_delivery_module/pages/asset_delivery_table_card_view.dart @@ -1,30 +1,28 @@ - import 'package:flutter/material.dart'; +import 'package:test_sa/controllers/providers/api/device_transfer_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/asset_delivery_data_model.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/views/widgets/requests/request_status.dart'; class AssetDeliveryTableCard extends StatelessWidget { - //Need to replace with AssetTableCard. - AssetInventoryModel deliveryDetails; - VoidCallback onViewHistoryPress; + AssetDeliveryTableModel deliveryTableModel; VoidCallback onCardTap; + VoidCallback onViewHistoryTap; AssetDeliveryTableCard({ super.key, - required this.deliveryDetails, - required this.onViewHistoryPress, + required this.deliveryTableModel, required this.onCardTap, + required this.onViewHistoryTap, }); @override Widget build(BuildContext context) { - deliveryDetails.status = 'New'; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -32,35 +30,35 @@ class AssetDeliveryTableCard extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ StatusLabel( - label: deliveryDetails.status, - textColor: AppColor.getRequestStatusTextColorByName(context, deliveryDetails.status), - backgroundColor: AppColor.getRequestStatusColorByName(context, deliveryDetails.status), + label: deliveryTableModel.status?.name, + textColor: AppColor.neutral50, + backgroundColor: AppColor.orange30, ), Row( children: [ - 'history_icon'.toSvgAsset(), - 6.width, + 'history_icon'.toSvgAsset(height: 14, width: 14), + 8.width, Text( 'View History'.addTranslation, - style: AppTextStyles.bodyText.copyWith(color: AppColor.blueStatus(context)), + style: AppTextStyles.bodyText.copyWith(color: AppColor.primary10), ), ], ).onPress(() { - onViewHistoryPress(); + onViewHistoryTap(); }), ], ), 8.height, Text( - 'Delivery Number: ${deliveryDetails.transactionDate?.toServiceRequestDetailsFormat ?? '-'}', + 'Delivery Number: ${deliveryTableModel.number ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), Text( - 'Delivery Amount: ${deliveryDetails.assetNumber ?? '-'}', + 'Delivery Amount: ${deliveryTableModel.deliveryAmount ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), Text( - 'Invoice Amount: ${deliveryDetails.assetName ?? '-'}', + 'Invoice Amount: ${deliveryTableModel.invoiceAmount ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), Align( @@ -68,7 +66,7 @@ class AssetDeliveryTableCard extends StatelessWidget { child: Icon(Icons.arrow_forward, color: AppColor.blueStatus(context), size: 14), ), ], - ).toShadowContainer(context, borderRadius: 20).onPress((){ + ).toShadowContainer(context, borderRadius: 20).onPress(() { onCardTap(); }); } diff --git a/lib/modules/asset_delivery_module/pages/attachment_view.dart b/lib/modules/asset_delivery_module/pages/attachment_view.dart new file mode 100644 index 00000000..0c22772e --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/attachment_view.dart @@ -0,0 +1,126 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/string_extensions.dart'; +import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/models/generic_attachment_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; +import 'package:test_sa/modules/cm_module/cm_request_utils.dart'; +import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; +import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; +import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; +import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; + +class AssetDeliveryAttachmentView extends StatefulWidget { + ///Need to check which parm need here. + final int? lineId; + final int? tableItemId; + final int? requestId; + final bool? isHmg; + + const AssetDeliveryAttachmentView({ + super.key, + this.lineId, + this.requestId, + this.tableItemId, + this.isHmg, + }); + + @override + State createState() => _AssetDeliveryAttachmentViewState(); +} + +class _AssetDeliveryAttachmentViewState extends State { + List _attachments = []; + bool isLoading = false; + late AssetDeliveryProvider assetDeliveryProvider; + + @override + void initState() { + super.initState(); + assetDeliveryProvider = Provider.of(context, listen: false); + WidgetsBinding.instance.addPostFrameCallback((_) { + getInitialData(); + }); + } + + void getInitialData() async { + ///get previoues Attachment from Apis. + isLoading = true; + setState(() {}); + _attachments = await assetDeliveryProvider.getAttachments(tableItemId: widget.tableItemId); + isLoading = false; + setState(() {}); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + appBar: DefaultAppBar( + title: 'Attachments'.addTranslation, + onBackPress: () { + Navigator.pop(context); + }, + ), + body: isLoading + ? const CircularProgressIndicator(color: AppColor.primary10).center + : Column( + children: [ + AttachmentPicker( + label: context.translation.attachments, + attachment: _attachments, + buttonColor: AppColor.primary10, + onlyImages: false, + // showAsGrid: true, + buttonIcon: 'quotation_icon'.toSvgAsset(color: AppColor.primary10), + onChange: (attachment) {}, + ) + .toShadowContainer( + context, + borderRadius: 20, + padding: 12, + margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + ) + .expanded, + FooterActionButton.footerContainer( + context: context, + child: AppFilledButton( + buttonColor: AppColor.primary10, + label: 'Save'.addTranslation, + maxWidth: true, + onPressed: () async { + List attachement = []; + for (var item in _attachments) { + String fileName = + CMRequestUtils.isLocalUrl(item.name ?? '') ? ("${item.name ?? ''.split("/").last}|${base64Encode(File(item.name ?? '').readAsBytesSync())}") : item.name ?? ''; + attachement.add(GenericAttachmentModel(id: item.id ?? 0, name: fileName)); + } + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + Map payLoad ={ + 'assetDeliveryExternalDeliveryId': widget.tableItemId, + 'attachments':attachement, + }; + await assetDeliveryProvider.saveAttachment(payload:payLoad).then((status) async { + Navigator.pop(context); + if (status) { + ///Need to verify need to stay on this page and refresh or go back.. + Navigator.pop(context); + // assetDeliveryProvider.getDeliveryLinesListById( + // itemId: widget.tableItemId, + // ); + } + }); + }), + ), + ], + ), + ); + } +} diff --git a/lib/modules/asset_delivery_module/pages/change_status_bottomsheet.dart b/lib/modules/asset_delivery_module/pages/change_status_bottomsheet.dart index e0f1baa5..696207bf 100644 --- a/lib/modules/asset_delivery_module/pages/change_status_bottomsheet.dart +++ b/lib/modules/asset_delivery_module/pages/change_status_bottomsheet.dart @@ -1,3 +1,5 @@ + + import 'package:flutter/material.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; @@ -19,7 +21,7 @@ class AssetDeliveryBottomSheet { ); } - static Future changeStatusBottomSheet({required BuildContext context}) { + static Future changeStatusBottomSheet({required BuildContext context,required VoidCallback cancelStatusTap,required VoidCallback statusChangeTap}) { return buildBottomSheetParent( context: context, childWidget: Column( @@ -46,12 +48,16 @@ class AssetDeliveryBottomSheet { // textColor: context.isDark ? AppColor.neutral30 : Colors.white, textColor: AppColor.red30, showBorder: true, - onPressed: () { - Navigator.pop(context); + onPressed: () async { + cancelStatusTap(); + }, ).expanded, 12.width, - AppFilledButton(buttonColor: AppColor.green70, label: 'Change Status'.addTranslation, maxWidth: true, onPressed: () {}).expanded, + AppFilledButton(buttonColor: AppColor.green70, label: 'Change Status'.addTranslation, maxWidth: true, onPressed: () { + statusChangeTap(); + + }).expanded, ], ), ], diff --git a/lib/modules/asset_delivery_module/pages/delivery_inspection/cost_center_form_view.dart b/lib/modules/asset_delivery_module/pages/delivery_inspection/cost_center_form_view.dart index afe55e40..4dec60db 100644 --- a/lib/modules/asset_delivery_module/pages/delivery_inspection/cost_center_form_view.dart +++ b/lib/modules/asset_delivery_module/pages/delivery_inspection/cost_center_form_view.dart @@ -1,35 +1,45 @@ + +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:test_sa/common_widgets/lookup_autocomplete_field.dart'; import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/enum_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/lookup.dart'; -import 'package:test_sa/models/new_models/work_order_detail_model.dart'; import 'package:test_sa/modules/asset_delivery_module/models/cost_center_model.dart'; -import 'package:test_sa/modules/cm_module/cm_detail_provider.dart'; -import 'package:test_sa/modules/cm_module/cm_request_utils.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/cost_center_provider.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; +import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; -import 'package:test_sa/providers/lookups/request_type_lookup_provider.dart'; -import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; -import 'package:test_sa/views/widgets/status/report/service_report_assistant_employee_menu.dart'; class CostCenterFormView extends StatefulWidget { final List? costCenterList; - final ValueChanged>? onListChanged; + final String? itemNo; + final String? itemDescription; + final int? lineId; + final int? tableItemId; + final int? requestId; + final bool? isHmg; final double? cardPadding; const CostCenterFormView({ super.key, this.costCenterList, - this.onListChanged, + this.lineId, + this.requestId, + this.tableItemId, + this.itemNo, + this.isHmg, + this.itemDescription, this.cardPadding, }); @@ -38,26 +48,47 @@ class CostCenterFormView extends StatefulWidget { } class _CostCenterFormViewState extends State { - late List _list; + List _list = []; + late AssetDeliveryProvider assetDeliveryProvider; @override void initState() { super.initState(); - _list = List.from(widget.costCenterList ?? []); + assetDeliveryProvider = Provider.of(context, listen: false); + WidgetsBinding.instance.addPostFrameCallback((_) { + getInitialData(); + }); + } + + void getInitialData() async { + _list = await assetDeliveryProvider.getAssetDeliveryCostCenterListForLines( + lineId: widget.lineId, + tableItemId: widget.tableItemId, + ); + if (_list.isEmpty) { + _list.add(CostCenterModel( + id: 0, + )); + } + if (widget.isHmg == true) { + CostCenterProvider costCenterProvider = Provider.of(context, listen: false); + if (costCenterProvider.items.isEmpty) { + await costCenterProvider.getData(id: widget.requestId); + } + } + setState(() {}); } void _addNewEntry() { setState(() { - _list.add(CostCenterModel()); + _list.add(CostCenterModel(costCenter: Lookup())); }); - widget.onListChanged?.call(_list); } void _removeEntry(int index) { setState(() { _list.removeAt(index); }); - widget.onListChanged?.call(_list); } void _updateModel(int index, void Function(CostCenterModel model) updateList) { @@ -68,8 +99,6 @@ class _CostCenterFormViewState extends State { @override Widget build(BuildContext context) { - ///Need to add check if status changes.. - final isReadOnly = Provider.of(context, listen: false).isReadOnlyRequest; return Scaffold( backgroundColor: Theme.of(context).scaffoldBackgroundColor, appBar: DefaultAppBar( @@ -78,51 +107,105 @@ class _CostCenterFormViewState extends State { Navigator.pop(context); }, ), - body: Column( - children: [ - ListView.builder( - itemCount: _list.length + 1, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - padding: EdgeInsets.all(widget.cardPadding ?? 16), - itemBuilder: (context, index) { - if (index == _list.length) { - return Visibility( - visible: !isReadOnly, - child: AppFilledButton( - label: "Add Cost Center".addTranslation, - maxWidth: true, - textColor: AppColor.textColor(context), - buttonColor: context.isDark ? AppColor.neutral60 : AppColor.white10, - icon: Icon(Icons.add_circle, color: AppColor.blueStatus(context)), - showIcon: true, - onPressed: _addNewEntry, - ), - ); - } - return CostCenterItemCard( - model: _list[index], - index: index, - isReadOnly: isReadOnly, - onUpdate: (updateList) => _updateModel(index, updateList), - onRemove: () => _removeEntry(index), - ); - }, - ).expanded, - 8.height, - FooterActionButton.footerContainer( - context: context, - child: AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: () {}), - ), - ], - ), + body: Consumer(builder: (context, provider, child) { + return Column( + children: [ + itemDetails(context: context, itemNo: widget.itemNo, itemDescription: widget.itemDescription), + provider.isLoading + ? const CircularProgressIndicator(color: AppColor.primary10).center + : ListView.builder( + itemCount: _list.length + 1, + shrinkWrap: true, + padding: EdgeInsets.all(widget.cardPadding ?? 16), + itemBuilder: (context, index) { + if (index == _list.length) { + return Visibility( + child: AppFilledButton( + label: "Add Cost Center".addTranslation, + maxWidth: true, + textColor: AppColor.textColor(context), + buttonColor: context.isDark ? AppColor.neutral60 : AppColor.white10, + icon: Icon(Icons.add_circle, color: AppColor.blueStatus(context)), + showIcon: true, + onPressed: _addNewEntry, + ), + ); + } + return CostCenterItemCard( + model: _list[index], + index: index, + isReadOnly: false, + isHmg: widget.isHmg, + requestId: widget.requestId, + onUpdate: (updateList) => _updateModel(index, updateList), + onRemove: () => _removeEntry(index), + ); + }, + ).expanded, + 8.height, + FooterActionButton.footerContainer( + context: context, + child: AppFilledButton( + buttonColor: AppColor.primary10, + label: 'Save'.addTranslation, + maxWidth: true, + onPressed: () async { + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + await assetDeliveryProvider.saveCostCenterToLineDeliveryInspection(tableItemId: widget.tableItemId, lineId: widget.lineId, list: _list).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context); + assetDeliveryProvider.getDeliveryLinesListById( + itemId: widget.tableItemId, + ); + } + }); + }), + ), + ], + ); + }), ); } } +Widget itemDetails({required BuildContext context, String? itemNo, String? itemDescription}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Item No'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + itemNo ?? '-', + style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), + ), + 8.height, + Text( + 'Item Description'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + itemDescription ?? '-', + style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), + ), + ], + ).toShadowContainer( + context, + borderRadius: 20, + padding: 12, + margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + ); +} + class CostCenterItemCard extends StatelessWidget { final CostCenterModel model; + final bool? isHmg; final int index; + final int? requestId; final bool isReadOnly; final void Function(void Function(CostCenterModel model)) onUpdate; final VoidCallback onRemove; @@ -130,6 +213,8 @@ class CostCenterItemCard extends StatelessWidget { const CostCenterItemCard({ super.key, required this.model, + this.requestId, + this.isHmg, required this.index, required this.isReadOnly, required this.onUpdate, @@ -138,8 +223,6 @@ class CostCenterItemCard extends StatelessWidget { @override Widget build(BuildContext context) { - final requestedDate = Provider.of(context, listen: false).currentWorkOrder?.data?.requestedDate; - return Column( children: [ if (!isReadOnly) @@ -160,50 +243,52 @@ class CostCenterItemCard extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - ///TODO replace with exact data or type like searchable dropdown... - AppTextFormField( - labelText: 'Item No'.addTranslation, - backgroundColor: AppColor.fieldBgColor(context), - initialValue: '232434', - textAlign: TextAlign.center, - labelStyle: AppTextStyles.textFieldLabelStyle, - showShadow: false, - enable: false, - style: Theme.of(context).textTheme.titleMedium, - ), + isHmg == true + ? SingleItemDropDownMenu( + context: context, + height: 56.toScreenHeight, + title: 'Cost Center'.addTranslation, + showShadow: false, + backgroundColor: AppColor.fieldBgColor(context), + requestById: requestId, + showAsBottomSheet: true, + matchBy: DropDownMatchType.name, + initialValue: model.costCenter, + onSelect: (status) { + if (status != null) { + model.costCenter = status; + model.costCenterName = status.name; + } + }, + ) + : AppTextFormField( + labelText: 'Cost Center'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + initialValue: model.costCenterName ?? '', + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + onChange: (value) { + model.costCenterName = value; + }, + style: Theme.of(context).textTheme.titleMedium, + ), 8.height, AppTextFormField( - labelText: 'Item Description', + labelText: 'Quantity'.addTranslation, backgroundColor: AppColor.fieldBgColor(context), - initialValue: 'test decription abc', + initialValue: model.quantity != null ? model.quantity.toString() : '', textAlign: TextAlign.center, + enable: true, + textInputType: TextInputType.number, labelStyle: AppTextStyles.textFieldLabelStyle, showShadow: false, - enable: false, - style: Theme.of(context).textTheme.titleMedium, - ), - 8.height, - LookUpAutoCompleteField( - clearAfterPick: false, - forAssetName: true, - onChanged: (value) {}, - initialValue: model.costCenter?.name ?? '', - label: 'Cost Center'.addTranslation, - onPick: (value) { - model.costCenter = value; - }, - ), - 8.height, - SingleItemDropDownMenu( - context: context, - showAsBottomSheet: true, - backgroundColor: AppColor.neutral100, - showShadow: false, - title: 'Quantity'.addTranslation, - initialValue: model.costCenter, - onSelect: (value) { - model.costCenter = value; + onChange: (value) { + if (value.isNotEmpty) { + model.quantity = double.tryParse(value); + } }, + style: Theme.of(context).textTheme.titleMedium, ), ], ) diff --git a/lib/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart b/lib/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart index cc1310b0..40a4f61c 100644 --- a/lib/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart +++ b/lib/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart @@ -1,45 +1,40 @@ -import 'dart:convert'; import 'dart:developer'; -import 'dart:io'; + import 'package:flutter/material.dart'; -import 'package:flutter_advanced_switch/flutter_advanced_switch.dart'; import 'package:provider/provider.dart'; -import 'package:test_sa/common_widgets/lookup_autocomplete_field.dart'; -import 'package:test_sa/controllers/providers/api/all_requests_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/models/generic_attachment_model.dart'; -import 'package:test_sa/models/lookup.dart'; -import 'package:test_sa/modules/asset_delivery_module/models/cost_center_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/asset_delivery_data_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/delivery_inspection_form_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/delivery_line_model.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/asset_delivery_line_card_view.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/attachment_view.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/delivery_inspection/cost_center_form_view.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/delivery_inspection/oracle_user_autocomplete_field.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart'; -import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart'; -import 'package:test_sa/modules/asset_inventory_module/pages/search_asset_view.dart'; -import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart'; -import 'package:test_sa/modules/cm_module/cm_request_utils.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; -import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; -import 'package:test_sa/providers/service_request_providers/last_situation_provider.dart'; +import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; -import 'package:test_sa/views/widgets/equipment/asset_picker.dart'; -import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; -import 'package:test_sa/views/widgets/images/multi_image_picker_item.dart'; -import 'package:test_sa/views/widgets/requests/request_status.dart'; +import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import '../../../../new_views/common_widgets/app_filled_button.dart'; -import '../../../../new_views/common_widgets/default_app_bar.dart'; class DeliveryInspectionFormView extends StatefulWidget { static const String id = "/delivery-inspection-form"; + final AssetDeliveryTableModel deliveryTableModel; + final AssetDeliveryDataModel? requestModel; DeliveryInspectionFormView({ Key? key, + required this.deliveryTableModel, + this.requestModel, }) : super(key: key); @override @@ -48,14 +43,39 @@ class DeliveryInspectionFormView extends StatefulWidget { class _DeliveryInspectionFormViewState extends State { final GlobalKey _formKey = GlobalKey(); - final GlobalKey _scaffoldKey = GlobalKey(); - bool viewOnly = true; + bool viewOnly = false; + AssetDeliveryProvider? assetDeliveryProvider; + DeliveryInspectionFormModel model = DeliveryInspectionFormModel(); + bool isLoading = false; @override void initState() { + viewOnly = widget.deliveryTableModel.status?.value != 2; + WidgetsBinding.instance.addPostFrameCallback((_) { + getInitialData(); + }); super.initState(); } + void getInitialData() async { + assetDeliveryProvider = Provider.of(context, listen: false); + setState(() { + isLoading = true; + }); + final results = await Future.wait([ + assetDeliveryProvider!.getAssetDeliveryInspectionData( + itemId: widget.deliveryTableModel.id, + ), + assetDeliveryProvider!.getDeliveryLinesListById( + itemId: widget.deliveryTableModel.id, + ), + ]); + model = results[0] as DeliveryInspectionFormModel; + setState(() { + isLoading = false; + }); + } + @override void dispose() { super.dispose(); @@ -63,162 +83,189 @@ class _DeliveryInspectionFormViewState extends State @override Widget build(BuildContext context) { - return Form( - key: _formKey, - child: Column( - children: [ - SingleChildScrollView( - padding: const EdgeInsets.symmetric(horizontal: 16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (!viewOnly) ...[inspectionDetailsForm()] else ...[inspectionDetails()], - 8.height, - const Divider().defaultStyle(context), - linesList(context), - ], - ).toShadowContainer(context, borderRadius: 20, padding: 12)) - .expanded, - if (!viewOnly) ...[ - 8.height, - FooterActionButton.footerContainer( - context: context, - child: AppFilledButton(buttonColor: AppColor.green70, label: 'Change Status'.addTranslation, maxWidth: true, onPressed: _changeStatusTap), - ), - 8.height, - ], - FooterActionButton.footerContainer( - context: context, - child: !viewOnly - ? Row( - children: [ - AppFilledButton( - label: 'Cancel'.addTranslation, - maxWidth: true, - buttonColor: AppColor.background(context), - // textColor: context.isDark ? AppColor.neutral30 : Colors.white, - textColor: AppColor.red30, - showBorder: true, - onPressed: _cancelTap, - ).expanded, - 12.width, - AppFilledButton(buttonColor: AppColor.black10, label: 'View History'.addTranslation, maxWidth: true, onPressed: _viewHistoryTap).expanded, - ], - ) - : Row( - children: [ - AppFilledButton(buttonColor: AppColor.black10, label: 'View History'.addTranslation, maxWidth: true, onPressed: _viewHistoryTap).expanded, - 12.width, - AppFilledButton(buttonColor: AppColor.primary10, label: 'Next'.addTranslation, maxWidth: true, onPressed: _nextTap).expanded, - ], - ), - ), - ], + return Scaffold( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + appBar: DefaultAppBar( + title: 'Delivery Inspection'.addTranslation, + onBackPress: () { + Navigator.pop(context); + }, ), + body: isLoading + ? const CircularProgressIndicator(color: AppColor.primary10).center + : Form( + key: _formKey, + child: Column( + children: [ + SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (!viewOnly) ...[inspectionDetailsForm()] else ...[inspectionDetails()], + 8.height, + Text( + 'Total Time'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + model.totalTime != null ? '${model.totalTime.toString()} hours' : '-', + style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), + ), + 8.height, + const Divider().defaultStyle(context), + Text( + "Lines", + style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + linesList(context), + ], + ).toShadowContainer(context, borderRadius: 20, padding: 12)) + .expanded, + if (!viewOnly) ...[ + FooterActionButton.footerContainer( + context: context, + child: AppFilledButton(buttonColor: AppColor.primary10, label: 'Attachments'.addTranslation, maxWidth: true, onPressed: _attachmentTap), + ), + 8.height, + ], + FooterActionButton.footerContainer( + context: context, + child: !viewOnly + ? Row( + children: [ + AppFilledButton( + label: 'Cancel'.addTranslation, + maxWidth: true, + buttonColor: AppColor.background(context), + // textColor: context.isDark ? AppColor.neutral30 : Colors.white, + textColor: AppColor.red30, + showBorder: true, + onPressed: _cancelTap, + ).expanded, + 12.width, + AppFilledButton(buttonColor: AppColor.green70, label: 'Change Status'.addTranslation, maxWidth: true, onPressed: _changeStatusTap).expanded, + ], + ) + : AppFilledButton(buttonColor: AppColor.primary10, label: 'Next'.addTranslation, maxWidth: true, onPressed: _nextTap), + ), + ], + ), + ), ); } Widget linesList(BuildContext context) { - final assetDeliveryTableList = ['abc', 'def', 'ghi', 'fhg', 'hjhh']; - return Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Lines", - style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), - ), - 8.height, - ListView.separated( - itemCount: assetDeliveryTableList.length, - separatorBuilder: (_, __) => 8.height, - padding: EdgeInsets.zero, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (listContext, itemIndex) { - return AssetDeliveryLineCard( - deliveryDetails: AssetInventoryModel(), - isViewOnly: viewOnly, - editPress: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => CostCenterFormView( - costCenterList: [CostCenterModel()], - onListChanged: (updatedList) { - // requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployList = updatedList; - }, - ))); - }, - ); - }, - ), - ], - ); + return Consumer(builder: (context, provider, child) { + List linesList = provider.deliveryLinesList; + return provider.isDeliveryLineListLoading + ? SizedBox(height: 200.toScreenHeight, child: const CircularProgressIndicator(color: AppColor.primary10).center) + : linesList.isEmpty + ? const NoDataFound().center + : ListView.separated( + itemCount: linesList.length, + separatorBuilder: (_, __) => 8.height, + padding: EdgeInsets.zero, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (listContext, itemIndex) { + DeliveryLineModel model = linesList[itemIndex]; + return AssetDeliveryLineCard( + deliveryLineModel: model, + isViewOnly: viewOnly, + editPress: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => CostCenterFormView( + itemNo: model.itemNumber, + lineId: model.id, + isHmg: widget.requestModel?.isHMG, + tableItemId: widget.deliveryTableModel.id, + requestId: widget.requestModel?.id, + itemDescription: model.itemDescription, + ))); + }, + ); + }, + ); + }); + } + + void calculateTotalTime() { + if (model.deliveryInspectionInspectedDateFrom == null || model.deliveryInspectionInspectedDateTo == null) { + model.totalTime = null; + return; + } + final fromDate = model.deliveryInspectionInspectedDateFrom!; + final toDate = model.deliveryInspectionInspectedDateTo!; + final hours = toDate.difference(fromDate).inSeconds / 3600.0; + model.totalTime = num.parse(hours.toStringAsFixed(3)); } Widget inspectionDetailsForm() { return Column( children: [ - SingleItemDropDownMenu( - context: context, - height: 56.toScreenHeight, - title: 'Inspected by'.addTranslation, - titleTextColor: AppColor.neutral120, - showShadow: false, - // backgroundColor: AppColor.neutral100, - backgroundColor: AppColor.fieldBgColor(context), - showAsBottomSheet: true, - // initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, - onSelect: (status) { - if (status != null) { - // requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; + if (widget.requestModel?.isHMG == true) ...[ + OracleUserAutoCompleteField( + clearAfterPick: false, + initialValue: model.deliveryInspectionInspectedBy ?? '', + label: 'Inspected by'.addTranslation, + onPick: (value) { + model.deliveryInspectionInspectedBy = value.fullName; setState(() {}); - } - }, - ), - // LookUpAutoCompleteField( - // clearAfterPick: false, - // forAssetName: true, - // onChanged: (value) { - // _scannedAssetModel?.newAssetNameId = null; - // _scannedAssetModel?.newAssetNameText = value; - // }, - // initialValue: _scannedAssetModel?.assetName ?? "", - // label: 'Asset Name'.addTranslation, - // onPick: (value) { - // _scannedAssetModel?.newAssetNameText = null; - // _scannedAssetModel?.assetName = value.name; - // _scannedAssetModel?.newAssetNameId = value.id; - // setState(() {}); - // }, - // ), - 8.height, - SingleItemDropDownMenu( - context: context, - height: 56.toScreenHeight, - title: 'Approved by'.addTranslation, - showShadow: false, - titleTextColor: AppColor.neutral120, - // backgroundColor: AppColor.neutral100, - backgroundColor: AppColor.fieldBgColor(context), - showAsBottomSheet: true, - // initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, - onSelect: (status) { - if (status != null) { - // requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; + }, + onChanged: (value) {}, + ), + 8.height, + OracleUserAutoCompleteField( + clearAfterPick: false, + initialValue: model.deliveryInspectionApprovedBy ?? '', + label: 'Approved by'.addTranslation, + onChanged: (value) {}, + onPick: (value) { + model.deliveryInspectionApprovedBy = value.fullName; setState(() {}); - } - }, - ), + }, + ), + ] //No HMG user free text insted of dropdown ... + else ...[ + AppTextFormField( + labelText: 'Inspected by'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + initialValue: model.deliveryInspectionInspectedBy ?? '', + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + onChange: (value) { + model.deliveryInspectionInspectedBy = value; + }, + style: Theme.of(context).textTheme.titleMedium, + ), + 8.height, + AppTextFormField( + labelText: 'Approved by'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + initialValue: model.deliveryInspectionApprovedBy ?? '', + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + onChange: (value) { + model.deliveryInspectionApprovedBy = value; + }, + style: Theme.of(context).textTheme.titleMedium, + ), + ], 8.height, ADatePicker( label: 'Inspected Date/Time From'.addTranslation, hideShadow: true, height: 56.toScreenHeight, backgroundColor: AppColor.fieldBgColor(context), - // date: _pickerStartAt, - // from: widget.pickerFromDate, + date: model.deliveryInspectionInspectedDateFrom, + from: DateTime(DateTime.now().year, 1, 1), formatDateWithTime: true, onDatePicker: (selectedDate) { showTimePicker( @@ -244,19 +291,23 @@ class _DeliveryInspectionFormViewState extends State }, ).then((selectedTime) { if (selectedTime != null) { - // _pickerStartAt = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + model.deliveryInspectionInspectedDateFrom = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + // calculateTotalTime(); + + ///need to check if need validation or not. // if (widget.pickerFromDate != null && _pickerStartAt!.isBefore(widget.pickerFromDate!)) { // "Start time is before the request time.".showToast; // _pickerStartAt = null; // selectedTime = null; // return; // } - // if (_pickerStartAt!.isAfter(DateTime.now())) { - // "Start time is after than current time".showToast; - // _pickerStartAt = null; - // selectedTime = null; - // return; - // } + if (model.deliveryInspectionInspectedDateFrom!.isAfter(DateTime.now())) { + "Start time is after than current time".showToast; + model.deliveryInspectionInspectedDateFrom = null; + selectedTime = null; + return; + } + setState(() {}); } }); @@ -268,8 +319,8 @@ class _DeliveryInspectionFormViewState extends State hideShadow: true, height: 56.toScreenHeight, backgroundColor: AppColor.fieldBgColor(context), - // date: _pickerStartAt, - // from: widget.pickerFromDate, + date: model.deliveryInspectionInspectedDateTo, + from: model.deliveryInspectionInspectedDateFrom, formatDateWithTime: true, onDatePicker: (selectedDate) { showTimePicker( @@ -295,19 +346,22 @@ class _DeliveryInspectionFormViewState extends State }, ).then((selectedTime) { if (selectedTime != null) { - // _pickerStartAt = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + model.deliveryInspectionInspectedDateTo = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + calculateTotalTime(); + + ///Need to check need validation or not.. // if (widget.pickerFromDate != null && _pickerStartAt!.isBefore(widget.pickerFromDate!)) { // "Start time is before the request time.".showToast; // _pickerStartAt = null; // selectedTime = null; // return; // } - // if (_pickerStartAt!.isAfter(DateTime.now())) { - // "Start time is after than current time".showToast; - // _pickerStartAt = null; - // selectedTime = null; - // return; - // } + if (model.deliveryInspectionInspectedDateTo!.isAfter(DateTime.now())) { + "End time is after than current time".showToast; + model.deliveryInspectionInspectedDateTo = null; + selectedTime = null; + return; + } setState(() {}); } }); @@ -327,7 +381,7 @@ class _DeliveryInspectionFormViewState extends State ), 8.height, Text( - 'Mahmoud Shrouf'.addTranslation, + model.deliveryInspectionInspectedBy ?? '-', style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), 8.height, @@ -337,7 +391,7 @@ class _DeliveryInspectionFormViewState extends State ), 8.height, Text( - 'Mahmoud Shrouf'.addTranslation, + model.deliveryInspectionApprovedBy ?? '-', style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), 8.height, @@ -347,7 +401,7 @@ class _DeliveryInspectionFormViewState extends State ), 8.height, Text( - '19 August, 2025'.addTranslation, + model.deliveryInspectionInspectedDateFrom != null ? model.deliveryInspectionInspectedDateFrom!.toString().toServiceRequestDetailsFormat : '-', style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), 8.height, @@ -357,22 +411,63 @@ class _DeliveryInspectionFormViewState extends State ), 8.height, Text( - '19 August, 2025'.addTranslation, + model.deliveryInspectionInspectedDateTo != null ? model.deliveryInspectionInspectedDateTo!.toString().toServiceRequestDetailsFormat : '-', style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), ], ); } - void _viewHistoryTap() async {} + void _attachmentTap() async { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AssetDeliveryAttachmentView( + tableItemId: widget.deliveryTableModel.id, + ))); + } - void _cancelTap() async {} + void _cancelTap() async { + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + await assetDeliveryProvider!.changeDeliveryStatusToCancel(itemId: widget.deliveryTableModel.id).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context); + await assetDeliveryProvider!.getAssetDeliveryTableListById(requestId: widget.requestModel?.id); + } + }); + } void _nextTap() { - Navigator.push(context, MaterialPageRoute(builder: (context) => TechnicalInspectionLinesListView())); + if (widget.deliveryTableModel.isContainsTechnicalInspection == true) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => TechnicalInspectionLinesListView( + deliveryTableModel: widget.deliveryTableModel, + requestModel: widget.requestModel, + ))); + } else { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => EndUserCostCenterLIstView( + deliveryTableModel: widget.deliveryTableModel, + requestModel: widget.requestModel, + ))); + } } void _changeStatusTap() async { _formKey.currentState!.save(); + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + model.assetDeliveryExternalDeliveryId = widget.deliveryTableModel.id; + await assetDeliveryProvider!.changeDeliveryStatus(requestPayload: model.toJson()).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context); + await assetDeliveryProvider!.getAssetDeliveryTableListById(requestId: widget.requestModel?.id); + } + }); } } diff --git a/lib/modules/asset_delivery_module/pages/delivery_inspection/oracle_user_autocomplete_field.dart b/lib/modules/asset_delivery_module/pages/delivery_inspection/oracle_user_autocomplete_field.dart new file mode 100644 index 00000000..5411081a --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/delivery_inspection/oracle_user_autocomplete_field.dart @@ -0,0 +1,114 @@ +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/oracle_user_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/app_style/app_text_style.dart'; +import 'package:test_sa/views/app_style/sizing.dart'; + +class OracleUserAutoCompleteField extends StatefulWidget { + final String initialValue; + final String label; + final bool clearAfterPick; + final Function(OracleUserModel) onPick; + final Function(String)? onChanged; + + const OracleUserAutoCompleteField({Key? key, required this.initialValue, required this.label, required this.onPick, this.clearAfterPick = true, this.onChanged}) : super(key: key); + + @override + _AutoCompletePartsFieldState createState() => _AutoCompletePartsFieldState(); +} + +class _AutoCompletePartsFieldState extends State { + AssetDeliveryProvider? assetDeliveryProvider; + late TextEditingController _controller; + + @override + void initState() { + _controller = TextEditingController(text: widget.initialValue); + super.initState(); + } + + @override + void didUpdateWidget(covariant OracleUserAutoCompleteField oldWidget) { + if (widget.initialValue != oldWidget.initialValue) { + _controller = TextEditingController(text: widget.initialValue); + } + super.didUpdateWidget(oldWidget); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + assetDeliveryProvider ??= Provider.of(context); + final border = UnderlineInputBorder(borderSide: BorderSide.none, borderRadius: BorderRadius.circular(10)); + return Container( + decoration: BoxDecoration( + color: AppColor.background(context), + borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), + // boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], + ), + child: Autocomplete( + optionsBuilder: (TextEditingValue textEditingValue) async { + if (textEditingValue.text.isEmpty) { + return const Iterable.empty(); + } + return await assetDeliveryProvider!.getOracleUserAutoCompleteDetails(query: textEditingValue.text); + }, + displayStringForOption: (OracleUserModel option) => option.fullName ?? "", + fieldViewBuilder: (BuildContext context, TextEditingController fieldTextEditingController, FocusNode fieldFocusNode, VoidCallback onFieldSubmitted) { + return TextField( + controller: _controller, + focusNode: fieldFocusNode, + style: AppTextStyles.bodyText.copyWith(color: AppColor.black10), + textAlign: TextAlign.start, + decoration: InputDecoration( + border: border, + disabledBorder: border, + focusedBorder: border, + enabledBorder: border, + errorBorder: border, + contentPadding: EdgeInsets.symmetric(vertical: 8.toScreenHeight, horizontal: 16.toScreenWidth), + constraints: const BoxConstraints(), + suffixIconConstraints: const BoxConstraints(minWidth: 0), + filled: true, + fillColor: AppColor.fieldBgColor(context), + errorStyle: AppTextStyle.tiny.copyWith(color: context.isDark ? AppColor.red50 : AppColor.red60), + floatingLabelStyle: AppTextStyle.body1.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? null : AppColor.neutral20), + labelText: widget.label, + labelStyle: AppTextStyles.tinyFont.copyWith(color: AppColor.textColor(context)), + ), + textInputAction: TextInputAction.search, + onChanged: (text) { + if (widget.onChanged != null) { + widget.onChanged!(text); + fieldTextEditingController.text = text; + } + }, + onSubmitted: (String value) { + onFieldSubmitted(); + }, + ); + }, + onSelected: (OracleUserModel selection) { + if (widget.clearAfterPick) { + _controller.clear(); + } else { + _controller.text = selection.fullName ?? ''; + } + widget.onPick(selection); + }, + ), + ); + } +} diff --git a/lib/modules/asset_delivery_module/pages/end_user_acceptance/cost_center_card_view.dart b/lib/modules/asset_delivery_module/pages/end_user_acceptance/cost_center_card_view.dart index d53d3754..59237ffd 100644 --- a/lib/modules/asset_delivery_module/pages/end_user_acceptance/cost_center_card_view.dart +++ b/lib/modules/asset_delivery_module/pages/end_user_acceptance/cost_center_card_view.dart @@ -1,23 +1,26 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; +import 'package:test_sa/common_widgets/lookup_autocomplete_field.dart'; import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/cost_center_model.dart'; import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; -class CostCenterCard extends StatelessWidget { - ///Need to replace with cost model. - AssetInventoryModel deliveryDetails; - ///if include in model skip this +class EndUserCostCenterCardView extends StatelessWidget { + CostCenterModel costModel; + VoidCallback? editPress; bool isViewOnly; - VoidCallback ?editPress; - CostCenterCard({ + EndUserCostCenterCardView({ super.key, - required this.isViewOnly, - required this.deliveryDetails, + required this.costModel, this.editPress, + required this.isViewOnly, }); @override @@ -29,32 +32,30 @@ class CostCenterCard extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - 'Item No: ${deliveryDetails.transactionDate?.toServiceRequestDetailsFormat ?? '-'}', - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + Flexible( + child: Text( + 'Cost Center Name: ${costModel.costCenterName ?? '-'}', + overflow: TextOverflow.ellipsis, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), ), - if(!isViewOnly) - 'edit_icon'.toSvgAsset().onPress(() { - if(editPress!=null){ - editPress!(); - } - }), + 8.width, + if (!isViewOnly) + 'edit_icon'.toSvgAsset(height: 18, width: 18).onPress(() { + if (editPress != null) { + editPress!(); + } + }), ], ), Text( - 'Asset Number: ${deliveryDetails.assetNumber ?? '-'}', - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), - ), - Text( - 'Asset Type: ${deliveryDetails.assetName ?? '-'}', + 'Accepted By: ${costModel.acceptedBy ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), - ), - Text( - 'Replaced Asset No: ${deliveryDetails.assetName ?? '-'}', + ),Text( + 'Accepted By Email: ${costModel.acceptedByEmail ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), - ), - Text( - 'Serial Number: ${deliveryDetails.assetName ?? '-'}', + ),Text( + 'Acceptance Date: ${costModel.acceptanceDate!=null? costModel.acceptanceDate.toString().toAssetDetailsFormat: '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), ], diff --git a/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_acceptance_form_view.dart b/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_acceptance_form_view.dart deleted file mode 100644 index 978a1d93..00000000 --- a/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_acceptance_form_view.dart +++ /dev/null @@ -1,171 +0,0 @@ -import 'dart:convert'; -import 'dart:developer'; -import 'dart:io'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_advanced_switch/flutter_advanced_switch.dart'; -import 'package:provider/provider.dart'; -import 'package:test_sa/common_widgets/lookup_autocomplete_field.dart'; -import 'package:test_sa/controllers/providers/api/all_requests_provider.dart'; -import 'package:test_sa/extensions/context_extension.dart'; -import 'package:test_sa/extensions/int_extensions.dart'; -import 'package:test_sa/extensions/string_extensions.dart'; -import 'package:test_sa/extensions/text_extensions.dart'; -import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/models/device/asset.dart'; -import 'package:test_sa/models/generic_attachment_model.dart'; -import 'package:test_sa/models/lookup.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/asset_delivery_line_card_view.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_cost_center_card_view.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_parent_asset_list_view.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/update_child_asset_view.dart'; -import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart'; -import 'package:test_sa/modules/asset_inventory_module/pages/search_asset_view.dart'; -import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart'; -import 'package:test_sa/modules/cm_module/cm_request_utils.dart'; -import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; -import 'package:test_sa/new_views/app_style/app_color.dart'; -import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; -import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; -import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; -import 'package:test_sa/providers/service_request_providers/last_situation_provider.dart'; -import 'package:test_sa/providers/service_request_providers/reject_reason_provider.dart'; -import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; -import 'package:test_sa/views/widgets/e_signature/e_signature.dart'; -import 'package:test_sa/views/widgets/equipment/asset_picker.dart'; -import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; -import 'package:test_sa/views/widgets/images/multi_image_picker_item.dart'; -import 'package:test_sa/views/widgets/requests/request_status.dart'; -import '../../../../new_views/common_widgets/app_filled_button.dart'; -import '../../../../new_views/common_widgets/default_app_bar.dart'; - -class EndUserAcceptanceFormView extends StatefulWidget { - EndUserAcceptanceFormView({ - Key? key, - }) : super(key: key); - - @override - State createState() => _EndUserAcceptanceFormViewState(); -} - -class _EndUserAcceptanceFormViewState extends State { - final GlobalKey _formKey = GlobalKey(); - final GlobalKey _scaffoldKey = GlobalKey(); - bool viewOnly = false; - Uint8List? newSignature; - String? endUserSignature; - - @override - void initState() { - super.initState(); - } - - @override - void dispose() { - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - key: _scaffoldKey, - appBar: DefaultAppBar( - title: 'Item Details'.addTranslation, - titleStyle: AppTextStyles.heading3.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), - ), - body: Form( - key: _formKey, - child: Column( - children: [ - SingleChildScrollView( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SingleItemDropDownMenu( - context: context, - height: 56.toScreenHeight, - title: 'Status'.addTranslation, - titleTextColor: AppColor.neutral120, - showShadow: false, - // backgroundColor: AppColor.neutral100, - backgroundColor: AppColor.fieldBgColor(context), - showAsBottomSheet: true, - // initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, - onSelect: (status) { - if (status != null) { - // requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; - setState(() {}); - } - }, - ), - 8.height, - SingleItemDropDownMenu( - context: context, - height: 56.toScreenHeight, - title: 'Rejection Reason '.addTranslation, - titleTextColor: AppColor.neutral120, - showShadow: false, - // backgroundColor: AppColor.neutral100, - backgroundColor: AppColor.fieldBgColor(context), - showAsBottomSheet: true, - // initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, - onSelect: (status) { - if (status != null) { - // requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; - setState(() {}); - } - }, - ), - 8.height, - AppTextFormField( - initialValue: '', - labelText: 'Description'.addTranslation, - backgroundColor: AppColor.fieldBgColor(context), - showShadow: false, - labelStyle: AppTextStyles.textFieldLabelStyle, - alignLabelWithHint: true, - textInputType: TextInputType.multiline, - onChange: (value) {}, - onSaved: (value) {}, - ), - 8.height, - ESignature( - title: 'End User Signature', - oldSignature: '', - newSignature: newSignature, - backgroundColor: AppColor.neutral100, - showShadow: false, - onChange: (signature) { - if (signature.isEmpty) return; - setState(() { - newSignature = signature; - endUserSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - }); - }, - onSaved: (signature) { - if (signature == null || signature.isEmpty) return; - setState(() { - newSignature = signature; - endUserSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - }); - }, - ), - ], - ).toShadowContainer(context, borderRadius: 20, padding: 12)) - .expanded, - FooterActionButton.footerContainer(context: context, child: AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: _saveTap)), - ], - ), - ), - ); - } - - ///Need to check which details show here... - - void _saveTap() async { - AssetInventoryProvider assetInventoryProvider = Provider.of(context, listen: false); - _formKey.currentState!.save(); - } -} diff --git a/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_asset_detail_card.dart b/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_asset_detail_card.dart new file mode 100644 index 00000000..838ba850 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_asset_detail_card.dart @@ -0,0 +1,116 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/end_user_asset_details_model.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/views/widgets/requests/request_status.dart'; + +class EndUserAssetDetailCard extends StatelessWidget { + EndUserAssetDetailsModel assetModel; + bool isViewOnly; + VoidCallback? editPress; + + EndUserAssetDetailCard({ + super.key, + required this.isViewOnly, + required this.assetModel, + this.editPress, + }); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + assetModel.status != null + ? StatusLabel( + label: assetModel.status?.name, + radius: 4, + textColor: getAssetStatusColor(context: context, status: assetModel.status?.name ?? '', isBackground: false), + backgroundColor: getAssetStatusColor(context: context, status: assetModel.status?.name ?? ''), + ) + : const SizedBox(), + if (!isViewOnly) + 'edit_icon'.toSvgAsset().onPress(() { + if (editPress != null) { + editPress!(); + } + }), + ], + ), + 8.height, + if (assetModel.type == 'Accessory') ...[ + Text( + 'Type: ${assetModel.type ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Item Number: ${assetModel.itemNumber ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Received Quantity: ${assetModel.receivedQty ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Rejection Reason: ${assetModel.rejectionReason?.name ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Rejected Quantity: ${assetModel.rejectedQty ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Description: ${assetModel.description ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + ] else ...[ + Text( + 'Type: ${assetModel.type ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Item Number: ${assetModel.itemNumber ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Asset Number: ${assetModel.assetNumber ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Serial No: ${assetModel.serialNo ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Replaced Asset No: ${assetModel.replacedAssetNo ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Rejection Reason: ${assetModel.rejectionReason?.name ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Description: ${assetModel.description ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + ], + ], + ).toShadowContainer(context, borderRadius: 20, padding: 12); + } + + Color getAssetStatusColor({required BuildContext context, required String status, bool? isBackground = true}) { + switch (status) { + case 'Accept': + return isBackground! ? AppColor.green70.withOpacity(0.4) : AppColor.green15; + case 'Reject': + return isBackground! ? AppColor.red30.withOpacity(0.4) : AppColor.red30; + default: + return Colors.blueGrey; + } + } +} diff --git a/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart b/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart index 4af7aa9f..3711f237 100644 --- a/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart +++ b/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart @@ -1,26 +1,30 @@ - import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/asset_delivery_data_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/cost_center_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/attachment_view.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/end_user_acceptance/cost_center_card_view.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_cost_center_view.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/update_technical_inspection_lines_view.dart'; -import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_cost_center_details_view.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; -import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; -import 'package:test_sa/providers/service_request_providers/last_situation_provider.dart'; -import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; +import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import '../../../../new_views/common_widgets/app_filled_button.dart'; import '../../../../new_views/common_widgets/default_app_bar.dart'; class EndUserCostCenterLIstView extends StatefulWidget { + final AssetDeliveryTableModel deliveryTableModel; + final AssetDeliveryDataModel? requestModel; + EndUserCostCenterLIstView({ Key? key, + required this.deliveryTableModel, + this.requestModel, }) : super(key: key); @override @@ -31,12 +35,33 @@ class _EndUserCostCenterLIstViewState extends State { final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); bool viewOnly = false; + List costCenterList = []; + AssetDeliveryProvider? assetDeliveryProvider; + bool isLoading = false; @override void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + getInitialData(); + }); super.initState(); } + void getInitialData() async { + assetDeliveryProvider = Provider.of(context, listen: false); + isLoading = true; + if (widget.deliveryTableModel.status?.value != null && widget.deliveryTableModel.status!.value! > 4) { + viewOnly = true; + } + setState(() {}); + costCenterList = (await assetDeliveryProvider?.getEndUserCostCenterList( + tableItemId: widget.deliveryTableModel.id, + )) ?? + []; + isLoading = false; + setState(() {}); + } + @override void dispose() { super.dispose(); @@ -52,59 +77,45 @@ class _EndUserCostCenterLIstViewState extends State { ), body: Form( key: _formKey, - child: Column( - children: [ - SingleChildScrollView( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - linesList(context), - ], - ).toShadowContainer(context, borderRadius: 20, padding: 12)) - .expanded, - if (!viewOnly) ...[ - 8.height, - FooterActionButton.footerContainer( - context: context, - child: AppFilledButton(buttonColor: AppColor.green70, label: 'Change Status'.addTranslation, maxWidth: true, onPressed: _changeStatusTap), - ), - 8.height, - ], - FooterActionButton.footerContainer( - context: context, - child: !viewOnly - ? Row( - children: [ - AppFilledButton( - label: 'Cancel'.addTranslation, - maxWidth: true, - buttonColor: AppColor.background(context), - // textColor: context.isDark ? AppColor.neutral30 : Colors.white, - textColor: AppColor.red30, - showBorder: true, - onPressed: _cancelTap, - ).expanded, - 12.width, - AppFilledButton(buttonColor: AppColor.black10, label: 'View History'.addTranslation, maxWidth: true, onPressed: _viewHistoryTap).expanded, - ], - ) - : Row( - children: [ - AppFilledButton(buttonColor: AppColor.black10, label: 'View History'.addTranslation, maxWidth: true, onPressed: _viewHistoryTap).expanded, - 12.width, - AppFilledButton(buttonColor: AppColor.primary10, label: 'Next'.addTranslation, maxWidth: true, onPressed: _nextTap).expanded, - ], + child: isLoading + ? const CircularProgressIndicator(color: AppColor.primary10).center + : Column( + children: [ + //Refactor this + SingleChildScrollView(padding: const EdgeInsets.all(16), child: linesList(context).toShadowContainer(context, borderRadius: 20, padding: 12)).expanded, + if (!viewOnly) ...[ + FooterActionButton.footerContainer( + context: context, + child: AppFilledButton(buttonColor: AppColor.primary10, label: 'Attachments'.addTranslation, maxWidth: true, onPressed: _attachmentTap), ), - ), - ], - ), + 8.height, + ], + !viewOnly + ? FooterActionButton.footerContainer( + context: context, + child: Row( + children: [ + AppFilledButton( + label: 'Cancel'.addTranslation, + maxWidth: true, + buttonColor: AppColor.background(context), + textColor: AppColor.red30, + showBorder: true, + onPressed: _cancelTap, + ).expanded, + 12.width, + AppFilledButton(buttonColor: AppColor.green70, label: 'Change Status'.addTranslation, maxWidth: true, onPressed: _changeStatusTap).expanded, + ], + )) + : const SizedBox(), + ], + ), ), ); } + //Need to refector don't use listview and singlechildview both @waseem. Widget linesList(BuildContext context) { - final assetDeliveryTableList = ['abc', 'def', 'ghi', 'fhg', 'hjhh']; return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -115,17 +126,27 @@ class _EndUserCostCenterLIstViewState extends State { ), 8.height, ListView.separated( - itemCount: assetDeliveryTableList.length, + itemCount: costCenterList.length, separatorBuilder: (_, __) => 8.height, padding: EdgeInsets.zero, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (listContext, itemIndex) { - return CostCenterCard( - deliveryDetails : AssetInventoryModel(), + return EndUserCostCenterCardView( + costModel: costCenterList[itemIndex], isViewOnly: viewOnly, - editPress: () { - Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateEndUserCostCenterView())); + editPress: () async { + bool isRefresh = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => UpdateEndUserCostCenterDetailsView( + costCenterModel: costCenterList[itemIndex], + tableItemId: widget.deliveryTableModel.id, + isHmg: widget.requestModel?.isHMG, + ))); + if (isRefresh) { + getInitialData(); + } }, ); }, @@ -134,210 +155,38 @@ class _EndUserCostCenterLIstViewState extends State { ); } - Widget inspectionDetailsForm() { - return Column( - children: [ - SingleItemDropDownMenu( - context: context, - height: 56.toScreenHeight, - title: 'Inspected by'.addTranslation, - titleTextColor: AppColor.neutral120, - showShadow: false, - // backgroundColor: AppColor.neutral100, - backgroundColor: AppColor.fieldBgColor(context), - showAsBottomSheet: true, - // initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, - onSelect: (status) { - if (status != null) { - // requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; - setState(() {}); - } - }, - ), - 8.height, - SingleItemDropDownMenu( - context: context, - height: 56.toScreenHeight, - title: 'Approved by'.addTranslation, - showShadow: false, - titleTextColor: AppColor.neutral120, - // backgroundColor: AppColor.neutral100, - backgroundColor: AppColor.fieldBgColor(context), - showAsBottomSheet: true, - // initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, - onSelect: (status) { - if (status != null) { - // requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; - setState(() {}); - } - }, - ), - 8.height, - ADatePicker( - label: 'Inspected Date/Time From'.addTranslation, - hideShadow: true, - height: 56.toScreenHeight, - backgroundColor: AppColor.fieldBgColor(context), - // date: _pickerStartAt, - // from: widget.pickerFromDate, - formatDateWithTime: true, - onDatePicker: (selectedDate) { - showTimePicker( - context: context, - initialTime: TimeOfDay.now(), - builder: (BuildContext context, Widget? child) { - final ThemeData currentTheme = Theme.of(context); - return Theme( - data: currentTheme.copyWith( - timePickerTheme: TimePickerThemeData( - dialHandColor: AppColor.primary10, - dialBackgroundColor: Colors.grey.withOpacity(0.1), - hourMinuteColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.grey.withOpacity(0.1)), - dayPeriodColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.transparent), - dayPeriodTextColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? Colors.white : AppColor.primary10), - dayPeriodBorderSide: BorderSide(color: Colors.grey.withOpacity(0.2)), - entryModeIconColor: AppColor.primary10, - ), - textButtonTheme: TextButtonThemeData(style: TextButton.styleFrom(foregroundColor: AppColor.primary10)), - ), - child: child!, - ); - }, - ).then((selectedTime) { - if (selectedTime != null) { - // _pickerStartAt = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); - // if (widget.pickerFromDate != null && _pickerStartAt!.isBefore(widget.pickerFromDate!)) { - // "Start time is before the request time.".showToast; - // _pickerStartAt = null; - // selectedTime = null; - // return; - // } - // if (_pickerStartAt!.isAfter(DateTime.now())) { - // "Start time is after than current time".showToast; - // _pickerStartAt = null; - // selectedTime = null; - // return; - // } - setState(() {}); - } - }); - }, - ), - 8.height, - ADatePicker( - label: 'Inspected Date/Time To'.addTranslation, - hideShadow: true, - height: 56.toScreenHeight, - backgroundColor: AppColor.fieldBgColor(context), - // date: _pickerStartAt, - // from: widget.pickerFromDate, - formatDateWithTime: true, - onDatePicker: (selectedDate) { - showTimePicker( - context: context, - initialTime: TimeOfDay.now(), - builder: (BuildContext context, Widget? child) { - final ThemeData currentTheme = Theme.of(context); - return Theme( - data: currentTheme.copyWith( - timePickerTheme: TimePickerThemeData( - dialHandColor: AppColor.primary10, - dialBackgroundColor: Colors.grey.withOpacity(0.1), - hourMinuteColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.grey.withOpacity(0.1)), - dayPeriodColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.transparent), - dayPeriodTextColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? Colors.white : AppColor.primary10), - dayPeriodBorderSide: BorderSide(color: Colors.grey.withOpacity(0.2)), - entryModeIconColor: AppColor.primary10, - ), - textButtonTheme: TextButtonThemeData(style: TextButton.styleFrom(foregroundColor: AppColor.primary10)), - ), - child: child!, - ); - }, - ).then((selectedTime) { - if (selectedTime != null) { - // _pickerStartAt = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); - // if (widget.pickerFromDate != null && _pickerStartAt!.isBefore(widget.pickerFromDate!)) { - // "Start time is before the request time.".showToast; - // _pickerStartAt = null; - // selectedTime = null; - // return; - // } - // if (_pickerStartAt!.isAfter(DateTime.now())) { - // "Start time is after than current time".showToast; - // _pickerStartAt = null; - // selectedTime = null; - // return; - // } - setState(() {}); - } - }); - }, - ), - ], - ); - } - - Widget inspectionDetails() { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Inspected by'.addTranslation, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), - ), - 8.height, - Text( - 'Mahmoud Shrouf'.addTranslation, - style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), - ), - 8.height, - Text( - 'Approved by'.addTranslation, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), - ), - 8.height, - Text( - 'Mahmoud Shrouf'.addTranslation, - style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), - ), - 8.height, - Text( - 'Inspected Date/Time From'.addTranslation, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), - ), - 8.height, - Text( - '19 August, 2025'.addTranslation, - style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), - ), - 8.height, - Text( - 'Inspected Date/Time To'.addTranslation, - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), - ), - 8.height, - Text( - '19 August, 2025'.addTranslation, - style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), - ), - ], - ); - } - - void _viewHistoryTap() async { - + void _attachmentTap() async { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AssetDeliveryAttachmentView( + tableItemId: widget.deliveryTableModel.id, + ))); } void _cancelTap() async { - - } - - void _nextTap() async { - Navigator.push(context, MaterialPageRoute(builder: (context) => EndUserCostCenterLIstView())); + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + await assetDeliveryProvider?.changeDeliveryStatusToCancel(itemId: widget.deliveryTableModel.id).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context); + await assetDeliveryProvider?.getAssetDeliveryTableListById(requestId: widget.requestModel?.id); + } + }); } void _changeStatusTap() async { + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + await assetDeliveryProvider?.changeDeliveryStatus(itemId: widget.deliveryTableModel.id).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context); + await assetDeliveryProvider?.getAssetDeliveryTableListById(requestId: widget.requestModel?.id); + } + }); + } + void _nextTap() async { + // Navigator.push(context, MaterialPageRoute(builder: (context) => EndUserCostCenterLIstView())); } } diff --git a/lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_asset_details_view.dart b/lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_asset_details_view.dart new file mode 100644 index 00000000..d48326f8 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_asset_details_view.dart @@ -0,0 +1,180 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/string_extensions.dart'; +import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/end_user_asset_details_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/end_user_rejection_reason_lookup_provider.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/end_user_status_lookup_provider.dart'; +import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; +import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; +import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; +import '../../../../new_views/common_widgets/app_filled_button.dart'; +import '../../../../new_views/common_widgets/default_app_bar.dart'; + +class UpdateEndUserAssetDetailsView extends StatefulWidget { + EndUserAssetDetailsModel? assetDetailsModel; + String? costCenterName; + int? tableId; + + UpdateEndUserAssetDetailsView({Key? key, this.assetDetailsModel, this.costCenterName, this.tableId}) : super(key: key); + + @override + State createState() => _UpdateEndUserAssetDetailsViewState(); +} + +class _UpdateEndUserAssetDetailsViewState extends State { + final GlobalKey _formKey = GlobalKey(); + final GlobalKey _scaffoldKey = GlobalKey(); + bool viewOnly = false; + late AssetDeliveryProvider assetDeliveryProvider; + EndUserAssetDetailsModel model = EndUserAssetDetailsModel(); + late TextEditingController quantityController; + late TextEditingController descriptionController; + + @override + void initState() { + quantityController = TextEditingController(); + descriptionController = TextEditingController(); + WidgetsBinding.instance.addPostFrameCallback((_) { + getInitialData(); + }); + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + void getInitialData() async { + assetDeliveryProvider = Provider.of(context, listen: false); + if (widget.assetDetailsModel != null) { + model = EndUserAssetDetailsModel.fromJson(widget.assetDetailsModel!.toJson()); + model.costCenterName = widget.costCenterName; + model.assetDeliveryExternalDeliveryId = widget.tableId; + model.status = widget.assetDetailsModel?.status; + model.rejectionReason = widget.assetDetailsModel?.rejectionReason; + } + quantityController.text = model.rejectedQty != null ? model.rejectedQty.toString() : ''; + descriptionController.text = model.description ?? ''; + setState(() {}); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + key: _scaffoldKey, + appBar: DefaultAppBar( + title: 'Item Details'.addTranslation, + titleStyle: AppTextStyles.heading3.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), + ), + body: Form( + key: _formKey, + child: Column( + children: [ + SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SingleItemDropDownMenu( + context: context, + height: 56.toScreenHeight, + title: 'Status'.addTranslation, + titleTextColor: AppColor.neutral120, + showShadow: false, + backgroundColor: AppColor.fieldBgColor(context), + showAsBottomSheet: true, + initialValue: model.status, + onSelect: (status) { + if (status != null) { + model.status = status; + setState(() {}); + } + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + height: 56.toScreenHeight, + title: 'Rejection Reason '.addTranslation, + titleTextColor: AppColor.neutral120, + showShadow: false, + backgroundColor: AppColor.fieldBgColor(context), + showAsBottomSheet: true, + initialValue: model.rejectionReason, + onSelect: (reason) { + if (reason != null) { + model.rejectionReason = reason; + setState(() {}); + } + }, + ), + 8.height, + if (model.type == 'Accessory') ...[ + AppTextFormField( + labelText: 'Rejected Quantity'.addTranslation, + controller: quantityController, + backgroundColor: AppColor.fieldBgColor(context), + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + textInputType: TextInputType.number, + showShadow: false, + onChange: (value) { + if (value.isNotEmpty) { + model.rejectedQty = model.rejectedQty = num.tryParse(value); + } + }, + style: Theme.of(context).textTheme.titleMedium, + ), + 8.height, + ], + AppTextFormField( + controller: descriptionController, + labelText: 'Description'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + showShadow: false, + labelStyle: AppTextStyles.textFieldLabelStyle, + alignLabelWithHint: true, + textInputType: TextInputType.multiline, + onChange: (value) { + model.description = value; + }, + onSaved: (value) { + model.description = value; + }, + ), + 8.height, + ], + ).toShadowContainer(context, borderRadius: 20, padding: 12)) + .expanded, + FooterActionButton.footerContainer(context: context, child: AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: _saveTap)), + ], + ), + ), + ); + } + + ///Need to check which details show here... + + void _saveTap() async { + _formKey.currentState!.save(); + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + await assetDeliveryProvider.saveEndUserAssetDataData(model: model).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context, true); + } + }); + } +} diff --git a/lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_cost_center_details_view.dart b/lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_cost_center_details_view.dart new file mode 100644 index 00000000..3b98beaa --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_cost_center_details_view.dart @@ -0,0 +1,317 @@ +import 'dart:convert'; +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/string_extensions.dart'; +import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/cost_center_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/end_user_asset_details_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/end_user_acceptance/end_user_asset_detail_card.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/delivery_inspection/oracle_user_autocomplete_field.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_asset_details_view.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; +import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; +import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; +import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; +import 'package:test_sa/views/widgets/e_signature/e_signature.dart'; +import '../../../../new_views/common_widgets/app_filled_button.dart'; +import '../../../../new_views/common_widgets/default_app_bar.dart'; + +class UpdateEndUserCostCenterDetailsView extends StatefulWidget { + int? tableItemId; + CostCenterModel? costCenterModel; + bool? isHmg; + + UpdateEndUserCostCenterDetailsView({ + Key? key, + this.tableItemId, + this.costCenterModel, + this.isHmg, + }) : super(key: key); + + @override + State createState() => _UpdateEndUserCostCenterDetailsViewState(); +} + +class _UpdateEndUserCostCenterDetailsViewState extends State { + final GlobalKey _formKey = GlobalKey(); + final GlobalKey _scaffoldKey = GlobalKey(); + bool viewOnly = false; + CostCenterModel model = CostCenterModel(); + List assetList = []; + late AssetDeliveryProvider assetDeliveryProvider; + Uint8List? newSignature; + String? endUserSignature; + bool isLoading = false; + late TextEditingController acceptedByController; + late TextEditingController acceptedByEmailController; + + @override + void initState() { + acceptedByController = TextEditingController(); + acceptedByEmailController = TextEditingController(); + WidgetsBinding.instance.addPostFrameCallback((_) { + getInitialData(); + }); + super.initState(); + } + + void getInitialData() async { + assetDeliveryProvider = Provider.of(context, listen: false); + + if (widget.costCenterModel != null) { + model = CostCenterModel.fromJson(widget.costCenterModel!.toEndUserAcceptanceFormJson()); + _fillControllers(); + } + setState(() { + isLoading = true; + }); + assetList = await assetDeliveryProvider.getEndUserAssetList(tableItemId: widget.tableItemId, costCenterName: widget.costCenterModel?.costCenterName); + setState(() { + isLoading = false; + }); + } + + void _fillControllers() { + acceptedByController.text = model.acceptedBy ?? ''; + acceptedByEmailController.text = model.acceptedByEmail ?? ''; + } + + @override + void dispose() { + acceptedByController.dispose(); + acceptedByEmailController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + key: _scaffoldKey, + appBar: DefaultAppBar( + title: 'End-User Acceptance'.addTranslation, + titleStyle: AppTextStyles.heading3.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), + ), + body: Form( + key: _formKey, + child: Column( + children: [ + SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + inspectionDetailsForm(), + 8.height, + const Divider().defaultStyle(context), + + ///Need to implement later as discuss with Ahmed. + // Text( + // "Acceptance Form", + // style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + // ), + // 6.height, + // Row( + // children: [ + // 'warning_icon'.toSvgAsset(height: 16, width: 16), + // 6.width, + // Text( + // 'Review the acceptance form'.addTranslation, + // style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), + // ), + // 6.width, + // 'web_link_icon'.toSvgAsset(height: 20, width: 20), + // ], + // ), + 16.height, + Text( + "Items", + style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + endUserAssetList(context), + ], + ).toShadowContainer(context, borderRadius: 20, padding: 12)) + .expanded, + FooterActionButton.footerContainer(context: context, child: AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: _saveTap)), + ], + ), + ), + ); + } + + Widget endUserAssetList(BuildContext context) { + return isLoading + ? const CircularProgressIndicator(color: AppColor.primary10).center + : ListView.separated( + itemCount: assetList.length, + separatorBuilder: (_, __) => 8.height, + padding: EdgeInsets.zero, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (listContext, itemIndex) { + EndUserAssetDetailsModel model = assetList[itemIndex]; + return EndUserAssetDetailCard( + assetModel: model, + isViewOnly: viewOnly, + editPress: () async { + bool isRefresh = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => UpdateEndUserAssetDetailsView( + assetDetailsModel: model, + costCenterName: widget.costCenterModel?.costCenterName, + tableId: widget.tableItemId, + ))); + if (isRefresh) { + getInitialData(); + } + }, + ); + }, + ); + } + + Widget inspectionDetailsForm() { + return Column( + children: [ + ADatePicker( + label: 'Accepted Date'.addTranslation, + hideShadow: true, + height: 56.toScreenHeight, + backgroundColor: AppColor.fieldBgColor(context), + date: model.acceptanceDate, + from: DateTime(DateTime.now().year, 1, 1), + formatDateWithTime: true, + onDatePicker: (selectedDate) { + showTimePicker( + context: context, + initialTime: TimeOfDay.now(), + builder: (BuildContext context, Widget? child) { + final ThemeData currentTheme = Theme.of(context); + return Theme( + data: currentTheme.copyWith( + timePickerTheme: TimePickerThemeData( + dialHandColor: AppColor.primary10, + dialBackgroundColor: Colors.grey.withOpacity(0.1), + hourMinuteColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.grey.withOpacity(0.1)), + dayPeriodColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.transparent), + dayPeriodTextColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? Colors.white : AppColor.primary10), + dayPeriodBorderSide: BorderSide(color: Colors.grey.withOpacity(0.2)), + entryModeIconColor: AppColor.primary10, + ), + textButtonTheme: TextButtonThemeData(style: TextButton.styleFrom(foregroundColor: AppColor.primary10)), + ), + child: child!, + ); + }, + ).then((selectedTime) { + if (selectedTime != null) { + model.acceptanceDate = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + setState(() {}); + } + }); + }, + ), + 8.height, + if (widget.isHmg == true) ...[ + OracleUserAutoCompleteField( + clearAfterPick: false, + initialValue: model.acceptedBy ?? '', + label: 'Accepted By'.addTranslation, + onPick: (value) { + model.acceptedBy = value.fullName; + model.acceptedByEmail = value.employeeEmail; + acceptedByEmailController.text = value.employeeEmail ?? ''; + setState(() {}); + }, + onChanged: (value) {}, + ), + 8.height, + AppTextFormField( + labelText: 'Accepted By Email'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + controller: acceptedByEmailController, + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + enable: false, + style: Theme.of(context).textTheme.titleMedium, + ), + ] else ...[ + AppTextFormField( + labelText: 'Accepted By'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + controller: acceptedByController, + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + onChange: (value) { + model.acceptedBy = value; + }, + style: Theme.of(context).textTheme.titleMedium, + ), + 8.height, + AppTextFormField( + labelText: 'Accepted By Email'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + controller: acceptedByEmailController, + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + onChange: (value) { + model.acceptedByEmail = value; + }, + style: Theme.of(context).textTheme.titleMedium, + ), + ], + 8.height, + ESignature( + title: 'End User Signature', + oldSignature: model.acceptedBySignature, + newSignature: newSignature, + backgroundColor: AppColor.neutral100, + showShadow: false, + onChange: (signature) { + log('onChange called.'); + updateSignature(signature: signature); + }, + onSaved: (signature) { + log('onSaved called.'); + updateSignature(signature: signature); + }, + ) + ], + ); + } + + void updateSignature({Uint8List? signature}) { + if (signature == null || signature.isEmpty) { + model.acceptedBySignature = ''; + return; + } + setState(() { + newSignature = signature; + model.acceptedBySignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + }); + } + + void _saveTap() async { + _formKey.currentState!.save(); + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + model.assetDeliveryExternalDetailId = widget.tableItemId; + await assetDeliveryProvider.saveEndUserFormData(model: model).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context, true); + } + }); + } +} diff --git a/lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_cost_center_view.dart b/lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_cost_center_view.dart deleted file mode 100644 index 28136296..00000000 --- a/lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_cost_center_view.dart +++ /dev/null @@ -1,220 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:test_sa/extensions/context_extension.dart'; -import 'package:test_sa/extensions/int_extensions.dart'; -import 'package:test_sa/extensions/string_extensions.dart'; -import 'package:test_sa/extensions/text_extensions.dart'; -import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/models/device/asset.dart'; -import 'package:test_sa/models/lookup.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/end_user_acceptance/end_user_acceptance_form_view.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart'; -import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart'; -import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; -import 'package:test_sa/new_views/app_style/app_color.dart'; -import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; -import 'package:test_sa/providers/service_request_providers/last_situation_provider.dart'; -import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; -import '../../../../new_views/common_widgets/app_filled_button.dart'; -import '../../../../new_views/common_widgets/default_app_bar.dart'; - -class UpdateEndUserCostCenterView extends StatefulWidget { - UpdateEndUserCostCenterView({ - Key? key, - }) : super(key: key); - - @override - State createState() => _UpdateEndUserCostCenterViewState(); -} - -class _UpdateEndUserCostCenterViewState extends State { - final GlobalKey _formKey = GlobalKey(); - final GlobalKey _scaffoldKey = GlobalKey(); - bool viewOnly = false; - - @override - void initState() { - super.initState(); - } - - @override - void dispose() { - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - key: _scaffoldKey, - appBar: DefaultAppBar( - title: 'End-User Acceptance'.addTranslation, - titleStyle: AppTextStyles.heading3.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), - ), - body: Form( - key: _formKey, - child: Column( - children: [ - SingleChildScrollView( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - inspectionDetailsForm(), - 8.height, - const Divider().defaultStyle(context), - Text( - "Acceptance Form", - style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), - ), - 6.height, - Row( - children: [ - 'warning_icon'.toSvgAsset(height: 16, width: 16), - 6.width, - Text( - 'Review the acceptance form'.addTranslation, - style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), - ), - 6.width, - 'web_link_icon'.toSvgAsset(height: 20, width: 20), - ], - ), - 16.height, - assetList(context), - ], - ).toShadowContainer(context, borderRadius: 20, padding: 12)) - .expanded, - FooterActionButton.footerContainer(context: context, child: AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: _viewHistoryTap)), - ], - ), - ), - ); - } - - Widget assetList(BuildContext context) { - final assetDeliveryTableList = ['abc', 'def', 'ghi', 'fhg', 'hjhh']; - return Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Asset", - style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), - ), - 8.height, - ListView.separated( - itemCount: assetDeliveryTableList.length, - separatorBuilder: (_, __) => 8.height, - padding: EdgeInsets.zero, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (listContext, itemIndex) { - return TechnicalInspectionAssetCard( - assetModel: Asset(), - isViewOnly: viewOnly, - ischild: true, - editPress: () { - Navigator.push(context, MaterialPageRoute(builder: (context) => EndUserAcceptanceFormView())); - }, - ); - }, - ), - ], - ); - } - - Widget inspectionDetailsForm() { - return Column( - children: [ - ADatePicker( - label: 'Accepted Date'.addTranslation, - hideShadow: true, - height: 56.toScreenHeight, - backgroundColor: AppColor.fieldBgColor(context), - // date: _pickerStartAt, - // from: widget.pickerFromDate, - formatDateWithTime: true, - onDatePicker: (selectedDate) { - showTimePicker( - context: context, - initialTime: TimeOfDay.now(), - builder: (BuildContext context, Widget? child) { - final ThemeData currentTheme = Theme.of(context); - return Theme( - data: currentTheme.copyWith( - timePickerTheme: TimePickerThemeData( - dialHandColor: AppColor.primary10, - dialBackgroundColor: Colors.grey.withOpacity(0.1), - hourMinuteColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.grey.withOpacity(0.1)), - dayPeriodColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.transparent), - dayPeriodTextColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? Colors.white : AppColor.primary10), - dayPeriodBorderSide: BorderSide(color: Colors.grey.withOpacity(0.2)), - entryModeIconColor: AppColor.primary10, - ), - textButtonTheme: TextButtonThemeData(style: TextButton.styleFrom(foregroundColor: AppColor.primary10)), - ), - child: child!, - ); - }, - ).then((selectedTime) { - if (selectedTime != null) { - // _pickerStartAt = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); - // if (widget.pickerFromDate != null && _pickerStartAt!.isBefore(widget.pickerFromDate!)) { - // "Start time is before the request time.".showToast; - // _pickerStartAt = null; - // selectedTime = null; - // return; - // } - // if (_pickerStartAt!.isAfter(DateTime.now())) { - // "Start time is after than current time".showToast; - // _pickerStartAt = null; - // selectedTime = null; - // return; - // } - setState(() {}); - } - }); - }, - ), - 8.height, - SingleItemDropDownMenu( - context: context, - height: 56.toScreenHeight, - title: 'Approved by'.addTranslation, - showShadow: false, - titleTextColor: AppColor.neutral120, - // backgroundColor: AppColor.neutral100, - backgroundColor: AppColor.fieldBgColor(context), - showAsBottomSheet: true, - // initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, - onSelect: (status) { - if (status != null) { - // requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; - setState(() {}); - } - }, - ), - ], - ); - } - - void _viewHistoryTap() async { - AssetInventoryProvider assetInventoryProvider = Provider.of(context, listen: false); - _formKey.currentState!.save(); - } - - void _cancelTap() async { - AssetInventoryProvider assetInventoryProvider = Provider.of(context, listen: false); - _formKey.currentState!.save(); - } - - void _nextTap() async { - AssetInventoryProvider assetInventoryProvider = Provider.of(context, listen: false); - _formKey.currentState!.save(); - } - - void _changeStatusTap() async { - AssetInventoryProvider assetInventoryProvider = Provider.of(context, listen: false); - _formKey.currentState!.save(); - } -} diff --git a/lib/modules/asset_delivery_module/pages/history_log_view.dart b/lib/modules/asset_delivery_module/pages/history_log_view.dart index 4990a708..9aace55d 100644 --- a/lib/modules/asset_delivery_module/pages/history_log_view.dart +++ b/lib/modules/asset_delivery_module/pages/history_log_view.dart @@ -1,102 +1,114 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; - -import 'package:test_sa/controllers/api_routes/urls.dart'; -import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/models/enums/user_types.dart'; -import 'package:test_sa/models/new_models/work_order_detail_model.dart'; -import 'package:test_sa/modules/cm_module/cm_detail_provider.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/history_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; import 'package:test_sa/modules/cm_module/cm_request_utils.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; - -import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; -import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; +import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/widgets/requests/request_status.dart'; -class AssetDeliveryHistoryLogView extends StatelessWidget { - const AssetDeliveryHistoryLogView({Key? key}) : super(key: key); +class AssetDeliveryHistoryLogView extends StatefulWidget { + final int? tableItemId; + const AssetDeliveryHistoryLogView({Key? key,this.tableItemId}) : super(key: key); + + @override + State createState() => _AssetDeliveryHistoryLogViewState(); +} + + + +class _AssetDeliveryHistoryLogViewState extends State { + List history = []; + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + getInitialData(); + }); + super.initState(); + } + + + void getInitialData() async { + history = await Provider.of(context, listen: false).getHistory(tableItemId: widget.tableItemId); + } @override Widget build(BuildContext context) { - ///Replace with provider and data.. - return Consumer(builder: (context, requestProvider, _) { - return requestProvider.isLoading - ? const CircularProgressIndicator(color: AppColor.primary10).center - : (requestProvider.currentWorkOrder == null || (requestProvider.currentWorkOrder?.data?.workOrderHistory.isEmpty ?? true) - ? const NoDataFound() - : Stack( - children: [ - Padding( - padding: EdgeInsets.only(left: 122.toScreenWidth), - child: const VerticalDivider( - color: AppColor.white40, - thickness: 2, - width: 20, - indent: 10, - endIndent: 10, + return Scaffold( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + appBar: DefaultAppBar( + title: 'History Log'.addTranslation, + onBackPress: () { + Navigator.pop(context); + }, + ), + body: Consumer(builder: (context, provider, _) { + return provider.isLoading + ? const CircularProgressIndicator(color: AppColor.primary10).center + : Stack( + children: [ + Padding( + padding: EdgeInsets.only(left: 122.toScreenWidth), + child: const VerticalDivider( + color: AppColor.white40, + thickness: 2, + width: 20, + indent: 10, + endIndent: 10, + ), ), - ), - SafeArea( - child: Builder(builder: (cxt) { - List items = []; - String lastStatus = ""; - DateTime? nextDate; - var workOrderHistory = requestProvider.currentWorkOrder!.data!.workOrderHistory; - bool isNurse = (Provider.of(context, listen: false).user?.type) == UsersTypes.normal_user; - if (isNurse) { - workOrderHistory.removeWhere((element) => element.step?.id == 5617); - } - for (int i = 0; i < workOrderHistory.length; i++) { - var object = workOrderHistory[i]; - String currentStatus = object.workorderStatus!.name!; - if (lastStatus.isEmpty) { - lastStatus = currentStatus; - } - if (lastStatus == currentStatus) { - if (i + 1 < workOrderHistory.length) { - nextDate = workOrderHistory[i + 1].date; - String timeDifference = CMRequestUtils.calculateTimeDifference(object.date!, nextDate!); - object.timeDifference = timeDifference; - } else { - object.timeDifference = ''; // Empty string for the last action + SafeArea( + child: Builder(builder: (cxt) { + List items = []; + String lastStatus = ""; + DateTime? nextDate; + for (int i = 0; i < history.length; i++) { + var object = history[i]; + String currentStatus = object.status!.name!; + if (lastStatus.isEmpty) { + lastStatus = currentStatus; } - items.add(historyLogCard(cxt, object)); - } else { - items.add(statusCard(cxt, lastStatus)); - lastStatus = currentStatus; - if (i + 1 < workOrderHistory.length) { - nextDate = workOrderHistory[i + 1].date; - String timeDifference = CMRequestUtils.calculateTimeDifference(object.date!, nextDate!); - object.timeDifference = timeDifference; + if (lastStatus == currentStatus) { + if (i + 1 < history.length) { + nextDate = history[i + 1].createdDate; + String timeDifference = CMRequestUtils.calculateTimeDifference(object.createdDate!, nextDate!); + object.timeDifference = timeDifference; + } else { + object.timeDifference = ''; // Empty string for the last action + } + items.add(historyLogCard(cxt, object)); } else { - object.timeDifference = ''; // Empty string for the last action + items.add(statusCard(cxt, lastStatus)); + lastStatus = currentStatus; + if (i + 1 < history.length) { + nextDate = history[i + 1].createdDate; + String timeDifference = CMRequestUtils.calculateTimeDifference(object.createdDate!, nextDate!); + object.timeDifference = timeDifference; + } else { + object.timeDifference = ''; // Empty string for the last action + } + items.add(historyLogCard(cxt, object)); } - items.add(historyLogCard(cxt, object)); } - } - items.add(statusCard(cxt, lastStatus)); - return SingleChildScrollView( - padding: const EdgeInsets.all(16), - child: Column(children: items), - ); - }), - ), - ], - )); - }); - } - - Widget historyLogCard(BuildContext context, WorkOrderHistory object) { - String title = object.step!.name!; + items.add(statusCard(cxt, lastStatus)); + return SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column(children: items), + ); + }), + ), + ], + ); + }), + );} - if (object.step!.value == 18 || object.step!.value == 27 || object.step!.value == 28) { - title = object.activityStatus?.name ?? ""; - } + Widget historyLogCard(BuildContext context, AssetDeliveryHistoryModel object) { + String title = object.status!.name!; return Row( crossAxisAlignment: CrossAxisAlignment.center, @@ -105,40 +117,18 @@ class AssetDeliveryHistoryLogView extends StatelessWidget { Align( alignment: Alignment.centerLeft, child: Text( - object.date.toString().toServiceRequestCardFormat, + object.createdDate.toString().toServiceRequestCardFormat, textAlign: TextAlign.end, style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), ).expanded, Expanded( flex: 2, - //.... child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (object.assetVerificationType?.value == 4 && object.photoVerfication != null) ...[ - Padding( - padding: EdgeInsets.symmetric(vertical: 12.toScreenWidth), - child: InteractiveViewer(child: Image.network(URLs.getFileUrl(object.photoVerfication ?? '')!, height: 143.toScreenHeight)), - ).onPress(() async { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => Scaffold( - body: SafeArea( - child: Stack( - children: [ - InteractiveViewer(child: Image.network(URLs.getFileUrl(object.photoVerfication ?? '')!)).center, - const ABackButton(), - ], - ), - ), - ), - ), - ); - }), - ], title.bodyText(context).custom(color: AppColor.textColor(context)), - object.timeDifference.isNotEmpty ? object.timeDifference.tinyFont(context).custom(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120) : const SizedBox(), + // object.timeDifference.isNotEmpty ? object.timeDifference?.tinyFont(context).custom(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120) : const SizedBox(), ], ), ), @@ -153,15 +143,15 @@ class AssetDeliveryHistoryLogView extends StatelessWidget { radius: 4, label: statusText(status.toLowerCase()), labelInCenter: true, - textColor: AppColor.getHistoryLogStatusTextColorByName(status), - backgroundColor: AppColor.getHistoryLogStatusColorByName(status), + textColor: AppColor.neutral50, + backgroundColor: AppColor.orange30, ), ).paddingOnly(bottom: 16, start: 40); } - +// Need to check status text we have String statusText(String status) { if (status == "new" || status == "open") { - return "Open Request".addTranslation; + return "New".addTranslation; } else if (status == "in progress") { return "Status update to In Progress".addTranslation; } else if (status == "closed") { @@ -176,12 +166,3 @@ class AssetDeliveryHistoryLogView extends StatelessWidget { return status; } } - -class HistoryLogModel { - String message; - DateTime date; - String? status; - Color? statusColor; - - HistoryLogModel({required this.message, required this.date, this.status, this.statusColor}); -} diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/asset_delivery_utils.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/asset_delivery_utils.dart new file mode 100644 index 00000000..ffa4a1b4 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/asset_delivery_utils.dart @@ -0,0 +1,18 @@ + + +import 'package:test_sa/modules/asset_delivery_module/models/technical_inspection_asset_model.dart'; + +class AssetDeliveryUtils{ + ///This is static list for now if change in future backend provide Api as discuss with backend team + static List inspectionChecklist = [ + InspectionChecklistItem(title: 'Physical Inspection As Per Manufacturer Instructions', value: 'flagphysicalInspection'), + InspectionChecklistItem(title: 'Functional Performance As Per Results Of Manufacturer Recommended Check List', value: 'flagFunctionPerformance'), + InspectionChecklistItem(title: 'Grounding Resistance: Ω', value: 'flagGroundingResistance'), + InspectionChecklistItem(title: 'Chassis Leakage Current: µA', value: 'flagChassiss'), + InspectionChecklistItem(title: 'Leads Leakage Current: µA', value: 'flagLeadsLeakage'), + InspectionChecklistItem(title: 'This Device Is Not Subject To Any Alert Or Recall Until The Date Of Preparation Of This Inspection Form', value: 'flagAlert'), + ]; + + + +} \ No newline at end of file diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/search_asset_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/search_asset_view.dart new file mode 100644 index 00000000..4344c633 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/search_asset_view.dart @@ -0,0 +1,194 @@ +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/devices_provider.dart'; +import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/string_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/models/device/asset.dart'; +import 'package:test_sa/models/device/asset_search.dart'; +import 'package:test_sa/models/device/model_definition.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/technical_inpection_asset_model.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; +import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; +import 'package:test_sa/new_views/common_widgets/custom_app_bar.dart'; +import 'package:test_sa/views/widgets/equipment/asset_item_listview.dart'; +import 'package:test_sa/views/widgets/horizontal_list_widget.dart'; +import 'package:test_sa/views/widgets/loaders/lazy_loading.dart'; +import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; + +class TechnicalInspectionSearchAssetView extends StatefulWidget { + /// add on route + static const String id = "search_asset_view"; + final int? lineId; + + const TechnicalInspectionSearchAssetView({ + Key? key, + this.lineId, + }) : super(key: key); + + @override + State createState() => _TechnicalInspectionSearchAssetViewState(); +} + +class _TechnicalInspectionSearchAssetViewState extends State { + int _selectedIndex = 0; + DeviceSearch? search; + late TextEditingController _searchController; + late AssetProvider _deviceProvider; + + //check for this list if not need remove + final List _searchableList = []; + final GlobalKey _formKey = GlobalKey(); + bool _isFirst = true; + + @override + void initState() { + _searchController = TextEditingController(); + super.initState(); + } + + @override + void dispose() { + _searchController.dispose(); + _deviceProvider.searchReset(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + List searchBy = [ + context.translation.assetName, + context.translation.assetNumber, + 'model'.addTranslation, + 'manufacturer'.addTranslation, + // 'assetType'.addTranslation, + // 'assetOrigin'.addTranslation, + ]; + + _deviceProvider = Provider.of(context, listen: false); + + return Scaffold( + resizeToAvoidBottomInset: false, + appBar: CustomAppBar( + title: context.translation.searchAsset, + ), + body: Column( + children: [ + HorizontalListWidget( + list: searchBy, + callBackFunction: (index) { + setState(() { + _selectedIndex = index; + }); + }, + ).paddingOnly(top: 16, bottom: 0), + Form( + key: _formKey, + child: AppTextFormField( + controller: _searchController, + textInputAction: TextInputAction.search, + labelText: "${context.translation.searchBy} ${searchBy[_selectedIndex]}", + onAction: _search, + onChange: (text) { + _searchController.text = text; + _searchController.selection = TextSelection.fromPosition(TextPosition(offset: _searchController.text.length)); + setState(() {}); + }, + onSaved: (value) { + setState(() { + search = DeviceSearch(); + }); + _setValue(value); + }, + suffixIcon: IconButton( + icon: const Icon(Icons.search), + splashColor: Colors.transparent, + onPressed: _searchController.text.isNotEmpty ? _search : null, + color: AppColor.neutral20, + ).paddingOnly(end: 0), + ).paddingOnly(top: 16, start: 16, end: 16, bottom: 8)), + Expanded( + child: _searchableList.isEmpty + ? _isFirst + ? const SizedBox() + : NoDataFound(message: context.translation.noDeviceFound) + : LazyLoading( + nextPage: _deviceProvider.nextPage, + onLazyLoad: () async { + if (_searchController.text.isNotEmpty) { + await _deviceProvider.getAssetsForAssetDelivery(search: search, lineId: widget.lineId, isSearchBy: true); + setState(() { + _searchableList.clear(); + _searchableList.addAll(_deviceProvider.technicalInspectionAsset); + }); + } + }, + child: ListView.separated( + itemCount: _searchableList.length, + separatorBuilder: (listContext, itemIndex) => 8.height, + padding: const EdgeInsets.all(16), + itemBuilder: (listContext, itemIndex) { + return AssetItemListView( + device: Asset( + id: _searchableList[itemIndex].id, + assetNumber: _searchableList[itemIndex].assetNumber, + assetSerialNo: _searchableList[itemIndex].assetNumber, + modelDefinition: ModelDefinition(assetName: _searchableList[itemIndex].assetName, modelName: _searchableList[itemIndex].model), + ), + onPressed: (device) { + Navigator.of(context).pop(device); + }, + ); + }, + ), + ), + ) + ], + )); + } + + void _search({bool loadMore = false}) async { + FocusScope.of(context).unfocus(); + _formKey.currentState?.save(); + _searchableList.clear(); + _deviceProvider.technicalInspectionAsset.clear(); + setState(() {}); + _deviceProvider.searchReset(); + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + await _deviceProvider.getAssetsForAssetDelivery( + search: search, + lineId: widget.lineId, + isSearchBy: true, + ); + + setState(() { + _searchableList.clear(); + _searchableList.addAll(_deviceProvider.technicalInspectionAsset); + _isFirst = false; + }); + + Navigator.pop(context); + } + + _setValue(String? value) { + search ??= DeviceSearch(); + switch (_selectedIndex) { + case 0: + search!.assetName = value; + break; + case 1: + search!.assetNo = value; + break; + case 2: + search!.model = value; + break; + case 3: + search!.manufacturer = value; + break; + } + } +} diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/status_checklist_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/status_checklist_view.dart new file mode 100644 index 00000000..520b51a7 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/status_checklist_view.dart @@ -0,0 +1,137 @@ +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/string_extensions.dart'; +import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/technical_inspection_asset_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/asset_delivery_utils.dart'; +import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; +import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; + +class InspectionChecklistBottomSheet extends StatefulWidget { + final List? initialValues; + + const InspectionChecklistBottomSheet({super.key, this.initialValues}); + + @override + State createState() => + _InspectionChecklistBottomSheetState(); +} + +class _InspectionChecklistBottomSheetState + extends State { + late List checklist; + + @override + void initState() { + super.initState(); + + /// Create local copy (no shared mutation) + checklist = AssetDeliveryUtils.inspectionChecklist + .map((e) => InspectionChecklistItem(title: e.title)) + .toList(); + + /// Apply initial values only if provided + if (widget.initialValues != null && widget.initialValues!.isNotEmpty) { + for (final item in checklist) { + final matched = widget.initialValues!.firstWhere( + (e) => e.title == item.title, + orElse: () => InspectionChecklistItem(), + ); + item.status = matched.status; // null-safe + } + } + } + + void updateStatus(int index, String value) { + setState(() { + checklist[index].status = value; + }); + } + + List get selectedValues => + checklist.where((e) => e.status != null).toList(); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColor.white10, + appBar: DefaultAppBar( + title: 'Asset Check List'.addTranslation, + showBackButton: false, + titleStyle: AppTextStyles.heading3.copyWith( + fontWeight: FontWeight.w500, + color: context.isDark + ? AppColor.neutral30 + : AppColor.neutral50, + ), + ), + body: Column( + children: [ + 12.height, + ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: checklist.length, + padding: const EdgeInsets.symmetric(horizontal: 12), + itemBuilder: (context, index) { + final item = checklist[index]; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + item.title ?? '', + style: AppTextStyles.heading6.copyWith( + color: context.isDark + ? AppColor.neutral30 + : AppColor.black10, + ), + ), + Row( + children: [ + Expanded( + child: RadioListTile( + title: const Text('Pass'), + value: 'PASS', + groupValue: item.status, + onChanged: (v) => + updateStatus(index, v!), + ), + ), + Expanded( + child: RadioListTile( + title: const Text('Fail'), + value: 'FAIL', + groupValue: item.status, + onChanged: (v) => + updateStatus(index, v!), + ), + ), + ], + ), + ], + ); + }, + ).expanded, + FooterActionButton.footerContainer( + context: context, + child: AppFilledButton( + buttonColor: AppColor.primary10, + label: 'Save'.addTranslation, + maxWidth: true, + onPressed: () { + Navigator.pop(context, selectedValues); + }, + ), + ), + ], + ), + ); + } +} + diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart index 0a4fc871..d5c75e54 100644 --- a/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart @@ -1,21 +1,16 @@ import 'dart:developer'; import 'package:flutter/material.dart'; -import 'package:test_sa/common_widgets/lookup_autocomplete_field.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; -import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/models/device/asset.dart'; -import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/technical_inspection_asset_model.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/views/widgets/requests/request_status.dart'; class TechnicalInspectionAssetCard extends StatelessWidget { - Asset assetModel; - - ///if include in model skip this + TechnicalInspectionAssetModel assetModel; bool isViewOnly; bool ischild; VoidCallback? editPress; @@ -33,16 +28,15 @@ class TechnicalInspectionAssetCard extends StatelessWidget { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - ///Need to give specific colors if (!ischild) ...[ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ StatusLabel( - label: 'Pass', + label: getAssetStatus(), radius: 4, - textColor: AppColor.getPriorityStatusTextColor(context, 1), - backgroundColor: AppColor.getPriorityStatusColor(context, 1), + textColor: getAssetStatusColor(context: context, status: getAssetStatus(), isBackground: false), + backgroundColor: getAssetStatusColor(context: context, status: getAssetStatus()), ), if (!isViewOnly) 'edit_icon'.toSvgAsset().onPress(() { @@ -70,40 +64,67 @@ class TechnicalInspectionAssetCard extends StatelessWidget { }), ], ), + 2.height, ], + Text( + 'Asset Name: ${assetModel.modelDefinition?.assetName ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), if (!ischild) Text( 'Asset Number: ${assetModel.assetNumber ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), Text( - 'Model: ${assetModel.modelDefinition ?? '-'}', + 'Serial Number: ${assetModel.serialNo ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), Text( - 'Serial Number: ${assetModel.assetSerialNo ?? '-'}', + 'System ID: ${assetModel.systemId ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), Text( - 'System ID: ${assetModel.systemID ?? '-'}', + 'Medical Department: ${assetModel.department?.name ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Installation Date: ${assetModel.installationDate ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Asset Type: ${assetModel.assetType?.name ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), - if (!ischild) - Text( - 'Medical Department: ${assetModel.department ?? '-'}', - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), - ), - if (!ischild) - Text( - 'Installation Date: ${assetModel.deliveryInspectionDate ?? '-'}', - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), - ), - if (!ischild) - Text( - 'Asset Type: ${assetModel.assetType ?? '-'}', - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), - ), ], ).toShadowContainer(context, borderRadius: 20, padding: 12); } + + Color getAssetStatusColor({required BuildContext context, required String status, bool? isBackground = true}) { + switch (status) { + case 'PASS': + return isBackground! ? AppColor.green70.withOpacity(0.4) : AppColor.green15; + case 'FAIL': + return isBackground! ? AppColor.red30.withOpacity(0.4) : AppColor.red30; + default: + return Colors.white10; + } + } + + String getAssetStatus() { + final flags = [ + assetModel.flagphysicalInspection, + assetModel.flagFunctionPerformance, + assetModel.flagGroundingResistance, + assetModel.flagChassiss, + assetModel.flagLeadsLeakage, + assetModel.flagAlert, + ]; + if (flags.any((f) => f == false)) { + return 'FAIL'; + } + if (flags.every((f) => f == true)) { + return 'PASS'; + } + return 'FAIL'; + } } diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_cost_center_card_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_cost_center_card_view.dart index 1470c34e..c9488779 100644 --- a/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_cost_center_card_view.dart +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_cost_center_card_view.dart @@ -1,25 +1,26 @@ import 'dart:developer'; import 'package:flutter/material.dart'; +import 'package:test_sa/common_widgets/lookup_autocomplete_field.dart'; import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/cost_center_model.dart'; import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; class TechnicalInspectionCostCard extends StatelessWidget { - ///Need to replace with Cost model. - AssetInventoryModel deliveryDetails; - ///if include in model skip this + CostCenterModel costModel; + VoidCallback? editPress; bool isViewOnly; - VoidCallback ?editPress; TechnicalInspectionCostCard({ super.key, - required this.isViewOnly, - required this.deliveryDetails, + required this.costModel, this.editPress, + required this.isViewOnly, }); @override @@ -31,44 +32,24 @@ class TechnicalInspectionCostCard extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - 'Item No: ${deliveryDetails.transactionDate?.toServiceRequestDetailsFormat ?? '-'}', - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + Flexible( + child: Text( + 'Cost Center Name: ${costModel.costCenterName ?? '-'}', + overflow: TextOverflow.ellipsis, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), ), - if(!isViewOnly) - 'edit_icon'.toSvgAsset().onPress(() { - if(editPress!=null){ - editPress!(); - } - }), + 8.width, + if (!isViewOnly) + 'edit_icon'.toSvgAsset(height: 18, width: 18).onPress(() { + if (editPress != null) { + editPress!(); + } + }), ], ), Text( - 'Cost Center: ${deliveryDetails.assetNumber ?? '-'}', - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), - ), - Text( - 'Power Supply Type: ${deliveryDetails.assetName ?? '-'}', - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), - ), - Text( - 'Cost Center: ${deliveryDetails.assetName ?? '-'}', - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), - ), - Text( - 'Power Reading: ${deliveryDetails.assetName ?? '-'}', - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), - ), - Text( - 'Max Current: ${deliveryDetails.assetName ?? '-'}', - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), - ), - Text( - 'Voltage: ${deliveryDetails.assetName ?? '-'}', - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), - ), - Text( - 'Frequency: ${deliveryDetails.assetName ?? '-'}', + 'Quantity: ${costModel.quantity ?? '-'}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), ], diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart index 82420e30..61e52c87 100644 --- a/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart @@ -1,25 +1,38 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/asset_delivery_data_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/delivery_line_model.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/asset_delivery_line_card_view.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/attachment_view.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/update_technical_inspection_lines_view.dart'; -import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; import 'package:test_sa/providers/service_request_providers/last_situation_provider.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; +import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import '../../../../new_views/common_widgets/app_filled_button.dart'; import '../../../../new_views/common_widgets/default_app_bar.dart'; class TechnicalInspectionLinesListView extends StatefulWidget { + final AssetDeliveryTableModel deliveryTableModel; + final AssetDeliveryDataModel? requestModel; + TechnicalInspectionLinesListView({ Key? key, + required this.deliveryTableModel, + this.requestModel, }) : super(key: key); @override @@ -29,13 +42,33 @@ class TechnicalInspectionLinesListView extends StatefulWidget { class _TechnicalInspectionLinesListViewState extends State { final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); - bool viewOnly = true; + bool viewOnly = false; + bool isLoading = false; + AssetDeliveryProvider? assetDeliveryProvider; + List technicalInspectionLinesList = []; @override void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + getInitialData(); + }); super.initState(); } + void getInitialData() async { + assetDeliveryProvider = Provider.of(context, listen: false); + viewOnly = widget.deliveryTableModel.status?.value != 3; + isLoading = true; + setState(() {}); + technicalInspectionLinesList = await assetDeliveryProvider!.getTechnicalInspectionLinesListById( + //TODO uncommit this after testing @waseem + itemId: widget.deliveryTableModel.id, + // itemId: 2, + ); + isLoading = false; + setState(() {}); + } + @override void dispose() { super.dispose(); @@ -53,20 +86,13 @@ class _TechnicalInspectionLinesListViewState extends State 8.height, - padding: EdgeInsets.zero, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (listContext, itemIndex) { - return AssetDeliveryLineCard( - deliveryDetails: AssetInventoryModel(), - isViewOnly: viewOnly, - editPress: () { - Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateTechnicalInspectionLinesView())); - }, - ); - }, - ), - ], - ); - } + if (isLoading) { + return SizedBox.expand( + child: const CircularProgressIndicator(color: AppColor.primary10).center, + ); + } - Widget inspectionDetailsForm() { - return Column( - children: [ - SingleItemDropDownMenu( - context: context, - height: 56.toScreenHeight, - title: 'Inspected by'.addTranslation, - titleTextColor: AppColor.neutral120, - showShadow: false, - // backgroundColor: AppColor.neutral100, - backgroundColor: AppColor.fieldBgColor(context), - showAsBottomSheet: true, - // initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, - onSelect: (status) { - if (status != null) { - // requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; - setState(() {}); - } - }, - ), - 8.height, - SingleItemDropDownMenu( - context: context, - height: 56.toScreenHeight, - title: 'Approved by'.addTranslation, - showShadow: false, - titleTextColor: AppColor.neutral120, - // backgroundColor: AppColor.neutral100, - backgroundColor: AppColor.fieldBgColor(context), - showAsBottomSheet: true, - // initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, - onSelect: (status) { - if (status != null) { - // requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; - setState(() {}); - } - }, - ), - 8.height, - ADatePicker( - label: 'Inspected Date/Time From'.addTranslation, - hideShadow: true, - height: 56.toScreenHeight, - backgroundColor: AppColor.fieldBgColor(context), - // date: _pickerStartAt, - // from: widget.pickerFromDate, - formatDateWithTime: true, - onDatePicker: (selectedDate) { - showTimePicker( - context: context, - initialTime: TimeOfDay.now(), - builder: (BuildContext context, Widget? child) { - final ThemeData currentTheme = Theme.of(context); - return Theme( - data: currentTheme.copyWith( - timePickerTheme: TimePickerThemeData( - dialHandColor: AppColor.primary10, - dialBackgroundColor: Colors.grey.withOpacity(0.1), - hourMinuteColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.grey.withOpacity(0.1)), - dayPeriodColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.transparent), - dayPeriodTextColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? Colors.white : AppColor.primary10), - dayPeriodBorderSide: BorderSide(color: Colors.grey.withOpacity(0.2)), - entryModeIconColor: AppColor.primary10, - ), - textButtonTheme: TextButtonThemeData(style: TextButton.styleFrom(foregroundColor: AppColor.primary10)), - ), - child: child!, - ); - }, - ).then((selectedTime) { - if (selectedTime != null) { - // _pickerStartAt = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); - // if (widget.pickerFromDate != null && _pickerStartAt!.isBefore(widget.pickerFromDate!)) { - // "Start time is before the request time.".showToast; - // _pickerStartAt = null; - // selectedTime = null; - // return; - // } - // if (_pickerStartAt!.isAfter(DateTime.now())) { - // "Start time is after than current time".showToast; - // _pickerStartAt = null; - // selectedTime = null; - // return; - // } - setState(() {}); - } - }); - }, - ), - 8.height, - ADatePicker( - label: 'Inspected Date/Time To'.addTranslation, - hideShadow: true, - height: 56.toScreenHeight, - backgroundColor: AppColor.fieldBgColor(context), - // date: _pickerStartAt, - // from: widget.pickerFromDate, - formatDateWithTime: true, - onDatePicker: (selectedDate) { - showTimePicker( - context: context, - initialTime: TimeOfDay.now(), - builder: (BuildContext context, Widget? child) { - final ThemeData currentTheme = Theme.of(context); - return Theme( - data: currentTheme.copyWith( - timePickerTheme: TimePickerThemeData( - dialHandColor: AppColor.primary10, - dialBackgroundColor: Colors.grey.withOpacity(0.1), - hourMinuteColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.grey.withOpacity(0.1)), - dayPeriodColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.transparent), - dayPeriodTextColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? Colors.white : AppColor.primary10), - dayPeriodBorderSide: BorderSide(color: Colors.grey.withOpacity(0.2)), - entryModeIconColor: AppColor.primary10, - ), - textButtonTheme: TextButtonThemeData(style: TextButton.styleFrom(foregroundColor: AppColor.primary10)), - ), - child: child!, - ); - }, - ).then((selectedTime) { - if (selectedTime != null) { - // _pickerStartAt = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); - // if (widget.pickerFromDate != null && _pickerStartAt!.isBefore(widget.pickerFromDate!)) { - // "Start time is before the request time.".showToast; - // _pickerStartAt = null; - // selectedTime = null; - // return; - // } - // if (_pickerStartAt!.isAfter(DateTime.now())) { - // "Start time is after than current time".showToast; - // _pickerStartAt = null; - // selectedTime = null; - // return; - // } - setState(() {}); - } - }); + if (technicalInspectionLinesList.isEmpty) { + return const NoDataFound().center; + } + + return ListView.separated( + padding: const EdgeInsets.all(16), + itemCount: technicalInspectionLinesList.length + 1, // +1 for the header + separatorBuilder: (_, __) => 8.height, + itemBuilder: (context, index) { + if (index == 0) { + return Text( + "Lines", + style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ); + } + + final DeliveryLineModel model = technicalInspectionLinesList[index - 1]; + return AssetDeliveryLineCard( + deliveryLineModel: model, + isViewOnly: viewOnly, + isTechnical: true, + editPress: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => UpdateTechnicalInspectionLinesView( + requestModel: widget.requestModel, + deliveryTableModel: widget.deliveryTableModel, + deliveryLineModel: model, + ), + ), + ); }, - ), - ], - ); + ); + }, + ).toShadowContainer(context, borderRadius: 20, padding: 12); } +//May be need to show data. Widget inspectionDetails() { return Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -324,13 +215,44 @@ class _TechnicalInspectionLinesListViewState extends State const AppLazyLoading()); + await assetDeliveryProvider?.changeDeliveryStatus(itemId: widget.deliveryTableModel.id).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context); + await assetDeliveryProvider?.getAssetDeliveryTableListById(requestId: widget.requestModel?.id); + } + }); + } + + void _attachmentTap() async { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => AssetDeliveryAttachmentView( + tableItemId: widget.deliveryTableModel.id, + ))); + } - void _cancelTap() async {} + void _cancelTap() async { + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + await assetDeliveryProvider?.changeDeliveryStatusToCancel(itemId: widget.deliveryTableModel.id).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context); + await assetDeliveryProvider?.getAssetDeliveryTableListById(requestId: widget.requestModel?.id); + } + }); + } void _nextTap() async { - Navigator.push(context, MaterialPageRoute(builder: (context) => EndUserCostCenterLIstView())); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => EndUserCostCenterLIstView( + requestModel: widget.requestModel, + deliveryTableModel: widget.deliveryTableModel, + ))); } - - void _changeStatusTap() async {} } diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_parent_asset_list_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_parent_asset_list_view.dart index 2ea5d088..5f6a60c6 100644 --- a/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_parent_asset_list_view.dart +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_parent_asset_list_view.dart @@ -1,19 +1,28 @@ - import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/models/device/asset.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/technical_inspection_asset_model.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/update_parent_asset_view.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import '../../../../new_views/common_widgets/default_app_bar.dart'; class TechnicalInspectionParentAssetListView extends StatefulWidget { + final int? costCenterId; + final int? tableItemId; + final int? lineId; + TechnicalInspectionParentAssetListView({ Key? key, + this.costCenterId, + this.tableItemId, + this.lineId, }) : super(key: key); @override @@ -24,12 +33,35 @@ class _TechnicalInspectionParentAssetListViewState extends State _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); bool viewOnly = false; + AssetDeliveryProvider? assetDeliveryProvider; + List assetList = []; + bool isLoading = false; @override void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + getInitialData(); + }); super.initState(); } + void getInitialData() async { + setState(() { + isLoading = true; + }); + assetDeliveryProvider = Provider.of(context, listen: false); + //TODO replace static id's after testing... + assetList = await assetDeliveryProvider!.getParentAssetList( + costCenterId: widget.costCenterId, + tableItemId: widget.tableItemId, + lineId: widget.lineId, + ); + + setState(() { + isLoading = false; + }); + } + @override void dispose() { super.dispose(); @@ -43,45 +75,59 @@ class _TechnicalInspectionParentAssetListViewState extends State 8.height, - padding: EdgeInsets.zero, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (listContext, itemIndex) { - return TechnicalInspectionAssetCard( - assetModel: Asset(), - isViewOnly: viewOnly, - editPress: () { - Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateParentAssetView())); - }, + if (isLoading) { + return SizedBox.expand( + child: const CircularProgressIndicator(color: AppColor.primary10).center, + ); + } + + if (assetList.isEmpty) { + return const NoDataFound().center; + } + + return ListView.separated( + padding: const EdgeInsets.all(16), + itemCount: assetList.length + 1, // +1 for the "Parents" header + separatorBuilder: (_, __) => 8.height, + itemBuilder: (context, index) { + if (index == 0) { + return Text( + "Parents", + style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ); + } + + final asset = assetList[index - 1]; + return TechnicalInspectionAssetCard( + assetModel: asset, + isViewOnly: viewOnly, + editPress: () async { + bool isRefreshed = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => UpdateParentAssetView( + assetModel: asset, + lineId: widget.lineId, + tableItemId: widget.tableItemId, + costCenterItemId: widget.costCenterId, + ), + ), ); + + if (isRefreshed) { + getInitialData(); + } }, - ), - ], + ); + }, ); } - } diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/update_child_asset_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/update_child_asset_view.dart index 8733e005..bb0b6ca9 100644 --- a/lib/modules/asset_delivery_module/pages/technical_inpection/update_child_asset_view.dart +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/update_child_asset_view.dart @@ -1,46 +1,42 @@ -import 'dart:convert'; import 'dart:developer'; -import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:flutter_advanced_switch/flutter_advanced_switch.dart'; import 'package:provider/provider.dart'; -import 'package:test_sa/common_widgets/lookup_autocomplete_field.dart'; -import 'package:test_sa/controllers/providers/api/all_requests_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/models/device/asset.dart'; -import 'package:test_sa/models/generic_attachment_model.dart'; -import 'package:test_sa/models/lookup.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/asset_delivery_line_card_view.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_cost_center_card_view.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_parent_asset_list_view.dart'; -import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart'; -import 'package:test_sa/modules/asset_inventory_module/pages/search_asset_view.dart'; -import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart'; -import 'package:test_sa/modules/cm_module/cm_request_utils.dart'; +import 'package:test_sa/models/new_models/building.dart'; +import 'package:test_sa/models/new_models/floor.dart'; +import 'package:test_sa/models/new_models/site.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/technical_inspection_asset_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/asset_delivery_utils.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/search_asset_view.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/status_checklist_view.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; -import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; -import 'package:test_sa/providers/service_request_providers/last_situation_provider.dart'; +import 'package:test_sa/providers/gas_request_providers/site_provider.dart'; +import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; -import 'package:test_sa/views/widgets/equipment/asset_picker.dart'; -import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; -import 'package:test_sa/views/widgets/images/multi_image_picker_item.dart'; -import 'package:test_sa/views/widgets/requests/request_status.dart'; +import '../../../../models/new_models/department.dart'; import '../../../../new_views/common_widgets/app_filled_button.dart'; import '../../../../new_views/common_widgets/default_app_bar.dart'; -///convert this to stateless no state needed when impleminting api's +//TODO need to refactor this screen when done ... + class UpdateChildAssetView extends StatefulWidget { - ///Need to pass model here... + final TechnicalInspectionAssetModel assetModel; + final int? lineId; + final int index; + UpdateChildAssetView({ Key? key, + required this.assetModel, + required this.index, + this.lineId, }) : super(key: key); @override @@ -50,15 +46,48 @@ class UpdateChildAssetView extends StatefulWidget { class _UpdateChildAssetViewState extends State { final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); - bool viewOnly = false; + List checkList = []; + late SiteProvider siteProvider; + late AssetDeliveryProvider assetDeliveryProvider; + late TextEditingController assetNumberCtrl; + late TextEditingController serialNoCtrl; + late TextEditingController systemIdCtrl; @override void initState() { + siteProvider = Provider.of(context, listen: false); + assetDeliveryProvider = Provider.of(context, listen: false); + assetNumberCtrl = TextEditingController(); + serialNoCtrl = TextEditingController(); + systemIdCtrl = TextEditingController(); + WidgetsBinding.instance.addPostFrameCallback((_) { + populateForm(); + }); super.initState(); } + void populateForm() async { + assetDeliveryProvider.isChildAssetDataLoading = true; + assetDeliveryProvider.setChildModel(widget.assetModel); + if (widget.assetModel.site != null) { + await assetDeliveryProvider.getSiteData(siteId: widget.assetModel.site?.id, model: assetDeliveryProvider.childFormModel); + } + populateTextFields(model: assetDeliveryProvider.childFormModel); + assetDeliveryProvider.isChildAssetDataLoading = false; + } + + void populateTextFields({required TechnicalInspectionAssetModel model}) { + assetNumberCtrl.text = model.assetNumber ?? ''; + serialNoCtrl.text = model.serialNo ?? ''; + systemIdCtrl.text = model.systemId ?? ''; + setState(() {}); + } + @override void dispose() { + assetNumberCtrl.dispose(); + serialNoCtrl.dispose(); + systemIdCtrl.dispose(); super.dispose(); } @@ -72,74 +101,328 @@ class _UpdateChildAssetViewState extends State { ), body: Form( key: _formKey, - child: Column( - children: [ - SingleChildScrollView( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SingleItemDropDownMenu( - context: context, - height: 56.toScreenHeight, - title: 'Asset Number'.addTranslation, - titleTextColor: AppColor.neutral120, - showShadow: false, - // backgroundColor: AppColor.neutral100, - backgroundColor: AppColor.fieldBgColor(context), - showAsBottomSheet: true, - // initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, - onSelect: (status) { - if (status != null) { - // requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; - setState(() {}); - } - }, - ), - 8.height, - AppTextFormField( - labelText: 'Model'.addTranslation, - backgroundColor: AppColor.fieldBgColor(context), - initialValue: '', - textAlign: TextAlign.center, - labelStyle: AppTextStyles.textFieldLabelStyle, - textInputType: TextInputType.number, - showShadow: false, - style: Theme.of(context).textTheme.titleMedium, - ), - 8.height, - AppTextFormField( - labelText: 'Serial Number'.addTranslation, - backgroundColor: AppColor.fieldBgColor(context), - initialValue: '', - textAlign: TextAlign.center, - labelStyle: AppTextStyles.textFieldLabelStyle, - showShadow: false, - style: Theme.of(context).textTheme.titleMedium, - ), - 8.height, - AppTextFormField( - labelText: 'System ID'.addTranslation, - backgroundColor: AppColor.fieldBgColor(context), - initialValue: '', - textAlign: TextAlign.center, - labelStyle: AppTextStyles.textFieldLabelStyle, - showShadow: false, - style: Theme.of(context).textTheme.titleMedium, - ), - 8.height, - ], - ).toShadowContainer(context, borderRadius: 20, padding: 12)) - .expanded, - FooterActionButton.footerContainer(context: context, child: AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: _saveTap)), - ], - ), + child: Consumer(builder: (context, provider, child) { + return provider.isChildAssetDataLoading + ? const CircularProgressIndicator(color: AppColor.primary10).center + : Column( + children: [ + SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + inspectionDetailsForm( + lineId: widget.lineId, + provider: provider, + ), + 8.height, + const Divider().defaultStyle(context), + 8.height, + testLines( + context: context, + ) + ], + ).toShadowContainer(context, borderRadius: 20, padding: 12)) + .expanded, + FooterActionButton.footerContainer(context: context, child: AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: _saveTap)), + ], + ); + }), ), ); } + Widget testLines({required BuildContext context}) { + return Row( + children: [ + Text( + "Test List", + style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.width, + 'web_link_icon'.toSvgAsset().onPress(() { + openInspectionChecklist(context); + }), + ], + ); + } + + /// Need to make reuseable as used in parent and child both. + + Widget inspectionDetailsForm({ + int? lineId, + required AssetDeliveryProvider provider, + }) { + TechnicalInspectionAssetModel model = provider.childFormModel; + return Column( + children: [ + AppTextFormField( + labelText: 'Asset Number'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + controller: assetNumberCtrl, + initialValue: model.assetNumber, + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + textInputType: TextInputType.number, + showShadow: false, + enable: false, + style: Theme.of(context).textTheme.titleMedium, + ).onPress(() async { + var data = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => TechnicalInspectionSearchAssetView( + lineId: lineId, + ))); + if (data != null) { + TechnicalInspectionAssetModel? assetModel = await provider.getAssetDetails(assetId: data?.id); + + if (assetModel != null) { + provider.setChildModel(assetModel); + if (assetModel.site != null) { + await provider.getSiteData(siteId: assetModel.site?.id, model: provider.childFormModel); + } + provider.setParentModel(assetModel); + log('child list length ${assetModel.childAssetList?.length}'); + populateTextFields(model: provider.childFormModel); + } + } + }), + 8.height, + AppTextFormField( + labelText: 'Serial Number'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + controller: serialNoCtrl, + initialValue: model.serialNo ?? '', + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + textInputType: TextInputType.number, + showShadow: false, + onSaved: (value) { + model.serialNo = value; + }, + style: Theme.of(context).textTheme.titleMedium, + ), + 8.height, + AppTextFormField( + labelText: 'System ID'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + controller: systemIdCtrl, + initialValue: model.systemId ?? '', + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + onSaved: (value) { + model.systemId = value; + }, + style: Theme.of(context).textTheme.titleMedium, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + title: 'Site', + initialValue: model.site, + loading: provider.isSiteLoading, + showAsBottomSheet: true, + backgroundColor: AppColor.fieldBgColor(context), + showShadow: false, + // enabled: false, + onSelect: (value) { + if (value == null) { + return; + } + model.site = value; + model.building = null; + model.floor = null; + model.department = null; + setState(() {}); + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + title: 'Building', + backgroundColor: AppColor.fieldBgColor(context), + showAsBottomSheet: true, + loading: provider.isSiteLoading, + showShadow: false, + initialValue: model.building, + enabled: model.site?.buildings?.isNotEmpty ?? false, + staticData: model.site?.buildings ?? [], + onSelect: (value) { + if (value == null) { + return; + } + model.building = value; + model.floor = null; + model.department = null; + setState(() {}); + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + showAsBottomSheet: true, + backgroundColor: AppColor.fieldBgColor(context), + loading: provider.isSiteLoading, + showShadow: false, + title: 'Floor', + initialValue: model.floor, + enabled: model.building?.floors?.isNotEmpty ?? false, + staticData: model.building?.floors ?? [], + onSelect: (value) { + if (value == null) { + return; + } + model.floor = value; + model.department = null; + setState(() {}); + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + title: 'Department', + backgroundColor: AppColor.fieldBgColor(context), + loading: provider.isSiteLoading, + showAsBottomSheet: true, + showShadow: false, + initialValue: model.department, + enabled: model.floor?.departments?.isNotEmpty ?? false, + staticData: model.floor?.departments ?? [], + onSelect: (value) { + if (value == null) { + return; + } + model.department = value; + model.room = null; + setState(() {}); + }, + ), + 8.height, + ADatePicker( + label: 'Installation Date'.addTranslation, + hideShadow: true, + height: 56.toScreenHeight, + backgroundColor: AppColor.fieldBgColor(context), + date: model.installationDate, + // from: widget.pickerFromDate, + formatDateWithTime: true, + onDatePicker: (selectedDate) { + showTimePicker( + context: context, + initialTime: TimeOfDay.now(), + builder: (BuildContext context, Widget? child) { + final ThemeData currentTheme = Theme.of(context); + return Theme( + data: currentTheme.copyWith( + timePickerTheme: TimePickerThemeData( + dialHandColor: AppColor.primary10, + dialBackgroundColor: Colors.grey.withOpacity(0.1), + hourMinuteColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.grey.withOpacity(0.1)), + dayPeriodColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.transparent), + dayPeriodTextColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? Colors.white : AppColor.primary10), + dayPeriodBorderSide: BorderSide(color: Colors.grey.withOpacity(0.2)), + entryModeIconColor: AppColor.primary10, + ), + textButtonTheme: TextButtonThemeData(style: TextButton.styleFrom(foregroundColor: AppColor.primary10)), + ), + child: child!, + ); + }, + ).then((selectedTime) { + if (selectedTime != null) { + model.installationDate = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + setState(() {}); + } + }); + }, + ), + 8.height, + ], + ); + } + + ///Need to check which details show here... + void _saveTap() async { - AssetInventoryProvider assetInventoryProvider = Provider.of(context, listen: false); _formKey.currentState!.save(); + //Need to check if not auto update. + // assetDeliveryProvider.parentFormModel.childAssetList?[widget.index]= assetDeliveryProvider.childFormModel; + Navigator.pop(context); + } + + Future openInspectionChecklist(BuildContext context) async { + applyInspectionFlagsToChecklist(model: assetDeliveryProvider.childFormModel); + + final result = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => InspectionChecklistBottomSheet( + initialValues: checkList, + ))); + if (result != null) { + checkList = result; + setState(() {}); + } + buildInspectionPayload(checkList); + } + + bool _isPass(List list, String title) { + return list + .firstWhere( + (e) => e.title == title, + orElse: () => InspectionChecklistItem(status: 'FAIL'), + ) + .status == + 'PASS'; + } + + buildInspectionPayload(List checklist) { + assetDeliveryProvider.childFormModel.flagphysicalInspection = _isPass(checklist, 'Physical Inspection As Per Manufacturer Instructions'); + assetDeliveryProvider.childFormModel.flagFunctionPerformance = _isPass(checklist, 'Functional Performance As Per Results Of Manufacturer Recommended Check List'); + assetDeliveryProvider.childFormModel.flagGroundingResistance = _isPass(checklist, 'Grounding Resistance: Ω'); + assetDeliveryProvider.childFormModel.flagChassiss = _isPass(checklist, 'Chassis Leakage Current: µA'); + assetDeliveryProvider.childFormModel.flagLeadsLeakage = _isPass(checklist, 'Leads Leakage Current: µA'); + assetDeliveryProvider.childFormModel.flagAlert = _isPass(checklist, 'This Device Is Not Subject To Any Alert Or Recall Until The Date Of Preparation Of This Inspection Form'); + } + + void applyInspectionFlagsToChecklist({ + required TechnicalInspectionAssetModel model, + }) { + if (checkList.isEmpty) { + checkList = AssetDeliveryUtils.inspectionChecklist; + } + for (final item in checkList) { + switch (item.value) { + case 'flagphysicalInspection': + item.status = _statusFromBool(model.flagphysicalInspection); + break; + + case 'flagFunctionPerformance': + item.status = _statusFromBool(model.flagFunctionPerformance); + break; + + case 'flagGroundingResistance': + item.status = _statusFromBool(model.flagGroundingResistance); + break; + + case 'flagChassiss': + item.status = _statusFromBool(model.flagChassiss); + break; + + case 'flagLeadsLeakage': + item.status = _statusFromBool(model.flagLeadsLeakage); + break; + + case 'flagAlert': + item.status = _statusFromBool(model.flagAlert); + break; + } + } + } + + String _statusFromBool(bool? value) { + return value == true ? 'PASS' :value==false? 'FAIL':''; } } diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/update_parent_asset_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/update_parent_asset_view.dart index 4ff14e0a..8bac4319 100644 --- a/lib/modules/asset_delivery_module/pages/technical_inpection/update_parent_asset_view.dart +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/update_parent_asset_view.dart @@ -1,45 +1,47 @@ -import 'dart:convert'; import 'dart:developer'; -import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:flutter_advanced_switch/flutter_advanced_switch.dart'; import 'package:provider/provider.dart'; -import 'package:test_sa/common_widgets/lookup_autocomplete_field.dart'; -import 'package:test_sa/controllers/providers/api/all_requests_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/models/device/asset.dart'; -import 'package:test_sa/models/generic_attachment_model.dart'; -import 'package:test_sa/models/lookup.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/asset_delivery_line_card_view.dart'; +import 'package:test_sa/models/new_models/building.dart'; +import 'package:test_sa/models/new_models/floor.dart'; +import 'package:test_sa/models/new_models/site.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/technical_inspection_asset_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/asset_delivery_utils.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/search_asset_view.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/status_checklist_view.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_cost_center_card_view.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_parent_asset_list_view.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/update_child_asset_view.dart'; -import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart'; -import 'package:test_sa/modules/asset_inventory_module/pages/search_asset_view.dart'; -import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart'; -import 'package:test_sa/modules/cm_module/cm_request_utils.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; -import 'package:test_sa/providers/service_request_providers/last_situation_provider.dart'; +import 'package:test_sa/providers/gas_request_providers/site_provider.dart'; +import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; -import 'package:test_sa/views/widgets/equipment/asset_picker.dart'; -import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; -import 'package:test_sa/views/widgets/images/multi_image_picker_item.dart'; -import 'package:test_sa/views/widgets/requests/request_status.dart'; +import '../../../../models/new_models/department.dart'; import '../../../../new_views/common_widgets/app_filled_button.dart'; import '../../../../new_views/common_widgets/default_app_bar.dart'; +//TODO need to refactor this screen also add loaders when done ... + class UpdateParentAssetView extends StatefulWidget { + final TechnicalInspectionAssetModel assetModel; + final int? lineId; + final int? tableItemId; + final int? costCenterItemId; + UpdateParentAssetView({ Key? key, + required this.assetModel, + this.lineId, + this.tableItemId, + this.costCenterItemId, }) : super(key: key); @override @@ -49,15 +51,52 @@ class UpdateParentAssetView extends StatefulWidget { class _UpdateParentAssetViewState extends State { final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); - bool viewOnly = false; + List checkList = []; + late SiteProvider siteProvider; + late AssetDeliveryProvider assetDeliveryProvider; + late TextEditingController assetNumberCtrl; + late TextEditingController serialNoCtrl; + late TextEditingController systemIdCtrl; @override void initState() { + siteProvider = Provider.of(context, listen: false); + assetDeliveryProvider = Provider.of(context, listen: false); + assetNumberCtrl = TextEditingController(); + serialNoCtrl = TextEditingController(); + systemIdCtrl = TextEditingController(); + WidgetsBinding.instance.addPostFrameCallback((_) { + populateForm(); + }); super.initState(); } + void populateForm() async { + assetDeliveryProvider.isLoading = true; + assetDeliveryProvider.setParentModel(widget.assetModel); + if (widget.assetModel.site != null) { + await assetDeliveryProvider.getSiteData(siteId: widget.assetModel.site?.id, model: assetDeliveryProvider.parentFormModel); + } else { + if (siteProvider.items.isEmpty) { + await siteProvider.getData(); + } + } + populateTextFields(model: assetDeliveryProvider.parentFormModel); + assetDeliveryProvider.isLoading = false; + } + + void populateTextFields({required TechnicalInspectionAssetModel model}) { + assetNumberCtrl.text = model.assetNumber ?? ''; + serialNoCtrl.text = model.serialNo ?? ''; + systemIdCtrl.text = model.systemId ?? ''; + setState(() {}); + } + @override void dispose() { + assetNumberCtrl.dispose(); + serialNoCtrl.dispose(); + systemIdCtrl.dispose(); super.dispose(); } @@ -71,127 +110,241 @@ class _UpdateParentAssetViewState extends State { ), body: Form( key: _formKey, - child: Column( - children: [ - SingleChildScrollView( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - inspectionDetailsForm(), - 8.height, - const Divider().defaultStyle(context), - 8.height, - childList(context), - ], - ).toShadowContainer(context, borderRadius: 20, padding: 12)) - .expanded, - FooterActionButton.footerContainer(context: context, child: AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: _saveTap)), - ], - ), + child: Consumer(builder: (context, provider, child) { + return provider.isLoading + ? const CircularProgressIndicator(color: AppColor.primary10).center + : Column( + children: [ + SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + inspectionDetailsForm(lineId: widget.lineId, provider: provider), + 8.height, + const Divider().defaultStyle(context), + 8.height, + Row( + children: [ + Text( + "Test List", + style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.width, + 'web_link_icon'.toSvgAsset().onPress(() { + openInspectionChecklist(context); + }), + ], + ), + 8.height, + childList( + context: context, + provider: provider, + ) + ], + ).toShadowContainer(context, borderRadius: 20, padding: 12)) + .expanded, + FooterActionButton.footerContainer(context: context, child: AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: _saveTap)), + ], + ); + }), ), ); } - Widget childList(BuildContext context) { - final assetDeliveryTableList = ['abc', 'def', 'ghi', 'fhg', 'hjhh']; - return Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Text( - "Test List", - style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), - ), - 8.width, - 'web_link_icon'.toSvgAsset().onPress((){ - ///Open webview... - }), - ], - ), - 8.height, - ListView.separated( - itemCount: assetDeliveryTableList.length, - separatorBuilder: (_, __) => 8.height, - padding: EdgeInsets.zero, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (listContext, itemIndex) { - return TechnicalInspectionAssetCard( - assetModel: Asset(), - ischild: true, - editPress: () { - Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateChildAssetView())); - }, - isViewOnly: viewOnly, - ); + Widget childList({required BuildContext context, required AssetDeliveryProvider provider}) { + final List assetDeliveryTableList = provider.parentFormModel.childAssetList ?? []; + return ListView.separated( + itemCount: assetDeliveryTableList.length, + separatorBuilder: (_, __) => 8.height, + padding: EdgeInsets.zero, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (listContext, itemIndex) { + TechnicalInspectionAssetModel model = assetDeliveryTableList[itemIndex]; + return TechnicalInspectionAssetCard( + assetModel: model, + ischild: true, + editPress: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => UpdateChildAssetView( + assetModel: model, + index: itemIndex, + ))); }, - ), - ], + isViewOnly: false, + ); + }, ); } - Widget inspectionDetailsForm() { + /// Need to make reuseable as used in parent and child both. + + Widget inspectionDetailsForm({ + int? lineId, + required AssetDeliveryProvider provider, + }) { + TechnicalInspectionAssetModel model = provider.parentFormModel; return Column( children: [ - SingleItemDropDownMenu( - context: context, - height: 56.toScreenHeight, - title: 'Asset Number'.addTranslation, - titleTextColor: AppColor.neutral120, - showShadow: false, - // backgroundColor: AppColor.neutral100, + //Replace with simple container... + AppTextFormField( + labelText: 'Asset Number'.addTranslation, backgroundColor: AppColor.fieldBgColor(context), - showAsBottomSheet: true, - // initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, - onSelect: (status) { - if (status != null) { - // requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; - setState(() {}); + controller: assetNumberCtrl, + initialValue: model.assetNumber, + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + textInputType: TextInputType.number, + showShadow: false, + enable: false, + style: Theme.of(context).textTheme.titleMedium, + ).onPress(() async { + var data = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => TechnicalInspectionSearchAssetView( + lineId: lineId, + ))); + if (data != null) { + TechnicalInspectionAssetModel? assetModel = await provider.getAssetDetails(assetId: data?.id); + + if (assetModel != null) { + provider.setParentModel(assetModel); + if (assetModel.site != null) { + await provider.getSiteData(siteId: assetModel.site?.id, model: provider.parentFormModel); + } + assetModel.assetDeliveryInternalDetailAssetId = assetModel.id; + assetModel.id = 0; + provider.setParentModel(assetModel); + log('child list length ${assetModel.childAssetList?.length}'); + populateTextFields(model: provider.parentFormModel); } - }, - ), + } + }), 8.height, AppTextFormField( labelText: 'Serial Number'.addTranslation, backgroundColor: AppColor.fieldBgColor(context), - initialValue: '', + controller: serialNoCtrl, + initialValue: model.serialNo ?? '', textAlign: TextAlign.center, labelStyle: AppTextStyles.textFieldLabelStyle, textInputType: TextInputType.number, showShadow: false, + onSaved: (value) { + model.serialNo = value; + }, style: Theme.of(context).textTheme.titleMedium, ), 8.height, AppTextFormField( labelText: 'System ID'.addTranslation, backgroundColor: AppColor.fieldBgColor(context), - initialValue: '', + controller: systemIdCtrl, + initialValue: model.systemId ?? '', textAlign: TextAlign.center, labelStyle: AppTextStyles.textFieldLabelStyle, showShadow: false, + onSaved: (value) { + model.systemId = value; + }, style: Theme.of(context).textTheme.titleMedium, ), 8.height, - AppTextFormField( - labelText: 'Medical Department'.addTranslation, + SingleItemDropDownMenu( + context: context, + title: 'Site', + initialValue: model.site, + loading: provider.isSiteLoading, + showAsBottomSheet: true, backgroundColor: AppColor.fieldBgColor(context), - initialValue: '', - textAlign: TextAlign.center, - labelStyle: AppTextStyles.textFieldLabelStyle, showShadow: false, - style: Theme.of(context).textTheme.titleMedium, + // enabled: false, + onSelect: (value) { + if (value == null) { + return; + } + model.site = value; + model.building = null; + model.floor = null; + model.department = null; + setState(() {}); + }, ), + 8.height, + SingleItemDropDownMenu( + context: context, + title: 'Building', + backgroundColor: AppColor.fieldBgColor(context), + showAsBottomSheet: true, + loading: provider.isSiteLoading, + showShadow: false, + initialValue: model.building, + enabled: model.site?.buildings?.isNotEmpty ?? false, + staticData: model.site?.buildings ?? [], + onSelect: (value) { + if (value == null) { + return; + } + model.building = value; + model.floor = null; + model.department = null; + setState(() {}); + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + showAsBottomSheet: true, + backgroundColor: AppColor.fieldBgColor(context), + loading: provider.isSiteLoading, + showShadow: false, + title: 'Floor', + initialValue: model.floor, + enabled: model.building?.floors?.isNotEmpty ?? false, + staticData: model.building?.floors ?? [], + onSelect: (value) { + if (value == null) { + return; + } + model.floor = value; + model.department = null; + setState(() {}); + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + title: 'Department', + backgroundColor: AppColor.fieldBgColor(context), + loading: provider.isSiteLoading, + showAsBottomSheet: true, + showShadow: false, + initialValue: model.department, + enabled: model.floor?.departments?.isNotEmpty ?? false, + staticData: model.floor?.departments ?? [], + onSelect: (value) { + if (value == null) { + return; + } + model.department = value; + model.room = null; + setState(() {}); + }, + ), + 8.height, ADatePicker( label: 'Installation Date'.addTranslation, hideShadow: true, height: 56.toScreenHeight, backgroundColor: AppColor.fieldBgColor(context), - // date: _pickerStartAt, - // from: widget.pickerFromDate, + date: model.installationDate, + //Need to check whare the picker start for now start from start of year + from: DateTime(DateTime.now().year, 1, 1), formatDateWithTime: true, onDatePicker: (selectedDate) { showTimePicker( @@ -217,34 +370,13 @@ class _UpdateParentAssetViewState extends State { }, ).then((selectedTime) { if (selectedTime != null) { - // _pickerStartAt = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); - // if (widget.pickerFromDate != null && _pickerStartAt!.isBefore(widget.pickerFromDate!)) { - // "Start time is before the request time.".showToast; - // _pickerStartAt = null; - // selectedTime = null; - // return; - // } - // if (_pickerStartAt!.isAfter(DateTime.now())) { - // "Start time is after than current time".showToast; - // _pickerStartAt = null; - // selectedTime = null; - // return; - // } + model.installationDate = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); setState(() {}); } }); }, ), 8.height, - AppTextFormField( - labelText: 'Asset Type'.addTranslation, - backgroundColor: AppColor.fieldBgColor(context), - initialValue: '', - textAlign: TextAlign.center, - labelStyle: AppTextStyles.textFieldLabelStyle, - showShadow: false, - style: Theme.of(context).textTheme.titleMedium, - ), ], ); } @@ -252,7 +384,541 @@ class _UpdateParentAssetViewState extends State { ///Need to check which details show here... void _saveTap() async { - AssetInventoryProvider assetInventoryProvider = Provider.of(context, listen: false); _formKey.currentState!.save(); + assetDeliveryProvider.parentFormModel.lineId = widget.lineId; + + assetDeliveryProvider.parentFormModel.tableItemId = widget.tableItemId; + assetDeliveryProvider.parentFormModel.costCenterId = widget.costCenterItemId; + log('model data ${assetDeliveryProvider.parentFormModel.toJson()}'); + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + await assetDeliveryProvider.saveTechnicalInspectionAssetData(model: assetDeliveryProvider.parentFormModel).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context, true); + } + }); + } + + Future openInspectionChecklist(BuildContext context) async { + applyInspectionFlagsToChecklist(model: assetDeliveryProvider.parentFormModel); + final result = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => InspectionChecklistBottomSheet( + initialValues: checkList, + ))); + + if (result != null) { + checkList = result; + setState(() {}); + } + buildInspectionPayload(checkList); + if (checkList.isNotEmpty) { + final isPass = checkList.every((e) => e.status == 'PASS'); + log('Final Status: ${isPass ? 'PASS' : 'FAIL'}'); + } + +// call this as bottomsheet. + // final result = await showModalBottomSheet>>( + // context: context, + // isScrollControlled: true, + // backgroundColor: Colors.transparent, + // builder: (_) => const InspectionChecklistBottomSheet(), + // ); + } + + bool _isPass(List list, String title) { + return list + .firstWhere( + (e) => e.title == title, + orElse: () => InspectionChecklistItem(status: 'FAIL'), + ) + .status == + 'PASS'; + } + + buildInspectionPayload(List checklist) { + assetDeliveryProvider.parentFormModel.flagphysicalInspection = _isPass(checklist, 'Physical Inspection As Per Manufacturer Instructions'); + assetDeliveryProvider.parentFormModel.flagFunctionPerformance = _isPass(checklist, 'Functional Performance As Per Results Of Manufacturer Recommended Check List'); + assetDeliveryProvider.parentFormModel.flagGroundingResistance = _isPass(checklist, 'Grounding Resistance: Ω'); + assetDeliveryProvider.parentFormModel.flagChassiss = _isPass(checklist, 'Chassis Leakage Current: µA'); + assetDeliveryProvider.parentFormModel.flagLeadsLeakage = _isPass(checklist, 'Leads Leakage Current: µA'); + assetDeliveryProvider.parentFormModel.flagAlert = _isPass(checklist, 'This Device Is Not Subject To Any Alert Or Recall Until The Date Of Preparation Of This Inspection Form'); + } + + void applyInspectionFlagsToChecklist({ + required TechnicalInspectionAssetModel model, + }) { + if (checkList.isEmpty) { + checkList = AssetDeliveryUtils.inspectionChecklist; + } + for (final item in checkList) { + switch (item.value) { + case 'flagphysicalInspection': + item.status = _statusFromBool(model.flagphysicalInspection); + break; + + case 'flagFunctionPerformance': + item.status = _statusFromBool(model.flagFunctionPerformance); + break; + + case 'flagGroundingResistance': + item.status = _statusFromBool(model.flagGroundingResistance); + break; + + case 'flagChassiss': + item.status = _statusFromBool(model.flagChassiss); + break; + + case 'flagLeadsLeakage': + item.status = _statusFromBool(model.flagLeadsLeakage); + break; + + case 'flagAlert': + item.status = _statusFromBool(model.flagAlert); + break; + } + } + checkList.forEach((item) { + log('items ${item.toJson()}'); + }); + } + + String _statusFromBool(bool? value) { + return value == true ? 'PASS' : 'FAIL'; } } + +// import 'dart:developer'; +// import 'package:flutter/material.dart'; +// import 'package:provider/provider.dart'; +// import 'package:test_sa/extensions/context_extension.dart'; +// import 'package:test_sa/extensions/int_extensions.dart'; +// import 'package:test_sa/extensions/string_extensions.dart'; +// import 'package:test_sa/extensions/text_extensions.dart'; +// import 'package:test_sa/extensions/widget_extensions.dart'; +// import 'package:test_sa/models/new_models/building.dart'; +// import 'package:test_sa/models/new_models/floor.dart'; +// import 'package:test_sa/models/new_models/site.dart'; +// import 'package:test_sa/modules/asset_delivery_module/models/technical_inspection_asset_model.dart'; +// import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/search_asset_view.dart'; +// import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/status_checklist_view.dart'; +// import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart'; +// import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/update_child_asset_view.dart'; +// import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; +// import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; +// import 'package:test_sa/new_views/app_style/app_color.dart'; +// import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; +// import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; +// import 'package:test_sa/providers/gas_request_providers/site_provider.dart'; +// import 'package:test_sa/providers/loading_list_notifier.dart'; +// import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; +// import '../../../../models/new_models/department.dart'; +// import '../../../../new_views/common_widgets/app_filled_button.dart'; +// import '../../../../new_views/common_widgets/default_app_bar.dart'; +// +// //TODO need to refactor this screen when done ... +// +// class UpdateParentAssetView extends StatefulWidget { +// final TechnicalInspectionParentAssetModel assetModel; +// final int? lineId; +// +// UpdateParentAssetView({ +// Key? key, +// required this.assetModel, +// this.lineId, +// }) : super(key: key); +// +// @override +// State createState() => _UpdateParentAssetViewState(); +// } +// +// class _UpdateParentAssetViewState extends State { +// final GlobalKey _formKey = GlobalKey(); +// final GlobalKey _scaffoldKey = GlobalKey(); +// List checkList = []; +// late SiteProvider siteProvider; +// late AssetDeliveryProvider assetDeliveryProvider; +// +// @override +// void initState() { +// siteProvider = Provider.of(context, listen: false); +// assetDeliveryProvider = Provider.of(context, listen: false); +// // WidgetsBinding.instance.addPostFrameCallback((_) { +// populateForm(); +// // }); +// super.initState(); +// } +// +// void populateForm() async { +// // _model = widget.assetModel; +// assetDeliveryProvider.setModel(widget.assetModel); +// applyInspectionFlagsToChecklist(model: widget.assetModel,checklist: checkList); +// if (widget.assetModel.site != null) { +// await assetDeliveryProvider.getSiteData(siteId: widget.assetModel.site?.id, model: _model); +// } +// setState(() {}); +// } +// +// @override +// void dispose() { +// super.dispose(); +// } +// +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// key: _scaffoldKey, +// appBar: DefaultAppBar( +// title: 'Parent Details'.addTranslation, +// titleStyle: AppTextStyles.heading3.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), +// ), +// body: Form( +// key: _formKey, +// child: Column( +// children: [ +// SingleChildScrollView( +// padding: const EdgeInsets.all(16), +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// inspectionDetailsForm(lineId: widget.lineId), +// 8.height, +// const Divider().defaultStyle(context), +// 8.height, +// childList(context), +// ], +// ).toShadowContainer(context, borderRadius: 20, padding: 12)) +// .expanded, +// FooterActionButton.footerContainer(context: context, child: AppFilledButton(buttonColor: AppColor.primary10, label: 'Save'.addTranslation, maxWidth: true, onPressed: _saveTap)), +// ], +// ), +// ), +// ); +// } +// +// Widget childList(BuildContext context) { +// final assetDeliveryTableList = ['abc', 'def', 'ghi', 'fhg', 'hjhh']; +// return Column( +// mainAxisSize: MainAxisSize.min, +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Row( +// children: [ +// Text( +// "Test List", +// style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), +// ), +// 8.width, +// 'web_link_icon'.toSvgAsset().onPress(() { +// openInspectionChecklist(context); +// }), +// ], +// ), +// 8.height, +// ListView.separated( +// itemCount: assetDeliveryTableList.length, +// separatorBuilder: (_, __) => 8.height, +// padding: EdgeInsets.zero, +// shrinkWrap: true, +// physics: const NeverScrollableScrollPhysics(), +// itemBuilder: (listContext, itemIndex) { +// return TechnicalInspectionAssetCard( +// assetModel: TechnicalInspectionParentAssetModel(), +// ischild: true, +// editPress: () { +// Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateChildAssetView())); +// }, +// isViewOnly: false, +// ); +// }, +// ), +// ], +// ); +// } +// +// Widget inspectionDetailsForm({int? lineId}) { +// return Column( +// children: [ +// //Replace with simple container... +// AppTextFormField( +// labelText: 'Asset Number'.addTranslation, +// backgroundColor: AppColor.fieldBgColor(context), +// initialValue: _model.assetNumber, +// textAlign: TextAlign.center, +// labelStyle: AppTextStyles.textFieldLabelStyle, +// textInputType: TextInputType.number, +// showShadow: false, +// enable: false, +// style: Theme.of(context).textTheme.titleMedium, +// ).onPress(() async { +// var data = await Navigator.push( +// context, +// MaterialPageRoute( +// builder: (context) => TechnicalInspectionSearchAssetView( +// lineId: lineId, +// ))); +// if (data != null) { +// TechnicalInspectionParentAssetModel? assetModel = await assetDeliveryProvider.getAssetDetails(assetId: data?.id); +// +// if (assetModel != null) { +// _model =TechnicalInspectionParentAssetModel(); +// setState(() { +// +// }); +// setState(() { +// _model = assetModel; +// }); +// if (assetModel.site != null) { +// await assetDeliveryProvider.getSiteData(siteId: assetModel.site?.id, model: _model); +// } +// setState(() {}); +// } +// } +// }), +// 8.height, +// AppTextFormField( +// labelText: 'Serial Number'.addTranslation, +// backgroundColor: AppColor.fieldBgColor(context), +// initialValue: _model.serialNo ?? '', +// textAlign: TextAlign.center, +// labelStyle: AppTextStyles.textFieldLabelStyle, +// textInputType: TextInputType.number, +// showShadow: false, +// onSaved: (value) { +// _model.serialNo = value; +// }, +// style: Theme.of(context).textTheme.titleMedium, +// ), +// 8.height, +// AppTextFormField( +// labelText: 'System ID'.addTranslation, +// backgroundColor: AppColor.fieldBgColor(context), +// initialValue: _model.systemId ?? '', +// textAlign: TextAlign.center, +// labelStyle: AppTextStyles.textFieldLabelStyle, +// showShadow: false, +// onSaved: (value) { +// _model.systemId = value; +// }, +// style: Theme.of(context).textTheme.titleMedium, +// ), +// 8.height, +// SingleItemDropDownMenu( +// context: context, +// title: 'Site', +// initialValue: _model.site, +// loading: assetDeliveryProvider.isSiteLoading, +// showAsBottomSheet: true, +// backgroundColor: AppColor.fieldBgColor(context), +// showShadow: false, +// // enabled: false, +// onSelect: (value) { +// if (value == null) { +// return; +// } +// _model.site = value; +// _model.building = null; +// _model.floor = null; +// _model.department = null; +// setState(() {}); +// }, +// ), +// 8.height, +// SingleItemDropDownMenu( +// context: context, +// title: 'Building', +// backgroundColor: AppColor.fieldBgColor(context), +// showAsBottomSheet: true, +// loading: assetDeliveryProvider.isSiteLoading, +// showShadow: false, +// initialValue: _model.building, +// enabled: _model.site?.buildings?.isNotEmpty ?? false, +// staticData: _model.site?.buildings ?? [], +// onSelect: (value) { +// if (value == null) { +// return; +// } +// _model.building = value; +// _model.floor = null; +// _model.department = null; +// setState(() {}); +// }, +// ), +// 8.height, +// SingleItemDropDownMenu( +// context: context, +// showAsBottomSheet: true, +// backgroundColor: AppColor.fieldBgColor(context), +// loading: assetDeliveryProvider.isSiteLoading, +// showShadow: false, +// title: 'Floor', +// initialValue: _model.floor, +// enabled: _model.building?.floors?.isNotEmpty ?? false, +// staticData: _model.building?.floors ?? [], +// onSelect: (value) { +// if (value == null) { +// return; +// } +// _model.floor = value; +// _model.department = null; +// setState(() {}); +// }, +// ), +// 8.height, +// SingleItemDropDownMenu( +// context: context, +// title: 'Department', +// backgroundColor: AppColor.fieldBgColor(context), +// loading: assetDeliveryProvider.isSiteLoading, +// showAsBottomSheet: true, +// showShadow: false, +// initialValue: _model.department, +// enabled: _model.floor?.departments?.isNotEmpty ?? false, +// staticData: _model.floor?.departments ?? [], +// onSelect: (value) { +// if (value == null) { +// return; +// } +// _model.department = value; +// _model.room = null; +// setState(() {}); +// }, +// ), +// +// 8.height, +// ADatePicker( +// label: 'Installation Date'.addTranslation, +// hideShadow: true, +// height: 56.toScreenHeight, +// backgroundColor: AppColor.fieldBgColor(context), +// date: _model.installationDate, +// // from: widget.pickerFromDate, +// formatDateWithTime: true, +// onDatePicker: (selectedDate) { +// showTimePicker( +// context: context, +// initialTime: TimeOfDay.now(), +// builder: (BuildContext context, Widget? child) { +// final ThemeData currentTheme = Theme.of(context); +// return Theme( +// data: currentTheme.copyWith( +// timePickerTheme: TimePickerThemeData( +// dialHandColor: AppColor.primary10, +// dialBackgroundColor: Colors.grey.withOpacity(0.1), +// hourMinuteColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.grey.withOpacity(0.1)), +// dayPeriodColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? AppColor.primary10 : Colors.transparent), +// dayPeriodTextColor: MaterialStateColor.resolveWith((states) => states.contains(MaterialState.selected) ? Colors.white : AppColor.primary10), +// dayPeriodBorderSide: BorderSide(color: Colors.grey.withOpacity(0.2)), +// entryModeIconColor: AppColor.primary10, +// ), +// textButtonTheme: TextButtonThemeData(style: TextButton.styleFrom(foregroundColor: AppColor.primary10)), +// ), +// child: child!, +// ); +// }, +// ).then((selectedTime) { +// if (selectedTime != null) { +// _model.installationDate = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); +// setState(() {}); +// } +// }); +// }, +// ), +// 8.height, +// ], +// ); +// } +// +// ///Need to check which details show here... +// +// void _saveTap() async { +// _formKey.currentState!.save(); +// } +// +// Future openInspectionChecklist(BuildContext context) async { +// final result = await Navigator.push( +// context, +// MaterialPageRoute( +// builder: (context) => InspectionChecklistBottomSheet( +// initialValues: checkList, +// ))); +// +// log('result i got is $result'); +// if(result!=null){ +// checkList = result; +// setState(() {}); +// } +// if (checkList.isNotEmpty) { +// final isPass = checkList.every((e) => e.status == 'PASS'); +// log('Final Status: ${isPass ? 'PASS' : 'FAIL'}'); +// } +// final payload = buildInspectionPayload(checkList); +// +// log('API Payload: $payload'); +// // call this as bottomsheet. +// // final result = await showModalBottomSheet>>( +// // context: context, +// // isScrollControlled: true, +// // backgroundColor: Colors.transparent, +// // builder: (_) => const InspectionChecklistBottomSheet(), +// // ); +// } +// +// bool _isPass(List list, String title) { +// return list +// .firstWhere( +// (e) => e.title == title, +// orElse: () => InspectionChecklistItem(status: 'FAIL'), +// ) +// .status == +// 'PASS'; +// } +// +// Map buildInspectionPayload(List checklist) { +// return { +// 'flagphysicalInspection': _isPass(checklist, 'Physical Inspection As Per Manufacturer Instructions'), +// 'flagFunctionPerformance': _isPass(checklist, 'Functional Performance As Per Results Of Manufacturer Recommended Check List'), +// 'flagGroundingResistance': _isPass(checklist, 'Grounding Resistance: Ω'), +// 'flagChassiss': _isPass(checklist, 'Chassis Leakage Current: µA'), +// 'flagLeadsLeakage': _isPass(checklist, 'Leads Leakage Current: µA'), +// 'flagAlert': _isPass(checklist, 'This Device Is Not Subject To Any Alert Or Recall Until The Date Of Preparation Of This Inspection Form'), +// }; +// } +// +// void applyInspectionFlagsToChecklist({ +// required List checklist, +// required TechnicalInspectionParentAssetModel model, +// }) { +// for (final item in checklist) { +// switch (item.title) { +// case 'Physical Inspection As Per Manufacturer Instructions': +// item.status = _statusFromBool(model.flagphysicalInspection); +// break; +// +// case 'Functional Performance As Per Results Of Manufacturer Recommended Check List': +// item.status = _statusFromBool(model.flagFunctionPerformance); +// break; +// +// case 'Grounding Resistance: Ω': +// item.status = _statusFromBool(model.flagGroundingResistance); +// break; +// +// case 'Chassis Leakage Current: µA': +// item.status = _statusFromBool(model.flagChassiss); +// break; +// +// case 'Leads Leakage Current: µA': +// item.status = _statusFromBool(model.flagLeadsLeakage); +// break; +// +// case 'This Device Is Not Subject To Any Alert Or Recall Until The Date Of Preparation Of This Inspection Form': +// item.status = _statusFromBool(model.flagAlert); +// break; +// } +// } +// } +// String _statusFromBool(bool? value) { +// return value == true ? 'PASS' : 'FAIL'; +// } +// } diff --git a/lib/modules/asset_delivery_module/pages/technical_inpection/update_technical_inspection_lines_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/update_technical_inspection_lines_view.dart index d13ab6b3..f64f1461 100644 --- a/lib/modules/asset_delivery_module/pages/technical_inpection/update_technical_inspection_lines_view.dart +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/update_technical_inspection_lines_view.dart @@ -1,44 +1,41 @@ -import 'dart:convert'; import 'dart:developer'; -import 'dart:io'; + import 'package:flutter/material.dart'; -import 'package:flutter_advanced_switch/flutter_advanced_switch.dart'; import 'package:provider/provider.dart'; -import 'package:test_sa/common_widgets/lookup_autocomplete_field.dart'; -import 'package:test_sa/controllers/providers/api/all_requests_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/models/generic_attachment_model.dart'; import 'package:test_sa/models/lookup.dart'; -import 'package:test_sa/modules/asset_delivery_module/pages/asset_delivery_line_card_view.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/asset_delivery_data_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/cost_center_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/delivery_line_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/technical_inspection_form_model.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_cost_center_card_view.dart'; import 'package:test_sa/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_parent_asset_list_view.dart'; -import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart'; -import 'package:test_sa/modules/asset_inventory_module/pages/search_asset_view.dart'; -import 'package:test_sa/modules/asset_inventory_module/provider/asset_inventory_provider.dart'; -import 'package:test_sa/modules/cm_module/cm_request_utils.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/asset_delivery_provider.dart'; +import 'package:test_sa/modules/asset_delivery_module/provider/power_supply_type_provider.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; -import 'package:test_sa/providers/service_request_providers/last_situation_provider.dart'; -import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; -import 'package:test_sa/views/widgets/equipment/asset_picker.dart'; -import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; -import 'package:test_sa/views/widgets/images/multi_image_picker_item.dart'; -import 'package:test_sa/views/widgets/requests/request_status.dart'; +import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import '../../../../new_views/common_widgets/app_filled_button.dart'; import '../../../../new_views/common_widgets/default_app_bar.dart'; class UpdateTechnicalInspectionLinesView extends StatefulWidget { static const String id = "/technical-inspection-form"; + final AssetDeliveryTableModel deliveryTableModel; + final AssetDeliveryDataModel? requestModel; + final DeliveryLineModel? deliveryLineModel; UpdateTechnicalInspectionLinesView({ Key? key, + required this.deliveryTableModel, + this.requestModel, + this.deliveryLineModel, }) : super(key: key); @override @@ -48,9 +45,15 @@ class UpdateTechnicalInspectionLinesView extends StatefulWidget { class _UpdateTechnicalInspectionLinesViewState extends State { final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); + TechnicalInspectionFormModel model = TechnicalInspectionFormModel(); + AssetDeliveryProvider? assetDeliveryProvider; + bool isLoading = false; @override void initState() { + WidgetsBinding.instance.addPostFrameCallback((_) { + getInitialData(); + }); super.initState(); } @@ -59,6 +62,18 @@ class _UpdateTechnicalInspectionLinesViewState extends State(context, listen: false); + isLoading = true; + setState(() {}); + model = await assetDeliveryProvider!.getTechnicalInspectionData( + lineId: widget.deliveryLineModel?.id, + tableId: widget.deliveryTableModel.id, + ); + isLoading = false; + setState(() {}); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -69,53 +84,87 @@ class _UpdateTechnicalInspectionLinesViewState extends State costCenterList = model.costCenters ?? []; + return costCenterList.isEmpty + ? const NoDataFound().center + : ListView.separated( + itemCount: costCenterList.length, + separatorBuilder: (_, __) => 8.height, + padding: EdgeInsets.zero, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (listContext, itemIndex) { + return TechnicalInspectionCostCard( + costModel: costCenterList[itemIndex], + editPress: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => TechnicalInspectionParentAssetListView( + costCenterId: costCenterList[itemIndex].id, + tableItemId: widget.deliveryTableModel.id, + lineId: widget.deliveryLineModel?.id, + ))); + }, + isViewOnly: false, + ); + }, + ); + } + + Widget itemDetails({required BuildContext context, String? itemNo, String? itemDescription}) { return Column( - mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "Cost Centers", - style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + 'Item No'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), ), 8.height, - ListView.separated( - itemCount: assetDeliveryTableList.length, - separatorBuilder: (_, __) => 8.height, - padding: EdgeInsets.zero, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (listContext, itemIndex) { - return TechnicalInspectionCostCard( - deliveryDetails: AssetInventoryModel(), - editPress: () { - Navigator.push(context, MaterialPageRoute(builder: (context) => TechnicalInspectionParentAssetListView())); - }, - isViewOnly: false, - ); - }, + Text( + itemNo ?? '-', + style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), + ), + 8.height, + Text( + 'Item Description'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + itemDescription ?? '-', + style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), ), ], ); @@ -124,81 +173,60 @@ class _UpdateTechnicalInspectionLinesViewState extends State( + SingleItemDropDownMenu( context: context, height: 56.toScreenHeight, title: 'Power Supply Type'.addTranslation, titleTextColor: AppColor.neutral120, showShadow: false, - // backgroundColor: AppColor.neutral100, backgroundColor: AppColor.fieldBgColor(context), showAsBottomSheet: true, - // initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, - onSelect: (status) { - if (status != null) { - // requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; + initialValue: model.powerSupplyType, + onSelect: (value) { + if (value != null) { + model.powerSupplyType = value; setState(() {}); } }, ), - // 8.height, - // LookUpAutoCompleteField( - // clearAfterPick: false, - // forAssetName: true, - // onChanged: (value) {}, - // initialValue: '', - // label: 'Cost Center'.addTranslation, - // onPick: (value) {}, - // ), 8.height, AppTextFormField( labelText: 'Power Reading'.addTranslation, backgroundColor: AppColor.fieldBgColor(context), - initialValue: '', + initialValue: model.powerReading != null ? model.powerReading.toString() : '', textAlign: TextAlign.center, labelStyle: AppTextStyles.textFieldLabelStyle, textInputType: TextInputType.number, showShadow: false, + onSaved: (value) { + model.powerReading = int.tryParse(value); + }, style: Theme.of(context).textTheme.titleMedium, ), 8.height, AppTextFormField( labelText: 'Max Current'.addTranslation, backgroundColor: AppColor.fieldBgColor(context), - initialValue: '', + initialValue: model.maxCurrent != null ? model.maxCurrent.toString() : '', textAlign: TextAlign.center, labelStyle: AppTextStyles.textFieldLabelStyle, + textInputType: TextInputType.number, showShadow: false, + onSaved: (value) { + model.maxCurrent = int.tryParse(value); + }, style: Theme.of(context).textTheme.titleMedium, ), 8.height, AppTextFormField( labelText: 'Voltage'.addTranslation, backgroundColor: AppColor.fieldBgColor(context), - initialValue: '', + textInputType: TextInputType.number, + initialValue: model.voltage != null ? model.voltage.toString() : '', textAlign: TextAlign.center, + onSaved: (value) { + model.voltage = int.tryParse(value); + }, labelStyle: AppTextStyles.textFieldLabelStyle, showShadow: false, style: Theme.of(context).textTheme.titleMedium, @@ -207,8 +235,12 @@ class _UpdateTechnicalInspectionLinesViewState extends State(context, listen: false); _formKey.currentState!.save(); + model.tableItemId = widget.deliveryTableModel.id; + model.lineId = widget.deliveryLineModel?.id; + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + await assetDeliveryProvider?.saveTechnicalInspection(model: model).then((status) async { + Navigator.pop(context); + if (status) { + Navigator.pop(context); + } + }); } } diff --git a/lib/modules/asset_delivery_module/provider/asset_delivery_provider.dart b/lib/modules/asset_delivery_module/provider/asset_delivery_provider.dart index b87e092c..a9dedb0d 100644 --- a/lib/modules/asset_delivery_module/provider/asset_delivery_provider.dart +++ b/lib/modules/asset_delivery_module/provider/asset_delivery_provider.dart @@ -1,294 +1,267 @@ import 'dart:convert'; import 'dart:developer'; - import 'package:flutter/material.dart'; -import 'package:fluttertoast/fluttertoast.dart'; import 'package:http/http.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; -import 'package:test_sa/extensions/context_extension.dart'; -import 'package:test_sa/extensions/string_extensions.dart'; -import 'package:test_sa/models/device/asset.dart'; -import 'package:test_sa/models/device/asset_search.dart'; -import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/models/generic_attachment_model.dart'; import 'package:test_sa/models/module_permissions_model.dart'; -import 'package:test_sa/models/service_request/pending_service_request_model.dart'; -import 'package:test_sa/models/service_request/service_report.dart'; -import 'package:test_sa/models/service_request/service_request.dart'; -import 'package:test_sa/models/service_request/service_request_search.dart'; -import 'package:test_sa/models/service_request/spare_parts.dart'; -import 'package:test_sa/models/service_request/supp_engineer_work_orders.dart'; -import 'package:test_sa/models/service_request/supplier_engineer_model.dart'; -import 'package:test_sa/models/timer_model.dart'; -import 'package:test_sa/modules/asset_inventory_module/models/asset_inventory_model.dart'; -import 'package:test_sa/modules/asset_inventory_module/models/session_model.dart'; - -import '../../../models/service_request/search_work_order.dart'; -import '../../../models/service_request/wo_call_request.dart'; -import '../../../models/user.dart'; -import '../../../new_views/common_widgets/app_lazy_loading.dart'; +import 'package:test_sa/models/new_models/building.dart'; +import 'package:test_sa/models/new_models/floor.dart'; +import 'package:test_sa/models/new_models/room_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/asset_delivery_data_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/cost_center_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/delivery_inspection_form_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/delivery_line_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/end_user_asset_details_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/history_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/technical_inspection_asset_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/models/technical_inspection_form_model.dart'; +import '../../../models/new_models/department.dart'; +import '../../../models/new_models/site.dart'; +import '../models/oracle_user_model.dart'; class AssetDeliveryProvider extends ChangeNotifier { final pageItemNumber = 10; final searchPageItemNumber = 10; int pageNo = 1; - List _devices = []; - List _searchDevices = []; - - List get devices => _devices; - - List get searchDevices => _searchDevices; - SessionModel? sessionModel; - - //TODO need to check i think don't need to create this obj - AssetInventoryResponse? assetInventoryResponse; - AssetInventoryResponse? siteFilterAssetResponse; - - List sessionAssetList = []; - List siteFilterAssetList = []; - + AssetDeliveryDataModel? assetDeliveryDataModel; + List assetDeliveryTableList = []; + List deliveryLinesList = []; ModulesPermissionsModel? modelPermission; + TechnicalInspectionAssetModel parentFormModel = TechnicalInspectionAssetModel(); + TechnicalInspectionAssetModel childFormModel = TechnicalInspectionAssetModel(); void reset() { pageNo = 1; - modelPermission = null; - assetInventoryResponse = null; - sessionModel = null; - sessionAssetList = []; stateCode = null; } int? stateCode; bool isDetailLoading = false; bool nextPage = false; - bool isNextPageLoading = false; bool isLoading = false; - bool isAllAssetLoading = false; + bool isSiteLoading = false; + bool isDeliveryTableListLoading = false; + bool isDeliveryLineListLoading = false; + bool isChildAssetDataLoading = false; - void searchReset() { - stateCode = null; - _searchDevices = []; + void setParentModel(TechnicalInspectionAssetModel m) { + parentFormModel = m; + notifyListeners(); + } + + void setChildModel(TechnicalInspectionAssetModel m) { + childFormModel = m; + notifyListeners(); } - Future getSessionById({required int id}) async { + Future getAssetDeliveryDetailById({int? requestId}) async { try { - sessionModel = SessionModel(); + assetDeliveryDataModel = AssetDeliveryDataModel(); isLoading = true; notifyListeners(); - final response = await ApiManager.instance.get(URLs.getAssetInventoryById + "?assetInventoryId=$id"); + final response = await ApiManager.instance.get(URLs.getAssetDeliveryDetailsById + "?Id=$requestId"); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { - sessionModel = SessionModel.fromJson(json.decode(response.body)["data"]); + assetDeliveryDataModel = AssetDeliveryDataModel.fromJson(json.decode(response.body)["data"]); } else { - sessionModel = null; + assetDeliveryDataModel = null; } - isLoading = false; notifyListeners(); + return assetDeliveryDataModel; } catch (e) { - log("getSessionError [error] : $e"); + log("getdelivery details [error] : $e"); isLoading = false; - sessionModel = null; + assetDeliveryDataModel = null; notifyListeners(); - return null; + return assetDeliveryDataModel; } } - Future getAssetsInSession({ - required int sessionId, - bool loadMore = false, - }) async { - if (isLoading || isNextPageLoading) return -2; - if (loadMore) { - isNextPageLoading = true; - pageNo += 1; - } else { - isLoading = true; - pageNo = 1; // reset pagination - } - notifyListeners(); + Future getAssetDeliveryTableListById({int? requestId}) async { try { - final payload = { - "pageSize": pageItemNumber, - "pageNumber": pageNo, - "sessionId": sessionId, - }; - final response = await ApiManager.instance.post(URLs.getAssetsInSession, body: payload); + assetDeliveryTableList.clear(); + isDeliveryTableListLoading = true; + notifyListeners(); + + final response = await ApiManager.instance.get( + "${URLs.getAssetDeliveryTableListById}?assetDeliveryExternalMasterId=$requestId", + ); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { - final Map jsonData = json.decode(response.body); - final newResponse = AssetInventoryResponse.fromJson(jsonData); - - if (loadMore) { - assetInventoryResponse?.assetList?.addAll(newResponse.assetList ?? []); - assetInventoryResponse?.totalRows = newResponse.totalRows; + final jsonData = json.decode(response.body)["data"]; + if (jsonData is List) { + assetDeliveryTableList = jsonData.map((e) => AssetDeliveryTableModel.fromJson(e)).toList(); } else { - assetInventoryResponse = newResponse; + assetDeliveryTableList = []; } - nextPage = (assetInventoryResponse?.assetList?.length ?? 0) < (assetInventoryResponse?.totalRows ?? 0); } else { - nextPage = false; + assetDeliveryTableList = []; } - isLoading = false; - isNextPageLoading = false; + + isDeliveryTableListLoading = false; notifyListeners(); - return response.statusCode; - } catch (error) { - isLoading = false; - isNextPageLoading = false; - stateCode = -1; - nextPage = false; + } catch (e) { + log("get Delivery Table details [error] : $e"); + isDeliveryTableListLoading = false; + assetDeliveryTableList = []; notifyListeners(); - return -1; } } - ///older code - // Future getAssetsInSession({ - // required int sessionId, - // bool loadMore = false, - // }) async { - // // if (isLoading || nextPage) return -2; - // - // if (loadMore) { - // nextPage = true; - // pageNo += 1; - // } else { - // isLoading = true; - // pageNo = 1; // reset pagination - // } - // - // notifyListeners(); - // log('Fetching page: $pageNo'); - // - // try { - // final payload = { - // "pageSize": pageItemNumber, - // "pageNumber": pageNo, - // "sessionId": sessionId, - // }; - // - // final response = await ApiManager.instance.post(URLs.getAssetsInSession, body: payload); - // stateCode = response.statusCode; - // - // if (response.statusCode >= 200 && response.statusCode < 300) { - // final Map jsonData = json.decode(response.body); - // final newResponse = AssetInventoryResponse.fromJson(jsonData); - // - // if (loadMore) { - // assetInventoryResponse?.assetList?.addAll(newResponse.assetList ?? []); - // assetInventoryResponse?.totalRows = newResponse.totalRows; - // } else { - // assetInventoryResponse = newResponse; - // } - // - // nextPage = (assetInventoryResponse?.assetList?.length ?? 0) < (assetInventoryResponse?.totalRows ?? 0); - // } - // - // isLoading = false; - // nextPage = false; - // notifyListeners(); - // return response.statusCode; - // } catch (error) { - // isLoading = false; - // nextPage = false; - // stateCode = -1; - // notifyListeners(); - // return -1; - // } - // } - - Future getInventoryDetailsByFilter({ - required Map payload, - bool loadMore = false, - }) async { - if (isLoading || isNextPageLoading) return -2; - - if (loadMore) { - isNextPageLoading = true; - pageNo += 1; - } else { - isLoading = true; - pageNo = 1; + Future getDeliveryLinesListById({int? itemId}) async { + try { + deliveryLinesList.clear(); + isDeliveryLineListLoading = true; + notifyListeners(); + final response = await ApiManager.instance.get( + "${URLs.getLineFromExternalPo}?assetDeliveryExternalDeliveryId=$itemId", + ); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + final jsonData = json.decode(response.body)["data"]; + if (jsonData is List) { + deliveryLinesList = jsonData.map((e) => DeliveryLineModel.fromJson(e)).toList(); + } else { + deliveryLinesList = []; + } + } else { + deliveryLinesList = []; + } + isDeliveryLineListLoading = false; + notifyListeners(); + } catch (e) { + log("get Delivery Lines List [error] : $e"); + isDeliveryLineListLoading = false; + deliveryLinesList = []; + notifyListeners(); } + } - notifyListeners(); - log('Fetching inventory page: $pageNo'); - + Future> getTechnicalInspectionLinesListById({int? itemId}) async { + List linesList = []; try { - final paginatedPayload = { - ...payload, - "pageSize": pageItemNumber, - "pageNumber": pageNo, - }; - - final response = await ApiManager.instance.post(URLs.getInventoryDetailsByFilter, body: paginatedPayload); + isLoading = true; + notifyListeners(); + final response = await ApiManager.instance.get( + "${URLs.getLineFromTechnicalInspection}?assetDeliveryExternalDeliveryId=$itemId", + ); stateCode = response.statusCode; - if (response.statusCode >= 200 && response.statusCode < 300) { - final Map jsonData = json.decode(response.body); - final newResponse = AssetInventoryResponse.fromJson(jsonData); - - if (loadMore) { - siteFilterAssetList.addAll(newResponse.assetList ?? []); - siteFilterAssetResponse?.totalRows = newResponse.totalRows; + final jsonData = json.decode(response.body)["data"]; + if (jsonData is List) { + linesList = jsonData.map((e) => DeliveryLineModel.fromJson(e)).toList(); } else { - siteFilterAssetResponse = newResponse; - siteFilterAssetList = newResponse.assetList ?? []; + assetDeliveryTableList = []; } - nextPage = (siteFilterAssetList.length) < (siteFilterAssetResponse?.totalRows ?? 0); } else { - siteFilterAssetList = []; - nextPage = false; + linesList = []; } + isLoading = false; + notifyListeners(); + return linesList; + } catch (e) { + log("get Delivery Lines List [error] : $e"); + isLoading = false; + linesList = []; + notifyListeners(); + return linesList; + } + } + Future> getAssetDeliveryCostCenterListForLines({int? lineId, int? tableItemId}) async { + List costCenterList = []; + try { + isLoading = true; + notifyListeners(); + final response = await ApiManager.instance.get( + "${URLs.getCostCenterListToLineDeliveryInspection}?AssetDeliveryExternalDetailId=$lineId&AssetDeliveryExternalDeliveryId=$tableItemId", + ); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + final jsonData = json.decode(response.body)["data"]; + if (jsonData is List) { + costCenterList = jsonData.map((e) => CostCenterModel.fromJson(e)).toList(); + } + } else { + costCenterList = []; + } isLoading = false; - isNextPageLoading = false; notifyListeners(); - return response.statusCode; - } catch (error) { + return costCenterList; + } catch (e) { + log("get Delivery Lines List [error] : $e"); isLoading = false; - isNextPageLoading = false; - nextPage = false; - stateCode = -1; + costCenterList = []; notifyListeners(); - return -1; + return costCenterList; } } - Future searchAsset({ - required Map payload, + Future addNewDelivery({ + int? requestId, + }) async { + isDeliveryTableListLoading = true; + Map payload = { + 'assetDeliveryExternalMasterId': requestId, + }; + try { + final response = await ApiManager.instance.post(URLs.addNewDelivery, body: payload); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + isDeliveryTableListLoading = false; + notifyListeners(); + return true; + } else { + isDeliveryTableListLoading = false; + notifyListeners(); + return false; + } + } catch (error) { + isDeliveryTableListLoading = false; + notifyListeners(); + return false; + } + } + + Future saveTechnicalInspection({ + required TechnicalInspectionFormModel model, }) async { isLoading = true; try { - final response = await ApiManager.instance.post(URLs.searchAsset, body: payload); + final response = await ApiManager.instance.post(URLs.saveTechnicalInspection, body: model.toJson()); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { - final Map jsonData = json.decode(response.body)["data"]; - AssetInventoryModel model = AssetInventoryModel.fromJson(jsonData); - log('model json ${model.toJson()}'); isLoading = false; notifyListeners(); - return model; + return true; } else { isLoading = false; notifyListeners(); - return null; + return false; } } catch (error) { isLoading = false; - stateCode = -1; notifyListeners(); - return null; + return false; } } - Future saveAssetInSession({ - AssetInventoryModel? model, + Future saveCostCenterToLineDeliveryInspection({ + int? tableItemId, + int? lineId, + List? list, }) async { isLoading = true; + Map payload = { + "assetDeliveryExternalDeliveryId": tableItemId, + "assetDeliveryExternalDetailId": lineId, + "costCenters": list?.map((x) => x.toJson()).toList(), + }; try { - final response = await ApiManager.instance.post(URLs.saveAssetInSession, body: model?.toJson() ?? {}); + final response = await ApiManager.instance.post(URLs.saveCostCenterToLineDeliveryInspection, body: payload); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { isLoading = false; @@ -306,151 +279,435 @@ class AssetDeliveryProvider extends ChangeNotifier { } } - Future getClassification({ - required Map payload, - }) async { + Future changeDeliveryStatusToCancel({int? itemId}) async { isLoading = true; - String? classification; try { - final response = await ApiManager.instance.post(URLs.getClassification, body: payload); + final response = await ApiManager.instance.get( + "${URLs.changeDeliveryStatusToCancel}?assetDeliveryExternalDeliveryId=$itemId", + ); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { - log('classifcation on response ${json.decode(response.body)["data"]['classification']}'); - classification = json.decode(response.body)["data"]['classification']; isLoading = false; notifyListeners(); - return classification; + return true; } else { isLoading = false; notifyListeners(); - return classification; + return false; } } catch (error) { isLoading = false; notifyListeners(); - return classification; + return false; } } - Future deleteAssetISession({required num id}) async { + Future changeDeliveryStatus({ + int? itemId, + Map? requestPayload, + }) async { + isLoading = true; + Map payload = { + 'assetDeliveryExternalDeliveryId': itemId, + }; try { - isLoading = true; - notifyListeners(); - final response = await ApiManager.instance.get(URLs.deleteAssetInSession + "?id=$id"); + final response = await ApiManager.instance.post(URLs.changeDeliveryStatus, body: requestPayload ?? payload); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { isLoading = false; notifyListeners(); return true; + } else { + isLoading = false; + notifyListeners(); + return false; } + } catch (error) { isLoading = false; notifyListeners(); return false; + } + } + + Future getAssetDeliveryInspectionData({int? itemId}) async { + isLoading = true; + DeliveryInspectionFormModel deliveryInspectionFormModel = DeliveryInspectionFormModel(); + try { + final response = await ApiManager.instance.get( + "${URLs.getAssetDeliveryInspectionData}?assetDeliveryExternalDeliveryId=$itemId", + ); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + deliveryInspectionFormModel = DeliveryInspectionFormModel.fromJson(json.decode(response.body)["data"]); + } + isLoading = false; + notifyListeners(); + return deliveryInspectionFormModel; } catch (e) { - log("Delete Asset [error] : $e"); + log("getAssetDeliveryInspectionData details [error] : $e"); isLoading = false; notifyListeners(); - return false; + return deliveryInspectionFormModel; } } - Future> getAutoCompleteDetails({ - bool? isManufacturer, - String? query, - int type = 0, - }) async { + Future getTechnicalInspectionData({int? lineId, int? tableId}) async { + isLoading = true; + TechnicalInspectionFormModel technicalInspectionFormModel = TechnicalInspectionFormModel(); try { - String url = ''; - switch (type) { - //for model and manufacturer.. - case 0: - url = URLs.getManufacturerOrModelAutoComplete; - break; - //for asset name.. - case 1: - url = URLs.searchAssetName; - break; - //for supplier... - case 2: - url = URLs.getSuppliersAutoCompleteInventory; - break; - default: - url = URLs.getManufacturerOrModelAutoComplete; - } - final queryParams = {}; - if (isManufacturer != null && type == 0) { - queryParams['isManufacturer'] = isManufacturer.toString(); + final response = await ApiManager.instance.get( + "${URLs.getTechnicalInspectionByDetailId}?assetDeliveryExternalDetailId=$lineId&assetDeliveryExternalDeliveryId=$tableId", + ); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + technicalInspectionFormModel = TechnicalInspectionFormModel.fromJson(json.decode(response.body)["data"]); } - if (query != null && query.isNotEmpty) { - queryParams['searchText'] = query; + isLoading = false; + notifyListeners(); + return technicalInspectionFormModel; + } catch (e) { + log("getTechnicalInspectionByDetailId details [error] : $e"); + isLoading = false; + notifyListeners(); + return technicalInspectionFormModel; + } + } + + Future getDeliveryHistories({int? itemId}) async { + isLoading = true; + DeliveryInspectionFormModel deliveryInspectionFormModel = DeliveryInspectionFormModel(); + try { + final response = await ApiManager.instance.get( + "${URLs.getAssetDeliveryInspectionData}?assetDeliveryExternalDeliveryId=$itemId", + ); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + deliveryInspectionFormModel = DeliveryInspectionFormModel.fromJson(json.decode(response.body)["data"]); } - if (queryParams.isNotEmpty) { - url += '?${Uri(queryParameters: queryParams).query}'; + isLoading = false; + notifyListeners(); + return deliveryInspectionFormModel; + } catch (e) { + log("getAssetDeliveryInspectionData details [error] : $e"); + isLoading = false; + notifyListeners(); + return deliveryInspectionFormModel; + } + } + + Future> getOracleUserAutoCompleteDetails({ + String? query, + }) async { + try { + isLoading = true; + final response = await ApiManager.instance.post(URLs.getOracleUserList, body: {'employeeName': query}); + List list = []; + if (response.statusCode >= 200 && response.statusCode < 300) { + isLoading = false; + notifyListeners(); + final data = json.decode(response.body)["data"]; + list = (data as List).map((e) => OracleUserModel.fromJson(e)).toList(); } - final response = await ApiManager.instance.get(url); + isLoading = false; + notifyListeners(); + return list; + } catch (error) { + log('error $error'); + isLoading = false; + notifyListeners(); + return []; + } + } - List list = []; + Future> getAttachments({ + num? tableItemId, + }) async { + try { + isLoading = true; + final response = await ApiManager.instance.get("${URLs.getAttachments}?assetDeliveryExternalDeliveryId=$tableItemId"); + List list = []; if (response.statusCode >= 200 && response.statusCode < 300) { + isLoading = false; + notifyListeners(); final data = json.decode(response.body)["data"]; - list = (data as List).map((e) => Lookup.fromJson(e)).toList(); + list = (data as List).map((e) => GenericAttachmentModel.fromJson(e)).toList(); } + isLoading = false; + notifyListeners(); return list; } catch (error) { log('error $error'); + isLoading = false; + notifyListeners(); return []; } } - Future getAssets({DeviceSearch? search, bool isQr = false, bool isSearchBy = false, num? sessionId}) async { - if (isLoading == true) return -2; + Future> getParentAssetList({int? costCenterId, int? tableItemId, int? lineId}) async { + List parentAssetList = []; + try { + isLoading = true; + notifyListeners(); + final response = await ApiManager.instance.get( + "${URLs.getTechnicalInspectionParentData}?assetDeliveryExternalDeliveryId=$tableItemId&assetDeliveryExternalDetailId=$lineId&costCenterId=$costCenterId", + ); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + final jsonData = json.decode(response.body)["data"]; + if (jsonData is List) { + parentAssetList = jsonData.map((e) => TechnicalInspectionAssetModel.fromJson(e)).toList(); + } + } else { + parentAssetList = []; + } + isLoading = false; + notifyListeners(); + return parentAssetList; + } catch (e) { + log("get parent List [error] : $e"); + isLoading = false; + parentAssetList = []; + notifyListeners(); + return parentAssetList; + } + } + + Future getSiteData({ + required num? siteId, + required TechnicalInspectionAssetModel model, + }) async { + isSiteLoading = true; + notifyListeners(); + + try { + final response = await ApiManager.instance.get( + "${URLs.getSiteAutoCompleteWithoutConditionSites}?id=$siteId", + ); + + stateCode = response.statusCode; + + if (response.statusCode >= 200 && response.statusCode < 300) { + final List? siteData = json.decode(response.body)["data"]; + + if (siteData != null && siteData.isNotEmpty) { + model.site = Site.fromJson(siteData.first); + } + + model.building = model.site?.buildings?.firstWhere( + (e) => e.value == model.building?.value, + orElse: () => Building(), + ); + + model.floor = model.building?.floors?.firstWhere( + (e) => e.value == model.floor?.value, + orElse: () => Floor(), + ); + + model.department = model.floor?.departments?.firstWhere( + (e) => e.departmentName == model.department?.departmentName, + orElse: () => Department(), + ); + + model.room = model.department?.rooms?.firstWhere( + (e) => e.value == model.room?.value, + orElse: () => Rooms(), + ); + } + + isSiteLoading = false; + notifyListeners(); + return model; + } catch (e) { + isSiteLoading = false; + stateCode = -1; + notifyListeners(); + return model; + } + } + + Future getAssetDetails({required num? assetId}) async { isLoading = true; notifyListeners(); - late Response response; try { - final Map body = { - "pageSize": isSearchBy ? searchPageItemNumber : pageItemNumber, - "pageNumber": isSearchBy ? (searchDevices.length / searchPageItemNumber).ceil() + 1 : devices.length ~/ pageItemNumber + 1, - "sessionId": sessionId ?? 0, - "assetSerialNo": search?.assetSerialNumber ?? '', - "assetName": search?.assetName ?? '', - "model": search?.model ?? '', - "manufacturer": search?.manufacturer ?? '', - "supplier": search?.supplier ?? '', - "siteName": search?.site ?? '', - // "buildingName":search?.??'', - // "floorName": search?.f??'', - "departmentName": search?.department ?? '', - // "roomName": search?.room - }; - // if (search != null) body.addAll(search.toJson()); - response = await ApiManager.instance.post(URLs.getAssetsTemp, body: body); + Response response = await ApiManager.instance.get(URLs.getAssetDetailsByAssetId + "?AssetDeliveryInternalDetailAssetId=$assetId"); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + final data = json.decode(response.body)["data"]; + TechnicalInspectionAssetModel assetModel = TechnicalInspectionAssetModel.fromJson(data); + isLoading = false; + notifyListeners(); + return assetModel; + } else { + return null; + } } catch (error) { isLoading = false; stateCode = -1; notifyListeners(); - return -1; + return null; } - stateCode = response.statusCode; - if (response.statusCode >= 200 && response.statusCode < 300) { - // client's request was successfully received - List equipmentListJson = json.decode(response.body)["data"]; - var dList = equipmentListJson.map((asset) => AssetInventoryModel.fromJson(asset)).toList() ?? []; - isSearchBy ? _searchDevices.addAll(dList) : _devices.addAll(dList); - nextPage = true; - } else { - nextPage = false; + } + + Future saveTechnicalInspectionAssetData({ + required TechnicalInspectionAssetModel model, + }) async { + isLoading = true; + try { + final response = await ApiManager.instance.post(URLs.saveTechnicalInspectionAsset, body: model.toJson()); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + isLoading = false; + notifyListeners(); + return true; + } else { + isLoading = false; + notifyListeners(); + return false; + } + } catch (error) { + isLoading = false; + notifyListeners(); + return false; } - isLoading = false; - notifyListeners(); - return response.statusCode; } - Future markAsComplete({ + Future saveAttachment({ required Map payload, }) async { isLoading = true; try { - final response = await ApiManager.instance.post(URLs.convertDetailToComplete, body: payload); + final response = await ApiManager.instance.post(URLs.saveAttachments, body: payload); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + isLoading = false; + notifyListeners(); + return true; + } else { + isLoading = false; + notifyListeners(); + return false; + } + } catch (error) { + isLoading = false; + notifyListeners(); + return false; + } + } + + Future> getHistory({ + num? tableItemId, + }) async { + try { + isLoading = true; + notifyListeners(); + final response = await ApiManager.instance.get("${URLs.getDeliveryHistories}?assetDeliveryExternalDeliveryId=$tableItemId"); + List list = []; + if (response.statusCode >= 200 && response.statusCode < 300) { + isLoading = false; + notifyListeners(); + final data = json.decode(response.body)["data"]; + list = (data as List).map((e) => AssetDeliveryHistoryModel.fromJson(e)).toList(); + } + isLoading = false; + notifyListeners(); + return list; + } catch (error) { + log('error $error'); + isLoading = false; + notifyListeners(); + return []; + } + } + + //End user + + Future> getEndUserCostCenterList({int? tableItemId}) async { + List costCenterList = []; + try { + isLoading = true; + notifyListeners(); + final response = await ApiManager.instance.get( + "${URLs.getEndUserAcceptanceCostCenter}?assetDeliveryExternalDeliveryId=$tableItemId", + ); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + final jsonData = json.decode(response.body)["data"]; + if (jsonData is List) { + costCenterList = jsonData.map((e) => CostCenterModel.fromJson(e)).toList(); + } + } else { + costCenterList = []; + } + isLoading = false; + notifyListeners(); + return costCenterList; + } catch (e) { + log("get costCenter for End user [error] : $e"); + isLoading = false; + costCenterList = []; + notifyListeners(); + return costCenterList; + } + } + + Future> getEndUserAssetList({int? tableItemId, String? costCenterName}) async { + List assetList = []; + try { + isLoading = true; + notifyListeners(); + final response = await ApiManager.instance.get( + "${URLs.getCostCenterAssetList}?assetDeliveryExternalDeliveryId=$tableItemId&costCenterName=$costCenterName", + ); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + final jsonData = json.decode(response.body)["data"]; + if (jsonData is List) { + assetList = jsonData.map((e) => EndUserAssetDetailsModel.fromJson(e)).toList(); + } + } else { + assetList = []; + } + isLoading = false; + notifyListeners(); + return assetList; + } catch (e) { + log("get End User AssetList [error] : $e"); + isLoading = false; + assetList = []; + notifyListeners(); + return assetList; + } + } + + Future saveEndUserFormData({ + required CostCenterModel model, + }) async { + isLoading = true; + try { + final response = await ApiManager.instance.post(URLs.saveEndUserFormData, body: model.toEndUserAcceptanceFormJson()); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + isLoading = false; + notifyListeners(); + return true; + } else { + isLoading = false; + notifyListeners(); + return false; + } + } catch (error) { + isLoading = false; + notifyListeners(); + return false; + } + } + + Future saveEndUserAssetDataData({ + required EndUserAssetDetailsModel model, + }) async { + isLoading = true; + try { + final response = await ApiManager.instance.post(URLs.saveEndUserAssetData, body: model.toJson()); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { isLoading = false; diff --git a/lib/modules/asset_delivery_module/provider/cost_center_provider.dart b/lib/modules/asset_delivery_module/provider/cost_center_provider.dart new file mode 100644 index 00000000..80cac313 --- /dev/null +++ b/lib/modules/asset_delivery_module/provider/cost_center_provider.dart @@ -0,0 +1,45 @@ +import 'dart:convert'; +import 'dart:developer'; + +import 'package:http/http.dart'; +import 'package:test_sa/controllers/api_routes/api_manager.dart'; +import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/modules/loan_module/models/medical_department_model.dart'; +import 'package:test_sa/providers/loading_list_notifier.dart'; + +class CostCenterProvider extends LoadingListNotifier { + @override + Future getData({int? id}) async { + if (loading) return; + loading = true; + notifyListeners(); + try { + final response = await ApiManager.instance.get( + URLs.getCostCenterToPo + "?assetDeliveryExternalMasterId=$id", + ); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + final List list = json.decode(response.body)['data']; + final Set seenNames = {}; + int index = 0; + items = + list.where((e) => e is Map && e['name'] != null && e['name'].toString().trim().isNotEmpty).map((e) => e['name'].toString().trim()).where((name) => seenNames.add(name)).map((name) { + final lookup = Lookup( + id: index, + value: index + 1, + name: name, + ); + index++; + return lookup; + }).toList(); + } + } catch (e, s) { + log('getData error', error: e, stackTrace: s); + stateCode = -1; + } finally { + loading = false; + notifyListeners(); + } + } +} diff --git a/lib/modules/asset_delivery_module/provider/end_user_rejection_reason_lookup_provider.dart b/lib/modules/asset_delivery_module/provider/end_user_rejection_reason_lookup_provider.dart new file mode 100644 index 00000000..f560e57e --- /dev/null +++ b/lib/modules/asset_delivery_module/provider/end_user_rejection_reason_lookup_provider.dart @@ -0,0 +1,33 @@ +import 'dart:convert'; +import 'package:http/http.dart'; +import 'package:test_sa/controllers/api_routes/api_manager.dart'; +import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/providers/loading_list_notifier.dart'; + +class EndUserRejectionReasonLookupProvider extends LoadingListNotifier { + @override + Future getData({int? id}) async { + if (loading == true) return -2; + loading = true; + notifyListeners(); + loading = true; + notifyListeners(); + try { + Response response = await ApiManager.instance.get(URLs.endUserRejectionReasonLookup); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + List categoriesListJson = json.decode(response.body)["data"]; + items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList(); + } + loading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + loading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + } +} diff --git a/lib/modules/asset_delivery_module/provider/end_user_status_lookup_provider.dart b/lib/modules/asset_delivery_module/provider/end_user_status_lookup_provider.dart new file mode 100644 index 00000000..866cc600 --- /dev/null +++ b/lib/modules/asset_delivery_module/provider/end_user_status_lookup_provider.dart @@ -0,0 +1,33 @@ +import 'dart:convert'; +import 'package:http/http.dart'; +import 'package:test_sa/controllers/api_routes/api_manager.dart'; +import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/providers/loading_list_notifier.dart'; + +class EndUserStatusLookupProvider extends LoadingListNotifier { + @override + Future getData({int? id}) async { + if (loading == true) return -2; + loading = true; + notifyListeners(); + loading = true; + notifyListeners(); + try { + Response response = await ApiManager.instance.get(URLs.endUserStatusLookup); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + List categoriesListJson = json.decode(response.body)["data"]; + items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList(); + } + loading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + loading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + } +} diff --git a/lib/modules/asset_delivery_module/provider/power_supply_type_provider.dart b/lib/modules/asset_delivery_module/provider/power_supply_type_provider.dart new file mode 100644 index 00000000..353b3ae2 --- /dev/null +++ b/lib/modules/asset_delivery_module/provider/power_supply_type_provider.dart @@ -0,0 +1,33 @@ +import 'dart:convert'; +import 'package:http/http.dart'; +import 'package:test_sa/controllers/api_routes/api_manager.dart'; +import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/providers/loading_list_notifier.dart'; + +class PowerSupplyTypeProvider extends LoadingListNotifier { + @override + Future getData({int? id}) async { + if (loading == true) return -2; + loading = true; + notifyListeners(); + loading = true; + notifyListeners(); + try { + Response response = await ApiManager.instance.get(URLs.powerSupplyTypeLookUp); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + List categoriesListJson = json.decode(response.body)["data"]; + items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList(); + } + loading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + loading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + } +} diff --git a/lib/modules/cm_module/views/components/bottom_sheets/service_request_bottomsheet.dart b/lib/modules/cm_module/views/components/bottom_sheets/service_request_bottomsheet.dart index 95e1d3ce..f149de8a 100644 --- a/lib/modules/cm_module/views/components/bottom_sheets/service_request_bottomsheet.dart +++ b/lib/modules/cm_module/views/components/bottom_sheets/service_request_bottomsheet.dart @@ -385,7 +385,7 @@ class ServiceRequestBottomSheet { ], ); }, - ).toShimmer(isShow: snapshot.loading,context: context); + ).toShimmer(isShow: snapshot.loading, context: context); }); } @@ -645,7 +645,7 @@ class ServiceRequestBottomSheet { borderRadius: BorderRadius.circular(14), // Circular border radius ), // color: AppColor.neutral80, - color: AppColor.background(context), + color: AppColor.background(context), child: Row( crossAxisAlignment: CrossAxisAlignment.start, // Align items at the top children: [ @@ -1191,30 +1191,26 @@ class ServiceRequestBottomSheet { 10.height, StatefulBuilder( builder: (context, setState) { - return Column( - children: [ - ESignature( - title: '', - oldSignature: '', - newSignature: newSignature, - backgroundColor: AppColor.neutral100, - showShadow: false, - onChange: (signature) { - if (signature.isEmpty) return; - setState(() { - newSignature = signature; - nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - }); - }, - onSaved: (signature) { - if (signature == null || signature.isEmpty) return; - setState(() { - newSignature = signature; - nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - }); - }, - ), - ], + return ESignature( + title: '', + oldSignature: '', + newSignature: newSignature, + backgroundColor: AppColor.neutral100, + showShadow: false, + onChange: (signature) { + if (signature.isEmpty) return; + setState(() { + newSignature = signature; + nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + }); + }, + onSaved: (signature) { + if (signature == null || signature.isEmpty) return; + setState(() { + newSignature = signature; + nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + }); + }, ); }, ), diff --git a/lib/modules/pm_module/recurrent_wo/recurrent_work_order_view.dart b/lib/modules/pm_module/recurrent_wo/recurrent_work_order_view.dart index fccf0af5..43601cec 100644 --- a/lib/modules/pm_module/recurrent_wo/recurrent_work_order_view.dart +++ b/lib/modules/pm_module/recurrent_wo/recurrent_work_order_view.dart @@ -69,7 +69,7 @@ class _RecurrentWorkOrderViewState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ RecurrentTaskInfoWidget(model: requestProvider.recurrentWoData), - requestProvider.recurrentWoData!.planRecurrentMedicalTaskRooms!.isNotEmpty + requestProvider.recurrentWoData!.planRecurrentMedicalTaskRooms != null && requestProvider.recurrentWoData!.planRecurrentMedicalTaskRooms!.isNotEmpty ? Column( children: [ 8.height, diff --git a/lib/new_views/common_widgets/default_app_bar.dart b/lib/new_views/common_widgets/default_app_bar.dart index faaca183..3b3fcf3f 100644 --- a/lib/new_views/common_widgets/default_app_bar.dart +++ b/lib/new_views/common_widgets/default_app_bar.dart @@ -13,10 +13,11 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget { final List? actions; final Function? onBackPress; final bool showHomeActionButton; + final bool showBackButton; final VoidCallback? onWillPopScope; final TextStyle? titleStyle; - const DefaultAppBar({this.title, this.onBackPress, this.onWillPopScope, this.actions,this.titleStyle, this.showHomeActionButton = false, Key? key}) : super(key: key); + const DefaultAppBar({this.title, this.onBackPress, this.onWillPopScope, this.actions,this.titleStyle, this.showHomeActionButton = false, this.showBackButton = true, Key? key}) : super(key: key); @override Widget build(BuildContext context) { @@ -42,6 +43,7 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget { titleSpacing: 16, title: Row( children: [ + if(showBackButton) const Icon(Icons.arrow_back_ios).onPress(() { if (onWillPopScope != null) { showDialog( diff --git a/lib/new_views/common_widgets/single_item_drop_down_menu.dart b/lib/new_views/common_widgets/single_item_drop_down_menu.dart index 5ea85f7c..ce7f7838 100644 --- a/lib/new_views/common_widgets/single_item_drop_down_menu.dart +++ b/lib/new_views/common_widgets/single_item_drop_down_menu.dart @@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/enum_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/new_views/app_style/app_text_style.dart'; @@ -32,6 +33,7 @@ class SingleItemDropDownMenu exte final int? requestById; final String? Function(T?)? validator; final AutovalidateMode? autovalidateMode; + final DropDownMatchType matchBy; /// To use a static data (without calling API) /// just send [NullableLoadingProvider] as generic data type and fill the [staticData] @@ -55,6 +57,7 @@ class SingleItemDropDownMenu exte this.requestById, this.validator, this.autovalidateMode, + this.matchBy = DropDownMatchType.identifier, }) : super(key: key); @override @@ -67,41 +70,97 @@ class _SingleItemDropDownMenuState(widget.context); } - if (widget.initialValue != null) { - final result = (X == NullableLoadingProvider ? widget.staticData : provider?.items)?.where((element) => element.identifier == widget.initialValue?.identifier); - if (result?.isNotEmpty ?? false) _selectedItem = result!.first as T?; - if (widget.onSelect != null && (widget.initialValue?.identifier ?? "") != (_selectedItem?.identifier ?? "")) { - widget.onSelect!(_selectedItem); // Non-null assertion after null check - } + if (widget.initialValue == null) return; + final List? items = (X == NullableLoadingProvider ? widget.staticData : provider?.items)?.cast(); + + if (items == null || items.isEmpty) return; + final Iterable matches = items.where((e) => _isSameItem(e, widget.initialValue!)); + + if (matches.isNotEmpty) { + _selectedItem = matches.first; + } else { + _selectedItem = null; + } + if (widget.onSelect != null && !_isSameItem(widget.initialValue!, _selectedItem ?? widget.initialValue!)) { + widget.onSelect!(_selectedItem); } - super.initState(); } + // @override + // void initState() { + // if (X != NullableLoadingProvider) { + // provider = Provider.of(widget.context); + // } + // if (widget.initialValue != null) { + // final result = (X == NullableLoadingProvider ? widget.staticData : provider?.items)?.where((element) => element.identifier == widget.initialValue?.identifier); + // if (result?.isNotEmpty ?? false) _selectedItem = result!.first as T?; + // if (widget.onSelect != null && (widget.initialValue?.identifier ?? "") != (_selectedItem?.identifier ?? "")) { + // widget.onSelect!(_selectedItem); // Non-null assertion after null check + // } + // } + // super.initState(); + // } + @override void setState(VoidCallback fn) { if (mounted) super.setState(fn); } + bool _isSameItem(Base a, Base b) { + switch (widget.matchBy) { + case DropDownMatchType.name: + return (a.name ?? '') == (b.name ?? ''); + case DropDownMatchType.identifier: + default: + return (a.identifier ?? '') == (b.identifier ?? ''); + } + } + + // @override + // void didUpdateWidget(covariant SingleItemDropDownMenu oldWidget) { + // if (widget.initialValue != null) { + // final result = (X == NullableLoadingProvider ? widget.staticData : provider?.items)?.where((element) => element.identifier == widget.initialValue?.identifier); + // + // if (result?.isNotEmpty ?? false) { + // _selectedItem = result?.first as T?; + // } else { + // _selectedItem = null; + // } + // if (widget.onSelect != null && (widget.initialValue?.identifier ?? "") != (_selectedItem?.identifier ?? "")) { + // widget.onSelect!(_selectedItem); // Non-null assertion after null check + // } + // } else { + // _selectedItem = null; + // } + // super.didUpdateWidget(oldWidget); + // } @override void didUpdateWidget(covariant SingleItemDropDownMenu oldWidget) { - if (widget.initialValue != null) { - final result = (X == NullableLoadingProvider ? widget.staticData : provider?.items)?.where((element) => element.identifier == widget.initialValue?.identifier); + super.didUpdateWidget(oldWidget); - if (result?.isNotEmpty ?? false) { - _selectedItem = result?.first as T?; - } else { - _selectedItem = null; - } - if (widget.onSelect != null && (widget.initialValue?.identifier ?? "") != (_selectedItem?.identifier ?? "")) { - widget.onSelect!(_selectedItem); // Non-null assertion after null check - } - } else { + if (oldWidget.initialValue == widget.initialValue) return; + + if (widget.initialValue == null) { _selectedItem = null; + return; + } + final List? items = (X == NullableLoadingProvider ? widget.staticData : provider?.items)?.cast(); + + T? matchedItem; + + if (items != null && items.isNotEmpty) { + final Iterable matches = items.where((e) => _isSameItem(e, widget.initialValue!)); + + if (matches.isNotEmpty) matchedItem = matches.first; + } + _selectedItem = matchedItem; + if (widget.onSelect != null && !_isSameItem(widget.initialValue!, _selectedItem ?? widget.initialValue!)) { + widget.onSelect!(_selectedItem); } - super.didUpdateWidget(oldWidget); } @override @@ -148,11 +207,7 @@ class _SingleItemDropDownMenuState( value: _selectedItem, diff --git a/lib/new_views/pages/land_page/my_request/my_requests_page.dart b/lib/new_views/pages/land_page/my_request/my_requests_page.dart index 70327c4c..d482356e 100644 --- a/lib/new_views/pages/land_page/my_request/my_requests_page.dart +++ b/lib/new_views/pages/land_page/my_request/my_requests_page.dart @@ -68,7 +68,8 @@ class _MyRequestsPageState extends State { if (context.userProvider.isEngineer) { requestsList.add(Request(10, 'Equipment Internal Audit')); requestsList.add(Request(11, 'System Internal Audit')); - requestsList.add(Request(12, "Asset Delivery")); + //Need to be added for new user role commissioning engineer + requestsList.add(Request(13, "Asset Delivery")); } requestsList.add(Request(12, "Loan Equipment")); diff --git a/lib/new_views/pages/land_page/widgets/request_item_view_list.dart b/lib/new_views/pages/land_page/widgets/request_item_view_list.dart index 8fc1a0f5..946cb7ba 100644 --- a/lib/new_views/pages/land_page/widgets/request_item_view_list.dart +++ b/lib/new_views/pages/land_page/widgets/request_item_view_list.dart @@ -70,11 +70,10 @@ class RequestItemViewList extends StatelessWidget { return EquipmentInternalAuditItemView(requestDetails: list[index]); case 11: return SystemInternalAuditItemView(requestDetails: list[index]); - //Need to use correct value .... - case 12: - return AssetDeliveryItemView(requestDetails: list[index]); case 12: return LoanEquipmentItemView(requestDetails: list[index]); + case 13: + return AssetDeliveryItemView(requestDetails: list[index]); default: Container( diff --git a/lib/views/widgets/requests/request_status.dart b/lib/views/widgets/requests/request_status.dart index 272ddf42..ab7a40e5 100644 --- a/lib/views/widgets/requests/request_status.dart +++ b/lib/views/widgets/requests/request_status.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/text_extensions.dart';