From 789522b79b02ede78db2ae9be9e6fc51b292c3be Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 Date: Tue, 9 Dec 2025 10:30:11 +0300 Subject: [PATCH] asset delivery modules design flow completed --- .../reports/problems/problems-report.html | 663 ++++++++++++++++++ assets/images/history_icon.svg | 4 + assets/images/web_link_icon.svg | 4 + .../models/asset_inventory_model.dart | 345 +++++++++ .../models/cost_center_model.dart | 27 + .../models/session_model.dart | 234 +++++++ .../pages/asset_delivery_detail_page.dart | 105 +++ .../pages/asset_delivery_item_view.dart | 113 +++ .../pages/asset_delivery_line_card_view.dart | 75 ++ .../pages/asset_delivery_page.dart | 249 +++++++ .../pages/asset_delivery_table_card_view.dart | 75 ++ .../pages/change_status_bottomsheet.dart | 60 ++ .../cost_center_form_view.dart | 213 ++++++ .../delivery_inspection_form_view.dart | 378 ++++++++++ .../cost_center_card_view.dart | 63 ++ .../end_user_acceptance_form_view.dart | 171 +++++ .../end_user_cost_center_list_view.dart | 343 +++++++++ .../update_end_user_cost_center_view.dart | 220 ++++++ .../pages/history_log_view.dart | 187 +++++ .../technical_inpection_asset_card_view.dart | 109 +++ ...nical_inpection_cost_center_card_view.dart | 77 ++ .../technical_inspection_lines_list_view.dart | 336 +++++++++ ...cal_inspection_parent_asset_list_view.dart | 87 +++ .../update_child_asset_view.dart | 145 ++++ .../update_parent_asset_view.dart | 258 +++++++ ...pdate_technical_inspection_lines_view.dart | 224 ++++++ .../provider/asset_delivery_provider.dart | 470 +++++++++++++ .../single_item_drop_down_menu.dart | 8 +- .../my_request/my_requests_page.dart | 3 +- .../requests/request_paginated_listview.dart | 3 + .../widgets/request_item_view_list.dart | 5 + 31 files changed, 5252 insertions(+), 2 deletions(-) create mode 100644 android/build/reports/problems/problems-report.html create mode 100644 assets/images/history_icon.svg create mode 100644 assets/images/web_link_icon.svg create mode 100644 lib/modules/asset_delivery_module/models/asset_inventory_model.dart create mode 100644 lib/modules/asset_delivery_module/models/cost_center_model.dart create mode 100644 lib/modules/asset_delivery_module/models/session_model.dart create mode 100644 lib/modules/asset_delivery_module/pages/asset_delivery_detail_page.dart create mode 100644 lib/modules/asset_delivery_module/pages/asset_delivery_item_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/asset_delivery_line_card_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/asset_delivery_page.dart create mode 100644 lib/modules/asset_delivery_module/pages/asset_delivery_table_card_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/change_status_bottomsheet.dart create mode 100644 lib/modules/asset_delivery_module/pages/delivery_inspection/cost_center_form_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/end_user_acceptance/cost_center_card_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_acceptance_form_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_cost_center_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/history_log_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_cost_center_card_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_parent_asset_list_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/technical_inpection/update_child_asset_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/technical_inpection/update_parent_asset_view.dart create mode 100644 lib/modules/asset_delivery_module/pages/technical_inpection/update_technical_inspection_lines_view.dart create mode 100644 lib/modules/asset_delivery_module/provider/asset_delivery_provider.dart diff --git a/android/build/reports/problems/problems-report.html b/android/build/reports/problems/problems-report.html new file mode 100644 index 00000000..d59d3b0f --- /dev/null +++ b/android/build/reports/problems/problems-report.html @@ -0,0 +1,663 @@ + + + + + + + + + + + + + Gradle Configuration Cache + + + +
+ +
+ Loading... +
+ + + + + + diff --git a/assets/images/history_icon.svg b/assets/images/history_icon.svg new file mode 100644 index 00000000..89ab3df8 --- /dev/null +++ b/assets/images/history_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/web_link_icon.svg b/assets/images/web_link_icon.svg new file mode 100644 index 00000000..9d77b3f7 --- /dev/null +++ b/assets/images/web_link_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/lib/modules/asset_delivery_module/models/asset_inventory_model.dart b/lib/modules/asset_delivery_module/models/asset_inventory_model.dart new file mode 100644 index 00000000..4a4e6587 --- /dev/null +++ b/lib/modules/asset_delivery_module/models/asset_inventory_model.dart @@ -0,0 +1,345 @@ +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 new file mode 100644 index 00000000..d465b58d --- /dev/null +++ b/lib/modules/asset_delivery_module/models/cost_center_model.dart @@ -0,0 +1,27 @@ +import 'package:test_sa/models/lookup.dart'; + +class CostCenterModel { + Lookup? costCenter; + double? quantity; + + CostCenterModel({ + this.costCenter, + this.quantity, + }); + + CostCenterModel.fromJson(Map json) { + costCenter = json['costCenter'] != null + ? Lookup.fromJson(json['costCenter']) + : null; + quantity = json['quantity']; + } + + Map toJson() { + final Map data = {}; + if (costCenter != null) { + data['costCenter'] = costCenter!.toJson(); + } + data['quantity'] = quantity; + return data; + } +} diff --git a/lib/modules/asset_delivery_module/models/session_model.dart b/lib/modules/asset_delivery_module/models/session_model.dart new file mode 100644 index 00000000..8de8503b --- /dev/null +++ b/lib/modules/asset_delivery_module/models/session_model.dart @@ -0,0 +1,234 @@ +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/pages/asset_delivery_detail_page.dart b/lib/modules/asset_delivery_module/pages/asset_delivery_detail_page.dart new file mode 100644 index 00000000..d0b4f264 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/asset_delivery_detail_page.dart @@ -0,0 +1,105 @@ + +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 new file mode 100644 index 00000000..99aafbf3 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/asset_delivery_item_view.dart @@ -0,0 +1,113 @@ +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/models/all_requests_and_count_model.dart'; +import 'package:test_sa/models/new_models/dashboard_detail.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/asset_delivery_page.dart'; +import 'package:test_sa/modules/asset_inventory_module/pages/asset_inventory_page.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/views/widgets/requests/request_status.dart'; + +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 + Widget build(BuildContext context) { + if (requestData != null) { + 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), + // infoWidget(label: 'No of Sites'.addTranslation, value: requestData?.numberOfSites != null ? requestData?.numberOfSites.toString() : '-', context: context), + 8.height, + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + context.translation.viewDetails, + style: AppTextStyles.bodyText.copyWith(color: AppColor.blueStatus(context)), + ), + 4.width, + Icon(Icons.arrow_forward, color: AppColor.blueStatus(context), size: 14) + ], + ), + ], + ).toShadowContainer(context, withShadow: showShadow).onPress(() async { + Navigator.of(context).push(MaterialPageRoute(builder: (_) => AssetInventoryPage(sessionId: requestData!.id!, moduleId: requestData!.transactionNo!))); + }); + } + 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), + 8.height, + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + context.translation.viewDetails, + style: AppTextStyles.bodyText.copyWith(color: AppColor.blueStatus(context)), + ), + 4.width, + Icon(Icons.arrow_forward, color: AppColor.blueStatus(context), size: 14) + ], + ), + ], + ).toShadowContainer(context, withShadow: showShadow).onPress(() async { + Navigator.of(context).push(MaterialPageRoute(builder: (_) => AssetDeliveryPage(requestId: requestDetails!.id!))); + }); + } + + Widget infoWidget({required String label, String? value, required BuildContext context}) { + if (value != null && value.isNotEmpty) { + return '$label: $value'.bodyText(context); + } + return const SizedBox(); + } +} 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 new file mode 100644 index 00000000..b8a22248 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/asset_delivery_line_card_view.dart @@ -0,0 +1,75 @@ +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/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 + bool isViewOnly; + VoidCallback ?editPress; + + AssetDeliveryLineCard({ + super.key, + required this.isViewOnly, + required this.deliveryDetails, + this.editPress, + }); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //need to check this @waseem. + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Item No: ${deliveryDetails.transactionDate?.toServiceRequestDetailsFormat ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + if(!isViewOnly) + 'edit_icon'.toSvgAsset().onPress(() { + if(editPress!=null){ + editPress!(); + } + }), + ], + ), + Text( + 'Item Description: ${deliveryDetails.assetNumber ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Quantity: ${deliveryDetails.assetName ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Remaining Quantity: ${deliveryDetails.assetName ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Quantity of this Delivery: ${deliveryDetails.assetName ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Marge Unit: ${deliveryDetails.assetName ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Unit price: ${deliveryDetails.assetName ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Total: ${deliveryDetails.assetName ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + ], + ).toShadowContainer(context, borderRadius: 20, padding: 12); + } +} diff --git a/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart b/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart new file mode 100644 index 00000000..eba6ccd8 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/asset_delivery_page.dart @@ -0,0 +1,249 @@ +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/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/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/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'; +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; + + const AssetDeliveryPage({ + Key? key, + this.requestId, + }) : super(key: key); + + @override + State createState() => _AssetDeliveryPageState(); +} + +class _AssetDeliveryPageState extends State { + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + appBar: DefaultAppBar( + title: 'Asset Delivery'.addTranslation, + onBackPress: () { + 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)), + ); + } + + TextStyle infoTextStyle(context) => AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120); + + Widget requestDetailCard(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Row( + // crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // 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), + // ), + // Text( + // sessionModel.createdDate!.toString().toServiceRequestCardFormat, + // textAlign: TextAlign.end, + // style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), + // ) + // ], + // ), + 8.height, + //neutral120 + Text( + 'PO No. Internal'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + 'PO8745623'.addTranslation, + 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, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + '50'.addTranslation, + style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), + ), + 8.height, + Text( + 'PO No.'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + 'PO438'.addTranslation, + style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), + ), + 8.height, + Text( + 'Warranty Period'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + '1 Year'.addTranslation, + style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), + ), + 8.height, + Text( + 'Payment Terms Amount'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + '70%'.addTranslation, + style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), + ), + 8.height, + Text( + 'EDD (Estimated Delivery Date)'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + '25 December, 2025'.addTranslation, + style: AppTextStyles.bodyText2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral120), + ), + 8.height, + Text( + 'Total'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + 8.height, + Text( + '4930'.addTranslation, + 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: () {}, + ); + }, + ), + ], + ); + } +} 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 new file mode 100644 index 00000000..bcbf9544 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/asset_delivery_table_card_view.dart @@ -0,0 +1,75 @@ + +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_inventory_module/models/asset_inventory_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; + VoidCallback onCardTap; + + AssetDeliveryTableCard({ + super.key, + required this.deliveryDetails, + required this.onViewHistoryPress, + required this.onCardTap, + }); + + @override + Widget build(BuildContext context) { + deliveryDetails.status = 'New'; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + StatusLabel( + label: deliveryDetails.status, + textColor: AppColor.getRequestStatusTextColorByName(context, deliveryDetails.status), + backgroundColor: AppColor.getRequestStatusColorByName(context, deliveryDetails.status), + ), + Row( + children: [ + 'history_icon'.toSvgAsset(), + 6.width, + Text( + 'View History'.addTranslation, + style: AppTextStyles.bodyText.copyWith(color: AppColor.blueStatus(context)), + ), + ], + ).onPress(() { + onViewHistoryPress(); + }), + ], + ), + 8.height, + Text( + 'Delivery Number: ${deliveryDetails.transactionDate?.toServiceRequestDetailsFormat ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Delivery Amount: ${deliveryDetails.assetNumber ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Invoice Amount: ${deliveryDetails.assetName ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Align( + alignment: Alignment.centerRight, + child: Icon(Icons.arrow_forward, color: AppColor.blueStatus(context), size: 14), + ), + ], + ).toShadowContainer(context, borderRadius: 20).onPress((){ + onCardTap(); + }); + } +} diff --git a/lib/modules/asset_delivery_module/pages/change_status_bottomsheet.dart b/lib/modules/asset_delivery_module/pages/change_status_bottomsheet.dart new file mode 100644 index 00000000..e0f1baa5 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/change_status_bottomsheet.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.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/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; + +class AssetDeliveryBottomSheet { + static buildBottomSheetParent({required BuildContext context, required Widget childWidget, bool? isDismissible}) { + return showModalBottomSheet( + context: context, + useSafeArea: true, + isScrollControlled: true, + isDismissible: isDismissible ?? true, + backgroundColor: Colors.transparent, + builder: (context) => SingleChildScrollView( + child: SafeArea(child: childWidget), + ).bottomSheetContainer(context), + ); + } + + static Future changeStatusBottomSheet({required BuildContext context}) { + return buildBottomSheetParent( + context: context, + childWidget: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox().indicatorWidget(), + 8.height, + Align( + alignment: AlignmentDirectional.centerStart, + child: Text('Change Status'.addTranslation,style: TextStyle( + fontSize: 21.toScreenWidth, + fontWeight: FontWeight.w500, + fontStyle: FontStyle.normal, + decoration: TextDecoration.none, + ),), + ), + 10.height, + Row( + children: [ + AppFilledButton( + label: 'Cancel'.addTranslation, + maxWidth: true, + buttonColor: Colors.white, + // textColor: context.isDark ? AppColor.neutral30 : Colors.white, + textColor: AppColor.red30, + showBorder: true, + onPressed: () { + Navigator.pop(context); + }, + ).expanded, + 12.width, + AppFilledButton(buttonColor: AppColor.green70, label: 'Change Status'.addTranslation, maxWidth: true, onPressed: () {}).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 new file mode 100644 index 00000000..afe55e40 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/delivery_inspection/cost_center_form_view.dart @@ -0,0 +1,213 @@ +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/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/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_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 double? cardPadding; + + const CostCenterFormView({ + super.key, + this.costCenterList, + this.onListChanged, + this.cardPadding, + }); + + @override + State createState() => _CostCenterFormViewState(); +} + +class _CostCenterFormViewState extends State { + late List _list; + + @override + void initState() { + super.initState(); + _list = List.from(widget.costCenterList ?? []); + } + + void _addNewEntry() { + setState(() { + _list.add(CostCenterModel()); + }); + 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) { + setState(() { + updateList(_list[index]); + }); + } + + @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( + title: 'Cost Center for Item'.addTranslation, + onBackPress: () { + 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: () {}), + ), + ], + ), + ); + } +} + +class CostCenterItemCard extends StatelessWidget { + final CostCenterModel model; + final int index; + final bool isReadOnly; + final void Function(void Function(CostCenterModel model)) onUpdate; + final VoidCallback onRemove; + + const CostCenterItemCard({ + super.key, + required this.model, + required this.index, + required this.isReadOnly, + required this.onUpdate, + required this.onRemove, + }); + + @override + Widget build(BuildContext context) { + final requestedDate = Provider.of(context, listen: false).currentWorkOrder?.data?.requestedDate; + + return Column( + children: [ + if (!isReadOnly) + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + 'Cost Center'.addTranslation.bodyText(context).custom(color: AppColor.textColor(context)), + if (!isReadOnly) + Container( + height: 28, + width: 28, + padding: const EdgeInsets.all(6), + child: "trash".toSvgAsset(height: 20, width: 20), + ).onPress(onRemove), + ], + ), + 8.height, + 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, + ), + 8.height, + AppTextFormField( + labelText: 'Item Description', + backgroundColor: AppColor.fieldBgColor(context), + initialValue: 'test decription abc', + textAlign: TextAlign.center, + 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; + }, + ), + ], + ) + ], + ).toShadowContainer(context, paddingObject: const EdgeInsets.symmetric(horizontal: 16, vertical: 12)).paddingOnly(bottom: 12); + } +} 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 new file mode 100644 index 00000000..cc1310b0 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/delivery_inspection/delivery_inspection_form_view.dart @@ -0,0 +1,378 @@ +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/pages/asset_delivery_line_card_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/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/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 '../../../../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"; + + DeliveryInspectionFormView({ + Key? key, + }) : super(key: key); + + @override + State createState() => _DeliveryInspectionFormViewState(); +} + +class _DeliveryInspectionFormViewState extends State { + final GlobalKey _formKey = GlobalKey(); + final GlobalKey _scaffoldKey = GlobalKey(); + bool viewOnly = true; + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @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, + ], + ), + ), + ], + ), + ); + } + + 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; + }, + ))); + }, + ); + }, + ), + ], + ); + } + + 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(() {}); + } + }, + ), + // 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; + 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 _cancelTap() async {} + + void _nextTap() { + Navigator.push(context, MaterialPageRoute(builder: (context) => TechnicalInspectionLinesListView())); + } + + void _changeStatusTap() async { + _formKey.currentState!.save(); + } +} 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 new file mode 100644 index 00000000..d53d3754 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/end_user_acceptance/cost_center_card_view.dart @@ -0,0 +1,63 @@ +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/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 + bool isViewOnly; + VoidCallback ?editPress; + + CostCenterCard({ + super.key, + required this.isViewOnly, + required this.deliveryDetails, + this.editPress, + }); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //need to check this @waseem. + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Item No: ${deliveryDetails.transactionDate?.toServiceRequestDetailsFormat ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + if(!isViewOnly) + 'edit_icon'.toSvgAsset().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 ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Replaced Asset No: ${deliveryDetails.assetName ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Serial Number: ${deliveryDetails.assetName ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + ], + ).toShadowContainer(context, borderRadius: 20, padding: 12); + } +} 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 new file mode 100644 index 00000000..978a1d93 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_acceptance_form_view.dart @@ -0,0 +1,171 @@ +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_cost_center_list_view.dart b/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart new file mode 100644 index 00000000..4af7aa9f --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/end_user_acceptance/end_user_cost_center_list_view.dart @@ -0,0 +1,343 @@ + +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/models/lookup.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/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 EndUserCostCenterLIstView extends StatefulWidget { + EndUserCostCenterLIstView({ + Key? key, + }) : super(key: key); + + @override + State createState() => _EndUserCostCenterLIstViewState(); +} + +class _EndUserCostCenterLIstViewState 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: [ + 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, + ], + ), + ), + ], + ), + ), + ); + } + + Widget linesList(BuildContext context) { + final assetDeliveryTableList = ['abc', 'def', 'ghi', 'fhg', 'hjhh']; + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Cost Center", + 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 CostCenterCard( + deliveryDetails : AssetInventoryModel(), + isViewOnly: viewOnly, + editPress: () { + Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateEndUserCostCenterView())); + }, + ); + }, + ), + ], + ); + } + + 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 _cancelTap() async { + + } + + void _nextTap() async { + Navigator.push(context, MaterialPageRoute(builder: (context) => EndUserCostCenterLIstView())); + } + + void _changeStatusTap() async { + + } +} 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 new file mode 100644 index 00000000..28136296 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/end_user_acceptance/update_end_user_cost_center_view.dart @@ -0,0 +1,220 @@ +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 new file mode 100644 index 00000000..4990a708 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/history_log_view.dart @@ -0,0 +1,187 @@ +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/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/views/widgets/requests/request_status.dart'; + +class AssetDeliveryHistoryLogView extends StatelessWidget { + const AssetDeliveryHistoryLogView({Key? key}) : super(key: key); + + @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, + ), + ), + 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 + } + 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; + } else { + object.timeDifference = ''; // Empty string for the last action + } + 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!; + + if (object.step!.value == 18 || object.step!.value == 27 || object.step!.value == 28) { + title = object.activityStatus?.name ?? ""; + } + + return Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text( + object.date.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(), + ], + ), + ), + ], + ).toShadowContainer(context, padding: 16).paddingOnly(bottom: 16); + } + + Widget statusCard(BuildContext context, String status) { + return SizedBox( + width: 153.toScreenWidth, + child: StatusLabel( + radius: 4, + label: statusText(status.toLowerCase()), + labelInCenter: true, + textColor: AppColor.getHistoryLogStatusTextColorByName(status), + backgroundColor: AppColor.getHistoryLogStatusColorByName(status), + ), + ).paddingOnly(bottom: 16, start: 40); + } + + String statusText(String status) { + if (status == "new" || status == "open") { + return "Open Request".addTranslation; + } else if (status == "in progress") { + return "Status update to In Progress".addTranslation; + } else if (status == "closed") { + return "Status update to Closed".addTranslation; + } else if (status == "completed") { + return "Status update to Completed".addTranslation; + } else if (status == "fixed") { + return "Status update to Fixed".addTranslation; + } else if (status == "reject") { + return "Status update to Rejected".addTranslation; + } else + 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/technical_inpection_asset_card_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart new file mode 100644 index 00000000..0a4fc871 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_asset_card_view.dart @@ -0,0 +1,109 @@ +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/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 + bool isViewOnly; + bool ischild; + VoidCallback? editPress; + + TechnicalInspectionAssetCard({ + super.key, + required this.isViewOnly, + this.ischild = false, + required this.assetModel, + this.editPress, + }); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ///Need to give specific colors + if (!ischild) ...[ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + StatusLabel( + label: 'Pass', + radius: 4, + textColor: AppColor.getPriorityStatusTextColor(context, 1), + backgroundColor: AppColor.getPriorityStatusColor(context, 1), + ), + if (!isViewOnly) + 'edit_icon'.toSvgAsset().onPress(() { + if (editPress != null) { + editPress!(); + } + }), + ], + ), + 8.height, + ], + if (ischild) ...[ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Asset Number: ${assetModel.assetNumber ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + if (!isViewOnly) + 'edit_icon'.toSvgAsset().onPress(() { + if (editPress != null) { + editPress!(); + } + }), + ], + ), + ], + if (!ischild) + Text( + 'Asset Number: ${assetModel.assetNumber ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Model: ${assetModel.modelDefinition ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'Serial Number: ${assetModel.assetSerialNo ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + 'System ID: ${assetModel.systemID ?? '-'}', + 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); + } +} 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 new file mode 100644 index 00000000..1470c34e --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inpection_cost_center_card_view.dart @@ -0,0 +1,77 @@ +import 'dart:developer'; + +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/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 + bool isViewOnly; + VoidCallback ?editPress; + + TechnicalInspectionCostCard({ + super.key, + required this.isViewOnly, + required this.deliveryDetails, + this.editPress, + }); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //need to check this @waseem. + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Item No: ${deliveryDetails.transactionDate?.toServiceRequestDetailsFormat ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + if(!isViewOnly) + 'edit_icon'.toSvgAsset().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 ?? '-'}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + ], + ).toShadowContainer(context, borderRadius: 20, padding: 12); + } +} 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 new file mode 100644 index 00000000..82420e30 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_lines_list_view.dart @@ -0,0 +1,336 @@ +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/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/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/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 TechnicalInspectionLinesListView extends StatefulWidget { + TechnicalInspectionLinesListView({ + Key? key, + }) : super(key: key); + + @override + State createState() => _TechnicalInspectionLinesListViewState(); +} + +class _TechnicalInspectionLinesListViewState extends State { + final GlobalKey _formKey = GlobalKey(); + final GlobalKey _scaffoldKey = GlobalKey(); + bool viewOnly = true; + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + key: _scaffoldKey, + appBar: DefaultAppBar( + title: 'Technical Inspection'.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: [ + 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, + ], + ), + ), + ], + ), + ), + ); + } + + 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) => UpdateTechnicalInspectionLinesView())); + }, + ); + }, + ), + ], + ); + } + + 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 _cancelTap() async {} + + void _nextTap() async { + Navigator.push(context, MaterialPageRoute(builder: (context) => EndUserCostCenterLIstView())); + } + + 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 new file mode 100644 index 00000000..2ea5d088 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/technical_inspection_parent_asset_list_view.dart @@ -0,0 +1,87 @@ + +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/models/device/asset.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/new_views/app_style/app_color.dart'; +import '../../../../new_views/common_widgets/default_app_bar.dart'; + +class TechnicalInspectionParentAssetListView extends StatefulWidget { + TechnicalInspectionParentAssetListView({ + Key? key, + }) : super(key: key); + + @override + State createState() => _TechnicalInspectionParentAssetListViewState(); +} + +class _TechnicalInspectionParentAssetListViewState 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: 'Technical Inspection'.addTranslation, + titleStyle: AppTextStyles.heading3.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), + ), + body: Form( + key: _formKey, + child: SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: parentAssetList(context).toShadowContainer(context, borderRadius: 20, padding: 12)) + .expanded, + ), + ); + } + + Widget parentAssetList(BuildContext context) { + final assetDeliveryTableList = ['abc', 'def', 'ghi', 'fhg', 'hjhh']; + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Parents", + 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, + editPress: () { + Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateParentAssetView())); + }, + ); + }, + ), + ], + ); + } + +} 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 new file mode 100644 index 00000000..8733e005 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/update_child_asset_view.dart @@ -0,0 +1,145 @@ +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/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 '../../../../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 +class UpdateChildAssetView extends StatefulWidget { + ///Need to pass model here... + UpdateChildAssetView({ + Key? key, + }) : super(key: key); + + @override + State createState() => _UpdateChildAssetViewState(); +} + +class _UpdateChildAssetViewState 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: 'Child 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: '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)), + ], + ), + ), + ); + } + + void _saveTap() async { + AssetInventoryProvider assetInventoryProvider = Provider.of(context, listen: false); + _formKey.currentState!.save(); + } +} 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 new file mode 100644 index 00000000..4ff14e0a --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/update_parent_asset_view.dart @@ -0,0 +1,258 @@ +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_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/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 '../../../../new_views/common_widgets/app_filled_button.dart'; +import '../../../../new_views/common_widgets/default_app_bar.dart'; + +class UpdateParentAssetView extends StatefulWidget { + UpdateParentAssetView({ + Key? key, + }) : super(key: key); + + @override + State createState() => _UpdateParentAssetViewState(); +} + +class _UpdateParentAssetViewState 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: '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(), + 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((){ + ///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 inspectionDetailsForm() { + return Column( + 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: 'Serial Number'.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: 'System ID'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + initialValue: '', + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + style: Theme.of(context).textTheme.titleMedium, + ), + 8.height, + AppTextFormField( + labelText: 'Medical Department'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + initialValue: '', + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + style: Theme.of(context).textTheme.titleMedium, + ), + 8.height, + ADatePicker( + label: 'Installation 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, + AppTextFormField( + labelText: 'Asset Type'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + initialValue: '', + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + style: Theme.of(context).textTheme.titleMedium, + ), + ], + ); + } + + ///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/technical_inpection/update_technical_inspection_lines_view.dart b/lib/modules/asset_delivery_module/pages/technical_inpection/update_technical_inspection_lines_view.dart new file mode 100644 index 00000000..d13ab6b3 --- /dev/null +++ b/lib/modules/asset_delivery_module/pages/technical_inpection/update_technical_inspection_lines_view.dart @@ -0,0 +1,224 @@ +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/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/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 '../../../../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"; + + UpdateTechnicalInspectionLinesView({ + Key? key, + }) : super(key: key); + + @override + State createState() => _UpdateTechnicalInspectionLinesViewState(); +} + +class _UpdateTechnicalInspectionLinesViewState extends State { + final GlobalKey _formKey = GlobalKey(); + final GlobalKey _scaffoldKey = GlobalKey(); + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + key: _scaffoldKey, + appBar: DefaultAppBar( + title: 'Technical Inspection'.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), + costCenterList(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 costCenterList(BuildContext context) { + final assetDeliveryTableList = ['abc', 'def', 'ghi', 'fhg', 'hjhh']; + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Cost Centers", + 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 TechnicalInspectionCostCard( + deliveryDetails: AssetInventoryModel(), + editPress: () { + Navigator.push(context, MaterialPageRoute(builder: (context) => TechnicalInspectionParentAssetListView())); + }, + isViewOnly: false, + ); + }, + ), + ], + ); + } + + Widget inspectionDetailsForm() { + return Column( + children: [ + 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, + ), + 8.height, + AppTextFormField( + labelText: 'Item Description', + backgroundColor: AppColor.fieldBgColor(context), + initialValue: 'test decription abc', + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + enable: false, + style: Theme.of(context).textTheme.titleMedium, + ), + 8.height, + 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; + 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: '', + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + textInputType: TextInputType.number, + showShadow: false, + style: Theme.of(context).textTheme.titleMedium, + ), + 8.height, + AppTextFormField( + labelText: 'Max Current'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + initialValue: '', + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + style: Theme.of(context).textTheme.titleMedium, + ), + 8.height, + AppTextFormField( + labelText: 'Voltage'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + initialValue: '', + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + style: Theme.of(context).textTheme.titleMedium, + ), + 8.height, + AppTextFormField( + labelText: 'Frequency'.addTranslation, + backgroundColor: AppColor.fieldBgColor(context), + initialValue: '', + textAlign: TextAlign.center, + labelStyle: AppTextStyles.textFieldLabelStyle, + showShadow: false, + style: Theme.of(context).textTheme.titleMedium, + ), + ], + ); + } + + void _saveTap() async { + AssetInventoryProvider assetInventoryProvider = Provider.of(context, listen: false); + _formKey.currentState!.save(); + } +} diff --git a/lib/modules/asset_delivery_module/provider/asset_delivery_provider.dart b/lib/modules/asset_delivery_module/provider/asset_delivery_provider.dart new file mode 100644 index 00000000..b87e092c --- /dev/null +++ b/lib/modules/asset_delivery_module/provider/asset_delivery_provider.dart @@ -0,0 +1,470 @@ +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/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'; + +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 = []; + + ModulesPermissionsModel? modelPermission; + + 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; + + void searchReset() { + stateCode = null; + _searchDevices = []; + } + + Future getSessionById({required int id}) async { + try { + sessionModel = SessionModel(); + isLoading = true; + notifyListeners(); + final response = await ApiManager.instance.get(URLs.getAssetInventoryById + "?assetInventoryId=$id"); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + sessionModel = SessionModel.fromJson(json.decode(response.body)["data"]); + } else { + sessionModel = null; + } + + isLoading = false; + notifyListeners(); + } catch (e) { + log("getSessionError [error] : $e"); + isLoading = false; + sessionModel = null; + notifyListeners(); + return null; + } + } + + 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(); + 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); + } else { + nextPage = false; + } + isLoading = false; + isNextPageLoading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + isLoading = false; + isNextPageLoading = false; + stateCode = -1; + nextPage = false; + 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; + } + + notifyListeners(); + log('Fetching inventory page: $pageNo'); + + try { + final paginatedPayload = { + ...payload, + "pageSize": pageItemNumber, + "pageNumber": pageNo, + }; + + final response = await ApiManager.instance.post(URLs.getInventoryDetailsByFilter, body: paginatedPayload); + 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; + } else { + siteFilterAssetResponse = newResponse; + siteFilterAssetList = newResponse.assetList ?? []; + } + nextPage = (siteFilterAssetList.length) < (siteFilterAssetResponse?.totalRows ?? 0); + } else { + siteFilterAssetList = []; + nextPage = false; + } + + isLoading = false; + isNextPageLoading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + isLoading = false; + isNextPageLoading = false; + nextPage = false; + stateCode = -1; + notifyListeners(); + return -1; + } + } + + Future searchAsset({ + required Map payload, + }) async { + isLoading = true; + try { + final response = await ApiManager.instance.post(URLs.searchAsset, body: payload); + 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; + } else { + isLoading = false; + notifyListeners(); + return null; + } + } catch (error) { + isLoading = false; + stateCode = -1; + notifyListeners(); + return null; + } + } + + Future saveAssetInSession({ + AssetInventoryModel? model, + }) async { + isLoading = true; + try { + final response = await ApiManager.instance.post(URLs.saveAssetInSession, 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; + } + } + + Future getClassification({ + required Map payload, + }) async { + isLoading = true; + String? classification; + try { + final response = await ApiManager.instance.post(URLs.getClassification, body: payload); + 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; + } else { + isLoading = false; + notifyListeners(); + return classification; + } + } catch (error) { + isLoading = false; + notifyListeners(); + return classification; + } + } + + Future deleteAssetISession({required num id}) async { + try { + isLoading = true; + notifyListeners(); + final response = await ApiManager.instance.get(URLs.deleteAssetInSession + "?id=$id"); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + isLoading = false; + notifyListeners(); + return true; + } + isLoading = false; + notifyListeners(); + return false; + } catch (e) { + log("Delete Asset [error] : $e"); + isLoading = false; + notifyListeners(); + return false; + } + } + + Future> getAutoCompleteDetails({ + bool? isManufacturer, + String? query, + int type = 0, + }) async { + 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(); + } + if (query != null && query.isNotEmpty) { + queryParams['searchText'] = query; + } + if (queryParams.isNotEmpty) { + url += '?${Uri(queryParameters: queryParams).query}'; + } + final response = await ApiManager.instance.get(url); + + List list = []; + if (response.statusCode >= 200 && response.statusCode < 300) { + final data = json.decode(response.body)["data"]; + list = (data as List).map((e) => Lookup.fromJson(e)).toList(); + } + return list; + } catch (error) { + log('error $error'); + return []; + } + } + + Future getAssets({DeviceSearch? search, bool isQr = false, bool isSearchBy = false, num? sessionId}) async { + if (isLoading == true) return -2; + 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); + } catch (error) { + isLoading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + 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; + } + isLoading = false; + notifyListeners(); + return response.statusCode; + } + + Future markAsComplete({ + required Map payload, + }) async { + isLoading = true; + try { + final response = await ApiManager.instance.post(URLs.convertDetailToComplete, 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; + } + } +} 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 d78e5f69..5ea85f7c 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 @@ -27,6 +27,7 @@ class SingleItemDropDownMenu exte final bool showShadow; final bool showCancel; final Color? backgroundColor; // Now nullable + final Color? titleTextColor; // Now nullable final bool? loading; // Now nullable final int? requestById; final String? Function(T?)? validator; @@ -49,6 +50,7 @@ class SingleItemDropDownMenu exte this.showShadow = true, this.showCancel = false, this.backgroundColor, + this.titleTextColor, this.loading, this.requestById, this.validator, @@ -146,7 +148,11 @@ 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 7f75b6bc..70327c4c 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 @@ -37,6 +37,7 @@ class _MyRequestsPageState extends State { @override Widget build(BuildContext context) { +//TODO need to refactor this and move out of build... if (_provider == null) { requestsList = [ Request(null, context.translation.allWorkOrder), @@ -67,6 +68,7 @@ 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")); } requestsList.add(Request(12, "Loan Equipment")); @@ -91,7 +93,6 @@ class _MyRequestsPageState extends State { _provider!.getAllRequests(context); }); } - return Scaffold( appBar: AppBar( automaticallyImplyLeading: false, diff --git a/lib/new_views/pages/land_page/requests/request_paginated_listview.dart b/lib/new_views/pages/land_page/requests/request_paginated_listview.dart index 0b76bf87..62580009 100644 --- a/lib/new_views/pages/land_page/requests/request_paginated_listview.dart +++ b/lib/new_views/pages/land_page/requests/request_paginated_listview.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/models/new_models/dashboard_detail.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/asset_delivery_item_view.dart'; import 'package:test_sa/modules/internal_audit_module/pages/equipment_internal_audit/equipment_internal_audit_item_view.dart'; import 'package:test_sa/modules/internal_audit_module/pages/system_internal_audit/system_internal_audit_item_view.dart'; import 'package:test_sa/modules/asset_inventory_module/pages/inventory_session_item_view.dart'; @@ -75,6 +76,8 @@ class RequestPaginatedListview extends StatelessWidget { return SystemInternalAuditItemView(requestData: request); case 12: return LoanEquipmentItemView(requestData: request); + case 13: + return AssetDeliveryItemView(requestData: request); default: return Container( height: 100, 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 23512cee..8fc1a0f5 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 @@ -6,6 +6,7 @@ import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/all_requests_and_count_model.dart'; +import 'package:test_sa/modules/asset_delivery_module/pages/asset_delivery_item_view.dart'; import 'package:test_sa/modules/internal_audit_module/pages/equipment_internal_audit/equipment_internal_audit_item_view.dart'; import 'package:test_sa/modules/internal_audit_module/pages/system_internal_audit/system_internal_audit_item_view.dart'; import 'package:test_sa/modules/asset_inventory_module/pages/inventory_session_item_view.dart'; @@ -69,8 +70,12 @@ 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]); + default: Container( height: 100,