Compare commits

...

4 Commits

@ -0,0 +1,3 @@
<svg width="17" height="20" viewBox="0 0 17 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.82353 1.94999C3.67937 1.94999 1.94118 3.69608 1.94118 5.84998V11.2125C1.94118 14.7126 4.76573 17.55 8.25 17.55C11.7343 17.55 14.5588 14.7126 14.5588 11.2125V9.75003C14.5588 9.21155 14.9934 8.77503 15.5294 8.77503C16.0655 8.77503 16.5 9.21155 16.5 9.75003V11.2125C16.5 15.7896 12.8063 19.5 8.25 19.5C3.69365 19.5 0 15.7896 0 11.2125V5.84998C0 2.61913 2.60728 0 5.82353 0C9.03978 0 11.6471 2.61913 11.6471 5.84998V11.2125C11.6471 13.0971 10.1261 14.625 8.25 14.625C6.37386 14.625 4.85294 13.0971 4.85294 11.2125V7.31248C4.85294 6.774 5.28749 6.33748 5.82353 6.33748C6.35957 6.33748 6.79412 6.774 6.79412 7.31248V11.2125C6.79412 12.0202 7.44594 12.675 8.25 12.675C9.05406 12.675 9.70588 12.0202 9.70588 11.2125V5.84998C9.70588 3.69608 7.96769 1.94999 5.82353 1.94999Z" fill="#3DA5E5"/>
</svg>

After

Width:  |  Height:  |  Size: 938 B

