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,