Merge branch 'refs/heads/design_3.0_loan_module' into design_3.0_asset_delivery_module

# Conflicts:
#	lib/controllers/api_routes/urls.dart
design_3.0_demo_module
Sikander Saleem 4 months ago
commit 9f670d4a0b

@ -469,8 +469,6 @@
"-framework", "-framework",
"\"nanopb\"", "\"nanopb\"",
"-framework", "-framework",
"\"qr_code_scanner\"",
"-framework",
"\"speech_to_text\"", "\"speech_to_text\"",
"-framework", "-framework",
"\"sqflite\"", "\"sqflite\"",
@ -689,8 +687,6 @@
"-framework", "-framework",
"\"nanopb\"", "\"nanopb\"",
"-framework", "-framework",
"\"qr_code_scanner\"",
"-framework",
"\"speech_to_text\"", "\"speech_to_text\"",
"-framework", "-framework",
"\"sqflite\"", "\"sqflite\"",
@ -795,8 +791,6 @@
"-framework", "-framework",
"\"nanopb\"", "\"nanopb\"",
"-framework", "-framework",
"\"qr_code_scanner\"",
"-framework",
"\"speech_to_text\"", "\"speech_to_text\"",
"-framework", "-framework",
"\"sqflite\"", "\"sqflite\"",

@ -1,7 +1,7 @@
class URLs { class URLs {
URLs._(); URLs._();
static const String appReleaseBuildNumber = "28"; static const String appReleaseBuildNumber = "31";
// static const host1 = "https://atomsm.hmg.com"; // production url // static const host1 = "https://atomsm.hmg.com"; // production url
static const host1 = "https://atomsmdev.hmg.com"; // local DEV url static const host1 = "https://atomsmdev.hmg.com"; // local DEV url
@ -67,8 +67,10 @@ class URLs {
//service request new flow urls. //service request new flow urls.
static get nurseDashboardCountUrl => '$_baseUrl/ServiceRequest/GetDashboardNurseCount'; static get nurseDashboardCountUrl => '$_baseUrl/ServiceRequest/GetDashboardNurseCount';
static get qaAuditorCount => '$_baseUrl/ServiceRequest/GetDashboardQAAuditorCount';
static get nurseDashboardDetailsUrl => '$_baseUrl/ServiceRequest/GetDashboardNurseDetails'; static get nurseDashboardDetailsUrl => '$_baseUrl/ServiceRequest/GetDashboardNurseDetails';
static get qaAuditorDetails => '$_baseUrl/ServiceRequest/GetDashboardQAAuditorDetails';
static get nurseRejectUrl => '$_baseUrl/ServiceRequest/NurseReject'; static get nurseRejectUrl => '$_baseUrl/ServiceRequest/NurseReject';

@ -110,12 +110,13 @@ class FirebaseNotificationManger {
serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString())); serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString()));
break; break;
case "7": case "7":
serviceClass = DeviceTransferDetails(model: DeviceTransfer(id: int.parse(messageData["requestNumber"].toString()))); serviceClass = DeviceTransferDetails(model: DeviceTransfer(id: int.parse(messageData["requestNumber"].toString())), moduleId: 3);
break; break;
case "9": case "9":
serviceClass = GasRefillDetailsPage( serviceClass = GasRefillDetailsPage(
priority: messageData["priority"], priority: messageData["priority"],
date: messageData["createdOn"], date: messageData["createdOn"],
moduleId: 2,
model: GasRefillModel(id: int.parse(messageData["requestNumber"].toString())), model: GasRefillModel(id: int.parse(messageData["requestNumber"].toString())),
); );
break; break;

@ -140,6 +140,7 @@ class AllRequestsProvider extends ChangeNotifier {
} }
if (context.userProvider.isQualityUser) { if (context.userProvider.isQualityUser) {
list = [10, 11]; list = [10, 11];
if (context.settingProvider.isUserFlowMedical) list.insert(0, 7);
return list; return list;
} }

@ -106,7 +106,9 @@ class DashBoardProvider extends ChangeNotifier {
isAllCountLoading = true; isAllCountLoading = true;
notifyListeners(); notifyListeners();
String url = ''; String url = '';
if (usersType == UsersTypes.engineer || usersType == UsersTypes.assessor || usersType == UsersTypes.assessorTl) { if (usersType == UsersTypes.qualityUser) {
url = URLs.qaAuditorCount;
} else if (usersType == UsersTypes.engineer || usersType == UsersTypes.assessor || usersType == UsersTypes.assessorTl) {
url = URLs.engineerDashboardCountUrl; url = URLs.engineerDashboardCountUrl;
} else { } else {
url = URLs.nurseDashboardCountUrl; url = URLs.nurseDashboardCountUrl;
@ -241,7 +243,10 @@ class DashBoardProvider extends ChangeNotifier {
Response response; Response response;
String url = ''; String url = '';
if (usersType == UsersTypes.engineer || usersType == UsersTypes.assessor || usersType == UsersTypes.assessorTl) {
if (usersType == UsersTypes.qualityUser) {
url = URLs.qaAuditorDetails;
} else if (usersType == UsersTypes.engineer || usersType == UsersTypes.assessor || usersType == UsersTypes.assessorTl) {
//need to check pagination for not assigned task @waseem. //need to check pagination for not assigned task @waseem.
//these checks are to call different apis for dashboard for engineer... //these checks are to call different apis for dashboard for engineer...
@ -372,6 +377,13 @@ class CategoryTabs {
return tabs; return tabs;
} }
if (userType == UsersTypes.qualityUser) {
tabs.add(CategoryTabs(label: 'Open', tag: 1, id: 2));
tabs.add(CategoryTabs(label: 'In Progress', tag: 2, id: 3));
tabs.add(CategoryTabs(label: 'Closed', tag: 3, id: 4));
return tabs;
}
tabs.add(CategoryTabs(label: 'Open', tag: 1, id: 2)); tabs.add(CategoryTabs(label: 'Open', tag: 1, id: 2));
tabs.add(CategoryTabs(label: 'In Progress', tag: 2, id: 3)); tabs.add(CategoryTabs(label: 'In Progress', tag: 2, id: 3));
tabs.add(CategoryTabs(label: 'Pending Acknowledgement', tag: 3, id: 1)); tabs.add(CategoryTabs(label: 'Pending Acknowledgement', tag: 3, id: 1));

@ -182,6 +182,13 @@ class ProgressFragment extends StatelessWidget {
ChartData('Open', snapshot.dashboardCount?.data?.countOpen?.toDouble() ?? 0.0, AppColor.blueStatus(context)), ChartData('Open', snapshot.dashboardCount?.data?.countOpen?.toDouble() ?? 0.0, AppColor.blueStatus(context)),
ChartData('In Progress', snapshot.dashboardCount?.data?.countInprogress?.toDouble() ?? 0.0, AppColor.orange70), ChartData('In Progress', snapshot.dashboardCount?.data?.countInprogress?.toDouble() ?? 0.0, AppColor.orange70),
]; ];
} else if (_userProvider.isQualityUser) {
total = (snapshot.dashboardCount?.data?.countComplete ?? 0) + (snapshot.dashboardCount?.data?.countInprogress ?? 0) + (snapshot.dashboardCount?.data?.countOpen ?? 0);
chartData = [
ChartData('Closed', snapshot.dashboardCount?.data?.countComplete?.toDouble() ?? 0.0, AppColor.green70),
ChartData('Open', snapshot.dashboardCount?.data?.countOpen?.toDouble() ?? 0.0, AppColor.blueStatus(context)),
ChartData('In Progress', snapshot.dashboardCount?.data?.countInprogress?.toDouble() ?? 0.0, AppColor.orange70),
];
} else { } else {
total = (snapshot.dashboardCount?.data?.countComplete ?? 0) + (snapshot.dashboardCount?.data?.countInprogress ?? 0) + (snapshot.dashboardCount?.data?.countOpen ?? 0); total = (snapshot.dashboardCount?.data?.countComplete ?? 0) + (snapshot.dashboardCount?.data?.countInprogress ?? 0) + (snapshot.dashboardCount?.data?.countOpen ?? 0);
chartData = [ chartData = [
@ -248,7 +255,7 @@ class ProgressFragment extends StatelessWidget {
showChartValuesOutside: false, showChartValuesOutside: false,
decimalPlaces: 1, decimalPlaces: 1,
), ),
).toShimmer(isShow: snapshot.isAllCountLoading, radius: 250,context: context).paddingAll(0).toShadowContainer(context), ).toShimmer(isShow: snapshot.isAllCountLoading, radius: 250, context: context).paddingAll(0).toShadowContainer(context),
], ],
), ),
), ),