@ -300,6 +300,7 @@ class URLs {
static get getPentry => "$_baseUrl/return/pentry/details"; // get
static get updatePentry => "$_baseUrl/Visit/UpdateVisit"; // get
static get getPentryTaskStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=403"; // get
// get
static get getPentryVisitStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=402"; // get
static get getPentryStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=401"; // get
// contacts
@ -310,4 +311,18 @@ class URLs {
static get getSiteContactInfo => "$_baseUrl/AssetGroupSiteContactInfo"; // add
static get getDepartmentBasedOnSite => "$_baseUrl/TRAFDataSource/GetDepartmentBasedOnSite"; // add
//internal Audit
static get getInternalAuditEquipmentById => "$_baseUrl/InternalAuditEquipments/GetInternalAuditEquipmentById";
static get getInternalAuditSystemById => "$_baseUrl/InternalAuditSystems/GetInternalAuditSystemByIdV2";
static get getInternalAuditChecklist => "$_baseUrl/Lookups/GetLookup?lookupEnum=43";
static get getInternalAuditWoType => "$_baseUrl/Lookups/GetLookup?lookupEnum=2500";
static get getInternalAuditFindingType => "$_baseUrl/Lookups/GetLookup?lookupEnum=2502";
static get addOrUpdateEquipmentInternalAudit => "$_baseUrl/InternalAuditEquipments/AddOrUpdateAuditEquipment";
static get addOrUpdateInternalAuditSystem => "$_baseUrl/InternalAuditSystems/AddOrUpdateInternalAuditSystem";
static get getWoAutoComplete => "$_baseUrl/InternalAuditSystems/AutoCompleteAllWorkOrder";
static get updateAuditEquipmentsEngineer => "$_baseUrl/InternalAuditEquipments/UpdateAuditEquipmentsEngineer";
static get updateAuditSystemEngineer => "$_baseUrl/InternalAuditSystems/UpdateAuditSystemEngineer";
static get loadAllWorkOrderDetailsByID => "$_baseUrl/InternalAuditSystems/LoadAllWorkOrderDetailsByID";
}

@ -140,9 +140,8 @@ class AllRequestsProvider extends ChangeNotifier {
return list;
}
if (context.userProvider.isQualityUser) {
//TODO Need to replace with actual number..
// list = [10];
list = [1];
list = [10,11];
return list;
}

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/new_models/dashboard_detail.dart';
import 'package:test_sa/modules/internal_audit_module/pages/internal_audit_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/tm_module/tasks_wo/task_request_item_view.dart';
import 'package:test_sa/modules/traf_module/traf_request_item_view.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
@ -54,7 +54,9 @@ class RequestCategoryList extends StatelessWidget {
return TrafRequestItemView(requestData: request);
//TODO need to verify this ...
case 10:
return InternalAuditItemView(requestData: request);
return EquipmentInternalAuditItemView(requestData: request);
case 11:
return EquipmentInternalAuditItemView(requestData: request);
default:
return Container(
height: 100,

@ -29,10 +29,12 @@ import 'package:test_sa/controllers/providers/api/status_drop_down/report/servic
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_types_provider.dart';
import 'package:test_sa/modules/cm_module/service_request_detail_provider.dart';
import 'package:test_sa/modules/cm_module/views/nurse/create_new_request_view.dart';
import 'package:test_sa/modules/internal_audit_module/pages/create_equipment_internal_audit_form.dart';
import 'package:test_sa/modules/internal_audit_module/pages/create_system_internal_audit_form.dart';
import 'package:test_sa/modules/internal_audit_module/pages/equipment_internal_audit/create_equipment_internal_audit_form.dart';
import 'package:test_sa/modules/internal_audit_module/pages/system_internal_audit/create_system_internal_audit_form.dart';
import 'package:test_sa/modules/internal_audit_module/pages/system_internal_audit/update_system_internal_audit_page.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_finding_type_provider.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_provider.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_wo_type_provider.dart';
import 'package:test_sa/modules/tm_module/tasks_wo/create_task_view.dart';
import 'package:test_sa/modules/traf_module/create_traf_request_page.dart';
import 'package:test_sa/modules/traf_module/traf_request_provider.dart';
@ -102,7 +104,7 @@ import 'controllers/providers/api/gas_refill_comments.dart';
import 'controllers/providers/api/user_provider.dart';
import 'controllers/providers/settings/setting_provider.dart';
import 'dashboard_latest/dashboard_provider.dart';
import 'modules/internal_audit_module/pages/update_internal_audit_page.dart';
import 'modules/internal_audit_module/pages/equipment_internal_audit/update_equipment_internal_audit_page.dart';
import 'modules/internal_audit_module/provider/internal_audit_checklist_provider.dart';
import 'new_views/pages/gas_refill_request_form.dart';
import 'providers/lookups/classification_lookup_provider.dart';
@ -292,6 +294,7 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => CommentsProvider()),
ChangeNotifierProvider(create: (_) => GasRefillCommentsProvider()),
ChangeNotifierProvider(create: (_) => InternalAuditCheckListProvider()),
ChangeNotifierProvider(create: (_) => InternalAuditWoTypeProvider()),
ChangeNotifierProvider(create: (_) => InternalAuditProvider()),
ChangeNotifierProvider(create: (_) => InternalAuditFindingTypeProvider()),
@ -363,7 +366,8 @@ class MyApp extends StatelessWidget {
HelpCenterPage.id: (_) => const HelpCenterPage(),
CreateEquipmentInternalAuditForm.id: (_) => const CreateEquipmentInternalAuditForm(),
CreateSystemInternalAuditForm.id: (_) => const CreateSystemInternalAuditForm(),
UpdateInternalAuditPage.id: (_) => const UpdateInternalAuditPage(),
UpdateEquipmentInternalAuditPage.id: (_) => UpdateEquipmentInternalAuditPage(),
UpdateSystemInternalAuditPage.id: (_) => UpdateSystemInternalAuditPage(),
// SwipeSuccessView.routeName: (_) => const SwipeSuccessView(),
// SwipeHistoryView.routeName: (_) => const SwipeHistoryView(),
},

@ -31,11 +31,11 @@ class ActivityMaintenanceHelperModel {
WorkOrderAssignedEmployee? assignedEmployee;
SuppEngineerWorkOrders? supEngineer;
ActivityMaintenanceAssistantEmployees? modelAssistantEmployees;
List<AssistantEmployeesModel>? assistantEmployList=[];
List<AssistantEmployees>? assistantEmployees;
List<ActivityMaintenanceTimers>? activityMaintenanceTimers = [];
TimerModel? activityMaintenanceTimerModel = TimerModel();
TimerModel? activityTimePicker;
List<AssistantEmployeesModel>? assistantEmployList=[];
List<TimerModel>? timerModelList = [];
ActivityMaintenanceHelperModel(

@ -0,0 +1,53 @@
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_model.dart';
class EngineerData {
int? id;
String? debrief;
String? startTime;
String? endTime;
double? totalHours;
bool? isComplete;
int? statusId;
int? requestId;
List<InternalAuditAttachments>? attachments;
EngineerData({
this.id,
this.debrief,
this.startTime,
this.endTime,
this.totalHours,
this.isComplete,
this.statusId,
this.requestId,
this.attachments,
});
EngineerData.fromJson(Map<String, dynamic> json) {
id = json['id'];
debrief = json['debrief'];
startTime = json['startTime'];
endTime = json['endTime'];
totalHours = (json['totalHours'] as num?)?.toDouble();
isComplete = json['isComplete'];
statusId = json['statusId'];
requestId = json['requestId'];
attachments = json['attachments'] != null ? (json['attachments'] as List).map((e) => InternalAuditAttachments.fromJson(e)).toList() : [];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = {};
data['id'] = id;
data['debrief'] = debrief;
data['startTime'] = startTime;
data['endTime'] = endTime;
data['totalHours'] = totalHours;
data['isComplete'] = isComplete;
data['statusId'] = statusId;
data['requestId'] = requestId;
if (attachments != null) {
data['attachments'] = attachments!.map((e) => e.toJson()).toList();
}
return data;
}
}

@ -0,0 +1,300 @@
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/engineer_data_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_timer_model.dart';
class EquipmentInternalAuditDataModel {
int? id;
String? requestNo;
String? createdDate;
int? requestNoSequence;
Auditor? auditor;
Status? status;
Asset? asset;
AssignEmployee? assignEmployee;
dynamic manufacture;
String? remarks;
List<EquipmentsFinding>? equipmentsFindings;
List<InternalAuditAttachments>? attachments;
EngineerData? engineerData;
EquipmentInternalAuditDataModel({
this.id,
this.requestNo,
this.createdDate,
this.requestNoSequence,
this.auditor,
this.status,
this.asset,
this.assignEmployee,
this.manufacture,
this.remarks,
this.equipmentsFindings,
this.attachments,
this.engineerData,
});
EquipmentInternalAuditDataModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
requestNo = json['requestNo'];
createdDate = json['createdDate'];
requestNoSequence = json['requestNoSequence'];
auditor = json['auditor'] != null ? Auditor.fromJson(json['auditor']) : null;
status = json['status'] != null ? Status.fromJson(json['status']) : null;
asset = json['asset'] != null ? Asset.fromJson(json['asset']) : null;
assignEmployee = json['assignEmployee'] != null ? AssignEmployee.fromJson(json['assignEmployee']) : null;
manufacture = json['manufacture'];
remarks = json['remarks'];
if (json['equipmentsFindings'] != null) {
equipmentsFindings = <EquipmentsFinding>[];
json['equipmentsFindings'].forEach((v) {
equipmentsFindings!.add(EquipmentsFinding.fromJson(v));
});
}
attachments = json['attachments'] != null
? (json['attachments'] as List)
.map((e) => InternalAuditAttachments.fromJson(e))
.where((e) => e.name != null) // optional filter if you want to skip null names
.toList()
: [];
engineerData = json['engineerData'] != null ? EngineerData.fromJson(json['engineerData']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = {};
data['id'] = id;
data['requestNo'] = requestNo;
data['createdDate'] = createdDate;
data['requestNoSequence'] = requestNoSequence;
if (auditor != null) {
data['auditor'] = auditor!.toJson();
}
if (status != null) {
data['status'] = status!.toJson();
}
if (asset != null) {
data['asset'] = asset!.toJson();
}
if (assignEmployee != null) {
data['assignEmployee'] = assignEmployee!.toJson();
}
data['manufacture'] = manufacture;
data['remarks'] = remarks;
if (equipmentsFindings != null) {
data['equipmentsFindings'] =
equipmentsFindings!.map((v) => v.toJson()).toList();
}
data['attachments'] = attachments;
if (engineerData != null) data['engineerData'] = engineerData!.toJson();
return data;
}
}
class Auditor {
String? userId;
String? userName;
String? email;
String? employeeId;
int? languageId;
String? extensionNo;
String? phoneNumber;
bool? isActive;
Auditor({
this.userId,
this.userName,
this.email,
this.employeeId,
this.languageId,
this.extensionNo,
this.phoneNumber,
this.isActive,
});
Auditor.fromJson(Map<String, dynamic> json) {
userId = json['userId'];
userName = json['userName'];
email = json['email'];
employeeId = json['employeeId'];
languageId = json['languageId'];
extensionNo = json['extensionNo'];
phoneNumber = json['phoneNumber'];
isActive = json['isActive'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = {};
data['userId'] = userId;
data['userName'] = userName;
data['email'] = email;
data['employeeId'] = employeeId;
data['languageId'] = languageId;
data['extensionNo'] = extensionNo;
data['phoneNumber'] = phoneNumber;
data['isActive'] = isActive;
return data;
}
}
class Status {
int? id;
String? name;
int? value;
Status({this.id, this.name, this.value});
Status.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
value = json['value'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = {};
data['id'] = id;
data['name'] = name;
data['value'] = value;
return data;
}
}
class Asset {
int? id;
String? assetNumber;
String? assetSerialNo;
String? assetName;
String? modelName;
String? manufacturerName;
String? siteName;
int? siteId;
String? modelDefinition;
Asset({
this.id,
this.assetNumber,
this.assetSerialNo,
this.assetName,
this.modelName,
this.manufacturerName,
this.siteName,
this.siteId,
this.modelDefinition,
});
Asset.fromJson(Map<String, dynamic> json) {
id = json['id'];
assetNumber = json['assetNumber'];
assetSerialNo = json['assetSerialNo'];
assetName = json['assetName'];
modelName = json['modelName'];
manufacturerName = json['manufacturerName'];
siteName = json['siteName'];
siteId = json['siteId'];
modelDefinition = json['modelDefinition'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = {};
data['id'] = id;
data['assetNumber'] = assetNumber;
data['assetSerialNo'] = assetSerialNo;
data['assetName'] = assetName;
data['modelName'] = modelName;
data['manufacturerName'] = manufacturerName;
data['siteName'] = siteName;
data['siteId'] = siteId;
data['modelDefinition'] = modelDefinition;
return data;
}
}
class AssignEmployee {
String? userId;
String? userName;
String? email;
String? employeeId;
int? languageId;
String? extensionNo;
String? phoneNumber;
bool? isActive;
AssignEmployee({
this.userId,
this.userName,
this.email,
this.employeeId,
this.languageId,
this.extensionNo,
this.phoneNumber,
this.isActive,
});
AssignEmployee.fromJson(Map<String, dynamic> json) {
userId = json['userId'];
userName = json['userName'];
email = json['email'];
employeeId = json['employeeId'];
languageId = json['languageId'];
extensionNo = json['extensionNo'];
phoneNumber = json['phoneNumber'];
isActive = json['isActive'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = {};
data['userId'] = userId;
data['userName'] = userName;
data['email'] = email;
data['employeeId'] = employeeId;
data['languageId'] = languageId;
data['extensionNo'] = extensionNo;
data['phoneNumber'] = phoneNumber;
data['isActive'] = isActive;
return data;
}
}
class EquipmentsFinding {
int? id;
Finding? finding;
EquipmentsFinding({this.id, this.finding});
EquipmentsFinding.fromJson(Map<String, dynamic> json) {
id = json['id'];
finding = json['finding'] != null ? Finding.fromJson(json['finding']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = {};
data['id'] = id;
if (finding != null) {
data['finding'] = finding!.toJson();
}
return data;
}
}
class Finding {
int? id;
String? name;
int? value;
Finding({this.id, this.name, this.value});
Finding.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
value = json['value'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = {};
data['id'] = id;
data['name'] = name;
data['value'] = value;
return data;
}
}

@ -0,0 +1,41 @@
import 'package:flutter/src/widgets/framework.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/device/asset.dart';
import 'package:test_sa/models/fault_description.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_model.dart';
class EquipmentInternalAuditFormModel {
int? id=0;
String? deviceArName;
String? auditorId;
String? woOrderNo;
List<String>? devicePhotos;
List<Lookup> findings =[];
List<InternalAuditAttachments> attachments = [];
String? remarks;
Asset? device;
EquipmentInternalAuditFormModel({
this.id,
this.deviceArName,
this.auditorId,
this.devicePhotos,
this.woOrderNo,
this.remarks,
});
Map<String, dynamic> toJson() {
return {
'id': id??0,
'assetId': device?.id,
'auditorId': auditorId,
'findings': findings.map((e) => {'findingId': e.value}).toList(),
'attachments': attachments.map((e) => e.toJson()).toList(),
'remarks': remarks,
};
}
}

@ -0,0 +1,27 @@
import 'dart:developer';
class InternalAuditAttachments {
InternalAuditAttachments({this.id, this.originalName, this.name, this.createdBy});
int? id;
String? name;
String? originalName;
String? createdBy;
InternalAuditAttachments.fromJson(Map<String, dynamic> json) {
log('name is ${json['name']}');
id = json['id'];
name = (json['name'] != null && !json['name'].toString().startsWith('data:image/jpeg')) ? json['name'] : null;
originalName = json['originalName'];
createdBy = json['createdBy'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
data['originalName'] = originalName;
// data['createdBy'] = createdBy;
return data;
}
}

@ -1,29 +0,0 @@
import 'package:flutter/src/widgets/framework.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/device/asset.dart';
import 'package:test_sa/models/fault_description.dart';
import 'package:test_sa/models/lookup.dart';
class InternalAuditModel {
String? id;
int? deviceId;
String? deviceArName;
String? woOrderNo;
List<String>? devicePhotos;
Lookup? auditCheckList;
String? comments;
Asset? device;
InternalAuditModel({
this.id,
this.deviceArName,
this.devicePhotos,
this.deviceId,
this.woOrderNo,
this.comments,
});
}

@ -0,0 +1,35 @@
class InternalAuditTimerModel {
int? id;
String? startDate;
String? endDate;
double? totalWorkingHour;
String? comment;
InternalAuditTimerModel({
this.id,
this.startDate,
this.endDate,
this.totalWorkingHour,
this.comment,
});
factory InternalAuditTimerModel.fromJson(Map<String, dynamic> json) {
return InternalAuditTimerModel(
id: json['id'] as int?,
startDate: json['startDate'],
endDate: json['endDate'],
totalWorkingHour: (json['totalWorkingHours'] as num?)?.toDouble(),
comment: json['comment'] as String?,
);
}
Map<String, dynamic> toJson() {
return {
'id': id,
'startDate': startDate,
'endDate': endDate,
'totalWorkingHours': totalWorkingHour,
'comment': comment,
};
}
}

@ -0,0 +1,138 @@
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/modules/internal_audit_module/models/engineer_data_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/system_internal_audit_form_model.dart';
class SystemInternalAuditDataModel {
int? id;
int? assetGroupId;
String? requestNo;
int? requestNoSequence;
Auditor? auditor;
Lookup? status;
Lookup? findingType;
String? findingDescription;
Lookup? workOrderType;
Auditor? assignEmployee;
SystemAuditWorkOrderDetailModel? workOrderDetails; // Already exists as a separate model
String? createdBy;
String? createdDate;
String? modifiedBy;
String? modifiedDate;
List<InternalAuditAttachments>? attachments;
EngineerData? engineerData;
SystemInternalAuditDataModel({
this.id,
this.assetGroupId,
this.requestNo,
this.requestNoSequence,
this.auditor,
this.status,
this.findingType,
this.findingDescription,
this.workOrderType,
this.assignEmployee,
this.workOrderDetails,
this.createdBy,
this.createdDate,
this.modifiedBy,
this.modifiedDate,
this.attachments,
this.engineerData,
});
SystemInternalAuditDataModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
assetGroupId = json['assetGroupId'];
requestNo = json['requestNo'];
requestNoSequence = json['requestNoSequence'];
auditor = json['auditor'] != null ? Auditor.fromJson(json['auditor']) : null;
status = json['status'] != null ? Lookup.fromJson(json['status']) : null;
findingType = json['findingType'] != null ? Lookup.fromJson(json['findingType']) : null;
findingDescription = json['findingDescription'];
workOrderType = json['workOrderType'] != null ? Lookup.fromJson(json['workOrderType']) : null;
assignEmployee = json['assignEmployee'] != null ? Auditor.fromJson(json['assignEmployee']) : null;
workOrderDetails = json['workOrderDetails'] != null ? SystemAuditWorkOrderDetailModel.fromJson(json['workOrderDetails']) : null; // Keep as-is
createdBy = json['createdBy'];
createdDate = json['createdDate'];
modifiedBy = json['modifiedBy'];
modifiedDate = json['modifiedDate'];
attachments = json['attachments'] != null
? (json['attachments'] as List)
.map((e) => InternalAuditAttachments.fromJson(e))
.where((e) => e.name != null) // optional filter if you want to skip null names
.toList()
: [];
engineerData = json['engineerData'] != null ? EngineerData.fromJson(json['engineerData']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = {};
data['id'] = id;
data['assetGroupId'] = assetGroupId;
data['requestNo'] = requestNo;
data['requestNoSequence'] = requestNoSequence;
if (auditor != null) data['auditor'] = auditor!.toJson();
if (status != null) data['status'] = status!.toJson();
if (findingType != null) data['findingType'] = findingType!.toJson();
data['findingDescription'] = findingDescription;
if (workOrderType != null) data['workOrderType'] = workOrderType!.toJson();
if (assignEmployee != null) data['assignEmployee'] = assignEmployee!.toJson();
data['workOrderDetails'] = workOrderDetails;
data['createdBy'] = createdBy;
data['createdDate'] = createdDate;
data['modifiedBy'] = modifiedBy;
data['modifiedDate'] = modifiedDate;
if (engineerData != null) data['engineerData'] = engineerData!.toJson();
return data;
}
}
class Auditor {
String? userId;
String? userName;
String? email;
String? employeeId;
int? languageId;
String? extensionNo;
String? phoneNumber;
bool? isActive;
Auditor({
this.userId,
this.userName,
this.email,
this.employeeId,
this.languageId,
this.extensionNo,
this.phoneNumber,
this.isActive,
});
Auditor.fromJson(Map<String, dynamic> json) {
userId = json['userId'];
userName = json['userName'];
email = json['email'];
employeeId = json['employeeId'];
languageId = json['languageId'];
extensionNo = json['extensionNo'];
phoneNumber = json['phoneNumber'];
isActive = json['isActive'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = {};
data['userId'] = userId;
data['userName'] = userName;
data['email'] = email;
data['employeeId'] = employeeId;
data['languageId'] = languageId;
data['extensionNo'] = extensionNo;
data['phoneNumber'] = phoneNumber;
data['isActive'] = isActive;
return data;
}
}

@ -0,0 +1,202 @@
import 'dart:developer';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_model.dart';
class SystemInternalAuditFormModel {
int? id;
String? auditorId;
String? assignEmployeeId;
Lookup? findingType;
String? findingDescription;
Lookup? workOrderType;
int? correctiveMaintenanceId;
int? planPreventiveVisitId;
int? assetTransferId;
List<InternalAuditAttachments>? attachments = [];
int? taskJobId;
int? taskAlertJobId;
int? gasRefillId;
int? planRecurrentTaskId;
int? statusId;
SystemAuditWorkOrderDetailModel? workOrderDetailModel;
SystemInternalAuditFormModel({
this.id,
this.auditorId,
this.assignEmployeeId,
this.findingType,
this.findingDescription,
this.workOrderType,
this.correctiveMaintenanceId,
this.planPreventiveVisitId,
this.assetTransferId,
this.taskJobId,
this.taskAlertJobId,
this.gasRefillId,
this.planRecurrentTaskId,
this.workOrderDetailModel,
this.statusId,
this.attachments,
});
Map<String, dynamic> toJson() {
return {
// 'id': id,
'auditorId': auditorId,
'assignEmployeeId': assignEmployeeId,
'findingTypeId': findingType?.id,
'findingDescription': findingDescription,
'workOrderTypeId': workOrderType?.id,
'correctiveMaintenanceId': correctiveMaintenanceId,
'planPreventiveVisitId': planPreventiveVisitId,
'assetTransferId': assetTransferId,
'taskJobId': taskJobId,
'taskAlertJobId': taskAlertJobId,
'gasRefillId': gasRefillId,
'planRecurrentTaskId': planRecurrentTaskId,
'statusId': statusId,
'attachments': attachments?.map((e) => e.toJson()).toList(),
};
}
}
class WoAutoCompleteModel {
int? id;
String? workOrderNo;
String? displayName;
WoAutoCompleteModel({this.id, this.workOrderNo, this.displayName});
WoAutoCompleteModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
workOrderNo = json['workOrderNo'];
displayName = json['workOrderNo'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['woOrderNo'] = workOrderNo;
data['displayName'] = workOrderNo;
return data;
}
}
class SystemAuditWorkOrderDetailModel {
String? createdBy;
DateTime? createdDate;
String? modifiedBy;
DateTime? modifiedDate;
int? id;
String? workOrderNo;
String? woAssignedEngineer;
String? woAssetNo;
String? wosn;
String? woAssetName;
String? woModel;
String? woManufacturer;
String? woSite;
String? woDepartment;
String? wOPMScheduleDate;
String? wOPMActualVisitDate;
String? wOAssetTransferDestinationSite;
String? wOAssetTransferSenderEngineer;
String? wOAssetTransferReceiverEngineer;
String? wOTaskAlertJobImpactedStatus;
String? wOTaskAlertJobAcknowledgment;
String? wOGasRefillType;
String? wORecurrentTaskTaskType;
String? wORecurrentTaskPlanNo;
String? wORecurrentTaskPlanName;
String? wORecurrentTaskStatus;
SystemAuditWorkOrderDetailModel({
this.createdBy,
this.createdDate,
this.modifiedBy,
this.modifiedDate,
this.id,
this.workOrderNo,
this.woAssignedEngineer,
this.woAssetNo,
this.wosn,
this.woAssetName,
this.woModel,
this.woManufacturer,
this.woSite,
this.woDepartment,
this.wOPMScheduleDate,
this.wOPMActualVisitDate,
this.wOAssetTransferDestinationSite,
this.wOAssetTransferSenderEngineer,
this.wOAssetTransferReceiverEngineer,
this.wOTaskAlertJobImpactedStatus,
this.wOTaskAlertJobAcknowledgment,
this.wOGasRefillType,
this.wORecurrentTaskTaskType,
this.wORecurrentTaskPlanNo,
this.wORecurrentTaskPlanName,
this.wORecurrentTaskStatus,
});
SystemAuditWorkOrderDetailModel.fromJson(Map<String, dynamic> json) {
createdBy = json['createdBy'];
createdDate = json['createdDate'] != null ? DateTime.tryParse(json['createdDate']) : null;
modifiedBy = json['modifiedBy'];
modifiedDate = json['modifiedDate'] != null ? DateTime.tryParse(json['modifiedDate']) : null;
id = json['id'];
workOrderNo = json['workOrderNo'];
woAssignedEngineer = json['woAssignedEngineer'];
woAssetNo = json['woAssetNo'];
wosn = json['wosn'];
woAssetName = json['woAssetName'];
woModel = json['woModel'];
woManufacturer = json['woManufacturer'];
woSite = json['woSite'];
woDepartment = json['woDepartment'];
wOPMScheduleDate = json['wO_PM_ScheduleDate'];
wOPMActualVisitDate = json['wO_PM_ActualVisitDate'];
wOAssetTransferDestinationSite = json['wO_AssetTransfer_DestinationSite'];
wOAssetTransferSenderEngineer = json['wO_AssetTransfer_SenderEngineer'];
wOAssetTransferReceiverEngineer = json['wO_AssetTransfer_ReceiverEngineer'];
wOTaskAlertJobImpactedStatus = json['wO_TaskAlertJob_ImpactedStatus'];
wOTaskAlertJobAcknowledgment = json['wO_TaskAlertJob_Acknowledgment'];
wOGasRefillType = json['wO_GasRefill_Type'];
wORecurrentTaskTaskType = json['wO_RecurrentTask_TaskType'];
wORecurrentTaskPlanNo = json['wO_RecurrentTask_PlanNo'];
wORecurrentTaskPlanName = json['wO_RecurrentTask_PlanName'];
wORecurrentTaskStatus = json['wO_RecurrentTask_Status'];
}
Map<String, dynamic> toJson() {
return {
'createdBy': createdBy,
'createdDate': createdDate?.toIso8601String(),
'modifiedBy': modifiedBy,
'modifiedDate': modifiedDate?.toIso8601String(),
'id': id,
'workOrderNo': workOrderNo,
'woAssignedEngineer': woAssignedEngineer,
'woAssetNo': woAssetNo,
'wosn': wosn,
'woAssetName': woAssetName,
'woModel': woModel,
'woManufacturer': woManufacturer,
'woSite': woSite,
'woDepartment': woDepartment,
'wO_PM_ScheduleDate': wOPMScheduleDate,
'wO_PM_ActualVisitDate': wOPMActualVisitDate,
'wO_AssetTransfer_DestinationSite': wOAssetTransferDestinationSite,
'wO_AssetTransfer_SenderEngineer': wOAssetTransferSenderEngineer,
'wO_AssetTransfer_ReceiverEngineer': wOAssetTransferReceiverEngineer,
'wO_TaskAlertJob_ImpactedStatus': wOTaskAlertJobImpactedStatus,
'wO_TaskAlertJob_Acknowledgment': wOTaskAlertJobAcknowledgment,
'wO_GasRefill_Type': wOGasRefillType,
'wO_RecurrentTask_TaskType': wORecurrentTaskTaskType,
'wO_RecurrentTask_PlanNo': wORecurrentTaskPlanNo,
'wO_RecurrentTask_PlanName': wORecurrentTaskPlanName,
'wO_RecurrentTask_Status': wORecurrentTaskStatus,
};
}
}

@ -0,0 +1,61 @@
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_timer_model.dart';
class AuditFormModel {
int? id;
String? createdDate;
int? requestId;
String? debrief;
DateTime? startTime;
DateTime? endTime;
double? totalHours;
List<InternalAuditAttachments>? attachments;
bool? isComplete;
TimerModel? auditTimerModel = TimerModel();
List<InternalAuditTimerModel>? auditTimers = [];
TimerModel? auditTimePicker;
List<TimerModel>? timerModelList = [];
AuditFormModel(
{this.id,
this.requestId,
this.debrief,
this.startTime,
this.endTime,
this.totalHours,
this.createdDate,
this.attachments,
this.isComplete,
this.auditTimerModel,
this.timerModelList,
this.auditTimePicker,
this.auditTimers});
AuditFormModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
requestId = json['requestId'];
debrief = json['debrief'];
startTime = json['startTime'] != null ? DateTime.tryParse(json['startTime']) : null;
endTime = json['endTime'] != null ? DateTime.tryParse(json['endTime']) : null;
totalHours = json['totalHours']?.toDouble();
if (json['attachments'] != null) {
attachments = (json['attachments'] as List).map((e) => InternalAuditAttachments.fromJson(e)).toList();
}
isComplete = json['isComplete'];
}
Map<String, dynamic> toJson() {
return {
'id': id,
'requestId': requestId,
'debrief': debrief,
'startTime': startTime?.toIso8601String(),
'endTime': endTime?.toIso8601String(),
// 'auditTimer': auditTimers,
'totalHours': totalHours,
'attachments': attachments?.map((e) => e.toJson()).toList(),
'isComplete': isComplete,
};
}
}

@ -9,24 +9,24 @@ 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/helper_data_models/workorder/work_order_helper_models.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/modules/cm_module/utilities/service_request_utils.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/equipment_internal_audit_form_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_model.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_checklist_provider.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_provider.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/new_views/common_widgets/multiple_item_drop_down_menu.dart';
import 'package:test_sa/views/widgets/equipment/asset_picker.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import '../../../../../../new_views/common_widgets/default_app_bar.dart';
class CreateEquipmentInternalAuditForm extends StatefulWidget {
static const String id = "/create-internal-audit-view";
static const String id = "/create-equipment-internal-audit-form";
const CreateEquipmentInternalAuditForm({Key? key}) : super(key: key);
@ -36,10 +36,11 @@ class CreateEquipmentInternalAuditForm extends StatefulWidget {
class _CreateEquipmentInternalAuditFormState extends State<CreateEquipmentInternalAuditForm> with TickerProviderStateMixin {
late TextEditingController _commentController;
final InternalAuditModel _internalAuditModel = InternalAuditModel();
final List<GenericAttachmentModel> _deviceImages = [];
final EquipmentInternalAuditFormModel _equipmentinternalAuditModel = EquipmentInternalAuditFormModel();
final List<GenericAttachmentModel> _attachments = [];
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
FocusNode auditCheckListNode = FocusNode();
@override
void initState() {
@ -68,28 +69,27 @@ class _CreateEquipmentInternalAuditFormState extends State<CreateEquipmentIntern
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AssetPicker(
device: _internalAuditModel.device,
device: _equipmentinternalAuditModel.device,
borderColor: AppColor.black20,
buttonColor: AppColor.white936,
onPick: (asset) async {
_internalAuditModel.device = asset;
_equipmentinternalAuditModel.device = asset;
setState(() {});
},
),
16.height,
SingleItemDropDownMenu<Lookup, InternalAuditCheckListProvider>(
//TODO need to check layout issue...
MultipleItemDropDownMenu<Lookup, InternalAuditCheckListProvider>(
context: context,
height: 56.toScreenHeight,
title: 'Internal Audit Checklist'.addTranslation,
showShadow: false,
initialValue: _internalAuditModel.auditCheckList,
backgroundColor: AppColor.fieldBgColor(context),
showAsBottomSheet: true,
onSelect: (status) {
if (status != null) {
_internalAuditModel.auditCheckList = status;
setState(() {});
}
backgroundColor: AppColor.neutral100,
showShadow: false,
showCancel: true,
requestById: context.userProvider.user?.clientId,
title: 'Internal Audit Checklist'.addTranslation,
initialValue: _equipmentinternalAuditModel.findings,
onSelect: (value) {
_equipmentinternalAuditModel.findings = value ?? [];
},
),
16.height,
@ -100,15 +100,18 @@ class _CreateEquipmentInternalAuditFormState extends State<CreateEquipmentIntern
alignLabelWithHint: true,
textInputType: TextInputType.multiline,
showShadow: false,
onSaved: (text) {},
onSaved: (value) {
_equipmentinternalAuditModel.remarks = value;
},
),
16.height,
AttachmentPicker(
label: context.translation.attachments,
attachment: _deviceImages,
attachment: _attachments,
buttonColor: AppColor.primary10,
onlyImages: false,
buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.primary10),
onChange: (value) {},
buttonIcon: 'attachment_icon'.toSvgAsset(color: AppColor.primary10),
),
],
).toShadowContainer(context),
@ -127,12 +130,18 @@ class _CreateEquipmentInternalAuditFormState extends State<CreateEquipmentIntern
InternalAuditProvider internalAuditProvider = Provider.of<InternalAuditProvider>(context, listen: false);
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
List<WorkOrderAttachments> attachement = [];
for (var item in _deviceImages) {
_equipmentinternalAuditModel.attachments = [];
for (var item in _attachments) {
String fileName = ServiceRequestUtils.isLocalUrl(item.name ?? '') ? ("${item.name ?? ''.split("/").last}|${base64Encode(File(item.name ?? '').readAsBytesSync())}") : item.name ?? '';
// attachement.add(WorkOrderAttachments(id: 0, name: fileName));
_equipmentinternalAuditModel.attachments.add(InternalAuditAttachments(id: item.id, name: fileName));
}
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
_equipmentinternalAuditModel.auditorId = context.userProvider.user?.userID;
bool status = await internalAuditProvider.addEquipmentInternalAudit(context: context, request: _equipmentinternalAuditModel);
Navigator.pop(context);
if(status){
Navigator.pop(context);
}
}
}
}

@ -2,41 +2,61 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/urls.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/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/modules/internal_audit_module/pages/update_internal_audit_page.dart';
import 'package:test_sa/modules/internal_audit_module/models/equipment_internal_audit_data_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_model.dart';
import 'package:test_sa/modules/internal_audit_module/pages/equipment_internal_audit/update_equipment_internal_audit_page.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_provider.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.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/no_data_found.dart';
class InternalAuditDetailPage extends StatefulWidget {
class EquipmentInternalAuditDetailPage extends StatefulWidget {
static const String id = "/details-internal-audit";
final int auditId;
InternalAuditDetailPage({Key? key, required this.auditId}) : super(key: key);
const EquipmentInternalAuditDetailPage({Key? key, required this.auditId}) : super(key: key);
@override
_InternalAuditDetailPageState createState() {
return _InternalAuditDetailPageState();
_EquipmentInternalAuditDetailPageState createState() {
return _EquipmentInternalAuditDetailPageState();
}
}
class _InternalAuditDetailPageState extends State<InternalAuditDetailPage> {
class _EquipmentInternalAuditDetailPageState extends State<EquipmentInternalAuditDetailPage> {
bool isWoType = true;
EquipmentInternalAuditDataModel? model;
late InternalAuditProvider _internalAuditProvider;
List<InternalAuditAttachments> allAttachments = [];
@override
void initState() {
super.initState();
//TODO need to get and assign data .
// Provider.of<InternalAuditProvider>(context, listen: false).getInternalAuditById(widget.auditId);
_internalAuditProvider = Provider.of<InternalAuditProvider>(context, listen: false);
WidgetsBinding.instance.addPostFrameCallback((_) {
getAuditData();
});
}
Future<void> getAuditData() async {
model = await _internalAuditProvider.getEquipmentInternalAuditById(widget.auditId);
allAttachments.clear();
allAttachments = [
...(model?.attachments ?? []),
...(model?.engineerData?.attachments ?? []),
];
}
@override
@ -53,6 +73,7 @@ class _InternalAuditDetailPageState extends State<InternalAuditDetailPage> {
selector: (_, provider) => provider.isLoading,
builder: (_, isLoading, __) {
if (isLoading) return const ALoading();
if (model == null) return NoDataFound(message: context.translation.noDataFound).center;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
@ -61,30 +82,24 @@ class _InternalAuditDetailPageState extends State<InternalAuditDetailPage> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
assetInformation(),
assetDetails(),
8.height,
isWoType ? workOrderInformation() : requestDetails(),
requestDetails(),
8.height,
//TODO need to check for comments
// if (model.comment?.isNotEmpty ?? false) ...[
const Divider().defaultStyle(context),
Text(
"Comments".addTranslation,
style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
// model.comment!.bodyText(context),
// 8.height,
// ],
//TODO need to check for attachments
// if ( _model.attachment.isNotEmpty) ...[
const Divider().defaultStyle(context),
Text(
"Attachments".addTranslation,
style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
8.height,
// FilesList(images: _model.attachment?.map((e) => URLs.getFileUrl(e.attachmentName ?? '') ?? '').toList() ?? []),
// ],
if (model?.remarks?.isNotEmpty ?? false) ...[
const Divider().defaultStyle(context),
model!.remarks!.bodyText(context),
8.height,
],
if (allAttachments.isNotEmpty) ...[
const Divider().defaultStyle(context),
Text(
"Attachments".addTranslation,
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
8.height,
FilesList(images: allAttachments.map((e) => URLs.getFileUrl(e.name ?? '') ?? '').toList() ?? []),
],
],
).paddingAll(0).toShadowContainer(context),
).expanded,
@ -94,8 +109,17 @@ class _InternalAuditDetailPageState extends State<InternalAuditDetailPage> {
child: AppFilledButton(
buttonColor: AppColor.primary10,
label: "Update",
onPressed: () {
Navigator.pushNamed(context, UpdateInternalAuditPage.id);
onPressed: () async {
final result = await Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => UpdateEquipmentInternalAuditPage(model: model),
),
);
if (result == true) {
await getAuditData();
setState(() {}); // refresh UI with new model
}
// Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdateEquipmentInternalAuditPage(model: model)));
}),
),
],
@ -136,13 +160,18 @@ class _InternalAuditDetailPageState extends State<InternalAuditDetailPage> {
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
6.height,
checklistWidget(value: 'Asset Tag'.addTranslation),
checklistWidget(value: 'Expired PM Tag'.addTranslation),
if (model != null && model!.equipmentsFindings != null && model!.equipmentsFindings!.isNotEmpty)
...model!.equipmentsFindings!.map((item) {
final findingName = item.finding?.name ?? 'Unknown';
return checklistWidget(value: findingName.addTranslation);
}).toList()
else
Text('No findings available'.addTranslation),
],
);
}
Widget assetInformation() {
Widget assetDetails() {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
@ -152,10 +181,10 @@ class _InternalAuditDetailPageState extends State<InternalAuditDetailPage> {
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
6.height,
'${context.translation.assetName}: ${'-'}'.bodyText(context),
'${context.translation.assetNo}: ${'-'}'.bodyText(context),
'${context.translation.manufacture}: ${'-'}'.bodyText(context),
'${context.translation.model}: ${'-'}'.bodyText(context),
'${context.translation.assetName}: ${model?.asset?.assetName ?? '-'}'.bodyText(context),
'${context.translation.assetNo}: ${model?.asset?.assetNumber ?? '-'}'.bodyText(context),
'${context.translation.manufacture}: ${model?.asset?.manufacturerName ?? '-'}'.bodyText(context),
'${context.translation.model}: ${model?.asset?.modelName ?? '-'}'.bodyText(context),
],
);
}

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
@ -6,16 +8,16 @@ 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/internal_audit_module/pages/internal_audit_detail_page.dart';
import 'package:test_sa/modules/internal_audit_module/pages/equipment_internal_audit/equipment_internal_audit_detail_page.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart';
class InternalAuditItemView extends StatelessWidget {
class EquipmentInternalAuditItemView extends StatelessWidget {
final Data? requestData;
final RequestsDetails? requestDetails;
final bool showShadow;
const InternalAuditItemView({Key? key, this.requestData, this.requestDetails, this.showShadow = true}) : super(key: key);
const EquipmentInternalAuditItemView({Key? key, this.requestData, this.requestDetails, this.showShadow = true}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -41,9 +43,8 @@ class InternalAuditItemView extends StatelessWidget {
],
),
8.height,
// (requestData?.typeTransaction ?? "Internal Audit Request").heading5(context),
("Internal Audit Request").heading5(context),
// infoWidget(label: context.translation.requestType, value: requestData?.requestTypeName, context: context),
(requestData?.typeTransaction ?? "Internal Audit Request").heading5(context),
infoWidget(label: context.translation.assetNumber, value: requestData?.assetNumber, context: context),
8.height,
Row(
@ -59,7 +60,7 @@ class InternalAuditItemView extends StatelessWidget {
),
],
).toShadowContainer(context, withShadow: showShadow).onPress(() async {
Navigator.push(context, MaterialPageRoute(builder: (context) => InternalAuditDetailPage(auditId: requestDetails!.id!)));
Navigator.push(context, MaterialPageRoute(builder: (context) => EquipmentInternalAuditDetailPage(auditId: requestDetails!.id!)));
});
}
return Column(
@ -82,10 +83,11 @@ class InternalAuditItemView extends StatelessWidget {
],
),
8.height,
// (requestDetails?.nameOfType ?? "Internal Audit Request").heading5(context),
("Internal Audit Request").heading5(context),
(requestDetails?.nameOfType ?? "Internal Audit Request").heading5(context),
8.height,
// infoWidget(label: context.translation.site, value: requestDetails!.site, 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.model, value: requestDetails!.model, context: context),
8.height,
Row(
mainAxisSize: MainAxisSize.min,
@ -100,7 +102,7 @@ class InternalAuditItemView extends StatelessWidget {
),
],
).toShadowContainer(context, withShadow: showShadow).onPress(() async {
Navigator.push(context, MaterialPageRoute(builder: (context) => InternalAuditDetailPage(auditId: requestDetails!.id!)));
Navigator.push(context, MaterialPageRoute(builder: (context) => EquipmentInternalAuditDetailPage(auditId: requestDetails!.id!)));
});
}

@ -0,0 +1,321 @@
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/api_manager.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/timer_model.dart';
import 'package:test_sa/modules/cm_module/utilities/service_request_utils.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_timer_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/update_audit_form_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/equipment_internal_audit_data_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_model.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_provider.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
import 'package:test_sa/new_views/common_widgets/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/working_time_tile.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/timer/app_timer.dart';
import 'package:test_sa/views/widgets/total_working_time_detail_bottomsheet.dart';
class UpdateEquipmentInternalAuditPage extends StatefulWidget {
static const String id = "update-equipment-internal-audit";
EquipmentInternalAuditDataModel? model;
UpdateEquipmentInternalAuditPage({Key? key, this.model}) : super(key: key);
@override
State<UpdateEquipmentInternalAuditPage> createState() => _UpdateEquipmentInternalAuditPageState();
}
class _UpdateEquipmentInternalAuditPageState extends State<UpdateEquipmentInternalAuditPage> {
final bool _isLoading = false;
double totalWorkingHours = 0.0;
AuditFormModel formModel = AuditFormModel();
final TextEditingController _workingHoursController = TextEditingController();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
List<GenericAttachmentModel> _attachments = [];
//TODO need to check if it's needed or not..
List<TimerHistoryModel> timerList = [];
@override
void initState() {
populateForm();
super.initState();
}
void populateForm() {
formModel.requestId = widget.model?.id;
formModel.id = widget.model?.id;
_attachments = widget.model?.engineerData?.attachments?.map((e) => GenericAttachmentModel(id: e.id?.toInt() ?? 0, name: e.name!)).toList() ?? [];
calculateWorkingTime();
}
void calculateWorkingTime() {
final helperModel = formModel;
final timers = helperModel.auditTimers ?? [];
totalWorkingHours = timers.fold<double>(0.0, (sum, item) {
if (item.startDate == null || item.endDate == null) return sum;
try {
final start = DateTime.parse(item.startDate!);
final end = DateTime.parse(item.endDate!);
final diffInHours = end.difference(start).inSeconds / 3600.0; // convert to hours
return sum + diffInHours;
} catch (_) {
return sum;
}
});
timerList = timers.map((e) {
return TimerHistoryModel(
id: e.id,
startTime: e.startDate,
endTime: e.endDate,
workingHours: e.startDate,
);
}).toList();
}
_onSubmit(BuildContext context) async {
bool isTimerPickerEnable = ApiManager.instance.assetGroup?.enabledEngineerTimer ?? false;
InternalAuditProvider provider = Provider.of<InternalAuditProvider>(context, listen: false);
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
formModel.auditTimers ??= [];
if (formModel.auditTimePicker != null) {
int durationInSecond = formModel.auditTimePicker!.endAt!.difference(formModel.auditTimePicker!.startAt!).inSeconds;
formModel.auditTimers?.add(
InternalAuditTimerModel(
id: 0,
startDate: formModel.auditTimePicker!.startAt!.toIso8601String(), // Handle potential null
endDate: formModel.auditTimePicker!.endAt?.toIso8601String(), // Handle potential null
totalWorkingHour: ((durationInSecond) / 60 / 60),
),
);
}
formModel.timerModelList?.forEach((timer) {
int durationInSecond = timer.endAt!.difference(timer.startAt!).inSeconds;
formModel.auditTimers?.add(
InternalAuditTimerModel(
id: 0,
startDate: timer.startAt!.toIso8601String(), // Handle potential null
endDate: timer.endAt?.toIso8601String(), // Handle potential null
totalWorkingHour: ((durationInSecond) / 60 / 60),
),
);
});
_formKey.currentState!.save();
formModel.attachments = [];
for (var item in _attachments) {
String fileName = ServiceRequestUtils.isLocalUrl(item.name ?? '') ? ("${item.name?.split("/").last}|${base64Encode(File(item.name ?? '').readAsBytesSync())}") : item.name ?? '';
formModel.attachments!.add(
InternalAuditAttachments(
id: item.id,
originalName: fileName,
name: fileName,
),
);
}
final success = await provider.updateEquipmentInternalAudit(model: formModel);
Navigator.pop(context);
if (formModel.isComplete == true) {
//Navigate to List screen.
} else if (formModel.isComplete == false) {
//Navigate to Detail screen.
if (success) {
Navigator.of(context).pop(true);
} else {
Fluttertoast.showToast(msg: 'Failed to update');
}
}
}
@override
void dispose() {
_workingHoursController.dispose();
super.dispose();
}
void updateTimer({TimerModel? timer}) {
if (timer?.startAt != null && timer?.endAt != null) {
final start = timer!.startAt!;
final end = timer.endAt!;
final difference = end.difference(start);
final totalHours = difference.inSeconds / 3600.0;
formModel.startTime = start;
formModel.endTime = end;
formModel.totalHours = totalHours;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: DefaultAppBar(
title: 'Update Information'.addTranslation,
onWillPopScope: () {
formModel.isComplete = false;
_onSubmit(context);
},
),
key: _scaffoldKey,
body: Form(
key: _formKey,
child: LoadingManager(
isLoading: _isLoading,
isFailedLoading: false,
stateCode: 200,
onRefresh: () async {},
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
8.height,
AppTextFormField(
labelText: 'Debrief'.addTranslation,
textInputType: TextInputType.multiline,
hintStyle: TextStyle(color: context.isDark ? AppColor.white10 : AppColor.black10),
labelStyle: TextStyle(color: context.isDark ? AppColor.white10 : AppColor.black10),
alignLabelWithHint: true,
initialValue: formModel.debrief,
backgroundColor: AppColor.fieldBgColor(context),
showShadow: false,
onSaved: (value) {
formModel.debrief = value;
},
),
8.height,
_timerWidget(context, totalWorkingHours),
16.height,
AttachmentPicker(
label: 'Upload Attachment',
attachment: _attachments,
buttonColor: AppColor.primary10,
onlyImages: false,
buttonIcon: 'attachment_icon'.toSvgAsset(
color: AppColor.primary10,
),
),
8.height,
],
).toShadowContainer(context),
).expanded,
FooterActionButton.footerContainer(
context: context,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
AppFilledButton(
label: context.translation.save,
buttonColor: context.isDark ? AppColor.neutral70 : AppColor.white60,
textColor: context.isDark ? AppColor.white10 : AppColor.black10,
onPressed: () {
formModel.isComplete = false;
_onSubmit(context);
}).expanded,
12.width,
AppFilledButton(
label: context.translation.complete,
buttonColor: AppColor.primary10,
onPressed: () {
formModel.isComplete = true;
_onSubmit(context);
}).expanded,
],
),
),
],
)),
),
).handlePopScope(
cxt: context,
onSave: () {
formModel.isComplete = false;
_onSubmit(context);
});
}
Widget _timerWidget(BuildContext context, double totalWorkingHours) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
//TODO multiple timer ..
// AppTimer(
// label: context.translation.timer,
// timer: formModel.auditTimerModel,
// // enabled: enableTimer,
// pickerTimer: formModel.auditTimePicker,
// pickerFromDate: DateTime.tryParse(widget.model?.createdDate ?? ''),
// onPick: (time) {
// formModel.auditTimePicker = time;
// setState(() {});
// log('Time picker start ${formModel.auditTimePicker?.startAt}');
// log('Time picker end ${formModel.auditTimePicker?.endAt}');
// },
// timerProgress: (isRunning) {},
// onChange: (timer) async {
// formModel.auditTimerModel = timer;
// log('start ${formModel.auditTimerModel?.startAt}');
// log('end ${formModel.auditTimerModel?.endAt}');
// if (timer.startAt != null && timer.endAt != null) {
// formModel.timerModelList = formModel.timerModelList ?? [];
// formModel.timerModelList!.add(timer);
// }
// setState(() {});
// log('list length ${formModel.timerModelList?.length}');
// return true;
// },
// ),
AppTimer(
label: context.translation.workingHours,
timer: formModel.auditTimerModel,
pickerFromDate: DateTime.tryParse(widget.model?.createdDate ?? ''),
pickerTimer: formModel.auditTimePicker,
onPick: (timer) {
updateTimer(timer: timer);
},
width: double.infinity,
decoration: BoxDecoration(
color: AppColor.fieldBgColor(context),
borderRadius: BorderRadius.circular(10),
),
timerProgress: (isRunning) {},
onChange: (timer) async {
updateTimer(timer: timer);
log('here onChange ${timer.startAt}');
return true;
},
),
if (totalWorkingHours > 0.0) ...[
12.height,
WorkingTimeTile(
timerList: timerList,
totalWorkingTime: totalWorkingHours,
),
],
],
);
}
}

