diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 1001fb0..2fd5f06 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -28,7 +28,8 @@ class URLs { static get getSitesAutoComplete => "$_baseUrl/Customer/GetCustomersAutoComplete"; // get static get getDepartments => "$_baseUrl/Customer/GetDepartmentLookup"; // get - static get getEquipment => "$_baseUrl/Asset/GetAssets"; // get ?client=208051 + static get getAssets => "$_baseUrl/Asset/GetAssets"; // get + static get getAssetById => "$_baseUrl/Asset/GetAssetById?assetId="; // get static get getModels => "$_baseUrl/ModelDefinition/GetModelDefinitionAsset"; // get ?client=2 // 08051 static get getServiceRequests => "$_baseUrl/CallRequest/GetCallRequests"; // get diff --git a/lib/controllers/providers/api/devices_provider.dart b/lib/controllers/providers/api/devices_provider.dart index ee60997..f6749f6 100644 --- a/lib/controllers/providers/api/devices_provider.dart +++ b/lib/controllers/providers/api/devices_provider.dart @@ -3,10 +3,12 @@ import 'dart:convert'; import 'package:flutter/cupertino.dart'; import 'package:http/http.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; +import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/models/device/asset_by_id_model.dart'; import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/user.dart'; - +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../../../models/device/device.dart'; class AssetProvider extends ChangeNotifier { @@ -19,13 +21,12 @@ class AssetProvider extends ChangeNotifier { final pageItemNumber = 10; bool nextPage = true; - // state code of current request to defied error message - // like 400 customer request failed - // 500 service not available int _stateCode; int get stateCode => _stateCode; + set stateCode(int code) => _stateCode = code; + List _devices = []; List get devices => _devices; @@ -37,30 +38,22 @@ class AssetProvider extends ChangeNotifier { bool get isLoading => _loading; + AssetByIdModel _assetById; + + AssetByIdModel get assetById => _assetById; + set isLoading(bool isLoading) { _loading = isLoading; notifyListeners(); } - /// return -2 if request in progress - /// return -1 if error happen when sending request - /// return state code if request complete may be 200, 404 or 403 - /// for more details check http state manager - /// lib\controllers\http_status_manger\http_status_manger.dart - Future getEquipment({ - @required String host, - @required User user, - @required int hospitalId, - String serialNumber, - String number, - bool isQr = false, - }) async { + Future getAssets({@required String host, @required User user, @required int hospitalId, String serialNumber, String number, bool isQr = false}) async { if (_loading == true) return -2; _loading = true; notifyListeners(); Response response; try { - response = await ApiManager.instance.post(URLs.getEquipment, body: { + response = await ApiManager.instance.post(URLs.getAssets, body: { "pageSize": pageItemNumber, "pageNumber": devices.length ~/ pageItemNumber + 1, "siteId": hospitalId, @@ -95,11 +88,24 @@ class AssetProvider extends ChangeNotifier { return response.statusCode; } - /// return -2 if request in progress - /// return -1 if error happen when sending request - /// return state code if request complete may be 200, 404 or 403 - /// for more details check http state manager - /// lib\controllers\http_status_manger\http_status_manger.dart + Future getAssetById(int assetId, AppLocalizations appLocalizations) async { + Response response; + try { + response = await ApiManager.instance.get(URLs.getAssetById + "$assetId"); + } catch (error) { + print(error); + throw (HttpStatusManger.getStatusMessage(status: -1, subtitle: appLocalizations)); + } + _stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + Map assetData = json.decode(response.body)["data"]; + _assetById = AssetByIdModel.fromJson(assetData); + return _assetById; + } + throw (HttpStatusManger.getStatusMessage(status: response.statusCode, subtitle: appLocalizations)); + } + Future> getDevicesList({ @required String host, @required User user, @@ -109,10 +115,10 @@ class AssetProvider extends ChangeNotifier { }) async { Response response; try { - response = await ApiManager.instance.post(URLs.getEquipment, body: { + response = await ApiManager.instance.post(URLs.getAssets, body: { "pageSize": pageItemNumber, "pageNumber": devices.length ~/ pageItemNumber + 1, - "siteId": devices.length ~/ pageItemNumber + 1, + "siteId": hospitalId, if (serialNumber?.isEmpty == false) "assetSerialNumber": serialNumber, if (number?.isEmpty == false) "assetNo": number, }); diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index ccd60f9..f2e6d32 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -251,6 +251,7 @@ "manufacture" : "Manufacture", "model" : "Model", "serialNumber" : "Serial Number", + "serialNo" : "Serial No", "device" : "Device", "pickAsset" : "Pick Asset", "firstAction" : "First Action", @@ -265,6 +266,8 @@ "callComments" : "Call Comments", "comments": "Comments", "recordVoice" : "Record Voice", + "assetDetails" : "Asset Details" + "recordVoice" : "Record Voice", "receiverName" : "Receiver Name", "receiverDetails" : "Receiver Details", "requestedThrough" : "Requested Through", diff --git a/lib/main.dart b/lib/main.dart index 511abe0..4f62131 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -66,13 +66,14 @@ import 'package:test_sa/views/pages/user/gas_refill/track_gas_refill.dart'; import 'package:test_sa/views/pages/user/land_page.dart' as old; import 'package:test_sa/views/pages/user/notifications/notifications_page.dart'; import 'package:test_sa/views/pages/user/report_issues_page.dart'; -import 'package:test_sa/views/pages/user/requests/create_request.dart'; +import 'package:test_sa/views/pages/user/requests/create_service_request_page.dart'; import 'package:test_sa/views/pages/user/requests/future_request_service_details.dart'; import 'package:test_sa/views/pages/user/requests/requests_page.dart'; import 'package:test_sa/views/pages/user/requests/work_order/work_orders_list_page.dart'; import 'package:test_sa/views/pages/user/visits/preventive_maintenance_visits_page.dart'; import 'package:test_sa/views/pages/user/visits/regular_visits_page.dart'; import 'package:test_sa/views/widgets/departments/single_department_picker.dart'; +import 'package:test_sa/views/widgets/equipment/asset_detail_page.dart'; import 'package:test_sa/views/widgets/equipment/single_device_picker.dart'; import 'package:test_sa/views/widgets/hospitals/single_hospital_picker.dart'; @@ -188,7 +189,7 @@ class MyApp extends StatelessWidget { ServiceRequestsPage.id: (_) => ServiceRequestsPage(), ReportIssuesPage.id: (_) => const ReportIssuesPage(), RequestGasRefill.id: (_) => const RequestGasRefill(), - CreateRequestPage.id: (_) => const CreateRequestPage(), + CreateServiceRequestPage.id: (_) => const CreateServiceRequestPage(), SingleHospitalPicker.id: (_) => SingleHospitalPicker(), SingleDevicePicker.id: (_) => SingleDevicePicker(), SingleDepartmentPicker.id: (_) => SingleDepartmentPicker(), @@ -202,6 +203,7 @@ class MyApp extends StatelessWidget { SearchSubWorkOrderPage.id: (_) => const SearchSubWorkOrderPage(), CreateSubWorkOrderPage.id: (_) => const CreateSubWorkOrderPage(), WorkOrderListPage.id: (_) => WorkOrderListPage(), + AssetDetailPage.id: (_) => AssetDetailPage(), }, ), ), diff --git a/lib/models/device/asset_by_id_model.dart b/lib/models/device/asset_by_id_model.dart new file mode 100644 index 0000000..88514e3 --- /dev/null +++ b/lib/models/device/asset_by_id_model.dart @@ -0,0 +1,707 @@ +import 'package:test_sa/models/device/technical_guidance_book.dart'; +import 'package:test_sa/models/lookup.dart'; + +class AssetByIdModel { + List multiAssets; + int id; + ModelDefinition modelDefinition; + Suppliers supplier; + String ipAddress; + String macAddress; + String portNumber; + AssetReplace assetReplace; + AssetInfo oldAsset; + AssetReplace isParent; + AssetInfo parentAsset; + AssetReplace assetType; + String demoRequest; + String missionCritical; + Site site; + AssetReplace building; + AssetReplace floor; + Department department; + String room; + int testsDay; + num purchasingPrice; + String nbv; + String currency; + String poDate; + String poNo; + String invoiceNumber; + String invoiceDate; + String replacementDate; + num budgetYear; + num lastPOPrice; + Lookup commissioningStatus; + Department originDepartment; + Site originSite; + String productionDate; + String edd; + String technicalInspectionDate; + String deliveryInspectionDate; + String endUserAcceptanceDate; + String technicalAcceptanceDate; + String finalAcceptanceDate; + String installationDate; + int siteWarrantyMonthNo; + num extendedWarrantyMonthNo; + num remainderWarrantyMonthNo; + num eomWarrantyMonthsNo; + num warrantyValue; + String warrantyEndDate; + String warrantyContractConditions; + List technicalGuidanceBooks; + String comment; + bool isEnabled; + String tagCode; + List assetAttachments; + String retirementTypeName; + String retirementStatusName; + String retirementDate; + AssetGroup assetGroup; + String assetPhoto; + String nextPMDate; + String lastPMDate; + + AssetByIdModel( + {this.multiAssets, + this.id, + this.modelDefinition, + this.supplier, + this.ipAddress, + this.macAddress, + this.portNumber, + this.assetReplace, + this.oldAsset, + this.isParent, + this.parentAsset, + this.assetType, + this.demoRequest, + this.missionCritical, + this.site, + this.building, + this.floor, + this.department, + this.room, + this.testsDay, + this.purchasingPrice, + this.nbv, + this.currency, + this.poDate, + this.poNo, + this.invoiceNumber, + this.invoiceDate, + this.replacementDate, + this.budgetYear, + this.lastPOPrice, + this.commissioningStatus, + this.originDepartment, + this.originSite, + this.productionDate, + this.edd, + this.technicalInspectionDate, + this.deliveryInspectionDate, + this.endUserAcceptanceDate, + this.technicalAcceptanceDate, + this.finalAcceptanceDate, + this.installationDate, + this.siteWarrantyMonthNo, + this.extendedWarrantyMonthNo, + this.remainderWarrantyMonthNo, + this.eomWarrantyMonthsNo, + this.warrantyValue, + this.warrantyEndDate, + this.warrantyContractConditions, + this.technicalGuidanceBooks, + this.comment, + this.isEnabled, + this.tagCode, + this.assetAttachments, + this.retirementTypeName, + this.retirementStatusName, + this.retirementDate, + this.assetGroup, + this.assetPhoto, + this.nextPMDate, + this.lastPMDate}); + + AssetByIdModel.fromJson(Map json) { + if (json['multiAssets'] != null) { + multiAssets = []; + json['multiAssets'].forEach((v) { + multiAssets.add(new MultiAssets.fromJson(v)); + }); + } + id = json['id']; + print("supplier:${json['supplier']}"); + modelDefinition = json['modelDefinition'] != null ? new ModelDefinition.fromJson(json['modelDefinition']) : null; + supplier = json['supplier'] != null ? Suppliers.fromJson(json['supplier']) : null; + ipAddress = json['ipAddress']; + macAddress = json['macAddress']; + portNumber = json['portNumber']; + assetReplace = json['assetReplace'] != null ? new AssetReplace.fromJson(json['assetReplace']) : null; + oldAsset = json['oldAsset'] != null ? AssetInfo.fromJson(json['oldAsset']) : null; + isParent = json['isParent'] != null ? new AssetReplace.fromJson(json['isParent']) : null; + parentAsset = json['parentAsset'] != null ? AssetInfo.fromJson(json['parentAsset']) : null; + assetType = json['assetType'] != null ? new AssetReplace.fromJson(json['assetType']) : null; + demoRequest = json['demoRequest']; + missionCritical = json['missionCritical']; + site = json['site'] != null ? new Site.fromJson(json['site']) : null; + building = json['building'] != null ? new AssetReplace.fromJson(json['building']) : null; + floor = json['floor'] != null ? new AssetReplace.fromJson(json['floor']) : null; + department = json['department'] != null ? new Department.fromJson(json['department']) : null; + room = json['room']; + testsDay = json['testsDay']; + purchasingPrice = json['purchasingPrice']; + nbv = json['nbv']; + currency = json['currency']; + poDate = json['poDate']; + poNo = json['poNo']; + invoiceNumber = json['invoiceNumber']; + invoiceDate = json['invoiceDate']; + replacementDate = json['replacementDate']; + budgetYear = json['budgetYear']; + lastPOPrice = json['lastPOPrice']; + commissioningStatus = json['commissioningStatus'] != null ? new Lookup.fromJson(json['commissioningStatus']) : null; + originDepartment = json['originDepartment'] != null ? new Department.fromJson(json['originDepartment']) : null; + originSite = json['originSite'] != null ? new Site.fromJson(json['originSite']) : null; + productionDate = json['productionDate']; + edd = json['edd']; + technicalInspectionDate = json['technicalInspectionDate']; + deliveryInspectionDate = json['deliveryInspectionDate']; + endUserAcceptanceDate = json['endUserAcceptanceDate']; + technicalAcceptanceDate = json['technicalAcceptanceDate']; + finalAcceptanceDate = json['finalAcceptanceDate']; + installationDate = json['installationDate']; + siteWarrantyMonthNo = json['siteWarrantyMonthNo']; + extendedWarrantyMonthNo = json['extendedWarrantyMonthNo']; + remainderWarrantyMonthNo = json['remainderWarrantyMonthNo']; + eomWarrantyMonthsNo = json['eomWarrantyMonthsNo']; + warrantyValue = json['warrantyValue']; + warrantyEndDate = json['warrantyEndDate']; + warrantyContractConditions = json['warrantyContractConditions']; + if (json['technicalGuidanceBooks'] != null) { + technicalGuidanceBooks = []; + json['technicalGuidanceBooks'].forEach((v) { + technicalGuidanceBooks.add(TechnicalGuidanceBook.fromJson(v)); + }); + } + comment = json['comment']; + isEnabled = json['isEnabled']; + tagCode = json['tagCode']; + if (json['assetAttachments'] != null) { + assetAttachments = []; + json['assetAttachments'].forEach((v) { + assetAttachments.add(v); + }); + } + retirementTypeName = json['retirementTypeName']; + retirementStatusName = json['retirementStatusName']; + retirementDate = json['retirementDate']; + assetGroup = json['assetGroup'] != null ? new AssetGroup.fromJson(json['assetGroup']) : null; + assetPhoto = json['assetPhoto']; + nextPMDate = json['nextPMDate']; + lastPMDate = json['lastPMDate']; + } + + Map toJson() { + final Map data = new Map(); + if (this.multiAssets != null) { + data['multiAssets'] = this.multiAssets.map((v) => v.toJson()).toList(); + } + data['id'] = this.id; + if (this.modelDefinition != null) { + data['modelDefinition'] = this.modelDefinition.toJson(); + } + if (this.supplier != null) { + data['supplier'] = this.supplier.toJson(); + } + data['ipAddress'] = this.ipAddress; + data['macAddress'] = this.macAddress; + data['portNumber'] = this.portNumber; + if (this.assetReplace != null) { + data['assetReplace'] = this.assetReplace.toJson(); + } + data['oldAsset'] = this.oldAsset?.toJson(); + if (this.isParent != null) { + data['isParent'] = this.isParent.toJson(); + } + data['parentAsset'] = this.parentAsset?.toJson(); + if (this.assetType != null) { + data['assetType'] = this.assetType.toJson(); + } + data['demoRequest'] = this.demoRequest; + data['missionCritical'] = this.missionCritical; + if (this.site != null) { + data['site'] = this.site.toJson(); + } + if (this.building != null) { + data['building'] = this.building.toJson(); + } + if (this.floor != null) { + data['floor'] = this.floor.toJson(); + } + if (this.department != null) { + data['department'] = this.department.toJson(); + } + data['room'] = this.room; + data['testsDay'] = this.testsDay; + data['purchasingPrice'] = this.purchasingPrice; + data['nbv'] = this.nbv; + data['currency'] = this.currency; + data['poDate'] = this.poDate; + data['poNo'] = this.poNo; + data['invoiceNumber'] = this.invoiceNumber; + data['invoiceDate'] = this.invoiceDate; + data['replacementDate'] = this.replacementDate; + data['budgetYear'] = this.budgetYear; + data['lastPOPrice'] = this.lastPOPrice; + data['commissioningStatus'] = this.commissioningStatus?.toJson(); + if (this.originDepartment != null) { + data['originDepartment'] = this.originDepartment.toJson(); + } + if (this.originSite != null) { + data['originSite'] = this.originSite.toJson(); + } + data['productionDate'] = this.productionDate; + data['edd'] = this.edd; + data['technicalInspectionDate'] = this.technicalInspectionDate; + data['deliveryInspectionDate'] = this.deliveryInspectionDate; + data['endUserAcceptanceDate'] = this.endUserAcceptanceDate; + data['technicalAcceptanceDate'] = this.technicalAcceptanceDate; + data['finalAcceptanceDate'] = this.finalAcceptanceDate; + data['installationDate'] = this.installationDate; + data['siteWarrantyMonthNo'] = this.siteWarrantyMonthNo; + data['extendedWarrantyMonthNo'] = this.extendedWarrantyMonthNo; + data['remainderWarrantyMonthNo'] = this.remainderWarrantyMonthNo; + data['eomWarrantyMonthsNo'] = this.eomWarrantyMonthsNo; + data['warrantyValue'] = this.warrantyValue; + data['warrantyEndDate'] = this.warrantyEndDate; + data['warrantyContractConditions'] = this.warrantyContractConditions; + if (this.technicalGuidanceBooks != null) { + data['technicalGuidanceBooks'] = this.technicalGuidanceBooks.map((v) => v).toList(); + } + data['comment'] = this.comment; + data['isEnabled'] = this.isEnabled; + data['tagCode'] = this.tagCode; + if (this.assetAttachments != null) { + data['assetAttachments'] = this.assetAttachments.map((v) => v).toList(); + } + data['retirementTypeName'] = this.retirementTypeName; + data['retirementStatusName'] = this.retirementStatusName; + data['retirementDate'] = this.retirementDate; + if (this.assetGroup != null) { + data['assetGroup'] = this.assetGroup.toJson(); + } + data['assetPhoto'] = this.assetPhoto; + data['nextPMDate'] = this.nextPMDate; + data['lastPMDate'] = this.lastPMDate; + return data; + } +} + +class MultiAssets { + String assetSerialNo; + String systemID; + String assetNumber; + + MultiAssets({this.assetSerialNo, this.systemID, this.assetNumber}); + + MultiAssets.fromJson(Map json) { + assetSerialNo = json['assetSerialNo']; + systemID = json['systemID']; + assetNumber = json['assetNumber']; + } + + Map toJson() { + final Map data = new Map(); + data['assetSerialNo'] = this.assetSerialNo; + data['systemID'] = this.systemID; + data['assetNumber'] = this.assetNumber; + return data; + } +} + +class ModelDefinition { + int id; + String assetName; + String assetDescription; + String modelDefCode; + String modelName; + int manufacturerId; + String manufacturerName; + String supplierName; + String replacementDate; + String essentialEquipement; + String businessCritical; + int lifeSpan; + List modelDefRelatedDefects; + List suppliers; + + ModelDefinition( + {this.id, + this.assetName, + this.assetDescription, + this.modelDefCode, + this.modelName, + this.manufacturerId, + this.manufacturerName, + this.supplierName, + this.replacementDate, + this.essentialEquipement, + this.businessCritical, + this.lifeSpan, + this.modelDefRelatedDefects, + this.suppliers}); + + ModelDefinition.fromJson(Map json) { + id = json['id']; + assetName = json['assetName']; + assetDescription = json['assetDescription']; + modelDefCode = json['modelDefCode']; + modelName = json['modelName']; + manufacturerId = json['manufacturerId']; + manufacturerName = json['manufacturerName']; + supplierName = json['supplierName']; + replacementDate = json['replacementDate']; + essentialEquipement = json['essentialEquipement']; + businessCritical = json['businessCritical']; + lifeSpan = json['lifeSpan']; + if (json['modelDefRelatedDefects'] != null) { + modelDefRelatedDefects = []; + json['modelDefRelatedDefects'].forEach((v) { + modelDefRelatedDefects.add(ModelDefRelatedDefects.fromJson(v)); + }); + } + if (json['suppliers'] != null) { + suppliers = []; + json['suppliers'].forEach((v) { + suppliers.add(new Suppliers.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['assetName'] = this.assetName; + data['assetDescription'] = this.assetDescription; + data['modelDefCode'] = this.modelDefCode; + data['modelName'] = this.modelName; + data['manufacturerId'] = this.manufacturerId; + data['manufacturerName'] = this.manufacturerName; + data['supplierName'] = this.supplierName; + data['replacementDate'] = this.replacementDate; + data['essentialEquipement'] = this.essentialEquipement; + data['businessCritical'] = this.businessCritical; + data['lifeSpan'] = this.lifeSpan; + if (this.modelDefRelatedDefects != null) { + data['modelDefRelatedDefects'] = this.modelDefRelatedDefects.map((v) => v.toJson()).toList(); + } + if (this.suppliers != null) { + data['suppliers'] = this.suppliers.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Suppliers { + int id; + String suppliername; + + Suppliers({this.id, this.suppliername}); + + Suppliers.fromJson(Map json) { + id = json['id']; + suppliername = json['suppliername']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['suppliername'] = this.suppliername; + return data; + } +} + +class AssetReplace { + int id; + String name; + int value; + + AssetReplace({this.id, this.name, this.value}); + + AssetReplace.fromJson(Map json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['name'] = this.name; + data['value'] = this.value; + return data; + } +} + +class Site { + int id; + int customerCode; + String custName; + List buildings; + + Site({this.id, this.customerCode, this.custName, this.buildings}); + + Site.fromJson(Map json) { + id = json['id']; + customerCode = json['customerCode']; + custName = json['custName']; + if (json['buildings'] != null) { + buildings = []; + json['buildings'].forEach((v) { + buildings.add(new Buildings.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['customerCode'] = this.customerCode; + data['custName'] = this.custName; + if (this.buildings != null) { + data['buildings'] = this.buildings.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Buildings { + int id; + String name; + int value; + List floors; + + Buildings({this.id, this.name, this.value, this.floors}); + + Buildings.fromJson(Map json) { + id = json['id']; + name = json['name']; + value = json['value']; + if (json['floors'] != null) { + floors = []; + json['floors'].forEach((v) { + floors.add(new Floors.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['name'] = this.name; + data['value'] = this.value; + if (this.floors != null) { + data['floors'] = this.floors.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Floors { + int id; + String name; + int value; + List departments; + + Floors({this.id, this.name, this.value, this.departments}); + + Floors.fromJson(Map json) { + id = json['id']; + name = json['name']; + value = json['value']; + if (json['departments'] != null) { + departments = []; + json['departments'].forEach((v) { + departments.add(new Departments.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['name'] = this.name; + data['value'] = this.value; + if (this.departments != null) { + data['departments'] = this.departments.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Departments { + int id; + String name; + + Departments({this.id, this.name}); + + Departments.fromJson(Map json) { + id = json['id']; + name = json['name']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['name'] = this.name; + return data; + } +} + +class Department { + int id; + String departmentName; + String departmentCode; + String ntCode; + + Department({this.id, this.departmentName, this.departmentCode, this.ntCode}); + + Department.fromJson(Map json) { + id = json['id']; + departmentName = json['departmentName']; + departmentCode = json['departmentCode']; + ntCode = json['ntCode']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['departmentName'] = this.departmentName; + data['departmentCode'] = this.departmentCode; + data['ntCode'] = this.ntCode; + return data; + } +} + +class AssetGroup { + int id; + String name; + String code; + + AssetGroup({this.id, this.name, this.code}); + + AssetGroup.fromJson(Map json) { + id = json['id']; + name = json['name']; + code = json['code']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['name'] = this.name; + data['code'] = this.code; + return data; + } +} + +class ModelDefRelatedDefects { + ModelDefRelatedDefects({ + this.id, + this.defectName, + this.workPerformed, + this.estimatedTime, + }); + + ModelDefRelatedDefects.fromJson(dynamic json) { + id = json['id']; + defectName = json['defectName']; + workPerformed = json['workPerformed']; + estimatedTime = json['estimatedTime']; + } + + num id; + String defectName; + String workPerformed; + String estimatedTime; + + ModelDefRelatedDefects copyWith({ + num id, + String defectName, + String workPerformed, + String estimatedTime, + }) => + ModelDefRelatedDefects( + id: id ?? this.id ?? 0, + defectName: defectName ?? this.defectName, + workPerformed: workPerformed ?? this.workPerformed, + estimatedTime: estimatedTime ?? this.estimatedTime, + ); + + Map toJson() { + final map = {}; + map['id'] = id; + map['defectName'] = defectName; + map['workPerformed'] = workPerformed; + map['estimatedTime'] = estimatedTime; + return map; + } +} + +class AssetInfo { + AssetInfo({ + this.id, + this.assetSerialNo, + this.assetNumber, + this.tagCode, + this.systemId, + this.assetName, + }); + + AssetInfo.fromJson(dynamic json) { + id = json['id']; + assetSerialNo = json['assetSerialNo']; + assetNumber = json['assetNumber']; + tagCode = json['tagCode']; + systemId = json['systemId']; + assetName = json['assetName']; + } + + num id; + String assetSerialNo; + String assetNumber; + String tagCode; + String systemId; + String assetName; + + AssetInfo copyWith({ + num id, + String assetSerialNo, + String assetNumber, + String tagCode, + String systemId, + String assetName, + }) => + AssetInfo( + id: id ?? this.id, + assetSerialNo: assetSerialNo ?? this.assetSerialNo, + assetNumber: assetNumber ?? this.assetNumber, + tagCode: tagCode ?? this.tagCode, + systemId: systemId ?? this.systemId, + assetName: assetName ?? this.assetName, + ); + + Map toJson() { + final map = {}; + map['id'] = id; + map['assetSerialNo'] = assetSerialNo; + map['assetNumber'] = assetNumber; + map['tagCode'] = tagCode; + map['systemId'] = systemId; + map['assetName'] = assetName; + return map; + } +} diff --git a/lib/models/device/device.dart b/lib/models/device/device.dart index b452360..a9e3ee5 100644 --- a/lib/models/device/device.dart +++ b/lib/models/device/device.dart @@ -58,6 +58,7 @@ class Device { this.technicalGuidanceBooks, this.comment, this.tagCode, + this.assetPhoto, }); Device.fromJson(dynamic json) { @@ -163,6 +164,7 @@ class Device { List technicalGuidanceBooks; String comment; String tagCode; + String assetPhoto; Device copyWith({ num id, String assetSerialNo, @@ -212,6 +214,7 @@ class Device { List technicalGuidanceBooks, String comment, String tagCode, + String assetPhoto, }) => Device( id: id ?? this.id, @@ -262,6 +265,7 @@ class Device { technicalGuidanceBooks: technicalGuidanceBooks ?? this.technicalGuidanceBooks, comment: comment ?? this.comment, tagCode: tagCode ?? this.tagCode, + assetPhoto: assetPhoto ?? this.assetPhoto, ); Map toJson() { final map = {}; @@ -351,6 +355,7 @@ class Device { } map['comment'] = comment; map['tagCode'] = tagCode; + map['assetPhoto'] = assetPhoto; return map; } } diff --git a/lib/models/device/model_definition.dart b/lib/models/device/model_definition.dart index e68720f..0c3a488 100644 --- a/lib/models/device/model_definition.dart +++ b/lib/models/device/model_definition.dart @@ -4,6 +4,7 @@ class ModelDefinition { ModelDefinition({ this.id, this.assetName, + this.assetDescription, this.modelDefCode, this.modelName, this.manufacturerId, @@ -20,6 +21,7 @@ class ModelDefinition { ModelDefinition.fromJson(dynamic json) { id = json['id']; assetName = json['assetName']; + assetDescription = json['assetDescription']; modelDefCode = json['modelDefCode']; modelName = json['modelName']; manufacturerId = json['manufacturerId']; @@ -44,6 +46,7 @@ class ModelDefinition { } num id; String assetName; + String assetDescription; String modelDefCode; String modelName; num manufacturerId; @@ -58,6 +61,7 @@ class ModelDefinition { ModelDefinition copyWith({ num id, String assetName, + String assetDescription, String modelDefCode, String modelName, num manufacturerId, @@ -73,6 +77,7 @@ class ModelDefinition { ModelDefinition( id: id ?? this.id, assetName: assetName ?? this.assetName, + assetDescription: assetDescription ?? this.assetDescription, modelDefCode: modelDefCode ?? this.modelDefCode, modelName: modelName ?? this.modelName, manufacturerId: manufacturerId ?? this.manufacturerId, @@ -89,6 +94,7 @@ class ModelDefinition { final map = {}; map['id'] = id; map['assetName'] = assetName; + map['assetDescription'] = assetDescription; map['modelDefCode'] = modelDefCode; map['modelName'] = modelName; map['manufacturerId'] = manufacturerId; diff --git a/lib/new_views/common_widgets/app_floating_action_button.dart b/lib/new_views/common_widgets/app_floating_action_button.dart index 456f592..aae061f 100644 --- a/lib/new_views/common_widgets/app_floating_action_button.dart +++ b/lib/new_views/common_widgets/app_floating_action_button.dart @@ -5,7 +5,7 @@ import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/new_views/pages/new_gas_refill_request_page.dart'; import 'package:test_sa/new_views/pages/new_transfer_request_page.dart'; -import 'package:test_sa/views/pages/user/requests/create_request.dart'; +import 'package:test_sa/views/pages/user/requests/create_service_request_page.dart'; import '../../models/enums/translation_keys.dart'; import '../app_style/app_color.dart'; @@ -55,7 +55,7 @@ class _AppFloatingActionButtonState extends State { const Divider().defaultStyle(context).paddingOnly(start: 16, end: 16), _FloatingButtonListTile(iconName: "transfer_request", label: context.translation.transferRequest, routeName: NewTransferRequestPage.routeName), const Divider().defaultStyle(context).paddingOnly(start: 16, end: 16), - _FloatingButtonListTile(iconName: "service_request", label: context.translation.serviceRequest, routeName: CreateRequestPage.id), + _FloatingButtonListTile(iconName: "service_request", label: context.translation.serviceRequest, routeName: CreateServiceRequestPage.id), ], ).paddingOnly(top: 8, bottom: 8), ), diff --git a/lib/views/pages/user/land_page.dart b/lib/views/pages/user/land_page.dart index 09a23c5..9f00f6b 100644 --- a/lib/views/pages/user/land_page.dart +++ b/lib/views/pages/user/land_page.dart @@ -17,7 +17,7 @@ import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/pages/device_transfer/track_device_transfer.dart'; import 'package:test_sa/views/pages/sub_workorder/search_sub_workorder_page.dart'; import 'package:test_sa/views/pages/user/gas_refill/track_gas_refill.dart'; -import 'package:test_sa/views/pages/user/requests/create_request.dart'; +import 'package:test_sa/views/pages/user/requests/create_service_request_page.dart'; import 'package:test_sa/views/pages/user/visits/regular_visits_page.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_icon_button.dart'; @@ -154,7 +154,7 @@ class _LandPageState extends State { text: "New Service Request", icon: FontAwesomeIcons.screwdriverWrench, onPressed: () { - Navigator.of(context).pushNamed(CreateRequestPage.id); + Navigator.of(context).pushNamed(CreateServiceRequestPage.id); }, ), LandPageItem( diff --git a/lib/views/pages/user/requests/create_request.dart b/lib/views/pages/user/requests/create_service_request_page.dart similarity index 96% rename from lib/views/pages/user/requests/create_request.dart rename to lib/views/pages/user/requests/create_service_request_page.dart index ead6d04..7aa6e51 100644 --- a/lib/views/pages/user/requests/create_request.dart +++ b/lib/views/pages/user/requests/create_service_request_page.dart @@ -27,17 +27,17 @@ import '../../../../providers/service_request_providers/equipment_status_provide import '../../../../providers/service_request_providers/priority_provider.dart'; import '../../../../providers/service_request_providers/type_of_request_provider.dart'; -class CreateRequestPage extends StatefulWidget { +class CreateServiceRequestPage extends StatefulWidget { static const String id = "/create-request"; final ServiceRequest serviceRequest; - const CreateRequestPage({this.serviceRequest, Key key}) : super(key: key); + const CreateServiceRequestPage({this.serviceRequest, Key key}) : super(key: key); @override - CreateRequestPageState createState() => CreateRequestPageState(); + CreateServiceRequestPageState createState() => CreateServiceRequestPageState(); } -class CreateRequestPageState extends State { +class CreateServiceRequestPageState extends State { TextEditingController _commentController; double _height; diff --git a/lib/views/pages/user/requests/future_request_service_details.dart b/lib/views/pages/user/requests/future_request_service_details.dart index 27096f9..e773c8b 100644 --- a/lib/views/pages/user/requests/future_request_service_details.dart +++ b/lib/views/pages/user/requests/future_request_service_details.dart @@ -32,13 +32,14 @@ class _FutureRequestServiceDetailsState extends State( future: ServiceRequestsProvider().getSingleServiceRequest(requestId: requestId, user: _userProvider.user, host: _settingProvider.host, subtitle: context.translation), builder: (BuildContext context, AsyncSnapshot snapshot) { - if (snapshot.hasError) + if (snapshot.hasError) { return FailedLoading( message: snapshot.error.toString(), onReload: () { setState(() {}); }, ); + } if (snapshot.hasData) { return ServiceRequestDetailsPage( serviceRequest: snapshot.data, diff --git a/lib/views/pages/user/requests/service_request_details.dart b/lib/views/pages/user/requests/service_request_details.dart index 71e896f..4356464 100644 --- a/lib/views/pages/user/requests/service_request_details.dart +++ b/lib/views/pages/user/requests/service_request_details.dart @@ -20,7 +20,7 @@ import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/sizing.dart'; -import 'package:test_sa/views/pages/user/requests/create_request.dart'; +import 'package:test_sa/views/pages/user/requests/create_service_request_page.dart'; import 'package:test_sa/views/pages/user/requests/work_order/create_service_report.dart'; import 'package:test_sa/views/pages/user/requests/work_order/future_service_report.dart'; import 'package:test_sa/views/pages/user/requests/work_order/work_orders_list_page.dart'; @@ -209,7 +209,7 @@ class ServiceRequestDetailsPage extends StatelessWidget { maxWidth: true, onPressed: () { Navigator.of(context).push( - MaterialPageRoute(builder: (_) => CreateRequestPage(serviceRequest: serviceRequest)), + MaterialPageRoute(builder: (_) => CreateServiceRequestPage(serviceRequest: serviceRequest)), ); }) : AppFilledButton( diff --git a/lib/views/widgets/app_text_form_field.dart b/lib/views/widgets/app_text_form_field.dart index 2b8f19f..24ea992 100644 --- a/lib/views/widgets/app_text_form_field.dart +++ b/lib/views/widgets/app_text_form_field.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:test_sa/views/app_style/sizing.dart'; -@Deprecated("Use the one inside the [new_views/common_widgets] folder") class ATextFormField extends StatefulWidget { final Function(String) onSaved; final Function(String) validator; diff --git a/lib/views/widgets/equipment/asset_detail_page.dart b/lib/views/widgets/equipment/asset_detail_page.dart new file mode 100644 index 0000000..77c7a43 --- /dev/null +++ b/lib/views/widgets/equipment/asset_detail_page.dart @@ -0,0 +1,177 @@ +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/devices_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/extensions/widget_extensions.dart'; +import 'package:test_sa/models/device/asset_by_id_model.dart'; +import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; +import 'package:test_sa/views/widgets/loaders/app_loading.dart'; +import 'package:test_sa/views/widgets/loaders/failed_loading.dart'; +import 'package:test_sa/views/widgets/loaders/lazy_loading.dart'; +import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; + +class AssetDetailPage extends StatefulWidget { + static const String id = "/asset-details"; + + AssetDetailPage({Key key}) : super(key: key); + + @override + _AssetDetailPageState createState() { + return _AssetDetailPageState(); + } +} + +class _AssetDetailPageState extends State { + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + int assetId; + AssetProvider _assetProvider; + + @override + Widget build(BuildContext context) { + assetId ??= ModalRoute.of(context).settings.arguments; + _assetProvider ??= Provider.of(context); + _assetProvider?.stateCode = null; + return Scaffold( + appBar: DefaultAppBar(title: context.translation.assetDetails), + body: FutureBuilder( + future: _assetProvider.getAssetById(assetId, context.translation), + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.hasError) { + return FailedLoading( + message: snapshot.error.toString(), + onReload: () { + setState(() {}); + }, + ); + } + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: ALoading()); + } else if (snapshot.hasData) {} + if (snapshot.hasData) { + return SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Container( + padding: const EdgeInsets.all(16), + decoration: ShapeDecoration( + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + shadows: const [BoxShadow(color: Color(0x07000000), blurRadius: 14, offset: Offset(0, 0), spreadRadius: 0)], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AspectRatio( + aspectRatio: 159 / 94, + child: Container( + width: 95, + height: 95, + decoration: ShapeDecoration( + color: const Color(0xFFEAF1F4), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage( + _assetProvider.assetById?.assetPhoto != null ? URLs.getFileUrl(_assetProvider.assetById.assetPhoto) : "https://www.lasteelcraft.com/images/no-image-available.png"), + )), + ), + ), + 6.height, + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + _assetProvider.assetById?.modelDefinition?.assetName ?? "-", + style: AppTextStyles.heading5.copyWith(color: Color(0xFF3B3D4A)), + ), + 8.height, + Text( + "${context.translation.assetNumber}: ${_assetProvider.assetById.multiAssets.first.assetNumber}", + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + Text( + "${context.translation.model}: ${_assetProvider.assetById.modelDefinition.modelDefCode}", + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + Text( + "${context.translation.serialNo}: ${_assetProvider.assetById.multiAssets.first.assetSerialNo}", + maxLines: 2, + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + Text( + "MD: ${_assetProvider.assetById.department.departmentName ?? "-"}", + maxLines: 2, + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + Text( + "Supplier: ${_assetProvider.assetById.supplier?.suppliername ?? "-"}", + maxLines: 2, + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + Text( + "Manufacturer: ${_assetProvider.assetById.modelDefinition.manufacturerName}", + maxLines: 2, + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + Text( + "Location: ${_assetProvider.assetById.site.custName}", + maxLines: 2, + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + 8.height, + const Divider(color: Color(0xFFEAF1F4), height: 1, thickness: 1), + 8.height, + Text( + "Installation Date: ${_assetProvider.assetById.installationDate ?? "-"}", + maxLines: 2, + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + Text( + "Next PM Date: ${_assetProvider.assetById.installationDate ?? "-"}", + maxLines: 2, + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + Text( + "Last PM Date: ${_assetProvider.assetById.installationDate ?? "-"}", + maxLines: 2, + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + if ((_assetProvider.assetById.modelDefinition.assetDescription ?? "").isNotEmpty) ...[ + 8.height, + const Divider(color: Color(0xFFEAF1F4), height: 1, thickness: 1), + 8.height, + Text( + _assetProvider.assetById.modelDefinition.assetDescription ?? "-", + maxLines: 2, + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + ] + ], + ) + ], + ), + ), + ); + } + return Center(child: ALoading()); + }, + ), + ); + } +} diff --git a/lib/views/widgets/equipment/asset_item_gridview.dart b/lib/views/widgets/equipment/asset_item_gridview.dart new file mode 100644 index 0000000..a43b037 --- /dev/null +++ b/lib/views/widgets/equipment/asset_item_gridview.dart @@ -0,0 +1,103 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/controllers/localization/localization.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/models/device/device.dart'; +import 'package:test_sa/models/subtitle.dart'; +import 'package:test_sa/views/app_style/colors.dart'; +import 'package:test_sa/views/app_style/sizing.dart'; + +import '../../../models/device/device.dart'; + +class AssetItemGridView extends StatelessWidget { + final Device device; + final Function(Device) onPressed; + + const AssetItemGridView({Key key, this.device, this.onPressed}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(16), + decoration: ShapeDecoration( + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + shadows: const [BoxShadow(color: Color(0x07000000), blurRadius: 14, offset: Offset(0, 0), spreadRadius: 0)], + ), + child: Column( + children: [ + AspectRatio( + aspectRatio: 159 / 94, + child: Container( + width: 95, + height: 95, + decoration: ShapeDecoration( + color: const Color(0xFFEAF1F4), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(device.assetPhoto != null ? URLs.getFileUrl(device.assetPhoto) : "https://www.lasteelcraft.com/images/no-image-available.png"), + )), + ), + ), + 6.height, + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + device.modelDefinition.assetName, + maxLines: 2, + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF3B3D4A)), + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + "${context.translation.assetNumber} : ${device.assetNumber}", + style: AppTextStyles.bodyText2.copyWith(color: Color(0xFF757575)), + ), + Text( + "${context.translation.model} : ${device.modelDefinition.modelDefCode}", + style: AppTextStyles.bodyText2.copyWith(color: Color(0xFF757575)), + ), + Text( + "${context.translation.serialNo} : ${device.assetSerialNo}", + maxLines: 2, + overflow: TextOverflow.fade, + style: AppTextStyles.bodyText2.copyWith( + color: Color(0xFF757575), + ), + ), + ], + ), + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + 'View Details', + style: AppTextStyles.bodyText2.copyWith(color: const Color(0xFF4A8DB7)), + ), + 4.width, + const Icon( + Icons.arrow_forward, + color: Color(0xFF4A8DB7), + size: 14, + ) + ], + ), + ], + ).expanded + ], + ), + ).onPress(() => onPressed(device)); + } +} diff --git a/lib/views/widgets/equipment/asset_item_listview.dart b/lib/views/widgets/equipment/asset_item_listview.dart new file mode 100644 index 0000000..9584cbb --- /dev/null +++ b/lib/views/widgets/equipment/asset_item_listview.dart @@ -0,0 +1,102 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/controllers/localization/localization.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/models/device/device.dart'; +import 'package:test_sa/models/subtitle.dart'; +import 'package:test_sa/views/app_style/colors.dart'; +import 'package:test_sa/views/app_style/sizing.dart'; + +import '../../../models/device/device.dart'; + +class AssetItemListView extends StatelessWidget { + final Device device; + final Function(Device) onPressed; + + const AssetItemListView({Key key, this.device, this.onPressed}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.all(16), + decoration: ShapeDecoration( + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + shadows: const [BoxShadow(color: Color(0x07000000), blurRadius: 14, offset: Offset(0, 0), spreadRadius: 0)], + ), + child: Row( + children: [ + Container( + width: 95, + height: 95, + decoration: ShapeDecoration( + color: const Color(0xFFEAF1F4), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + image: DecorationImage( + fit: BoxFit.cover, + image: NetworkImage(device.assetPhoto != null ? URLs.getFileUrl(device.assetPhoto) : "https://www.lasteelcraft.com/images/no-image-available.png"), + )), + ), + 15.width, + Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + device.modelDefinition.assetName, + maxLines: 2, + style: AppTextStyles.heading5.copyWith(color: Color(0xFF3B3D4A)), + ), + Text( + "${context.translation.assetNumber} : ${device.assetNumber}", + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + Text( + "${context.translation.model} : ${device.modelDefinition.modelDefCode}", + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + ], + ), + Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + "${context.translation.serialNo} : ${device.assetSerialNo}", + maxLines: 2, + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ).expanded, + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + 'View Details', + style: AppTextStyles.bodyText.copyWith(color: const Color(0xFF4A8DB7)), + ), + 4.width, + const Icon( + Icons.arrow_forward, + color: Color(0xFF4A8DB7), + size: 14, + ) + ], + ), + ], + ) + ], + ).expanded + ], + ), + ).onPress(() => onPressed(device)); + } +} diff --git a/lib/views/widgets/equipment/auto_complete_devices_field.dart b/lib/views/widgets/equipment/auto_complete_devices_field.dart index 6c2fdcb..e9bf7df 100644 --- a/lib/views/widgets/equipment/auto_complete_devices_field.dart +++ b/lib/views/widgets/equipment/auto_complete_devices_field.dart @@ -51,7 +51,7 @@ class _AutoCompleteDeviceFieldState extends State { stateCode: _devicesProvider.stateCode, onRefresh: () async { _devicesProvider.reset(); - await _devicesProvider.getEquipment(host: _settingProvider.host, user: _userProvider.user, hospitalId: widget.hospitalId); + await _devicesProvider.getAssets(host: _settingProvider.host, user: _userProvider.user, hospitalId: widget.hospitalId); }, child: Container( padding: const EdgeInsets.symmetric(horizontal: 16), diff --git a/lib/views/widgets/equipment/device_item.dart b/lib/views/widgets/equipment/device_item.dart deleted file mode 100644 index 913e642..0000000 --- a/lib/views/widgets/equipment/device_item.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:test_sa/controllers/localization/localization.dart'; -import 'package:test_sa/extensions/context_extension.dart'; -import 'package:test_sa/models/device/device.dart'; -import 'package:test_sa/models/subtitle.dart'; -import 'package:test_sa/views/app_style/colors.dart'; -import 'package:test_sa/views/app_style/sizing.dart'; - -import '../../../models/device/device.dart'; - -class DeviceItem extends StatelessWidget { - final Device device; - final Function(Device) onPressed; - - const DeviceItem({Key key, this.device, this.onPressed}) : super(key: key); - - @override - Widget build(BuildContext context) { - - return Padding( - padding: EdgeInsets.symmetric(horizontal: 16, vertical: 6), - child: ElevatedButton( - style: ElevatedButton.styleFrom( - primary: AColors.primaryColor, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), - ), - ), - onPressed: () { - onPressed(device); - }, - child: ListTile( - title: Text( - "${context.translation.assetName} : \n${device.modelDefinition.assetName}", - style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white), - ), - subtitle: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Divider( - color: Theme.of(context).scaffoldBackgroundColor, - ), - Text( - "${context.translation.assetNumber} : ${device.assetNumber}", - style: Theme.of(context).textTheme.subtitle1.copyWith(color: AColors.white), - ), - Divider( - color: Theme.of(context).scaffoldBackgroundColor, - ), - Text( - "${context.translation.brand} : ${device.modelDefinition.manufacturerName}", - style: Theme.of(context).textTheme.subtitle1.copyWith(color: AColors.white), - ), - Divider( - color: Theme.of(context).scaffoldBackgroundColor, - ), - Text( - "${context.translation.model} : ${device.modelDefinition.modelName}", - style: Theme.of(context).textTheme.subtitle1.copyWith(color: AColors.white), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/views/widgets/equipment/pick_asset.dart b/lib/views/widgets/equipment/pick_asset.dart index 3bcd110..33665a3 100644 --- a/lib/views/widgets/equipment/pick_asset.dart +++ b/lib/views/widgets/equipment/pick_asset.dart @@ -38,6 +38,7 @@ class PickAsset extends StatelessWidget { }).expanded, "qr".toSvgAsset(height: 24, fit: BoxFit.fitHeight, color: context.isDark ? AppColor.primary40 : AppColor.primary70), ], + // TODO [Zaid] : if you have container as parent widget, no need to add padding widget separately ).paddingOnly(start: 16, end: 16, top: 8, bottom: 8), ), if (device != null) AssetInfoCard(asset: device).paddingOnly(top: 8), diff --git a/lib/views/widgets/equipment/single_device_picker.dart b/lib/views/widgets/equipment/single_device_picker.dart index 64c83bd..e026e8f 100644 --- a/lib/views/widgets/equipment/single_device_picker.dart +++ b/lib/views/widgets/equipment/single_device_picker.dart @@ -7,8 +7,11 @@ 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/new_views/common_widgets/app_text_form_field.dart'; +import 'package:test_sa/views/widgets/equipment/asset_detail_page.dart'; +import 'package:test_sa/views/widgets/equipment/asset_item_gridview.dart'; +import 'package:test_sa/views/widgets/equipment/asset_item_listview.dart'; import 'package:test_sa/views/widgets/loaders/lazy_loading.dart'; +import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/no_item_found.dart'; @@ -33,14 +36,15 @@ class _SingleDevicePickerState extends State { List _initList = []; bool _firstTime = true; + bool showListView = true; + TextEditingController numberController = TextEditingController(); TextEditingController snController = TextEditingController(); _getDevice(String result, {bool isQr = false}) async { if (result == null) return; - // List devices = await _devicesProvider.getDevicesListBySN(host: _settingProvider.host, user: _userProvider.user, hospitalId: _userProvider.user.clientId, sn: result); _devicesProvider.reset(); - await _devicesProvider.getEquipment( + await _devicesProvider.getAssets( user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, @@ -50,13 +54,6 @@ class _SingleDevicePickerState extends State { ); _searchableList.clear(); _searchableList.addAll(_devicesProvider.devices); - // Navigator.of(context).pop(); - // Navigator.of(context).pop(); - // if (devices.isEmpty) { - // Fluttertoast.showToast(msg: _subtitle.noDeviceFound); - // return; - // } - // Navigator.of(context).pop(devices.first); } @override @@ -86,6 +83,52 @@ class _SingleDevicePickerState extends State { return Scaffold( resizeToAvoidBottomInset: false, + appBar: AppBar( + automaticallyImplyLeading: false, + titleSpacing: 0, + title: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + height: 40, + padding: const EdgeInsets.only(left: 16, right: 8), + alignment: Alignment.center, + decoration: ShapeDecoration( + color: Color(0xFFEAF1F4), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + child: Row( + children: [ + const Icon(Icons.search, color: Color(0xFF757575), size: 16), + 8.width, + Text( + context.translation.search, + style: AppTextStyles.bodyText.copyWith( + color: const Color(0xFF757575), + ), + ).expanded, + ], + ), + ).onPress(() { + // todo 'sikander' add search screen + }).expanded, + 16.width, + const Icon( + Icons.grid_view_outlined, + color: Color(0xFF757575), + ).onPress(() => setState(() { + showListView = !showListView; + })), + 16.width, + Text( + 'Filter', + style: AppTextStyles.bodyText2.copyWith(color: const Color(0xFF4A8DB7)), + ), + ], + ).paddingOnly(start: 16, end: 16), + ), body: SafeArea( child: LoadingManager( isLoading: _devicesProvider.isLoading, @@ -93,11 +136,12 @@ class _SingleDevicePickerState extends State { isFailedLoading: _devicesProvider.devices == null, onRefresh: () async { _devicesProvider.reset(); - await _devicesProvider.getEquipment(user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId); + await _devicesProvider.getAssets(user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId); }, child: Column( children: [ const SizedBox(height: 16), + // todo "Siaknder" will remove when add search screen Padding( padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), child: Column( @@ -110,7 +154,7 @@ class _SingleDevicePickerState extends State { textInputAction: TextInputAction.search, onAction: () async { _devicesProvider.reset(); - await _devicesProvider.getEquipment( + await _devicesProvider.getAssets( user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: snController.text, number: numberController.text); _searchableList.clear(); _searchableList.addAll(_devicesProvider.devices); @@ -127,7 +171,7 @@ class _SingleDevicePickerState extends State { textInputAction: TextInputAction.search, onAction: () async { _devicesProvider.reset(); - await _devicesProvider.getEquipment( + await _devicesProvider.getAssets( user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: snController.text, number: numberController.text); _searchableList.clear(); _searchableList.addAll(_devicesProvider.devices); @@ -147,16 +191,35 @@ class _SingleDevicePickerState extends State { await _devicesProvider.getDevicesList( user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: snController.text, number: numberController.text); }, - child: ListView.builder( - padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth), - shrinkWrap: true, - itemCount: _searchableList.length, - itemBuilder: (listContext, itemIndex) { - return AssetInfoCard(asset: _searchableList[itemIndex]).onPress(() { - Navigator.of(context).pop(_searchableList[itemIndex]); - }); - }, - ), + child: showListView + ? ListView.separated( + padding: const EdgeInsets.all(16), + itemCount: _searchableList.length, + separatorBuilder: (listContext, itemIndex) => 8.height, + itemBuilder: (listContext, itemIndex) { + return AssetItemListView( + device: _searchableList[itemIndex], + onPressed: (device) { + Navigator.of(context).pop(device); + }, + ); + }, + ) + : GridView.builder( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 191 / 261, crossAxisSpacing: 16, mainAxisSpacing: 16), + itemCount: _searchableList.length, + padding: const EdgeInsets.all(16), + itemBuilder: (context, index) { + return AssetItemGridView( + device: _searchableList[index], + onPressed: (device) { + Navigator.of(context).pushNamed(AssetDetailPage.id, arguments: device.id); + return; + Navigator.of(context).pop(device); + }, + ); + }, + ), )), ], ),