@ -38,6 +38,7 @@ class DeviceTransfer {
this.senderEngSignature, this.senderEngSignature,
this.senderAttachments, this.senderAttachments,
this.receiverAssignedEmployeeId, this.receiverAssignedEmployeeId,
this.receiverAssignedEmployeeNumber,
this.receiverMachineStatusId, this.receiverMachineStatusId,
this.senderMachineStatusValue, this.senderMachineStatusValue,
this.receiverComment, this.receiverComment,
@ -74,6 +75,7 @@ class DeviceTransfer {
this.receiverMachineStatusValue, this.receiverMachineStatusValue,
this.receiverMachineStatusName, this.receiverMachineStatusName,
this.senderAssignedEmployeeName, this.senderAssignedEmployeeName,
this.senderAssignedEmployeeNumber,
this.senderBuildingName, this.senderBuildingName,
this.senderDepartmentName, this.senderDepartmentName,
this.senderEngSignatureUrl, this.senderEngSignatureUrl,
@ -144,6 +146,7 @@ class DeviceTransfer {
}); });
} }
receiverAssignedEmployeeId = json['receiverAssignedEmployeeId']; receiverAssignedEmployeeId = json['receiverAssignedEmployeeId'];
receiverAssignedEmployeeNumber = json['receiverAssignedEmployeeNumber'];
receiverMachineStatusId = json['receiverMachineStatusId']; receiverMachineStatusId = json['receiverMachineStatusId'];
receiverMachineStatusValue = json['receiverMachineStatusValue']; receiverMachineStatusValue = json['receiverMachineStatusValue'];
receiverComment = json['receiverComment']; receiverComment = json['receiverComment'];
@ -220,6 +223,7 @@ class DeviceTransfer {
receiverEngSignatureUrl = json['receiverEngSignatureUrl']; receiverEngSignatureUrl = json['receiverEngSignatureUrl'];
receiverMachineStatusName = json['receiverMachineStatusName']; receiverMachineStatusName = json['receiverMachineStatusName'];
senderAssignedEmployeeName = json['senderAssignedEmployeeName']; senderAssignedEmployeeName = json['senderAssignedEmployeeName'];
senderAssignedEmployeeNumber = json['senderAssignedEmployeeNumber'];
senderBuildingName = json['senderBuildingName']; senderBuildingName = json['senderBuildingName'];
senderDepartmentName = json['senderDepartmentName']; senderDepartmentName = json['senderDepartmentName'];
senderEngSignatureUrl = json['senderEngSignatureUrl']; senderEngSignatureUrl = json['senderEngSignatureUrl'];
@ -270,6 +274,7 @@ class DeviceTransfer {
List<AssetTransferAttachment>? attachments; List<AssetTransferAttachment>? attachments;
List<AssetTransferAttachment>? assetTransferAttachments; List<AssetTransferAttachment>? assetTransferAttachments;
String? receiverAssignedEmployeeId; String? receiverAssignedEmployeeId;
String? receiverAssignedEmployeeNumber;
num? receiverMachineStatusId; num? receiverMachineStatusId;
int? receiverMachineStatusValue; int? receiverMachineStatusValue;
String? receiverComment; String? receiverComment;
@ -290,6 +295,7 @@ class DeviceTransfer {
String? senderFloorName; String? senderFloorName;
String? senderDepartmentName; String? senderDepartmentName;
String? senderAssignedEmployeeName; String? senderAssignedEmployeeName;
String? senderAssignedEmployeeNumber;
String? senderMachineStatusName; String? senderMachineStatusName;
String? senderEngSignatureUrl; String? senderEngSignatureUrl;
String? receiverAssignedEmployeeName; String? receiverAssignedEmployeeName;
@ -345,6 +351,7 @@ class DeviceTransfer {
String? senderEngSignature, String? senderEngSignature,
List<AssetTransferAttachment>? senderAttachments, List<AssetTransferAttachment>? senderAttachments,
String? receiverAssignedEmployeeId, String? receiverAssignedEmployeeId,
String? receiverAssignedEmployeeNumber,
num? receiverMachineStatusId, num? receiverMachineStatusId,
String? receiverComment, String? receiverComment,
String? receiverStartDate, String? receiverStartDate,
@ -364,6 +371,7 @@ class DeviceTransfer {
String? senderFloorName, String? senderFloorName,
String? senderDepartmentName, String? senderDepartmentName,
String? senderAssignedEmployeeName, String? senderAssignedEmployeeName,
String? senderAssignedEmployeeNumber,
String? senderMachineStatusName, String? senderMachineStatusName,
String? senderEngSignatureUrl, String? senderEngSignatureUrl,
String? receiverAssignedEmployeeName, String? receiverAssignedEmployeeName,
@ -420,6 +428,7 @@ class DeviceTransfer {
senderEngSignature: senderEngSignature ?? this.senderEngSignature, senderEngSignature: senderEngSignature ?? this.senderEngSignature,
senderAttachments: senderAttachments ?? this.senderAttachments, senderAttachments: senderAttachments ?? this.senderAttachments,
receiverAssignedEmployeeId: receiverAssignedEmployeeId ?? this.receiverAssignedEmployeeId, receiverAssignedEmployeeId: receiverAssignedEmployeeId ?? this.receiverAssignedEmployeeId,
receiverAssignedEmployeeNumber: receiverAssignedEmployeeNumber ?? this.receiverAssignedEmployeeNumber,
receiverMachineStatusId: receiverMachineStatusId ?? this.receiverMachineStatusId, receiverMachineStatusId: receiverMachineStatusId ?? this.receiverMachineStatusId,
receiverComment: receiverComment ?? this.receiverComment, receiverComment: receiverComment ?? this.receiverComment,
receiverStartDate: receiverStartDate ?? this.receiverStartDate, receiverStartDate: receiverStartDate ?? this.receiverStartDate,
@ -439,6 +448,7 @@ class DeviceTransfer {
senderFloorName: senderFloorName ?? this.senderFloorName, senderFloorName: senderFloorName ?? this.senderFloorName,
senderDepartmentName: senderDepartmentName ?? this.senderDepartmentName, senderDepartmentName: senderDepartmentName ?? this.senderDepartmentName,
senderAssignedEmployeeName: senderAssignedEmployeeName ?? this.senderAssignedEmployeeName, senderAssignedEmployeeName: senderAssignedEmployeeName ?? this.senderAssignedEmployeeName,
senderAssignedEmployeeNumber: senderAssignedEmployeeNumber ?? this.senderAssignedEmployeeNumber,
senderMachineStatusName: senderMachineStatusName ?? this.senderMachineStatusName, senderMachineStatusName: senderMachineStatusName ?? this.senderMachineStatusName,
senderMachineStatusValue: senderMachineStatusValue ?? this.senderMachineStatusValue, senderMachineStatusValue: senderMachineStatusValue ?? this.senderMachineStatusValue,
senderEngSignatureUrl: senderEngSignatureUrl ?? this.senderEngSignatureUrl, senderEngSignatureUrl: senderEngSignatureUrl ?? this.senderEngSignatureUrl,
@ -503,6 +513,7 @@ class DeviceTransfer {
map['senderAttachments'] = senderAttachments!.map((v) => v.toJson()).toList(); map['senderAttachments'] = senderAttachments!.map((v) => v.toJson()).toList();
} }
map['receiverAssignedEmployeeId'] = receiverAssignedEmployeeId; map['receiverAssignedEmployeeId'] = receiverAssignedEmployeeId;
map['receiverAssignedEmployeeNumber'] = receiverAssignedEmployeeNumber;
map['receiverMachineStatusId'] = receiverMachineStatusId; map['receiverMachineStatusId'] = receiverMachineStatusId;
map['receiverComment'] = receiverComment; map['receiverComment'] = receiverComment;
map['receiverStartDate'] = receiverStartDate; map['receiverStartDate'] = receiverStartDate;
@ -524,6 +535,7 @@ class DeviceTransfer {
map["senderFloorName"] = senderFloorName; map["senderFloorName"] = senderFloorName;
map["senderDepartmentName"] = senderDepartmentName; map["senderDepartmentName"] = senderDepartmentName;
map["senderAssignedEmployeeName"] = senderAssignedEmployeeName; map["senderAssignedEmployeeName"] = senderAssignedEmployeeName;
map["senderAssignedEmployeeNumber"] = senderAssignedEmployeeNumber;
map["senderMachineStatusName"] = senderMachineStatusName; map["senderMachineStatusName"] = senderMachineStatusName;
map["senderEngSignatureUrl"] = senderEngSignatureUrl; map["senderEngSignatureUrl"] = senderEngSignatureUrl;
map["receiverAssignedEmployeeName"] = receiverAssignedEmployeeName; map["receiverAssignedEmployeeName"] = receiverAssignedEmployeeName;
@ -631,6 +643,7 @@ class DeviceTransfer {
map['assetTransferReceiverTimers'] = receiverVisitTimers!.map((v) => v.toJson()).toList(); map['assetTransferReceiverTimers'] = receiverVisitTimers!.map((v) => v.toJson()).toList();
} }
map['receiverAssignedEmployeeId'] = receiverAssignedEmployeeId; map['receiverAssignedEmployeeId'] = receiverAssignedEmployeeId;
map['receiverAssignedEmployeeNumber'] = receiverAssignedEmployeeNumber;
map['receiverMachineStatusId'] = receiverMachineStatusId; map['receiverMachineStatusId'] = receiverMachineStatusId;
map['receiverComment'] = receiverComment; map['receiverComment'] = receiverComment;
map['receiverStartDate'] = receiverStartDate; map['receiverStartDate'] = receiverStartDate;
@ -674,6 +687,7 @@ class DeviceTransfer {
senderEngSignature = assetTransfer.senderEngSignature; senderEngSignature = assetTransfer.senderEngSignature;
senderAttachments = assetTransfer.senderAttachments; senderAttachments = assetTransfer.senderAttachments;
receiverAssignedEmployeeId = assetTransfer.receiverAssignedEmployeeId; receiverAssignedEmployeeId = assetTransfer.receiverAssignedEmployeeId;
receiverAssignedEmployeeNumber = assetTransfer.receiverAssignedEmployeeNumber;
receiverMachineStatusId = assetTransfer.receiverMachineStatusId; receiverMachineStatusId = assetTransfer.receiverMachineStatusId;
receiverComment = assetTransfer.receiverComment; receiverComment = assetTransfer.receiverComment;
receiverStartDate = assetTransfer.receiverStartDate; receiverStartDate = assetTransfer.receiverStartDate;
@ -693,6 +707,7 @@ class DeviceTransfer {
senderFloorName = assetTransfer.senderFloorName; senderFloorName = assetTransfer.senderFloorName;
senderDepartmentName = assetTransfer.senderDepartmentName; senderDepartmentName = assetTransfer.senderDepartmentName;
senderAssignedEmployeeName = assetTransfer.senderAssignedEmployeeName; senderAssignedEmployeeName = assetTransfer.senderAssignedEmployeeName;
senderAssignedEmployeeNumber = assetTransfer.senderAssignedEmployeeNumber;
senderMachineStatusName = assetTransfer.senderMachineStatusName; senderMachineStatusName = assetTransfer.senderMachineStatusName;
senderEngSignatureUrl = assetTransfer.senderEngSignatureUrl; senderEngSignatureUrl = assetTransfer.senderEngSignatureUrl;
receiverAssignedEmployeeName = assetTransfer.receiverAssignedEmployeeName; receiverAssignedEmployeeName = assetTransfer.receiverAssignedEmployeeName;

@ -523,3 +523,55 @@ class GasRefillContactPerson {
}; };
} }
} }
class AssignedEmployee {
String? id;
String? name;
String? email;
String? employeeId;
int? languageId;
String? extensionNo;
String? phoneNumber;
String? positionName;
String? position;
bool? isActive;
AssignedEmployee(
{this.id,
this.name,
this.email,
this.employeeId,
this.languageId,
this.extensionNo,
this.phoneNumber,
this.positionName,
this.position,
this.isActive});
AssignedEmployee.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
email = json['email'];
employeeId = json['employeeId'];
languageId = json['languageId'];
extensionNo = json['extensionNo'];
phoneNumber = json['phoneNumber'];
positionName = json['positionName'];
position = json['position'];
isActive = json['isActive'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['name'] = this.name;
data['email'] = this.email;
data['employeeId'] = this.employeeId;
data['languageId'] = this.languageId;
data['extensionNo'] = this.extensionNo;
data['phoneNumber'] = this.phoneNumber;
data['positionName'] = this.positionName;
data['position'] = this.position;
data['isActive'] = this.isActive;
return data;
}
}

@ -110,6 +110,8 @@ class User {
return UsersTypes.assessorTl; return UsersTypes.assessorTl;
case "R-3": // Quality User case "R-3": // Quality User
return UsersTypes.qualityUser; return UsersTypes.qualityUser;
case "R-58": // Quality User
return UsersTypes.qualityUser;
default: default:
return null; return null;
} }

@ -153,7 +153,8 @@ class _CMDetailPageState extends State<CMDetailPage> {
], ],
), ),
).onPress(() { ).onPress(() {
Navigator.push(context, MaterialPageRoute(builder: (context) => CreateLoanRequestPage(workOrderId: widget.requestId))); CMDetailProvider provider = Provider.of<CMDetailProvider>(context, listen: false);
Navigator.push(context, MaterialPageRoute(builder: (context) => CreateLoanRequestPage(workOrderId: widget.requestId, workOrder: provider.currentWorkOrder!.data)));
}); });
} }
return const SizedBox(); return const SizedBox();