@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@ -13,10 +14,14 @@ import 'package:test_sa/models/helper_data_models/workorder/work_order_helper_mo
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/modules/cm_module/utilities/service_request_utils.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/equipment_internal_audit_form_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/system_internal_audit_form_model.dart';
import 'package:test_sa/modules/internal_audit_module/pages/system_internal_audit/system_audit_work_order_auto_complete_field.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_checklist_provider.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_finding_type_provider.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_provider.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_wo_type_provider.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
@ -25,7 +30,7 @@ import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.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/parts/auto_complete_parts_field.dart';
import '../../../../../../new_views/common_widgets/default_app_bar.dart';
import '../../../../../../../new_views/common_widgets/default_app_bar.dart';
class CreateSystemInternalAuditForm extends StatefulWidget {
static const String id = "/create-system-audit-view";
@ -40,22 +45,25 @@ class CreateSystemInternalAuditForm extends StatefulWidget {
class _CreateSystemInternalAuditFormState extends State<CreateSystemInternalAuditForm> with TickerProviderStateMixin {
late TextEditingController _commentController;
late InternalAuditProvider _internalAuditProvider;
final InternalAuditModel _internalAuditModel = InternalAuditModel();
final SystemInternalAuditFormModel _model = SystemInternalAuditFormModel();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final List<GenericAttachmentModel> _deviceImages = [];
final List<GenericAttachmentModel> _attachments = [];
late TextEditingController _woAutoCompleteController;
bool showLoading = false;
@override
void initState() {
super.initState();
_commentController = TextEditingController();
_woAutoCompleteController = TextEditingController();
_internalAuditProvider = Provider.of<InternalAuditProvider>(context, listen: false);
}
@override
void dispose() {
_commentController.dispose();
_woAutoCompleteController.dispose();
super.dispose();
}
@ -73,14 +81,41 @@ class _CreateSystemInternalAuditFormState extends State<CreateSystemInternalAudi
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AutoCompletePartsField(
assetId: 0,
SingleItemDropDownMenu<Lookup, InternalAuditWoTypeProvider>(
context: context,
height: 56.toScreenHeight,
title: 'Wo Type'.addTranslation,
showShadow: false,
backgroundColor: AppColor.fieldBgColor(context),
showAsBottomSheet: true,
initialValue: _model.workOrderType,
onSelect: (status) {
if (status != null) {
_model.workOrderType = status;
_model.workOrderDetailModel = SystemAuditWorkOrderDetailModel();
_clearWorkOrderSelectionIds();
_woAutoCompleteController.clear();
setState(() {});
}
},
),
12.height,
SystemAuditWoAutoCompleteField(
woTypeId: _model.workOrderType?.value,
controller: _woAutoCompleteController,
clearAfterPick: false,
byName: true,
initialValue: _internalAuditModel.woOrderNo ?? "",
onPick: (part) {
_internalAuditModel.woOrderNo = part.name;
setState(() {});
initialValue: '',
onPick: (wo) async {
InternalAuditProvider provider = Provider.of<InternalAuditProvider>(context, listen: false);
setState(() {
showLoading = true;
});
_model.workOrderDetailModel = await provider.loadAllWorkOrderDetailsByID(workOrderId: wo.id!, workOrderTypeId: _model.workOrderType!.value!);
updateWorkOrderReference(woTypeId: _model.workOrderType?.value, selectedId: wo.id);
setState(() {
showLoading = false;
});
},
),
12.height,
@ -94,10 +129,10 @@ class _CreateSystemInternalAuditFormState extends State<CreateSystemInternalAudi
showShadow: false,
backgroundColor: AppColor.fieldBgColor(context),
showAsBottomSheet: true,
initialValue: _internalAuditModel.auditCheckList,
initialValue: _model.findingType,
onSelect: (status) {
if (status != null) {
_internalAuditModel.auditCheckList = status;
_model.findingType = status;
setState(() {});
}
},
@ -110,15 +145,17 @@ class _CreateSystemInternalAuditFormState extends State<CreateSystemInternalAudi
alignLabelWithHint: true,
textInputType: TextInputType.multiline,
showShadow: false,
onSaved: (text) {},
onSaved: (value) {
_model.findingDescription = value;
},
),
16.height,
AttachmentPicker(
label: context.translation.attachments,
attachment: _deviceImages,
attachment: _attachments,
buttonColor: AppColor.primary10,
onlyImages: false,
buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.primary10),
buttonIcon: 'attachment_icon'.toSvgAsset(color: AppColor.primary10),
),
],
).toShadowContainer(context),
@ -138,14 +175,21 @@ class _CreateSystemInternalAuditFormState extends State<CreateSystemInternalAudi
}
Future<void> _submit() async {
InternalAuditProvider internalAuditProvider = Provider.of<InternalAuditProvider>(context, listen: false);
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
List<WorkOrderAttachments> attachement = [];
for (var item in _deviceImages) {
_model.attachments=[];
for (var item in _attachments) {
String fileName = ServiceRequestUtils.isLocalUrl(item.name ?? '') ? ("${item.name ?? ''.split("/").last}|${base64Encode(File(item.name ?? '').readAsBytesSync())}") : item.name ?? '';
// attachement.add(WorkOrderAttachments(id: 0, name: fileName));
_model.attachments?.add(InternalAuditAttachments(id: item.id, name: fileName));
}
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
_model.auditorId = context.userProvider.user?.userID;
bool status = await internalAuditProvider.addSystemInternalAudit(context: context, request: _model);
Navigator.pop(context);
if (status) {
Navigator.pop(context);
}
// showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
}
}
@ -165,7 +209,7 @@ class _CreateSystemInternalAuditFormState extends State<CreateSystemInternalAudi
Row(
children: [
Text(
"WO Type",
_model.workOrderType?.name ?? 'WO Type',
style: TextStyle(
fontSize: 14.toScreenWidth,
fontWeight: FontWeight.w500,
@ -173,7 +217,7 @@ class _CreateSystemInternalAuditFormState extends State<CreateSystemInternalAudi
color: Colors.black87,
decoration: TextDecoration.none,
),
).toShimmer(isShow: showLoading, context: context).expanded,
).expanded,
const Icon(
Icons.info,
color: Color(0xff7D859A),
@ -182,15 +226,53 @@ class _CreateSystemInternalAuditFormState extends State<CreateSystemInternalAudi
],
),
6.height,
"${context.translation.site}: ${'ABC'}".bodyText(context),
"${'Eng. Name'.addTranslation}: ${'ABC'}".bodyText(context),
"${'Asset Name'.addTranslation}: ${'ABC'}".bodyText(context),
"${context.translation.model}: ${'ABC'}".bodyText(context),
"${context.translation.manufacture}: ${'ABC'}".bodyText(context),
"${'SN'.addTranslation}: ${'ABC'}".bodyText(context),
"${context.translation.assetNo}: ${'ABC'}".bodyText(context),
"${context.translation.site}: ${_model.workOrderDetailModel?.woSite ?? '-'}".bodyText(context),
"${'Eng. Name'.addTranslation}: ${_model.workOrderDetailModel?.woAssignedEngineer ?? '-'}".bodyText(context),
"${'Asset Name'.addTranslation}: ${_model.workOrderDetailModel?.woAssetName ?? '-'}".bodyText(context),
"${context.translation.model}: ${_model.workOrderDetailModel?.woModel ?? '-'}".bodyText(context),
"${context.translation.manufacture}: ${_model.workOrderDetailModel?.woManufacturer ?? '-'}".bodyText(context),
"${'SN'.addTranslation}: ${_model.workOrderDetailModel?.wosn ?? '-'}".bodyText(context),
"${context.translation.assetNo}: ${_model.workOrderDetailModel?.woAssetNo ?? '-'}".bodyText(context),
],
),
);
).toShimmer(isShow: showLoading, context: context);
}
void updateWorkOrderReference({int? woTypeId, int? selectedId}) {
_clearWorkOrderSelectionIds();
if (woTypeId == null || selectedId == null) return;
switch (woTypeId) {
case 1: // CM
_model.correctiveMaintenanceId = selectedId;
break;
case 2: // Gas Refill
_model.gasRefillId = selectedId;
break;
case 3: // Asset Transfer
_model.assetTransferId = selectedId;
break;
case 4: // PPM Request
_model.planPreventiveVisitId = selectedId;
break;
case 5: // Recurrent WOx
_model.planRecurrentTaskId = selectedId;
break;
case 6: // Task
_model.taskJobId = selectedId;
break;
case 7: // Recall & Alert
_model.taskAlertJobId = selectedId;
break;
}
}
void _clearWorkOrderSelectionIds() {
_model.correctiveMaintenanceId = null;
_model.planPreventiveVisitId = null;
_model.assetTransferId = null;
_model.taskJobId = null;
_model.taskAlertJobId = null;
_model.gasRefillId = null;
_model.planRecurrentTaskId = null;
}
}

@ -0,0 +1,149 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/modules/internal_audit_module/models/system_internal_audit_form_model.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_provider.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/app_style/app_text_style.dart';
import 'package:test_sa/views/app_style/sizing.dart';
class SystemAuditWoAutoCompleteField extends StatefulWidget {
final String initialValue;
final int? woTypeId;
final TextEditingController controller;
final bool clearAfterPick;
final Function(WoAutoCompleteModel) onPick;
const SystemAuditWoAutoCompleteField({Key? key, required this.initialValue, this.woTypeId, required this.onPick, this.clearAfterPick = true, required this.controller}) : super(key: key);
@override
_SystemAuditWoAutoCompleteFieldState createState() => _SystemAuditWoAutoCompleteFieldState();
}
class _SystemAuditWoAutoCompleteFieldState extends State<SystemAuditWoAutoCompleteField> {
late InternalAuditProvider _provider;
//
// late TextEditingController _controller;
bool loading = false;
@override
void initState() {
// w controller = widget.controller ?? TextEditingController(text: widget.initialValue);
super.initState();
_provider = Provider.of<InternalAuditProvider>(context, listen: false);
}
@override
void didUpdateWidget(covariant SystemAuditWoAutoCompleteField oldWidget) {
// if (widget.initialValue != oldWidget.initialValue) {
// // _controller = widget.controller ?? TextEditingController(text: widget.initialValue);
// }
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
if (widget.controller == null) {
// _controller.dispose();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
final border = UnderlineInputBorder(borderSide: BorderSide.none, borderRadius: BorderRadius.circular(10));
return Container(
decoration: BoxDecoration(
color: AppColor.background(context),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
// boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
),
child: Autocomplete<WoAutoCompleteModel>(
optionsBuilder: (TextEditingValue textEditingValue) async {
if (textEditingValue.text.isEmpty) {
if (loading) {
setState(() {
loading = false;
});
}
return const Iterable<WoAutoCompleteModel>.empty();
}
if (!loading) {
setState(() {
loading = true;
});
}
List<WoAutoCompleteModel> workOrders = (await _provider.getWorkOrderByWoType(text: textEditingValue.text, woId:widget.woTypeId));
setState(() {
loading = false;
});
return workOrders;
},
displayStringForOption: (WoAutoCompleteModel option) => option.displayName ?? '',
fieldViewBuilder: (BuildContext context, TextEditingController fieldTextEditingController, FocusNode fieldFocusNode, VoidCallback onFieldSubmitted) {
return TextField(
controller: widget.controller,
focusNode: fieldFocusNode,
style: AppTextStyles.bodyText.copyWith(color: AppColor.black10),
textAlign: TextAlign.start,
decoration: InputDecoration(
border: border,
disabledBorder: border,
focusedBorder: border,
enabledBorder: border,
errorBorder: border,
contentPadding: EdgeInsets.symmetric(vertical: 8.toScreenHeight, horizontal: 16.toScreenWidth),
constraints: const BoxConstraints(),
suffixIconConstraints: const BoxConstraints(maxHeight: 24, maxWidth: 24 + 8),
filled: true,
fillColor: AppColor.fieldBgColor(context),
errorStyle: AppTextStyle.tiny.copyWith(color: context.isDark ? AppColor.red50 : AppColor.red60),
floatingLabelStyle: AppTextStyle.body1.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? null : AppColor.neutral20),
labelText: context.translation.woNumber,
labelStyle: AppTextStyles.tinyFont.copyWith(color: AppColor.textColor(context)),
suffixIcon: loading ? const CircularProgressIndicator(color: AppColor.primary10, strokeWidth: 3.0).paddingOnly(end: 8) : null,
),
textInputAction: TextInputAction.search,
onChanged: (text) {
fieldTextEditingController.text = text;
},
onSubmitted: (String value) {
onFieldSubmitted();
},
);
},
onSelected: (WoAutoCompleteModel selection) {
if (widget.clearAfterPick) {
widget.controller.clear();
} else {
widget.controller.text = (selection.displayName ?? "");
}
widget.onPick(selection);
},
),
);
}
// String getUrl(int? woTypeId) {
// if (woTypeId == null) return '';
// String base = URLs.woAutoCompleteBase;
// var urlMap = {
// 1: '$base/ServiceRequest/WorkOrderAutoComplete', // CM
// 2: '$base/GasRefill/GetGasRefillAutoComplete', // Gas Refill
// 3: '$base/AssetTransfer/GetAssetTransferAutoComplete', // Asset Transfer
// 4: '$base/PlanPreventiveVisit/GetAutoCompletePlanPreventiveVisit', // PPM Request
// 5: '$base/PlanRecurrentTasks/GetPlanRecurrentTask', // Recurrent WO
// 6: '$base/TaskJobs/AutocompleteTaskJob', // Task
// 7: '$base/TaskJobs/AutocompleteTaskJob', // Recall & Alert
// };
// return urlMap[woTypeId] ?? '';
// }
}