@ -199,8 +199,6 @@ class _ServiceRequestDetailViewState extends State<ServiceRequestDetailView> {
'${context.translation.assetName}: ${workOrder.assetNdModel!.name?.cleanupWhitespace?.capitalizeFirstOfEach}', '${context.translation.assetName}: ${workOrder.assetNdModel!.name?.cleanupWhitespace?.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
), ),
// 8.height,
Text( Text(
'${context.translation.assetNumber}: ${workOrder.asset!.assetNumber}', '${context.translation.assetNumber}: ${workOrder.asset!.assetNumber}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),

@ -73,25 +73,26 @@ class _ChatWidgetState extends State<ChatWidget> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<ChatProvider>(builder: (pContext, requestProvider, _) { return widget.isShow
return IconButton( ? Consumer<ChatProvider>(builder: (pContext, requestProvider, _) {
icon: const Icon(Icons.chat_bubble), return IconButton(
onPressed: () { icon: const Icon(Icons.chat_bubble),
Navigator.push( onPressed: () {
context, Navigator.push(
CupertinoPageRoute( context,
builder: (context) => ChatPage( CupertinoPageRoute(
moduleId: widget.moduleId, builder: (context) => ChatPage(
requestId: widget.requestId, moduleId: widget.moduleId,
title: widget.title, requestId: widget.requestId,
readOnly: widget.isReadOnly, title: widget.title,
assigneeEmployeeNumber: widget.assigneeEmployeeNumber, readOnly: widget.isReadOnly,
contactEmployeeINumber: widget.contactEmployeeINumber, assigneeEmployeeNumber: widget.assigneeEmployeeNumber,
myLoginUserID: widget.myLoginUserID, contactEmployeeINumber: widget.contactEmployeeINumber,
))); myLoginUserID: widget.myLoginUserID,
}, )));
).toShimmer(context: context, isShow: requestProvider.chatLoginTokenLoading, radius: 30, height: 30, width: 30); },
}); ).toShimmer(context: context, isShow: requestProvider.chatLoginTokenLoading, radius: 30, height: 30, width: 30);
; })
: const SizedBox();
} }
} }

@ -127,8 +127,9 @@ class ChatFileViewer extends StatelessWidget {
Future<File?> downloadFile() async { Future<File?> downloadFile() async {
try { try {
// print("downloadUrl:$downloadUrl");
return await ChatApiClient() return await ChatApiClient()
.downloadFileWithHttp(downloadUrl, fileName: fileTypeResponse.fileName, fileTypeDescription: fileTypeResponse.fileTypeDescription, fileSource: fileTypeResponse.fileTypeId!); .downloadFileWithHttp(downloadUrl, fileName: fileTypeResponse.fileName, fileTypeDescription: fileTypeResponse.fileTypeDescription ?? "", fileSource: fileTypeResponse.fileTypeId!);
} catch (ex) { } catch (ex) {
print("downloadFile:$ex"); print("downloadFile:$ex");
return null; return null;

@ -170,6 +170,8 @@ class Asset {
String? siteName; String? siteName;
int? siteId; int? siteId;
String? modelDefinition; String? modelDefinition;
int? departmentId;
String? departmentName;
Asset({ Asset({
this.id, this.id,
@ -181,6 +183,8 @@ class Asset {
this.siteName, this.siteName,
this.siteId, this.siteId,
this.modelDefinition, this.modelDefinition,
this.departmentId,
this.departmentName,
}); });
Asset.fromJson(Map<String, dynamic> json) { Asset.fromJson(Map<String, dynamic> json) {
@ -193,6 +197,8 @@ class Asset {
siteName = json['siteName']; siteName = json['siteName'];
siteId = json['siteId']; siteId = json['siteId'];
modelDefinition = json['modelDefinition']; modelDefinition = json['modelDefinition'];
departmentId = json['departmentId'];
departmentName = json['departmentName'];
} }
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -206,6 +212,8 @@ class Asset {
data['siteName'] = siteName; data['siteName'] = siteName;
data['siteId'] = siteId; data['siteId'] = siteId;
data['modelDefinition'] = modelDefinition; data['modelDefinition'] = modelDefinition;
data['departmentId'] = departmentId;
data['departmentName'] = departmentName;
return data; return data;
} }
} }

@ -42,6 +42,8 @@ class _CreateEquipmentInternalAuditFormState extends State<CreateEquipmentIntern
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
FocusNode auditCheckListNode = FocusNode(); FocusNode auditCheckListNode = FocusNode();
int noFindingValue = 4;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@ -78,7 +80,6 @@ class _CreateEquipmentInternalAuditFormState extends State<CreateEquipmentIntern
}, },
), ),
16.height, 16.height,
//TODO need to check layout issue...
MultipleItemDropDownMenu<Lookup, InternalAuditCheckListProvider>( MultipleItemDropDownMenu<Lookup, InternalAuditCheckListProvider>(
context: context, context: context,
showAsBottomSheet: true, showAsBottomSheet: true,
@ -89,6 +90,15 @@ class _CreateEquipmentInternalAuditFormState extends State<CreateEquipmentIntern
title: 'Internal Audit Checklist'.addTranslation, title: 'Internal Audit Checklist'.addTranslation,
initialValue: _equipmentinternalAuditModel.findings, initialValue: _equipmentinternalAuditModel.findings,
onSelect: (value) { onSelect: (value) {
if ((value ?? []).isNotEmpty) {
Lookup? noFindingElement;
try {
noFindingElement = value!.singleWhere((element) => element.value == noFindingValue);
} catch (ex) {}
if (noFindingElement != null) {
value!.removeWhere((element) => element.value != noFindingElement!.value);
}
}
_equipmentinternalAuditModel.findings = value ?? []; _equipmentinternalAuditModel.findings = value ?? [];
}, },
), ),
@ -137,9 +147,9 @@ class _CreateEquipmentInternalAuditFormState extends State<CreateEquipmentIntern
} }
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
_equipmentinternalAuditModel.auditorId = context.userProvider.user?.userID; _equipmentinternalAuditModel.auditorId = context.userProvider.user?.userID;
bool status = await internalAuditProvider.addEquipmentInternalAudit(context: context, request: _equipmentinternalAuditModel); bool status = await internalAuditProvider.addEquipmentInternalAudit(context: context, request: _equipmentinternalAuditModel);
Navigator.pop(context); Navigator.pop(context);
if(status){ if (status) {
Navigator.pop(context); Navigator.pop(context);
} }
} }

@ -19,6 +19,7 @@ import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/views/widgets/images/files_list.dart'; import 'package:test_sa/views/widgets/images/files_list.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart';
class EquipmentInternalAuditDetailPage extends StatefulWidget { class EquipmentInternalAuditDetailPage extends StatefulWidget {
static const String id = "/details-internal-audit"; static const String id = "/details-internal-audit";
@ -51,12 +52,10 @@ class _EquipmentInternalAuditDetailPageState extends State<EquipmentInternalAudi
Future<void> getAuditData() async { Future<void> getAuditData() async {
model = await _internalAuditProvider.getEquipmentInternalAuditById(widget.auditId); model = await _internalAuditProvider.getEquipmentInternalAuditById(widget.auditId);
allAttachments.clear(); allAttachments.clear();
allAttachments = [ allAttachments = [
...(model?.attachments ?? []), ...(model?.attachments ?? []),
...(model?.engineerData?.attachments ?? []), ...(model?.engineerData?.attachments ?? []),
]; ];
} }
@override @override
@ -82,12 +81,43 @@ class _EquipmentInternalAuditDetailPageState extends State<EquipmentInternalAudi
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
StatusLabel(
label: model!.status!.name,
id: model!.status!.value,
radius: 4,
textColor: AppColor.getRequestStatusTextColorByName(
context,
model!.status!.name,
),
backgroundColor: AppColor.getRequestStatusColorByName(
context,
model!.status!.name,
),
// textColor: AppColor.green15,
// backgroundColor: AppColor.greenStatus(context),
),
Text(
model!.createdDate!.toString().toServiceRequestCardFormat,
textAlign: TextAlign.end,
style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
)
],
),
8.height,
assetDetails(), assetDetails(),
8.height, 8.height,
requestDetails(), requestDetails(),
8.height, 8.height,
if (model?.remarks?.isNotEmpty ?? false) ...[ if (model?.remarks?.isNotEmpty ?? false) ...[
const Divider().defaultStyle(context), const Divider().defaultStyle(context),
Text(
"Remarks",
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
model!.remarks!.bodyText(context), model!.remarks!.bodyText(context),
8.height, 8.height,
], ],
@ -103,7 +133,7 @@ class _EquipmentInternalAuditDetailPageState extends State<EquipmentInternalAudi
], ],
).paddingAll(0).toShadowContainer(context), ).paddingAll(0).toShadowContainer(context),
).expanded, ).expanded,
if (context.userProvider.isEngineer&&model?.status?.value!=3) if (context.userProvider.isEngineer && model?.status?.value != 3)
FooterActionButton.footerContainer( FooterActionButton.footerContainer(
context: context, context: context,
child: AppFilledButton( child: AppFilledButton(
@ -160,6 +190,7 @@ class _EquipmentInternalAuditDetailPageState extends State<EquipmentInternalAudi
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
), ),
6.height, 6.height,
'${context.translation.requestNo}: ${model?.requestNo ?? '-'}'.bodyText(context),
if (model != null && model!.equipmentsFindings != null && model!.equipmentsFindings!.isNotEmpty) if (model != null && model!.equipmentsFindings != null && model!.equipmentsFindings!.isNotEmpty)
...model!.equipmentsFindings!.map((item) { ...model!.equipmentsFindings!.map((item) {
final findingName = item.finding?.name ?? 'Unknown'; final findingName = item.finding?.name ?? 'Unknown';
@ -177,14 +208,17 @@ class _EquipmentInternalAuditDetailPageState extends State<EquipmentInternalAudi
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
"Asset Details", "Asset Information",
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
), ),
6.height, 6.height,
'${context.translation.assetName}: ${model?.asset?.assetName ?? '-'}'.bodyText(context), '${context.translation.assetName}: ${model?.asset?.assetName ?? '-'}'.bodyText(context),
'${context.translation.assetNo}: ${model?.asset?.assetNumber ?? '-'}'.bodyText(context), '${context.translation.assetNo}: ${model?.asset?.assetNumber ?? '-'}'.bodyText(context),
'${context.translation.serialNumber}: ${model?.asset?.assetNumber ?? '-'}'.bodyText(context),
'${context.translation.manufacture}: ${model?.asset?.manufacturerName ?? '-'}'.bodyText(context), '${context.translation.manufacture}: ${model?.asset?.manufacturerName ?? '-'}'.bodyText(context),
'${context.translation.model}: ${model?.asset?.modelName ?? '-'}'.bodyText(context), '${context.translation.model}: ${model?.asset?.modelName ?? '-'}'.bodyText(context),
'${context.translation.site}: ${model?.asset?.siteName ?? '-'}'.bodyText(context),
'${context.translation.department}: ${model?.asset?.departmentName ?? '-'}'.bodyText(context),
], ],
); );
} }