@ -0,0 +1,219 @@
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/urls.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/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/system_internal_audit_data_model.dart';
import 'package:test_sa/modules/internal_audit_module/pages/equipment_internal_audit/update_equipment_internal_audit_page.dart';
import 'package:test_sa/modules/internal_audit_module/pages/system_internal_audit/update_system_internal_audit_page.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_provider.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/views/widgets/images/files_list.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart';
class SystemInternalAuditDetailPage extends StatefulWidget {
static const String id = "/details-system-internal-audit";
final int auditId;
SystemInternalAuditDetailPage({Key? key, required this.auditId}) : super(key: key);
@override
_SystemInternalAuditDetailPageState createState() {
return _SystemInternalAuditDetailPageState();
}
}
class _SystemInternalAuditDetailPageState extends State<SystemInternalAuditDetailPage> {
bool isWoType = true;
SystemInternalAuditDataModel? model;
late InternalAuditProvider _internalAuditProvider;
List<InternalAuditAttachments> allAttachments = [];
@override
void initState() {
super.initState();
_internalAuditProvider = Provider.of<InternalAuditProvider>(context, listen: false);
WidgetsBinding.instance.addPostFrameCallback((_) {
getAuditData();
});
}
Future<void> getAuditData() async {
model = await _internalAuditProvider.getInternalSystemAuditById(widget.auditId);
allAttachments.clear();
allAttachments = [
...(model?.attachments ?? []),
...(model?.engineerData?.attachments ?? []),
];
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
//TODO need to check when implementing provider needed or not .
return Scaffold(
appBar: const DefaultAppBar(title: "Request Details"),
body: Selector<InternalAuditProvider, bool>(
selector: (_, provider) => provider.isLoading,
builder: (_, isLoading, __) {
if (isLoading) return const ALoading();
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
assetInformation(),
8.height,
workOrderInformation(),
8.height,
//TODO need to check for comments
if (model?.findingDescription?.isNotEmpty ?? false) ...[
const Divider().defaultStyle(context),
// Text(
// "Comments".addTranslation,
// style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
// ),
model!.findingDescription!.bodyText(context),
],
//TODO need to check for attachments
if (allAttachments.isNotEmpty) ...[
const Divider().defaultStyle(context),
Text(
"Attachments".addTranslation,
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
8.height,
FilesList(images: allAttachments.map((e) => URLs.getFileUrl(e.name ?? '') ?? '').toList() ?? []),
],
],
).paddingAll(0).toShadowContainer(context),
).expanded,
if (context.userProvider.isEngineer)
FooterActionButton.footerContainer(
context: context,
child: AppFilledButton(
buttonColor: AppColor.primary10,
label: "Update",
onPressed: () async {
final result = await Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => UpdateSystemInternalAuditPage(model: model),
),
);
if (result == true) {
await getAuditData();
setState(() {}); // refresh UI with new model
}
}),
),
],
);
},
));
}
Widget workOrderInformation() {
final details = model?.workOrderDetails;
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Divider().defaultStyle(context),
Text(
"WO Info",
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
6.height,
labelValueText(context, context.translation.woNumber, details?.workOrderNo),
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.manufacture, details?.woManufacturer),
labelValueText(context, context.translation.model, details?.woModel),
],
);
}
Widget requestDetails() {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Divider().defaultStyle(context),
Text(
"Request Details",
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
6.height,
checklistWidget(value: 'Asset Tag'.addTranslation),
checklistWidget(value: 'Expired PM Tag'.addTranslation),
],
);
}
Widget assetInformation() {
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.model, details?.woModel),
],
);
}
Widget labelValueText(BuildContext context, String label, String? value) {
if (value == null || value.isEmpty) return const SizedBox.shrink();
return Padding(
padding: const EdgeInsets.only(bottom: 4),
child: Text(
'$label: $value',
style: AppTextStyles.bodyText.copyWith(
color: context.isDark ? AppColor.neutral30 : AppColor.neutral120,
),
),
);
}
Widget checklistWidget({required String value}) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Checkbox(
value: true,
activeColor: AppColor.neutral120,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
visualDensity: const VisualDensity(horizontal: -4, vertical: -3),
onChanged: (value) {},
),
value.bodyText(context),
],
);
}
}

@ -0,0 +1,117 @@
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/all_requests_and_count_model.dart';
import 'package:test_sa/models/new_models/dashboard_detail.dart';
import 'package:test_sa/modules/internal_audit_module/pages/equipment_internal_audit/equipment_internal_audit_detail_page.dart';
import 'package:test_sa/modules/internal_audit_module/pages/system_internal_audit/system_internal_audit_detail_page.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/views/widgets/requests/request_status.dart';
class SystemInternalAuditItemView extends StatelessWidget {
final Data? requestData;
final RequestsDetails? requestDetails;
final bool showShadow;
const SystemInternalAuditItemView({Key? key, this.requestData, this.requestDetails, this.showShadow = true}) : super(key: key);
@override
Widget build(BuildContext context) {
//TODO need to refactor this code repetation @waseem
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,
(requestData?.typeTransaction ?? "Internal Audit Request").heading5(context),
infoWidget(label: context.translation.assetNo, value: requestData?.assetNumber, 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.push(context, MaterialPageRoute(builder: (context) => SystemInternalAuditDetailPage(auditId: requestDetails!.id!)));
});
}
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,
(requestDetails?.nameOfType ?? "Internal Audit Request").heading5(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.model, value: requestDetails!.model, context: context),
8.height,
// infoWidget(label: context.translation.site, value: requestDetails!.site, 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.push(context, MaterialPageRoute(builder: (context) => SystemInternalAuditDetailPage(auditId: 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();
}
}

@ -0,0 +1,314 @@
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/api_manager.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/timer_model.dart';
import 'package:test_sa/modules/cm_module/utilities/service_request_utils.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_timer_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/system_internal_audit_data_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/update_audit_form_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_model.dart';
import 'package:test_sa/modules/internal_audit_module/provider/internal_audit_provider.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
import 'package:test_sa/new_views/common_widgets/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/working_time_tile.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/timer/app_timer.dart';
import 'package:test_sa/views/widgets/total_working_time_detail_bottomsheet.dart';
class UpdateSystemInternalAuditPage extends StatefulWidget {
static const String id = "update-system-internal-audit";
SystemInternalAuditDataModel? model;
UpdateSystemInternalAuditPage({Key? key, this.model}) : super(key: key);
@override
State<UpdateSystemInternalAuditPage> createState() => _UpdateSystemInternalAuditPageState();
}
class _UpdateSystemInternalAuditPageState extends State<UpdateSystemInternalAuditPage> {
final bool _isLoading = false;
double totalWorkingHours = 0.0;
AuditFormModel formModel = AuditFormModel();
final TextEditingController _workingHoursController = TextEditingController();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
List<GenericAttachmentModel> _attachments = [];
//TODO need to check if it's needed or not..
List<TimerHistoryModel> timerList = [];
@override
void initState() {
populateForm();
super.initState();
}
void populateForm() {
formModel.requestId = widget.model?.id;
formModel.id = widget.model?.id;
_attachments = widget.model?.engineerData?.attachments?.map((e) => GenericAttachmentModel(id: e.id?.toInt() ?? 0, name: e.name!)).toList() ?? [];
calculateWorkingTime();
}
void calculateWorkingTime() {
final helperModel = formModel;
final timers = helperModel.auditTimers ?? [];
totalWorkingHours = timers.fold<double>(0.0, (sum, item) {
if (item.startDate == null || item.endDate == null) return sum;
try {
final start = DateTime.parse(item.startDate!);
final end = DateTime.parse(item.endDate!);
final diffInHours = end.difference(start).inSeconds / 3600.0; // convert to hours
return sum + diffInHours;
} catch (_) {
return sum;
}
});
timerList = timers.map((e) {
return TimerHistoryModel(
id: e.id,
startTime: e.startDate,
endTime: e.endDate,
workingHours: e.startDate,
);
}).toList();
}
_onSubmit(BuildContext context) async {
bool isTimerPickerEnable = ApiManager.instance.assetGroup?.enabledEngineerTimer ?? false;
InternalAuditProvider provider = Provider.of<InternalAuditProvider>(context, listen: false);
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
formModel.auditTimers ??= [];
if (formModel.auditTimePicker != null) {
int durationInSecond = formModel.auditTimePicker!.endAt!.difference(formModel.auditTimePicker!.startAt!).inSeconds;
formModel.auditTimers?.add(
InternalAuditTimerModel(
id: 0,
startDate: formModel.auditTimePicker!.startAt!.toIso8601String(), // Handle potential null
endDate: formModel.auditTimePicker!.endAt?.toIso8601String(), // Handle potential null
totalWorkingHour: ((durationInSecond) / 60 / 60),
),
);
}
formModel.timerModelList?.forEach((timer) {
int durationInSecond = timer.endAt!.difference(timer.startAt!).inSeconds;
formModel.auditTimers?.add(
InternalAuditTimerModel(
id: 0,
startDate: timer.startAt!.toIso8601String(), // Handle potential null
endDate: timer.endAt?.toIso8601String(), // Handle potential null
totalWorkingHour: ((durationInSecond) / 60 / 60),
),
);
});
_formKey.currentState!.save();
formModel.attachments = [];
for (var item in _attachments) {
String fileName = ServiceRequestUtils.isLocalUrl(item.name ?? '') ? ("${item.name?.split("/").last}|${base64Encode(File(item.name ?? '').readAsBytesSync())}") : item.name ?? '';
formModel.attachments!.add(
InternalAuditAttachments(
id: item.id,
// originalName: fileName,
name: fileName,
),
);
}
log('submit press');
log('data ${formModel.toJson()}');
final success = await provider.updateSystemInternalAudit(model: formModel);
Navigator.pop(context);
if (formModel.isComplete == true) {
//Navigate to List screen.
} else if (formModel.isComplete == false) {
if (success) {
Navigator.of(context).pop(true);
} else {
Fluttertoast.showToast(msg: 'Failed to update');
}
}
}
@override
void dispose() {
_workingHoursController.dispose();
super.dispose();
}
void updateTimer({TimerModel? timer}) {
if (timer?.startAt != null && timer?.endAt != null) {
final start = timer!.startAt!;
final end = timer.endAt!;
final difference = end.difference(start);
final totalHours = difference.inSeconds / 3600.0;
formModel.startTime = start;
formModel.endTime = end;
formModel.totalHours = totalHours;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: DefaultAppBar(
title: 'Update Information'.addTranslation,
onWillPopScope: () {
formModel.isComplete = false;
_onSubmit(context);
},
),
key: _scaffoldKey,
body: Form(
key: _formKey,
child: LoadingManager(
isLoading: _isLoading,
isFailedLoading: false,
stateCode: 200,
onRefresh: () async {},
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
8.height,
AppTextFormField(
labelText: 'Debrief'.addTranslation,
textInputType: TextInputType.multiline,
hintStyle: TextStyle(color: context.isDark ? AppColor.white10 : AppColor.black10),
labelStyle: TextStyle(color: context.isDark ? AppColor.white10 : AppColor.black10),
alignLabelWithHint: true,
initialValue: formModel.debrief,
backgroundColor: AppColor.fieldBgColor(context),
showShadow: false,
onSaved: (value) {
formModel.debrief = value;
},
),
8.height,
_timerWidget(context, totalWorkingHours),
16.height,
AttachmentPicker(
label: 'Upload Attachment',
attachment: _attachments,
buttonColor: AppColor.primary10,
onlyImages: false,
buttonIcon: 'attachment_icon'.toSvgAsset(
color: AppColor.primary10,
),
),
8.height,
],
).toShadowContainer(context),
).expanded,
FooterActionButton.footerContainer(
context: context,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
AppFilledButton(
label: context.translation.save,
buttonColor: context.isDark ? AppColor.neutral70 : AppColor.white60,
textColor: context.isDark ? AppColor.white10 : AppColor.black10,
onPressed: () {
log('button press ');
formModel.isComplete = false;
_onSubmit(context);
}).expanded,
12.width,
AppFilledButton(
label: context.translation.complete,
buttonColor: AppColor.primary10,
onPressed: () {
formModel.isComplete = true;
_onSubmit(context);
}).expanded,
],
),
),
],
)),
),
).handlePopScope(
cxt: context,
onSave: () {
formModel.isComplete = false;
_onSubmit(context);
});
}
Widget _timerWidget(BuildContext context, double totalWorkingHours) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
// AppTimer(
// label: context.translation.timer,
// timer: formModel.auditTimerModel,
// // enabled: enableTimer,
// pickerTimer: formModel.auditTimePicker,
// pickerFromDate: DateTime.tryParse(widget.model?.createdDate ?? ''),
// onPick: (time) {
// formModel.auditTimePicker = time;
// },
// timerProgress: (isRunning) {},
// onChange: (timer) async {
// formModel.auditTimerModel = timer;
// if (timer.startAt != null && timer.endAt != null) {
// formModel.timerModelList = formModel.timerModelList ?? [];
// formModel.timerModelList!.add(timer);
// }
// return true;
// },
// ),
AppTimer(
label: context.translation.workingHours,
timer: formModel.auditTimerModel,
pickerFromDate: DateTime.tryParse(widget.model?.createdDate ?? ''),
pickerTimer: formModel.auditTimePicker,
onPick: (time) {
updateTimer(timer: time);
},
width: double.infinity,
decoration: BoxDecoration(
color: AppColor.fieldBgColor(context),
borderRadius: BorderRadius.circular(10),
),
timerProgress: (isRunning) {},
onChange: (timer) async {
updateTimer(timer: timer);
log('here onChange ${timer.startAt}');
return true;
},
),
if (totalWorkingHours > 0.0) ...[
12.height,
WorkingTimeTile(
timerList: timerList,
totalWorkingTime: totalWorkingHours,
),
],
],
);
}
}