@ -21,7 +21,6 @@ class EquipmentInternalAuditItemView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
//TODO need to refactor this code repetation @waseem
if (requestData != null) { if (requestData != null) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -44,8 +43,8 @@ class EquipmentInternalAuditItemView extends StatelessWidget {
), ),
8.height, 8.height,
(requestData?.typeTransaction ?? "Internal Audit Request").heading5(context), (requestData?.typeTransaction ?? "Internal Audit Request").heading5(context),
infoWidget(label: context.translation.assetNumber, value: requestData?.assetNumber, context: context), infoWidget(label: context.translation.requestNo, value: requestData!.requestNo, context: context),
infoWidget(label: context.translation.assetNumber, value: requestData!.assetNumber, context: context),
8.height, 8.height,
Row( Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -60,7 +59,7 @@ class EquipmentInternalAuditItemView extends StatelessWidget {
), ),
], ],
).toShadowContainer(context, withShadow: showShadow).onPress(() async { ).toShadowContainer(context, withShadow: showShadow).onPress(() async {
Navigator.push(context, MaterialPageRoute(builder: (context) => EquipmentInternalAuditDetailPage(auditId: requestDetails!.id!))); Navigator.push(context, MaterialPageRoute(builder: (context) => EquipmentInternalAuditDetailPage(auditId: requestData!.id!)));
}); });
} }
return Column( return Column(
@ -85,9 +84,11 @@ class EquipmentInternalAuditItemView extends StatelessWidget {
8.height, 8.height,
(requestDetails?.nameOfType ?? "Internal Audit Request").heading5(context), (requestDetails?.nameOfType ?? "Internal Audit Request").heading5(context),
8.height, 8.height,
infoWidget(label: context.translation.requestNo, value: requestDetails!.requestNo, context: context),
infoWidget(label: context.translation.assetNumber, value: requestDetails!.assetNo, context: context), infoWidget(label: context.translation.assetNumber, value: requestDetails!.assetNo, context: context),
infoWidget(label: context.translation.assetSN, value: requestDetails!.assetSN, context: context), infoWidget(label: context.translation.assetSN, value: requestDetails!.assetSN, context: context),
infoWidget(label: context.translation.model, value: requestDetails!.model, context: context), infoWidget(label: context.translation.model, value: requestDetails!.model, context: context),
infoWidget(label: context.translation.site, value: requestDetails!.site, context: context),
8.height, 8.height,
Row( Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,

@ -20,6 +20,7 @@ import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/views/widgets/images/files_list.dart'; import 'package:test_sa/views/widgets/images/files_list.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart';
class SystemInternalAuditDetailPage extends StatefulWidget { class SystemInternalAuditDetailPage extends StatefulWidget {
static const String id = "/details-system-internal-audit"; static const String id = "/details-system-internal-audit";
@ -79,17 +80,45 @@ class _SystemInternalAuditDetailPageState extends State<SystemInternalAuditDetai
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
assetInformation(), Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
StatusLabel(
label: model!.status!.name,
id: model!.status!.value,
radius: 4,
textColor: AppColor.getRequestStatusTextColorByName(
context,
model!.status!.name,
),
backgroundColor: AppColor.getRequestStatusColorByName(
context,
model!.status!.name,
),
// textColor: AppColor.green15,
// backgroundColor: AppColor.greenStatus(context),
),
Text(
model!.createdDate!.toString().toServiceRequestCardFormat,
textAlign: TextAlign.end,
style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
)
],
),
8.height, 8.height,
workOrderInformation(), workOrderInfo(),
const Divider().defaultStyle(context),
8.height, 8.height,
assetInfo(),
//TODO need to check for comments //TODO need to check for comments
if (model?.findingDescription?.isNotEmpty ?? false) ...[ if (model?.findingDescription?.isNotEmpty ?? false) ...[
const Divider().defaultStyle(context), const Divider().defaultStyle(context),
// Text( Text(
// "Comments".addTranslation, "Remarks",
// style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
// ), ),
model!.findingDescription!.bodyText(context), model!.findingDescription!.bodyText(context),
], ],
//TODO need to check for attachments //TODO need to check for attachments
@ -143,10 +172,33 @@ class _SystemInternalAuditDetailPageState extends State<SystemInternalAuditDetai
6.height, 6.height,
labelValueText(context, context.translation.woNumber, details?.workOrderNo), labelValueText(context, context.translation.woNumber, details?.workOrderNo),
labelValueText(context, 'WO Type'.addTranslation, model?.workOrderType?.name), labelValueText(context, 'WO Type'.addTranslation, model?.workOrderType?.name),
labelValueText(context, context.translation.site, details?.woSite),
labelValueText(context, context.translation.assetName, details?.woAssetName), labelValueText(context, context.translation.assetName, details?.woAssetName),
labelValueText(context, context.translation.assetNo, details?.woAssetNo),
labelValueText(context, context.translation.manufacture, details?.woManufacturer), labelValueText(context, context.translation.manufacture, details?.woManufacturer),
labelValueText(context, context.translation.serialNumber, details?.wosn),
labelValueText(context, context.translation.model, details?.woModel), labelValueText(context, context.translation.model, details?.woModel),
labelValueText(context, context.translation.site, details?.woSite),
labelValueText(context, context.translation.department, details?.woDepartment),
],
);
}
Widget workOrderInfo() {
final details = model?.workOrderDetails;
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"WO Info",
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
6.height,
labelValueText(context, context.translation.requestNo, model?.requestNo),
labelValueText(context, 'WO Type'.addTranslation, model?.workOrderType?.name),
labelValueText(context, context.translation.woNumber, details?.workOrderNo),
labelValueText(context, "Finding Type", model?.findingType?.name),
labelValueText(context, "Assigned Engineer", model?.workOrderDetails?.woAssignedEngineer),
], ],
); );
} }
@ -187,6 +239,28 @@ class _SystemInternalAuditDetailPageState extends State<SystemInternalAuditDetai
); );
} }
Widget assetInfo() {
final details = model?.workOrderDetails;
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Asset Details",
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
6.height,
labelValueText(context, context.translation.assetName, details?.woAssetName),
labelValueText(context, context.translation.assetNo, details?.woAssetNo),
labelValueText(context, context.translation.manufacture, details?.woManufacturer),
labelValueText(context, context.translation.serialNumber, details?.wosn),
labelValueText(context, context.translation.model, details?.woModel),
labelValueText(context, context.translation.site, details?.woSite),
labelValueText(context, context.translation.department, details?.woDepartment),
],
);
}
Widget labelValueText(BuildContext context, String label, String? value) { Widget labelValueText(BuildContext context, String label, String? value) {
if (value == null || value.isEmpty) return const SizedBox.shrink(); if (value == null || value.isEmpty) return const SizedBox.shrink();

@ -44,9 +44,9 @@ class SystemInternalAuditItemView extends StatelessWidget {
], ],
), ),
8.height, 8.height,
(requestData?.typeTransaction ?? "Internal Audit Request").heading5(context), (requestData?.typeTransaction ?? "System Audit Request").heading5(context),
infoWidget(label: context.translation.assetNo, value: requestData?.assetNumber, context: context), infoWidget(label: context.translation.requestNo, value: requestData!.requestNo, context: context),
infoWidget(label: context.translation.assetNumber, value: requestData?.assetNumber, context: context),
8.height, 8.height,
Row( Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -61,7 +61,7 @@ class SystemInternalAuditItemView extends StatelessWidget {
), ),
], ],
).toShadowContainer(context, withShadow: showShadow).onPress(() async { ).toShadowContainer(context, withShadow: showShadow).onPress(() async {
Navigator.push(context, MaterialPageRoute(builder: (context) => SystemInternalAuditDetailPage(auditId: requestDetails!.id!))); Navigator.push(context, MaterialPageRoute(builder: (context) => SystemInternalAuditDetailPage(auditId: requestData!.id!)));
}); });
} }
return Column( return Column(
@ -85,9 +85,12 @@ class SystemInternalAuditItemView extends StatelessWidget {
), ),
8.height, 8.height,
(requestDetails?.nameOfType ?? "Internal Audit Request").heading5(context), (requestDetails?.nameOfType ?? "Internal Audit Request").heading5(context),
infoWidget(label: context.translation.requestNo, value: requestDetails!.requestNo, context: context),
infoWidget(label: context.translation.assetNumber, value: requestDetails!.assetNo, context: context), infoWidget(label: context.translation.assetNumber, value: requestDetails!.assetNo, context: context),
infoWidget(label: context.translation.assetSN, value: requestDetails!.assetSN, context: context), infoWidget(label: context.translation.assetSN, value: requestDetails!.assetSN, context: context),
infoWidget(label: context.translation.model, value: requestDetails!.model, context: context), infoWidget(label: context.translation.model, value: requestDetails!.model, context: context),
infoWidget(label: context.translation.site, value: requestDetails!.site, context: context),
8.height, 8.height,
// infoWidget(label: context.translation.site, value: requestDetails!.site, context: context), // infoWidget(label: context.translation.site, value: requestDetails!.site, context: context),
8.height, 8.height,

@ -1,18 +1,20 @@
import 'package:test_sa/models/base.dart'; import 'package:test_sa/models/base.dart';
class MedicalDepartmentModel extends Base { class MedicalDepartmentModel extends Base {
MedicalDepartmentModel({ MedicalDepartmentModel(
this.departmentName, this.departmentCode, this.ntCode, this.costCenterNumber, this.costCenterName, this.name, this.id, this.createdBy, this.createdDate, this.modifiedBy, this.modifiedDate {this.departmentName, this.departmentCode, this.ntCode, this.costCenterNumber, this.costCenterName, this.name, this.id, this.createdBy, this.createdDate, this.modifiedBy, this.modifiedDate})
}) : super(identifier: id?.toString() ?? '', name: departmentName); // Handle potential null id : super(identifier: id?.toString() ?? '', name: departmentName); // Handle potential null id
MedicalDepartmentModel.fromJson(Map<String, dynamic> json) { MedicalDepartmentModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
identifier = id?.toString() ?? '';
name = json['departmentName'] ?? json['name'];
departmentName = json['departmentName'] ?? json['name']; departmentName = json['departmentName'] ?? json['name'];
departmentCode = json['departmentCode']; departmentCode = json['departmentCode'];
ntCode = json['ntCode']; ntCode = json['ntCode'];
costCenterNumber = json['costCenterNumber']; costCenterNumber = json['costCenterNumber'];
costCenterName = json['costCenterName']; costCenterName = json['costCenterName'];
name = json['name']; name = json['name'];
id = json['id'];
createdBy = json['createdBy']; createdBy = json['createdBy'];
createdDate = json['createdDate']; createdDate = json['createdDate'];
modifiedBy = json['modifiedBy']; modifiedBy = json['modifiedBy'];
@ -30,6 +32,4 @@ class MedicalDepartmentModel extends Base {
String? createdDate; String? createdDate;
String? modifiedBy; String? modifiedBy;
String? modifiedDate; String? modifiedDate;
} }

@ -16,14 +16,9 @@ import 'package:test_sa/models/device/asset.dart';
import 'package:test_sa/models/enums/user_types.dart'; import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/generic_attachment_model.dart'; import 'package:test_sa/models/generic_attachment_model.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/new_models/building.dart';
import 'package:test_sa/models/new_models/floor.dart';
import 'package:test_sa/models/new_models/mapped_sites.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/new_models/site.dart';
import 'package:test_sa/models/new_models/task_request/task_request_model.dart';
import 'package:test_sa/models/new_models/task_request/task_type_model.dart'; import 'package:test_sa/models/new_models/task_request/task_type_model.dart';
import 'package:test_sa/models/service_request/pending_service_request_model.dart'; import 'package:test_sa/models/new_models/work_order_detail_model.dart';
import 'package:test_sa/modules/cm_module/cm_request_utils.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/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/modules/loan_module/models/loan_form_model.dart'; import 'package:test_sa/modules/loan_module/models/loan_form_model.dart';
@ -39,20 +34,15 @@ import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart
import 'package:test_sa/providers/department_provider.dart'; import 'package:test_sa/providers/department_provider.dart';
import 'package:test_sa/providers/gas_request_providers/site_provider.dart'; import 'package:test_sa/providers/gas_request_providers/site_provider.dart';
import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/providers/loading_list_notifier.dart';
import 'package:test_sa/providers/task_request_provider/task_job_provider.dart';
import 'package:test_sa/providers/task_request_provider/task_request_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.dart';
import '../../../../../../new_views/common_widgets/default_app_bar.dart'; import '../../../../../../new_views/common_widgets/default_app_bar.dart';
import '../../../models/new_models/department.dart';
class CreateLoanRequestPage extends StatefulWidget { class CreateLoanRequestPage extends StatefulWidget {
static const String id = "/create-loan"; static const String id = "/create-loan";
int? workOrderId; int? workOrderId;
WorkOrderData? workOrder;
CreateLoanRequestPage({Key? key, this.workOrderId}) : super(key: key); CreateLoanRequestPage({Key? key, this.workOrderId, this.workOrder}) : super(key: key);
@override @override
_CreateLoanRequestPageState createState() => _CreateLoanRequestPageState(); _CreateLoanRequestPageState createState() => _CreateLoanRequestPageState();
@ -62,7 +52,6 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
final List<GenericAttachmentModel> attachments = []; final List<GenericAttachmentModel> attachments = [];
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
Asset? device;
TaskType? selectedType; TaskType? selectedType;
final LoanFormModel _loanFormModel = LoanFormModel(); final LoanFormModel _loanFormModel = LoanFormModel();
@ -70,11 +59,14 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
bool get isBackUpRequest => widget.workOrderId != null; bool get isBackUpRequest => widget.workOrderId != null;
List<Lookup> loanTypes = [];
@override @override
void initState() { void initState() {
super.initState(); super.initState();
Provider.of<MedicalDepartmentProvider>(context, listen: false).reset(); Provider.of<MedicalDepartmentProvider>(context, listen: false).reset();
Provider.of<LoanPeriodProvider>(context, listen: false).reset(); Provider.of<LoanPeriodProvider>(context, listen: false).reset();
loanTypes = [Lookup(id: 0, name: "Standard", value: 1), Lookup(id: 1, name: "Backup", value: 2)];
} }
@override @override
@ -92,23 +84,55 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
SingleItemDropDownMenu<Lookup, NullableLoadingProvider>(
context: context,
title: "Loan Type",
enabled: false,
staticData: loanTypes,
initialValue: isBackUpRequest ? loanTypes[1] : loanTypes[0],
showShadow: false,
backgroundColor: AppColor.fieldBgColor(context),
showAsBottomSheet: true,
onSelect: (value) {},
),
16.height,
if (isBackUpRequest) ...[ if (isBackUpRequest) ...[
scanAssetButton(), 'Asset Information'.addTranslation.bodyText(context).custom(color: AppColor.black10),
8.height,
Text(
'${context.translation.assetName}: ${widget.workOrder!.assetNdModel!.name?.cleanupWhitespace?.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.assetNumber}: ${widget.workOrder!.asset!.assetNumber}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.serialNo}: ${widget.workOrder!.asset!.assetSerialNo}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.model}: ${widget.workOrder!.model?.name!.cleanupWhitespace?.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
Text(
'${context.translation.manufacture}: ${widget.workOrder!.manufacturer?.name?.cleanupWhitespace?.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120),
),
16.height, 16.height,
], ],
...doctorInfoSection(),
// ...contactInfoSection(), // ...contactInfoSection(),
// 16.height,
...itemDetailsSection(),
16.height, 16.height,
...doctorInfoSection(), ...itemDetailsSection(),
16.height, 16.height,
...vendorDetailsSection(), ...vendorDetailsSection(),
16.height, 16.height,
AttachmentPicker( AttachmentPicker(
label: context.translation.attachments, label: context.translation.attachments,
attachment: attachments, attachment: attachments,
buttonColor: AppColor.black10,
onlyImages: false, onlyImages: false,
showAsListView: true,
buttonIcon: 'image-plus'.toSvgAsset(color: context.isDark ? AppColor.primary10 : AppColor.neutral120), buttonIcon: 'image-plus'.toSvgAsset(color: context.isDark ? AppColor.primary10 : AppColor.neutral120),
onChange: (attachments) { onChange: (attachments) {
attachments = attachments; attachments = attachments;
@ -473,24 +497,8 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
]; ];
} }
Widget scanAssetButton() {
return AssetPicker(
device: device,
showLoading: false,
borderColor: AppColor.black20,
onPick: (asset) async {
device = asset;
setState(() {});
},
);
}
Future<void> _submit() async { Future<void> _submit() async {
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
if (isBackUpRequest && device == null) {
"Please scan or pick asset".showToast;
return;
}
if (_formKey.currentState!.validate()) { if (_formKey.currentState!.validate()) {
_formKey.currentState!.save(); _formKey.currentState!.save();
@ -507,7 +515,12 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
body["requestorUserID"] = context.userProvider.user!.userID; body["requestorUserID"] = context.userProvider.user!.userID;
if (isBackUpRequest) { if (isBackUpRequest) {
body["assetId"] = device!.id; body["assetId"] = widget.workOrder!.asset!.id;
body["assetName"] = widget.workOrder!.assetNdModel!.name;
body["assetNumber"] = widget.workOrder!.asset!.assetNumber;
body["assetSerialNumber"] = widget.workOrder!.asset!.assetSerialNo;
body["model"] = widget.workOrder!.model?.name;
body["manufacturer"] = widget.workOrder!.manufacturer?.name;
body["cMWOItemId"] = widget.workOrderId; body["cMWOItemId"] = widget.workOrderId;
} }
bool isSuccess = await loanProvider.addLoanRequest(body); bool isSuccess = await loanProvider.addLoanRequest(body);

@ -1,4 +1,5 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
@ -8,9 +9,10 @@ import 'dart:convert';
class LoanProvider extends ChangeNotifier { class LoanProvider extends ChangeNotifier {
Future<bool> addLoanRequest(Map<String, dynamic> body) async { Future<bool> addLoanRequest(Map<String, dynamic> body) async {
try { try {
Response response = await ApiManager.instance.post(URLs.addLoan, body: body); Response response = await ApiManager.instance.post(URLs.addLoan, body: body, showToast: false);
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
// trafRequestDataModel = TrafRequestDataModel.fromJson(json.decode(response.body)["data"]); String message = (jsonDecode(response.body)["data"] ?? "") + " " + (jsonDecode(response.body)["message"] ?? "");
Fluttertoast.showToast(msg: message ?? "", toastLength: Toast.LENGTH_LONG);
return true; return true;
} }
return false; return false;

@ -9,6 +9,7 @@ import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/device/device_transfer.dart'; import 'package:test_sa/models/device/device_transfer.dart';
import 'package:test_sa/modules/cx_module/chat/chat_widget.dart';
import 'package:test_sa/views/widgets/images/files_list.dart'; import 'package:test_sa/views/widgets/images/files_list.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
@ -22,8 +23,9 @@ import 'update_device_transfer.dart';
class DeviceTransferDetails extends StatefulWidget { class DeviceTransferDetails extends StatefulWidget {
final DeviceTransfer model; final DeviceTransfer model;
final int moduleId;
const DeviceTransferDetails({Key? key, required this.model}) : super(key: key); const DeviceTransferDetails({Key? key, required this.model, required this.moduleId}) : super(key: key);
@override @override
State<DeviceTransferDetails> createState() => _DeviceTransferDetailsState(); State<DeviceTransferDetails> createState() => _DeviceTransferDetailsState();
@ -131,6 +133,7 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
] else ...[ ] else ...[
// sender card // sender card
_buildCard( _buildCard(
_model!,
isSender: true, isSender: true,
site: _model?.senderSiteName?.cleanupWhitespace.capitalizeFirstOfEach ?? "", site: _model?.senderSiteName?.cleanupWhitespace.capitalizeFirstOfEach ?? "",
dept: _model?.senderDepartmentName?.cleanupWhitespace.capitalizeFirstOfEach ?? "", dept: _model?.senderDepartmentName?.cleanupWhitespace.capitalizeFirstOfEach ?? "",
@ -150,6 +153,7 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
8.height, 8.height,
// receiver card // receiver card
_buildCard( _buildCard(
_model!,
isSender: false, isSender: false,
site: _model?.destSiteName?.cleanupWhitespace.capitalizeFirstOfEach ?? "", site: _model?.destSiteName?.cleanupWhitespace.capitalizeFirstOfEach ?? "",
dept: _model?.destDepartmentName?.cleanupWhitespace.capitalizeFirstOfEach ?? "", dept: _model?.destDepartmentName?.cleanupWhitespace.capitalizeFirstOfEach ?? "",
@ -215,7 +219,17 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
], ],
), ),
], ],
), ).expanded,
if (context.userProvider.isEngineer || context.userProvider.isNurse)
ChatWidget(
moduleId: widget.moduleId,
isShow: _model!.senderMachineStatusValue! != 4,
isReadOnly: _model!.senderMachineStatusValue! != 1,
requestId: widget.model.id!.toInt(),
assigneeEmployeeNumber: _model!.senderAssignedEmployeeNumber,
myLoginUserID: context.userProvider.user!.username!,
contactEmployeeINumber: _model!.assetTransferContactPersons!.first.employeeNumber,
),
if ((_userProvider!.user?.type == UsersTypes.engineer)) if ((_userProvider!.user?.type == UsersTypes.engineer))
if (isCurrentEngineerEligibleForEdit && isCurrentRequestEditAble) if (isCurrentEngineerEligibleForEdit && isCurrentRequestEditAble)
"edit".toSvgAsset(height: 40, width: 40).onPress(() async { "edit".toSvgAsset(height: 40, width: 40).onPress(() async {
@ -248,7 +262,8 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
).toShadowContainer(context); ).toShadowContainer(context);
} }
_buildCard({required String site, String? building, String? dept, String? floor, required String comment, required bool isSender, StatusLabel? statusLabel, String? assignTo}) { _buildCard(DeviceTransfer _deviceTransfer,
{required String site, String? building, String? dept, String? floor, required String comment, required bool isSender, StatusLabel? statusLabel, String? assignTo}) {
bool isCurrentEngineerEligibleForEdit = isSender ? _model?.senderAssignedEmployeeId == _userProvider!.user?.userID : _model?.receiverAssignedEmployeeId == _userProvider!.user?.userID; bool isCurrentEngineerEligibleForEdit = isSender ? _model?.senderAssignedEmployeeId == _userProvider!.user?.userID : _model?.receiverAssignedEmployeeId == _userProvider!.user?.userID;
bool isCurrentRequestClosed = isSender ? ((_model?.senderMachineStatusValue == 3)) : ((_model?.receiverMachineStatusValue == 3)); bool isCurrentRequestClosed = isSender ? ((_model?.senderMachineStatusValue == 3)) : ((_model?.receiverMachineStatusValue == 3));
@ -265,7 +280,17 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
if (statusLabel != null) 8.height, if (statusLabel != null) 8.height,
isSender ? context.translation.senderDetails.heading5(context) : context.translation.receiverDetails.heading5(context), isSender ? context.translation.senderDetails.heading5(context) : context.translation.receiverDetails.heading5(context),
], ],
), ).expanded,
if (context.userProvider.isEngineer || context.userProvider.isNurse)
ChatWidget(
moduleId: widget.moduleId,
isShow: (isSender ? _deviceTransfer.senderMachineStatusValue! : _deviceTransfer.receiverMachineStatusValue!) != 0,
isReadOnly: (isSender ? _deviceTransfer.senderMachineStatusValue! : _deviceTransfer.receiverMachineStatusValue) != 1,
requestId: widget.model.id!.toInt(),
assigneeEmployeeNumber: isSender ? _deviceTransfer.senderAssignedEmployeeNumber! : _deviceTransfer.receiverAssignedEmployeeNumber!,
myLoginUserID: context.userProvider.user!.username!,
contactEmployeeINumber: _deviceTransfer.assetTransferContactPersons!.first.employeeNumber,
),
if ((_userProvider!.user?.type == UsersTypes.engineer)) if ((_userProvider!.user?.type == UsersTypes.engineer))
if (isCurrentEngineerEligibleForEdit && !isCurrentRequestClosed) if (isCurrentEngineerEligibleForEdit && !isCurrentRequestClosed)
@ -273,7 +298,7 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
// ? (!(_model?.senderMachineStatusName?.toLowerCase()?.contains("close") ?? false) && !(_model?.senderMachineStatusName?.toLowerCase()?.contains("complete") ?? false)) // ? (!(_model?.senderMachineStatusName?.toLowerCase()?.contains("close") ?? false) && !(_model?.senderMachineStatusName?.toLowerCase()?.contains("complete") ?? false))
// : (!(_model?.receiverMachineStatusName?.toLowerCase()?.contains("close") ?? false) && !(_model?.receiverMachineStatusName?.toLowerCase()?.contains("complete") ?? false))) // : (!(_model?.receiverMachineStatusName?.toLowerCase()?.contains("close") ?? false) && !(_model?.receiverMachineStatusName?.toLowerCase()?.contains("complete") ?? false)))
// //
"edit".toSvgAsset(height: 48, width: 48).onPress(() async { "edit".toSvgAsset(height: 48, width: 48).onPress(() async {
bool isReload = (await Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdateDeviceTransfer(model: _model!, isSender: isSender)))) as bool; bool isReload = (await Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdateDeviceTransfer(model: _model!, isSender: isSender)))) as bool;
if (isReload ?? false) { if (isReload ?? false) {
setState(() {}); setState(() {});

@ -28,8 +28,9 @@ import 'update_gas_refill_request.dart';
class GasRefillDetailsPage extends StatefulWidget { class GasRefillDetailsPage extends StatefulWidget {
GasRefillModel model; GasRefillModel model;
String? priority, date; String? priority, date;
final int moduleId;
GasRefillDetailsPage({Key? key, this.priority, this.date, required this.model}) : super(key: key); GasRefillDetailsPage({Key? key, this.priority, this.date, required this.model, required this.moduleId}) : super(key: key);
@override @override
State<GasRefillDetailsPage> createState() => _GasRefillDetailsPageState(); State<GasRefillDetailsPage> createState() => _GasRefillDetailsPageState();
@ -59,21 +60,22 @@ class _GasRefillDetailsPageState extends State<GasRefillDetailsPage> {
appBar: DefaultAppBar( appBar: DefaultAppBar(
title: context.translation.gasRefillDetails, title: context.translation.gasRefillDetails,
actions: [ actions: [
// if (context.userProvider.isEngineer || context.userProvider.isNurse) if (context.userProvider.isEngineer || context.userProvider.isNurse)
// Selector<GasRefillProvider, GasRefillModel?>( Selector<GasRefillProvider, GasRefillModel?>(
// selector: (_, myModel) => myModel.gasRefillModel, // Selects only the userName selector: (_, myModel) => myModel.gasRefillModel, // Selects only the userName
// builder: (_, _gasRefillModel, __) { builder: (_, _gasRefillModel, __) {
// if (_gasRefillModel == null) return const SizedBox(); if (_gasRefillModel == null) return const SizedBox();
// return ChatWidget(
// moduleId: 2, return ChatWidget(
// isShow: _gasRefillModel.status!.value! == 1, moduleId: widget.moduleId,
// // isReadOnly: _gasRefillModel.status!.value! == 1, isShow: _gasRefillModel.status!.value! != 0,
// requestId: widget.model.id!.toInt(), isReadOnly: _gasRefillModel.status!.value! != 1,
// assigneeEmployeeNumber: _gasRefillModel.assignedEmployee!.name!, requestId: widget.model.id!.toInt(),
// myLoginUserID: context.userProvider.user!.username!, assigneeEmployeeNumber: _gasRefillModel.assignedEmployee?.employeeId!,
// contactEmployeeINumber: _gasRefillModel.gasRefillContactPerson!.first.employeeCode!, myLoginUserID: context.userProvider.user!.username!,
// ); contactEmployeeINumber: _gasRefillModel.gasRefillContactPerson!.first.employeeCode!,
// }) );
})
], ],
), ),
key: _scaffoldKey, key: _scaffoldKey,

@ -11,6 +11,7 @@ import 'package:test_sa/models/all_requests_and_count_model.dart';
import 'package:test_sa/models/new_models/task_request/task_request_model.dart'; import 'package:test_sa/models/new_models/task_request/task_request_model.dart';
import 'package:test_sa/modules/cm_module/cm_request_utils.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/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/modules/cx_module/chat/chat_widget.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/new_views/common_widgets/working_time_tile.dart'; import 'package:test_sa/new_views/common_widgets/working_time_tile.dart';
import 'package:test_sa/providers/task_request_provider/task_request_provider.dart'; import 'package:test_sa/providers/task_request_provider/task_request_provider.dart';
@ -29,8 +30,9 @@ class TaskRequestDetailsView extends StatefulWidget {
static const String id = "/task-request-detail"; static const String id = "/task-request-detail";
final int taskId; final int taskId;
final RequestsDetails? requestDetails; final RequestsDetails? requestDetails;
final int moduleId;
const TaskRequestDetailsView({Key? key, required this.taskId, this.requestDetails}) : super(key: key); const TaskRequestDetailsView({Key? key, required this.taskId, this.requestDetails, required this.moduleId}) : super(key: key);
@override @override
_TaskRequestDetailsViewState createState() { _TaskRequestDetailsViewState createState() {
@ -65,7 +67,27 @@ class _TaskRequestDetailsViewState extends State<TaskRequestDetailsView> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
userProvider ??= Provider.of<UserProvider>(context, listen: false); userProvider ??= Provider.of<UserProvider>(context, listen: false);
return Scaffold( return Scaffold(
appBar: DefaultAppBar(title: context.translation.taskRequest), appBar: DefaultAppBar(
title: context.translation.taskRequest,
actions: [
if (context.userProvider.isEngineer || context.userProvider.isNurse)
Selector<TaskRequestProvider, TaskData?>(
selector: (_, myModel) => myModel.taskRequestModel, // Selects only the userName
builder: (_, _taskReqModel, __) {
if (_taskReqModel == null) return const SizedBox();
return ChatWidget(
moduleId: widget.moduleId,
isShow: _taskReqModel.taskJobStatus!.value! != 1,
isReadOnly: _taskReqModel.taskJobStatus!.value! != 2,
requestId: widget.taskId.toInt(),
assigneeEmployeeNumber: _taskReqModel.assignedEngineer?.employeeId!,
myLoginUserID: context.userProvider.user!.username!,
contactEmployeeINumber: _taskReqModel.taskJobContactPersons!.first.user?.employeeId,
);
})
],
),
body: Consumer<TaskRequestProvider>(builder: (context, taskProvider, child) { body: Consumer<TaskRequestProvider>(builder: (context, taskProvider, child) {
TaskData? taskModel = taskProvider.taskRequestModel; TaskData? taskModel = taskProvider.taskRequestModel;
return taskProvider.isLoading return taskProvider.isLoading

@ -68,7 +68,8 @@ class TaskRequestItemView extends StatelessWidget {
Navigator.of(context).push(MaterialPageRoute( Navigator.of(context).push(MaterialPageRoute(
builder: (_) => TaskRequestDetailsView( builder: (_) => TaskRequestDetailsView(
taskId: requestData!.id!, taskId: requestData!.id!,
requestDetails: RequestsDetails(nameOfType: requestData?.nameOfType, status: requestData?.statusName, priority: requestData?.priorityName, date: requestData?.transactionDate), moduleId: requestData!.transactionNo!,
requestDetails: RequestsDetails(nameOfType: requestData?.nameOfType, status: requestData?.statusName, priority: requestData?.priorityName, date: requestData?.transactionDate, ),
))); )));
}); });
} }
@ -122,6 +123,7 @@ class TaskRequestItemView extends StatelessWidget {
Navigator.of(context).push(MaterialPageRoute( Navigator.of(context).push(MaterialPageRoute(
builder: (_) => TaskRequestDetailsView( builder: (_) => TaskRequestDetailsView(
taskId: requestDetails!.id!, taskId: requestDetails!.id!,
moduleId: requestDetails!.transactionType!,
requestDetails: requestDetails, requestDetails: requestDetails,
))); )));
}); });

@ -102,7 +102,9 @@ class _AllRequestsFilterPageState extends State<AllRequestsFilterPage> {
types = {"TRAF": 9}; types = {"TRAF": 9};
} }
if (context.userProvider.isQualityUser) { if (context.userProvider.isQualityUser) {
types = {'Equipment Internal Audit': 10, 'System Internal Audit': 11}; if (context.settingProvider.isUserFlowMedical) types = {'Recall and Alert': 7};
types['Equipment Internal Audit'] = 10;
types['System Internal Audit'] = 11;
} }
final statuses = { final statuses = {

@ -83,6 +83,7 @@ class _MyRequestsPageState extends State<MyRequestsPage> {
if (context.userProvider.isQualityUser) { if (context.userProvider.isQualityUser) {
requestsList = [ requestsList = [
Request(null, context.translation.allWorkOrder), Request(null, context.translation.allWorkOrder),
if (context.settingProvider.isUserFlowMedical) Request(7, 'Recall and Alert'),
Request(10, 'Equipment Internal Audit'), Request(10, 'Equipment Internal Audit'),
Request(11, 'System Internal Audit'), Request(11, 'System Internal Audit'),
]; ];

@ -77,7 +77,7 @@ class DeviceItemView extends StatelessWidget {
), ),
], ],
).toShadowContainer(context, withShadow: showShadow).onPress(() { ).toShadowContainer(context, withShadow: showShadow).onPress(() {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => DeviceTransferDetails(model: DeviceTransfer(id: requestData!.id!)))); Navigator.of(context).push(MaterialPageRoute(builder: (_) => DeviceTransferDetails(model: DeviceTransfer(id: requestData!.id!), moduleId: requestData!.transactionNo!)));
}); });
} }
@ -138,7 +138,11 @@ class DeviceItemView extends StatelessWidget {
), ),
], ],
).toShadowContainer(context, withShadow: showShadow).onPress(() { ).toShadowContainer(context, withShadow: showShadow).onPress(() {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => DeviceTransferDetails(model: DeviceTransfer(id: requestDetails!.id!)))); Navigator.of(context).push(MaterialPageRoute(
builder: (_) => DeviceTransferDetails(
model: DeviceTransfer(id: requestDetails!.id!),
moduleId: requestDetails!.transactionType!,
)));
}); });
} }