@ -1,327 +0,0 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/api_manager.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/generic_attachment_model.dart';
import 'package:test_sa/models/timer_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/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/working_time_tile.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/timer/app_timer.dart';
import 'package:test_sa/views/widgets/total_working_time_detail_bottomsheet.dart';
class UpdateInternalAuditPage extends StatefulWidget {
static const String id = "update-internal-audit";
final model;
const UpdateInternalAuditPage({this.model, Key? key}) : super(key: key);
@override
State<UpdateInternalAuditPage> createState() => _UpdateInternalAuditPageState();
}
class _UpdateInternalAuditPageState extends State<UpdateInternalAuditPage> {
final bool _isLoading = false;
double totalWorkingHours = 0.0;
late UserProvider _userProvider;
// GasRefillDetails _currentDetails = GasRefillDetails();
final TextEditingController _commentController = TextEditingController();
final TextEditingController _workingHoursController = TextEditingController();
// final GasRefillModel _formModel = GasRefillModel(gasRefillDetails: []);
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
bool _firstTime = true;
List<GenericAttachmentModel> _attachments = [];
List<TimerHistoryModel> timerList = [];
@override
void initState() {
super.initState();
// if (widget.gasRefillModel != null) {
// _formModel.fromGasRefillModel(widget.gasRefillModel!);
// _commentController.text = _formModel.techComment ?? "";
// calculateWorkingTime();
// try {
// _deliveredQuantity = deliveredQuantity.singleWhere((element) => element.value == _formModel.gasRefillDetails![0].deliverdQty);
// _currentDetails.deliverdQty = _deliveredQuantity!.value;
// } catch (ex) {}
// }
// if (_formModel.gasRefillAttachments != null && _formModel.gasRefillAttachments!.isNotEmpty) {
// _attachments.addAll(_formModel.gasRefillAttachments!.map((e) => GenericAttachmentModel(id:e.id,name:e.attachmentName!)).toList());
// }
}
void calculateWorkingTime() {
// final timers = _formModel.gasRefillTimers ?? [];
// totalWorkingHours = timers.fold<double>(0.0, (sum, item) {
// if (item.startDate == null || item.endDate == null) return sum;
// try {
// final start = DateTime.parse(item.startDate!);
// final end = DateTime.parse(item.endDate!);
// final diffInHours = end.difference(start).inSeconds / 3600.0; // convert to hours
// return sum + diffInHours;
// } catch (_) {
// return sum;
// }
// });
//
// timerList = timers.map((e) {
// return TimerHistoryModel(
// id: e.id,
// startTime: e.startDate,
// endTime: e.endDate,
// workingHours: e.workingHours,
// );
// }).toList();
}
@override
void setState(VoidCallback fn) {
if (mounted) super.setState(() {});
}
_onSubmit(BuildContext context, int status) async {
bool isTimerPickerEnable = ApiManager.instance.assetGroup?.enabledEngineerTimer ?? false;
// if (isTimerPickerEnable) {
// if (_formModel.timer?.startAt == null && _formModel.gasRefillTimePicker == null) {
// Fluttertoast.showToast(msg: "Working Hours Required");
// return false;
// }
// if (_formModel.gasRefillTimePicker == null) {
// if (_formModel.timer?.startAt == null) {
// Fluttertoast.showToast(msg: "Working Hours Required");
// return false;
// }
// if (_formModel.timer?.endAt == null) {
// Fluttertoast.showToast(msg: "Please Stop The Timer");
// return false;
// }
// }
// } else {
// if (_formModel.timer?.startAt == null) {
// Fluttertoast.showToast(msg: "Working Hours Required");
// return false;
// }
// if (_formModel.timer?.endAt == null) {
// Fluttertoast.showToast(msg: "Please Stop The Timer");
// return false;
// }
// }
//
// if (_currentDetails.deliverdQty == null) {
// await Fluttertoast.showToast(msg: "Delivered Quantity is Required");
// return false;
// }
// _formModel.gasRefillDetails = [];
// _formModel.gasRefillDetails?.add(_currentDetails);
//
// showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
// _formModel.gasRefillTimers = _formModel.gasRefillTimers ?? [];
// if (_formModel.gasRefillTimePicker != null) {
// int durationInSecond = _formModel.gasRefillTimePicker!.endAt!.difference(_formModel.gasRefillTimePicker!.startAt!).inSeconds;
// _formModel.gasRefillTimers?.add(
// GasRefillTimer(
// id: 0,
// startDate: _formModel.gasRefillTimePicker!.startAt!.toIso8601String(), // Handle potential null
// endDate: _formModel.gasRefillTimePicker!.endAt?.toIso8601String(), // Handle potential null
// workingHours: ((durationInSecond) / 60 / 60),
// ),
// );
// }
// _formModel.timerModelList?.forEach((timer) {
// int durationInSecond = timer.endAt!.difference(timer.startAt!).inSeconds;
// _formModel.gasRefillTimers?.add(
// GasRefillTimer(
// id: 0,
// startDate: timer.startAt!.toIso8601String(), // Handle potential null
// endDate: timer.endAt?.toIso8601String(), // Handle potential null
// workingHours: ((durationInSecond) / 60 / 60),
// ),
// );
// });
// _formModel.gasRefillAttachments = [];
// for (var item in _attachments) {
// String fileName = ServiceRequestUtils.isLocalUrl(item.name??'') ? ("${item.name??''.split("/").last}|${base64Encode(File(item.name??'').readAsBytesSync())}") :item.name??'';
// _formModel.gasRefillAttachments?.add(GasRefillAttachments(
// id: item.id, gasRefillId: _formModel.id ?? 0, attachmentName: fileName));
// }
// await _gasRefillProvider?.updateGasRefill(status: status, model: _formModel).then((success) {
// Navigator.pop(context);
// if (success) {
// if (status == 1) {
// AllRequestsProvider allRequestsProvider = Provider.of<AllRequestsProvider>(context, listen: false);
// // when click complete then this request remove from the list and status changes to closed..
// _gasRefillProvider?.reset();
// allRequestsProvider.getAllRequests(context, typeTransaction: 2);
// }
// Navigator.pop(context);
// }
// });
}
@override
void dispose() {
_commentController.dispose();
_workingHoursController.dispose();
super.dispose();
}
void updateTimer({TimerModel? timer}) {
// _formModel.timer = timer;
// if (timer?.startAt != null && timer?.endAt != null) {
// _formModel.timerModelList = _formModel.timerModelList ?? [];
// _formModel.timerModelList!.add(timer!);
// }
// notifyListeners();
}
@override
Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context);
if (_firstTime) {
String? clientName;
// if (widget.gasRefillModel != null) {
// _gasRefillProvider!.expectedDateTime = DateTime.tryParse(_formModel.expectedDate ?? "");
// _formModel.timer = TimerModel(startAt: DateTime.tryParse(widget.gasRefillModel?.startDate ?? ""), endAt: DateTime.tryParse(widget.gasRefillModel?.endDate ?? ""));
// } else {
// _formModel.timer = null;
// }
}
return Scaffold(
appBar: DefaultAppBar(
title: 'Update Information'.addTranslation,
onWillPopScope: () {
_onSubmit(context, 0);
},
),
key: _scaffoldKey,
body: Form(
key: _formKey,
child: LoadingManager(
isLoading: _isLoading,
isFailedLoading: false,
stateCode: 200,
onRefresh: () async {},
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SingleChildScrollView(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
8.height,
AppTextFormField(
labelText: 'Debrief'.addTranslation,
textInputType: TextInputType.multiline,
hintStyle: TextStyle(color: context.isDark ? AppColor.white10 : AppColor.black10),
labelStyle: TextStyle(color: context.isDark ? AppColor.white10 : AppColor.black10),
alignLabelWithHint: true,
backgroundColor: AppColor.fieldBgColor(context),
showShadow: false,
controller: _commentController,
onChange: (value) {},
onSaved: (value) {},
),
8.height,
_timerWidget(context, totalWorkingHours),
16.height,
AttachmentPicker(
label: context.translation.attachFiles,
attachment: _attachments,
buttonColor: AppColor.primary10,
onlyImages: false,
buttonIcon: 'image-plus'.toSvgAsset(
color: AppColor.primary10,
),
),
8.height,
],
).toShadowContainer(context),
).expanded,
FooterActionButton.footerContainer(
context: context,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
AppFilledButton(
label: context.translation.save,
buttonColor: context.isDark ? AppColor.neutral70 : AppColor.white60,
textColor: context.isDark ? AppColor.white10 : AppColor.black10,
onPressed: () => _onSubmit(context, 0),
).expanded,
12.width,
AppFilledButton(
label: context.translation.complete,
buttonColor: AppColor.primary10,
onPressed: () => _onSubmit(context, 1),
).expanded,
],
),
),
],
)),
),
).handlePopScope(
cxt: context,
onSave: () {
_onSubmit(context, 0);
});
}
Widget _timerWidget(BuildContext context, double totalWorkingHours) {
TimerModel? timer = TimerModel();
TimerModel? timerPicker;
List<TimerModel>? timerModelList = [];
return Column(
mainAxisSize: MainAxisSize.min,
children: [
AppTimer(
label: context.translation.workingHours,
timer: timer,
// pickerFromDate: DateTime.tryParse(widget.gasRefillModel?.createdDate ?? ''),
pickerFromDate: DateTime.tryParse(''),
pickerTimer: timerPicker,
onPick: (time) {
//timerPicker = time;
},
width: double.infinity,
decoration: BoxDecoration(
color: AppColor.fieldBgColor(context),
// color: AppColor.neutral100,
borderRadius: BorderRadius.circular(10),
),
timerProgress: (isRunning) {},
onChange: (timer) async {
updateTimer(timer: timer);
return true;
},
),
if (totalWorkingHours > 0.0) ...[
12.height,
WorkingTimeTile(
timerList: timerList,
totalWorkingTime: totalWorkingHours,
),
],
],
);
}
}

@ -15,7 +15,7 @@ class InternalAuditCheckListProvider extends LoadingListNotifier<Lookup> {
notifyListeners();
Response response;
try {
response = await ApiManager.instance.get(URLs.getPentryTaskStatus);
response = await ApiManager.instance.get(URLs.getInternalAuditChecklist);
} catch (error) {
loading = false;
stateCode = -1;

@ -14,7 +14,7 @@ class InternalAuditFindingTypeProvider extends LoadingListNotifier<Lookup> {
notifyListeners();
Response response;
try {
response = await ApiManager.instance.get(URLs.getPentryTaskStatus);
response = await ApiManager.instance.get(URLs.getInternalAuditFindingType);
} catch (error) {
loading = false;
stateCode = -1;

@ -2,41 +2,210 @@ 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/models/device/asset_search.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/new_models/asset_nd_auto_complete_by_dynamic_codes_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/update_audit_form_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/equipment_internal_audit_data_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/equipment_internal_audit_form_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/system_internal_audit_data_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/system_internal_audit_form_model.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
class InternalAuditProvider extends ChangeNotifier {
final pageItemNumber = 10;
final searchPageItemNumber = 10;
int pageNo = 1;
void reset() {
pageNo = 1;
stateCode = null;
}
int? stateCode;
bool isDetailLoading = false;
bool nextPage = false;
bool isNextPageLoading = false;
bool isLoading = false;
Future<int> getInternalAuditById(int id) async {
Future<EquipmentInternalAuditDataModel?> getEquipmentInternalAuditById(int id) async {
try {
isLoading = true;
notifyListeners();
//Need to replace
Response response = await ApiManager.instance.get("${URLs.getTRAFById}?id=$id");
Response response = await ApiManager.instance.get(
"${URLs.getInternalAuditEquipmentById}?internalAuditEquipmentId=$id",
);
if (response.statusCode >= 200 && response.statusCode < 300) {
// trafRequestDataModel = TrafRequestDataModel.fromJson(json.decode(response.body)["data"]);
final decodedBody = jsonDecode(response.body);
EquipmentInternalAuditDataModel model = EquipmentInternalAuditDataModel.fromJson(decodedBody["data"]);
isLoading = false;
notifyListeners();
return model;
} else {
isLoading = false;
notifyListeners();
return null;
}
} catch (error) {
isLoading = false;
notifyListeners();
return null;
}
}
Future<SystemInternalAuditDataModel?> getInternalSystemAuditById(int id) async {
try {
isLoading = true;
notifyListeners();
Response response = await ApiManager.instance.get("${URLs.getInternalAuditSystemById}?AuditSystemId=$id");
if (response.statusCode >= 200 && response.statusCode < 300) {
final decodedBody = jsonDecode(response.body);
SystemInternalAuditDataModel model = SystemInternalAuditDataModel.fromJson(decodedBody["data"]);
isLoading = false;
notifyListeners();
return model;
} else {
isLoading = false;
notifyListeners();
return null;
}
} catch (error) {
isLoading = false;
notifyListeners();
return null;
}
}
Future<SystemAuditWorkOrderDetailModel?> loadAllWorkOrderDetailsByID({required int workOrderTypeId, required int workOrderId}) async {
try {
isLoading = true;
notifyListeners();
Response response = await ApiManager.instance.get("${URLs.loadAllWorkOrderDetailsByID}?workOrderTypeId=$workOrderTypeId&workOrderId=$workOrderId");
if (response.statusCode >= 200 && response.statusCode < 300) {
final decodedBody = jsonDecode(response.body);
SystemAuditWorkOrderDetailModel model = SystemAuditWorkOrderDetailModel.fromJson(decodedBody["data"]);
isLoading = false;
notifyListeners();
return model;
} else {
isLoading = false;
notifyListeners();
return null;
}
} catch (error) {
isLoading = false;
notifyListeners();
return null;
}
}
Future<bool> updateEquipmentInternalAudit({required AuditFormModel model}) async {
isLoading = true;
Response response;
try {
response = await ApiManager.instance.put(URLs.updateAuditEquipmentsEngineer, body: model.toJson());
stateCode = response.statusCode;
isLoading = false;
notifyListeners();
if (stateCode == 200) {
return true;
}
return false;
} catch (error) {
isLoading = false;
stateCode = -1;
notifyListeners();
return false;
}
}
Future<bool> updateSystemInternalAudit({required AuditFormModel model}) async {
isLoading = true;
Response response;
try {
response = await ApiManager.instance.put(URLs.updateAuditSystemEngineer, body: model.toJson());
stateCode = response.statusCode;
isLoading = false;
notifyListeners();
return 0;
log('status code ${stateCode}');
if (stateCode == 200) {
return true;
}
return false;
} catch (error) {
isLoading = false;
stateCode = -1;
notifyListeners();
return -1;
return false;
}
}
Future<bool> addEquipmentInternalAudit({
required BuildContext context,
required EquipmentInternalAuditFormModel request,
}) async {
bool status = false;
Response response;
try {
response = await ApiManager.instance.post(URLs.addOrUpdateEquipmentInternalAudit, body: request.toJson());
if (response.statusCode >= 200 && response.statusCode < 300) {
status = true;
notifyListeners();
} else {
Fluttertoast.showToast(msg: "${context.translation.failedRequestMessage} :${json.decode(response.body)['message']}");
status = false;
}
return status;
} catch (error) {
print(error);
status = false;
notifyListeners();
return status;
}
}
Future<bool> addSystemInternalAudit({
required BuildContext context,
required SystemInternalAuditFormModel request,
}) async {
bool status = false;
Response response;
try {
response = await ApiManager.instance.post(URLs.addOrUpdateInternalAuditSystem, body: request.toJson());
if (response.statusCode >= 200 && response.statusCode < 300) {
status = true;
notifyListeners();
} else {
Fluttertoast.showToast(msg: "${context.translation.failedRequestMessage} :${json.decode(response.body)['message']}");
status = false;
}
return status;
} catch (error) {
print(error);
status = false;
notifyListeners();
return status;
}
}
Future<List<WoAutoCompleteModel>> getWorkOrderByWoType({String? text, required int? woId}) async {
late Response response;
try {
Response response = await ApiManager.instance.get("${URLs.getWoAutoComplete}?workOrderTypeId=$woId&search=$text");
// response = await ApiManager.instance.post(url, body: {"search": text});
List<WoAutoCompleteModel> woOrderList = [];
if (response.statusCode >= 200 && response.statusCode < 300) {
List categoriesListJson = json.decode(response.body)["data"];
woOrderList = categoriesListJson.map((wo) => WoAutoCompleteModel.fromJson(wo)).toList();
}
return woOrderList;
} catch (error) {
return [];
}
}
}

@ -0,0 +1,35 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
class InternalAuditWoTypeProvider extends LoadingListNotifier<Lookup> {
@override
Future getData({int? id}) async {
if (loading ?? false) return -2;
loading = true;
notifyListeners();
Response response;
try {
response = await ApiManager.instance.get(URLs.getInternalAuditWoType);
} catch (error) {
loading = false;
stateCode = -1;
notifyListeners();
return -1;
}
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
List listJson = json.decode(response.body)["data"];
items = listJson.map((department) => Lookup.fromJson(department)).toList();
}
loading = false;
notifyListeners();
return response.statusCode;
}
}

@ -271,7 +271,7 @@ class _UpdateTaskRequestState extends State<UpdateTaskRequest> {
taskModel?.timerModelList?.forEach((timer) {
int durationInSecond = timer.endAt!.difference(timer.startAt!).inSeconds;
taskModel.taskJobActivityEngineerTimers?.add(
TaskJobActivityEngineerTimer(
TaskJobActivityEngineerTimer (
id: 0, startDate: timer.startAt!.toIso8601String(), endDate: timer.endAt?.toIso8601String(), totalWorkingHour: ((durationInSecond) / 60 / 60), comment: timer.comments ?? comments),
);
});

@ -9,8 +9,8 @@ import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/modules/cm_module/views/nurse/create_new_request_view.dart';
import 'package:test_sa/modules/internal_audit_module/pages/create_equipment_internal_audit_form.dart';
import 'package:test_sa/modules/internal_audit_module/pages/create_system_internal_audit_form.dart';
import 'package:test_sa/modules/internal_audit_module/pages/equipment_internal_audit/create_equipment_internal_audit_form.dart';
import 'package:test_sa/modules/internal_audit_module/pages/system_internal_audit/create_system_internal_audit_form.dart';
import 'package:test_sa/modules/tm_module/tasks_wo/create_task_view.dart';
import 'package:test_sa/modules/traf_module/create_traf_request_page.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';

@ -58,9 +58,9 @@ class _MyRequestsPageState extends State<MyRequestsPage> {
requestsList.add(Request(9, 'TRAF'));
}
if (context.userProvider.isEngineer) {
//TODO need to replace with actual number.
// requestsList.add(Request(10, 'Internal Audit'));
requestsList.add(Request(1, 'Internal Audit'));
// TODO need to replace with actual number.
requestsList.add(Request(10, 'Equipment Internal Audit'));
requestsList.add(Request(11, 'System Internal Audit'));
}
if (context.userProvider.isAssessor) {
@ -73,9 +73,8 @@ class _MyRequestsPageState extends State<MyRequestsPage> {
requestsList = [
Request(null, context.translation.allWorkOrder),
//TODO need to replace with actual number.
// Request(10, 'Internal Audit'),
Request(1, 'Internal Audit'),
Request(10, 'Equipment Internal Audit'),
Request(11, 'System Internal Audit'),
];
}

@ -1,7 +1,8 @@
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/internal_audit_module/pages/internal_audit_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/tm_module/tasks_wo/task_request_item_view.dart';
import 'package:test_sa/modules/traf_module/traf_request_item_view.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
@ -55,7 +56,8 @@ class RequestPaginatedListview extends StatelessWidget {
bool isRecurrentTask = request.transactionNo == 5;
bool isTask = request.transactionNo == 6;
bool isTRAF = request.transactionNo == 9;
bool isInternalAudit = request.transactionNo == 10;
bool isEquipmentInternalAudit = request.transactionNo == 10;
bool isSystemInternalAudit = request.transactionNo == 11;
if (isServiceRequest) {
return ServiceRequestItemView(requestData: request, refreshData: false);
@ -69,14 +71,13 @@ class RequestPaginatedListview extends StatelessWidget {
return RecurrentWoItemView(requestData: request);
} else if (isTask) {
return TaskRequestItemView(requestData: request);
}
else if (isTRAF) {
} else if (isTRAF) {
return TrafRequestItemView(requestData: request);
}
else if (isInternalAudit) {
return InternalAuditItemView(requestData: request);
}
else {
} else if (isEquipmentInternalAudit) {
return EquipmentInternalAuditItemView(requestData: request);
} else if (isSystemInternalAudit) {
return SystemInternalAuditItemView(requestData: request);
} else {
return Container(
height: 100,
width: double.infinity,

@ -1,12 +1,16 @@
//request tab page
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/widget_extensions.dart';
import 'package:test_sa/models/all_requests_and_count_model.dart';
import 'package:test_sa/modules/internal_audit_module/pages/internal_audit_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/tm_module/tasks_wo/task_request_item_view.dart';
import 'package:test_sa/modules/traf_module/traf_request_item_view.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/pages/land_page/requests/device_item_view.dart';
import 'package:test_sa/new_views/pages/land_page/requests/gas_refill_item_view.dart';
import 'package:test_sa/new_views/pages/land_page/requests/ppm_item_view.dart';
@ -29,11 +33,19 @@ class RequestItemViewList extends StatelessWidget {
shrinkWrap: true,
itemBuilder: (cxt, index) {
if (isLoading) return const SizedBox().toRequestShimmer(cxt, isLoading);
// if (list[index].transactionType == null) {
// return EquipmentInternalAuditItemView(requestDetails: list[index]);
// // return Container(
// // height: 100,
// // width: double.infinity,
// // color: AppColor.neutral40,
// // );
// }
switch (list[index].transactionType) {
// case 1:
// return ServiceRequestItemView(requestDetails: list[index]);
case 1:
return InternalAuditItemView(requestDetails: list[index]);
return ServiceRequestItemView(requestDetails: list[index]);
// case 1:
// return InternalAuditItemView(requestDetails: list[index]);
case 2:
return GasRefillItemView(requestDetails: list[index]);
case 3:
@ -48,9 +60,11 @@ class RequestItemViewList extends StatelessWidget {
return TaskRequestItemView(requestDetails: list[index]);
case 9:
return TrafRequestItemView(requestDetails: list[index]);
//Need to verify the type No..
case 10:
return InternalAuditItemView(requestDetails: list[index]);
//Need to verify the type No..
case 10:
return EquipmentInternalAuditItemView(requestDetails: list[index]);
case 11:
return SystemInternalAuditItemView(requestDetails: list[index]);
default:
Container(
height: 100,

Loading…
Cancel
Save