@ -74,6 +74,7 @@ class GasRefillItemView extends StatelessWidget {
builder: (_) => GasRefillDetailsPage( builder: (_) => GasRefillDetailsPage(
priority: requestData!.priorityName, priority: requestData!.priorityName,
date: requestData!.transactionDate!, date: requestData!.transactionDate!,
moduleId: requestData!.transactionNo!,
model: GasRefillModel(id: requestData!.id), model: GasRefillModel(id: requestData!.id),
), ),
), ),
@ -135,6 +136,7 @@ class GasRefillItemView extends StatelessWidget {
builder: (_) => GasRefillDetailsPage( builder: (_) => GasRefillDetailsPage(
priority: requestDetails!.priority!, priority: requestDetails!.priority!,
date: requestDetails!.date, date: requestDetails!.date,
moduleId: requestDetails!.transactionType!,
model: GasRefillModel(id: requestDetails!.id), model: GasRefillModel(id: requestDetails!.id),
), ),
), ),

@ -77,6 +77,7 @@ class TaskRequestProvider extends ChangeNotifier {
Future getTaskById({required int id, bool? showLoading = true}) async { Future getTaskById({required int id, bool? showLoading = true}) async {
try { try {
isLoading = showLoading ?? true; isLoading = showLoading ?? true;
taskRequestModel = null;
notifyListeners(); notifyListeners();
final response = await ApiManager.instance.get(URLs.getTaskByIdUrl + "?taskJobId=$id"); final response = await ApiManager.instance.get(URLs.getTaskByIdUrl + "?taskJobId=$id");
stateCode = response.statusCode; stateCode = response.statusCode;
@ -129,7 +130,6 @@ class TaskRequestProvider extends ChangeNotifier {
isLoading = false; isLoading = false;
notifyListeners(); notifyListeners();
if (stateCode == 200) { if (stateCode == 200) {
return true; return true;
} }
return false; return false;

@ -1,10 +1,15 @@
import 'dart:io'; import 'dart:io';
import 'package:ellipsized_text/ellipsized_text.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:open_file/open_file.dart'; import 'package:open_file/open_file.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.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/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/loaders/image_loader.dart'; import 'package:test_sa/views/widgets/loaders/image_loader.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@ -12,78 +17,180 @@ import 'package:url_launcher/url_launcher.dart';
class FilesList extends StatelessWidget { class FilesList extends StatelessWidget {
final List<String> images; final List<String> images;
final EdgeInsets? padding; final EdgeInsets? padding;
final bool showAsListView;
const FilesList({Key? key, this.images = const <String>[], this.padding}) : super(key: key); const FilesList({Key? key, this.images = const <String>[], this.padding, this.showAsListView = false}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GridView.builder( return showAsListView
padding: const EdgeInsets.only(top: 8, bottom: 8), ? ListView.separated(
physics: const NeverScrollableScrollPhysics(), shrinkWrap: true,
shrinkWrap: true, padding: const EdgeInsets.only(top: 8),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 6, mainAxisSpacing: 8, crossAxisSpacing: 8), physics: const NeverScrollableScrollPhysics(),
itemCount: images.length, itemBuilder: (cxt, itemIndex) {
itemBuilder: (context, itemIndex) { if (!images[itemIndex].contains(".")) {
if (!images[itemIndex].contains(".")) { return const Text("Bad\nFile");
return const Text("Bad\nFile"); }
} var isImage =
var isImage = images[itemIndex].split(".").last.toLowerCase() == "png" || images[itemIndex].split(".").last.toLowerCase() == "jpg" || images[itemIndex].split(".").last.toLowerCase() == "jpeg"; images[itemIndex].split(".").last.toLowerCase() == "png" || images[itemIndex].split(".").last.toLowerCase() == "jpg" || images[itemIndex].split(".").last.toLowerCase() == "jpeg";
var isPdf = images[itemIndex].split(".").last.toLowerCase() == "pdf"; var isPdf = images[itemIndex].split(".").last.toLowerCase() == "pdf";
var isExcel = images[itemIndex].split(".").last.toLowerCase() == "xlsx"; var isExcel = images[itemIndex].split(".").last.toLowerCase() == "xlsx";
return Container( return Row(
decoration: ShapeDecoration( children: [
color: Colors.white, Container(
shape: RoundedRectangleBorder( width: 48.toScreenWidth,
side: const BorderSide(width: 1, color: Color(0xFFEAF1F4)), height: 48.toScreenWidth,
borderRadius: BorderRadius.circular(8), decoration: ShapeDecoration(
), color: Colors.white,
), shape: RoundedRectangleBorder(
child: ClipRRect( side: const BorderSide(width: 1, color: Color(0xFFEAF1F4)),
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
child: (isImage ),
? (_isLocalUrl(images[itemIndex]) ),
? Image.file(File(images[itemIndex])) child: ClipRRect(
: ImageLoader( borderRadius: BorderRadius.circular(8),
url: images[itemIndex], child: (isImage
boxFit: BoxFit.cover, ? (_isLocalUrl(images[itemIndex])
height: 48, ? Image.file(File(images[itemIndex]))
width: 48, : ImageLoader(
)) url: images[itemIndex],
: Image.asset("assets/images/${isPdf ? "pdf" : isExcel ? "excel" : "doc"}.png")), boxFit: BoxFit.cover,
), height: 48,
).onPress(() async { width: 48,
if (isImage) { ))
Navigator.of(context).push( : Image.asset("assets/images/${isPdf ? "pdf" : isExcel ? "excel" : "doc"}.png")),
MaterialPageRoute(
builder: (_) => Scaffold(
body: SafeArea(
child: Stack(
children: [
// InteractiveViewer(child: Image(image: getImageObject(itemIndex))).center,
InteractiveViewer(child: getImageWidget(itemIndex)).center,
const ABackButton(),
],
), ),
), ),
), 8.width,
), Column(
); crossAxisAlignment: CrossAxisAlignment.start,
} else if (_isLocalUrl(images[itemIndex])) { children: [
OpenFile.open(images[itemIndex]); EllipsizedText(
} else { images[itemIndex].split("/").last,
try { style: AppTextStyles.heading6.copyWith(color: AppColor.black10),
if (!await launchUrl(Uri.parse(images[itemIndex]), mode: LaunchMode.externalApplication)) { type: EllipsisType.start, // or EllipsisType.middle
Fluttertoast.showToast(msg: "UnExpected Error with file."); ),
throw Exception('Could not launch '); 4.height,
RichText(
text: TextSpan(
text: 'Asset Guide | ',
style: AppTextStyles.bodyText.copyWith(color: AppColor.neutral120),
children: <TextSpan>[
TextSpan(
text: 'View',
recognizer: TapGestureRecognizer()
..onTap = () async {
if (isImage) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => Scaffold(
body: SafeArea(
child: Stack(
children: [
// InteractiveViewer(child: Image(image: getImageObject(itemIndex))).center,
InteractiveViewer(child: getImageWidget(itemIndex)).center,
const ABackButton(),
],
),
),
),
),
);
} else if (_isLocalUrl(images[itemIndex])) {
OpenFile.open(images[itemIndex]);
} else {
try {
if (!await launchUrl(Uri.parse(images[itemIndex]), mode: LaunchMode.externalApplication)) {
Fluttertoast.showToast(msg: "UnExpected Error with file.");
throw Exception('Could not launch ');
}
} catch (ex) {
Fluttertoast.showToast(msg: "No Viewer found.");
}
}
},
style: AppTextStyles.bodyText.copyWith(color: AppColor.primary10, decoration: TextDecoration.underline),
),
],
),
),
],
).expanded
],
);
},
separatorBuilder: (cxt, index) => 8.height,
itemCount: images.length)
: GridView.builder(
padding: const EdgeInsets.only(top: 8, bottom: 8),
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 6, mainAxisSpacing: 8, crossAxisSpacing: 8),
itemCount: images.length,
itemBuilder: (context, itemIndex) {
if (!images[itemIndex].contains(".")) {
return const Text("Bad\nFile");
} }
} catch (ex) { var isImage =
Fluttertoast.showToast(msg: "No Viewer found."); images[itemIndex].split(".").last.toLowerCase() == "png" || images[itemIndex].split(".").last.toLowerCase() == "jpg" || images[itemIndex].split(".").last.toLowerCase() == "jpeg";
} var isPdf = images[itemIndex].split(".").last.toLowerCase() == "pdf";
} var isExcel = images[itemIndex].split(".").last.toLowerCase() == "xlsx";
});
}, return Container(
); decoration: ShapeDecoration(
color: Colors.white,
shape: RoundedRectangleBorder(
side: const BorderSide(width: 1, color: Color(0xFFEAF1F4)),
borderRadius: BorderRadius.circular(8),
),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: (isImage
? (_isLocalUrl(images[itemIndex])
? Image.file(File(images[itemIndex]))
: ImageLoader(
url: images[itemIndex],
boxFit: BoxFit.cover,
height: 48,
width: 48,
))
: Image.asset("assets/images/${isPdf ? "pdf" : isExcel ? "excel" : "doc"}.png")),
),
).onPress(() async {
if (isImage) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => Scaffold(
body: SafeArea(
child: Stack(
children: [
// InteractiveViewer(child: Image(image: getImageObject(itemIndex))).center,
InteractiveViewer(child: getImageWidget(itemIndex)).center,
const ABackButton(),
],
),
),
),
),
);
} else if (_isLocalUrl(images[itemIndex])) {
OpenFile.open(images[itemIndex]);
} else {
try {
if (!await launchUrl(Uri.parse(images[itemIndex]), mode: LaunchMode.externalApplication)) {
Fluttertoast.showToast(msg: "UnExpected Error with file.");
throw Exception('Could not launch ');
}
} catch (ex) {
Fluttertoast.showToast(msg: "No Viewer found.");
}
}
});
},
);
// return ListView.separated( // return ListView.separated(
// padding: padding ?? EdgeInsets.symmetric(horizontal: 32 * AppStyle.getScaleFactor(context)), // padding: padding ?? EdgeInsets.symmetric(horizontal: 32 * AppStyle.getScaleFactor(context)),

@ -320,6 +320,7 @@ class AttachmentPicker extends StatefulWidget {
Color? buttonColor; Color? buttonColor;
final Function(List<GenericAttachmentModel>)? onChange; final Function(List<GenericAttachmentModel>)? onChange;
final bool showAsGrid; final bool showAsGrid;
final bool showAsListView;
AttachmentPicker( AttachmentPicker(
{Key? key, {Key? key,
@ -332,6 +333,7 @@ class AttachmentPicker extends StatefulWidget {
this.onlyImages = false, this.onlyImages = false,
this.onChange, this.onChange,
this.showAsGrid = false, this.showAsGrid = false,
this.showAsListView = false,
this.buttonColor}) this.buttonColor})
: super(key: key); : super(key: key);
@ -357,29 +359,54 @@ class _AttachmentPickerState extends State<AttachmentPicker> {
: onFilePicker), : onFilePicker),
16.height, 16.height,
if (widget.attachment.isNotEmpty) if (widget.attachment.isNotEmpty)
Wrap( widget.showAsListView
spacing: 8.toScreenWidth, ? ListView.separated(
children: List.generate( shrinkWrap: true,
widget.attachment.length, physics: const NeverScrollableScrollPhysics(),
(index) { padding: EdgeInsets.zero,
File image = File(widget.attachment[index].name!); itemBuilder: (cxt, index) {
return MultiFilesPickerItem( File image = File(widget.attachment[index].name!);
file: image, return MultiFilesPickerItem(
enabled: widget.enabled, file: image,
onRemoveTap: (image) { showAsListView: widget.showAsListView,
if (!widget.enabled) { enabled: widget.enabled,
return; onRemoveTap: (image) {
} if (!widget.enabled) {
widget.attachment.removeAt(index); return;
if (widget.onChange != null) { }
widget.onChange!(widget.attachment); widget.attachment.removeAt(index);
} if (widget.onChange != null) {
setState(() {}); widget.onChange!(widget.attachment);
}
setState(() {});
},
);
}, },
); separatorBuilder: (cxt, index) => 8.height,
}, itemCount: widget.attachment.length)
), : Wrap(
), spacing: 8.toScreenWidth,
children: List.generate(
widget.attachment.length,
(index) {
File image = File(widget.attachment[index].name!);
return MultiFilesPickerItem(
file: image,
enabled: widget.enabled,
onRemoveTap: (image) {
if (!widget.enabled) {
return;
}
widget.attachment.removeAt(index);
if (widget.onChange != null) {
widget.onChange!(widget.attachment);
}
setState(() {});
},
);
},
),
),
], ],
); );
} }
@ -402,11 +429,6 @@ class _AttachmentPickerState extends State<AttachmentPicker> {
} }
void showFileSourceSheet() async { void showFileSourceSheet() async {
// if (widget.attachment.length >= 5) {
// Fluttertoast.showToast(msg: context.translation.maxImagesNumberIs5);
// return;
// }
ImageSource source = (await showModalBottomSheet( ImageSource source = (await showModalBottomSheet(
context: context, context: context,
shape: const RoundedRectangleBorder( shape: const RoundedRectangleBorder(
@ -475,11 +497,6 @@ class _AttachmentPickerState extends State<AttachmentPicker> {
} }
onFilePicker() async { onFilePicker() async {
//TODO removed on request by Backend as they don't have anyissue with large number of files
// if (widget.attachment.length >= 5) {
// Fluttertoast.showToast(msg: context.translation.maxImagesNumberIs5);
// return;
// }
ImageSource? source = await showModalBottomSheet<ImageSource>( ImageSource? source = await showModalBottomSheet<ImageSource>(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {

@ -1,5 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:ellipsized_text/ellipsized_text.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:open_file/open_file.dart'; import 'package:open_file/open_file.dart';
@ -18,8 +20,16 @@ class MultiFilesPickerItem extends StatelessWidget {
final bool enabled; final bool enabled;
final Function(File) onRemoveTap; final Function(File) onRemoveTap;
final VoidCallback? onRemove; final VoidCallback? onRemove;
final bool showAsListView;
const MultiFilesPickerItem({Key? key, required this.file, required this.enabled, required this.onRemoveTap, this.onRemove}) : super(key: key); const MultiFilesPickerItem({
Key? key,
required this.file,
required this.enabled,
required this.onRemoveTap,
this.onRemove,
this.showAsListView = false,
}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -27,6 +37,96 @@ class MultiFilesPickerItem extends StatelessWidget {
bool isPdf = file.path.split(".").last.toLowerCase() == "pdf"; bool isPdf = file.path.split(".").last.toLowerCase() == "pdf";
bool isExcel = file.path.split(".").last.toLowerCase() == "xlsx"; bool isExcel = file.path.split(".").last.toLowerCase() == "xlsx";
if (showAsListView) {
return Row(
children: [
Container(
width: 48.toScreenWidth,
height: 48.toScreenWidth,
decoration: BoxDecoration(
color: AppColor.neutral90,
border: Border.all(width: 1, color: context.isDark ? AppColor.neutral30 : AppColor.neutral30),
image: DecorationImage(
image: getImage(isImage, isPdf, isExcel, file),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.circular(8),
),
),
8.width,
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Flexible(
child: EllipsizedText(
file.path.split("/").last,
style: AppTextStyles.bodyText.copyWith(color: AppColor.black10),
type: EllipsisType.start, // or EllipsisType.middle
),
),
8.width,
if (enabled)
InkWell(
child: "remove".toSvgAsset(width: 16),
onTap: () {
onRemoveTap(file);
if (onRemove != null) {
onRemove!();
}
},
)
],
),
4.height,
RichText(
text: TextSpan(
text: 'Asset Guide | ',
style: AppTextStyles.bodyText.copyWith(color: AppColor.neutral120),
children: <TextSpan>[
TextSpan(
text: 'View',
recognizer: TapGestureRecognizer()
..onTap = () async {
if (isImage) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => Scaffold(
appBar: const DefaultAppBar(),
body: SafeArea(
child: InteractiveViewer(
child: _isLocalUrl(file.path)
? Image.file(file)
: ImageLoader(
url: URLs.getFileUrl(file.path),
boxFit: BoxFit.cover,
),
).center,
),
),
),
);
} else if (_isLocalUrl(file.path)) {
OpenFile.open(file.path);
} else {
if (!await launchUrl(Uri.parse(URLs.getFileUrl(file.path)!), mode: LaunchMode.externalApplication)) {
Fluttertoast.showToast(msg: "UnExpected Error with file.");
throw Exception('Could not launch');
}
}
},
style: AppTextStyles.bodyText.copyWith(color: AppColor.primary10, decoration: TextDecoration.underline),
),
],
),
),
],
).expanded
],
);
}
return SizedBox( return SizedBox(
width: 60.toScreenWidth, width: 60.toScreenWidth,
height: 60.toScreenWidth, height: 60.toScreenWidth,

@ -265,6 +265,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.1.0"
ellipsized_text:
dependency: "direct main"
description:
name: ellipsized_text
sha256: d4d372c2baf8d4adfb2ca3728c1e5955d1683e75fae774b311d557ad13317105
url: "https://pub.dev"
source: hosted
version: "1.2.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:

@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.3.11+30 version: 1.4.0+31
environment: environment:
sdk: ">=3.5.0 <4.0.0" sdk: ">=3.5.0 <4.0.0"
@ -98,6 +98,7 @@ dependencies:
tree_view_flutter: ^1.0.2 tree_view_flutter: ^1.0.2
audio_waveforms: ^1.3.0 audio_waveforms: ^1.3.0
signalr_netcore: ^1.4.4 signalr_netcore: ^1.4.4
ellipsized_text: ^1.2.0
local_auth_darwin: any local_auth_darwin: any
dev_dependencies: dev_dependencies:

Loading…
Cancel
Save