internal audit api's implementation in progress

design_3.0_internal_audit_module
WaseemAbbasi22 3 weeks ago
parent 81dd799672
commit 81dd189025

@ -314,11 +314,14 @@ class URLs {
//internal Audit
static get getInternalAuditEquipmentById => "$_baseUrl/InternalAuditEquipments/GetInternalAuditEquipmentById";
static get getInternalAuditSystemById => "$_baseUrl/InternalAuditSystems/GetInternalAuditSystemById";
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 loadAllWorkOrderDetailsByID => "$_baseUrl/InternalAuditSystems/LoadAllWorkOrderDetailsByID";
}

@ -103,7 +103,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';
@ -365,7 +365,7 @@ class MyApp extends StatelessWidget {
HelpCenterPage.id: (_) => const HelpCenterPage(),
CreateEquipmentInternalAuditForm.id: (_) => const CreateEquipmentInternalAuditForm(),
CreateSystemInternalAuditForm.id: (_) => const CreateSystemInternalAuditForm(),
UpdateInternalAuditPage.id: (_) => const UpdateInternalAuditPage(),
UpdateEquipmentInternalAuditPage.id: (_) => UpdateEquipmentInternalAuditPage(),
// SwipeSuccessView.routeName: (_) => const SwipeSuccessView(),
// SwipeHistoryView.routeName: (_) => const SwipeHistoryView(),
},

@ -0,0 +1,56 @@
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/modules/internal_audit_module/models/internal_audit_attachment_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();
AuditFormModel({
this.id,
this.requestId,
this.debrief,
this.startTime,
this.endTime,
this.totalHours,
this.createdDate,
this.attachments,
this.isComplete,
this.auditTimerModel,
});
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(),
'totalHours': totalHours,
'attachments': attachments?.map((e) => e.toJson()).toList(),
'isComplete': isComplete,
};
}
}

@ -1,4 +1,8 @@
class EquipmentInternalAuditDataModel {
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 EquipmentInternalAuditDataModel {
int? id;
String? requestNo;
String? createdDate;
@ -10,7 +14,7 @@
dynamic manufacture;
String? remarks;
List<EquipmentsFinding>? equipmentsFindings;
List<dynamic>? attachments;
List<InternalAuditAttachments>? attachments;
EquipmentInternalAuditDataModel({
this.id,
@ -44,7 +48,7 @@
equipmentsFindings!.add(EquipmentsFinding.fromJson(v));
});
}
attachments = json['attachments'] != null ? List<dynamic>.from(json['attachments']) : [];
// attachments = json['attachments'] != null ? List<InternalAuditAttachments>.from(json['attachments']) : [];
}
Map<String, dynamic> toJson() {

@ -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,122 @@
import 'package:test_sa/models/lookup.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;
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,
});
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'];
}
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;
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;
}
}

@ -4,7 +4,7 @@ import 'dart:developer';
import 'package:test_sa/models/lookup.dart';
class SystemInternalAuditFormModel {
int? id = 0;
int? id;
String? auditorId;
String? assignEmployeeId;
Lookup? findingType;
@ -18,6 +18,7 @@ class SystemInternalAuditFormModel {
int? gasRefillId;
int? planRecurrentTaskId;
int? statusId;
SystemAuditWorkOrderDetailModel ?workOrderDetailModel;
SystemInternalAuditFormModel({
this.id,
@ -33,12 +34,13 @@ class SystemInternalAuditFormModel {
this.taskAlertJobId,
this.gasRefillId,
this.planRecurrentTaskId,
this.workOrderDetailModel,
this.statusId,
});
Map<String, dynamic> toJson() {
return {
'id': id,
// 'id': id,
'auditorId': auditorId,
'assignEmployeeId': assignEmployeeId,
'findingTypeId': findingType?.id,
@ -77,6 +79,123 @@ class WoAutoCompleteModel {
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,
};
}
}

@ -9,13 +9,13 @@ 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/equipment_internal_audit_data_model.dart';
import 'package:test_sa/modules/internal_audit_module/pages/update_internal_audit_page.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 EquipmentInternalAuditDetailPage extends StatefulWidget {
static const String id = "/details-internal-audit";
@ -62,7 +62,8 @@ class _EquipmentInternalAuditDetailPageState extends State<EquipmentInternalAudi
selector: (_, provider) => provider.isLoading,
builder: (_, isLoading, __) {
if (isLoading) return const ALoading();
return Column(
if (model==null) return NoDataFound(message: context.translation.noDataFound).center;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SingleChildScrollView(
@ -74,25 +75,24 @@ class _EquipmentInternalAuditDetailPageState extends State<EquipmentInternalAudi
8.height,
requestDetails(),
8.height,
//TODO need to check for comments
if (model?.remarks?.isNotEmpty ?? false) ...[
const Divider().defaultStyle(context),
Text(
"Remarks".addTranslation,
style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
model!.remarks!.bodyText(context),
8.height,
const Divider().defaultStyle(context),
Text(
"Remarks".addTranslation,
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
model!.remarks!.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() ?? []),
//TODO need to check for attachments backend need to fix the name they are sending wrong string
// if (model!.attachments!.isNotEmpty) ...[
// const Divider().defaultStyle(context),
// Text(
// "Attachments".addTranslation,
// style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
// ),
// 8.height,
// FilesList(images: model!.attachments!.map((e) => URLs.getFileUrl(e.name ?? '') ?? '').toList() ?? []),
// ],
],
).paddingAll(0).toShadowContainer(context),
@ -104,7 +104,7 @@ class _EquipmentInternalAuditDetailPageState extends State<EquipmentInternalAudi
buttonColor: AppColor.primary10,
label: "Update",
onPressed: () {
Navigator.pushNamed(context, UpdateInternalAuditPage.id);
Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdateEquipmentInternalAuditPage(model: model)));
}),
),
],

@ -22,7 +22,6 @@ class EquipmentInternalAuditItemView extends StatelessWidget {
@override
Widget build(BuildContext context) {
//TODO need to refactor this code repetation @waseem
log('request details ${requestDetails?.toJson()}');
if (requestData != null) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,

@ -0,0 +1,342 @@
import 'dart:convert';
import 'dart:developer';
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/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/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_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?.attachments?.map((e) => GenericAttachmentModel(id: e.id?.toInt()??0, name: e.name!)).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();
}
_onSubmit(BuildContext context) async {
bool isTimerPickerEnable = ApiManager.instance.assetGroup?.enabledEngineerTimer ?? false;
InternalAuditProvider provider = Provider.of<InternalAuditProvider>(context,listen: false);
_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,
),
);
}
provider.updateEquipmentInternalAudit(model: formModel);
log('payload ${formModel.toJson()}');
// 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() {
_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: 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: (){
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) {
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.model?.createdDate ?? ''),
pickerTimer: timerPicker,
onPick: (time) {
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,
),
],
],
);
}
}

@ -91,7 +91,8 @@ class _CreateSystemInternalAuditFormState extends State<CreateSystemInternalAudi
onSelect: (status) {
if (status != null) {
_model.workOrderType = status;
_clearWorkOrderSelection();
_model.workOrderDetailModel = SystemAuditWorkOrderDetailModel();
_clearWorkOrderSelectionIds();
_woAutoCompleteController.clear();
setState(() {});
}
@ -103,9 +104,17 @@ class _CreateSystemInternalAuditFormState extends State<CreateSystemInternalAudi
controller: _woAutoCompleteController,
clearAfterPick: false,
initialValue: '',
onPick: (wo) {
updateWorkOrderReference(woTypeId: _model.workOrderType?.value, selectedId:wo.id);
setState(() {});
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,
@ -166,14 +175,16 @@ 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) {
String fileName = ServiceRequestUtils.isLocalUrl(item.name ?? '') ? ("${item.name ?? ''.split("/").last}|${base64Encode(File(item.name ?? '').readAsBytesSync())}") : item.name ?? '';
// attachement.add(WorkOrderAttachments(id: 0, 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());
}
}
@ -193,7 +204,7 @@ class _CreateSystemInternalAuditFormState extends State<CreateSystemInternalAudi
Row(
children: [
Text(
"WO Type",
_model.workOrderType?.name ?? 'WO Type',
style: TextStyle(
fontSize: 14.toScreenWidth,
fontWeight: FontWeight.w500,
@ -201,7 +212,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),
@ -210,19 +221,20 @@ 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}) {
_clearWorkOrderSelection();
_clearWorkOrderSelectionIds();
if (woTypeId == null || selectedId == null) return;
switch (woTypeId) {
case 1: // CM
@ -237,7 +249,7 @@ class _CreateSystemInternalAuditFormState extends State<CreateSystemInternalAudi
case 4: // PPM Request
_model.planPreventiveVisitId = selectedId;
break;
case 5: // Recurrent WO
case 5: // Recurrent WOx
_model.planRecurrentTaskId = selectedId;
break;
case 6: // Task
@ -249,7 +261,7 @@ class _CreateSystemInternalAuditFormState extends State<CreateSystemInternalAudi
}
}
void _clearWorkOrderSelection() {
void _clearWorkOrderSelectionIds() {
_model.correctiveMaintenanceId = null;
_model.planPreventiveVisitId = null;
_model.assetTransferId = null;
@ -258,6 +270,4 @@ class _CreateSystemInternalAuditFormState extends State<CreateSystemInternalAudi
_model.gasRefillId = null;
_model.planRecurrentTaskId = null;
}
}

@ -8,7 +8,7 @@ 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/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';
@ -30,12 +30,20 @@ class SystemInternalAuditDetailPage extends StatefulWidget {
class _SystemInternalAuditDetailPageState extends State<SystemInternalAuditDetailPage> {
bool isWoType = true;
// EquipmentInternalAuditDataModel? model;
late InternalAuditProvider _internalAuditProvider;
@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 {
await _internalAuditProvider.getInternalSystemAuditById(widget.auditId);
}
@override
@ -69,7 +77,7 @@ class _SystemInternalAuditDetailPageState extends State<SystemInternalAuditDetai
const Divider().defaultStyle(context),
Text(
"Comments".addTranslation,
style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
// model.comment!.bodyText(context),
// 8.height,
@ -79,7 +87,7 @@ class _SystemInternalAuditDetailPageState extends State<SystemInternalAuditDetai
const Divider().defaultStyle(context),
Text(
"Attachments".addTranslation,
style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
8.height,
// FilesList(images: _model.attachment?.map((e) => URLs.getFileUrl(e.attachmentName ?? '') ?? '').toList() ?? []),
@ -94,7 +102,7 @@ class _SystemInternalAuditDetailPageState extends State<SystemInternalAuditDetai
buttonColor: AppColor.primary10,
label: "Update",
onPressed: () {
Navigator.pushNamed(context, UpdateInternalAuditPage.id);
Navigator.pushNamed(context, UpdateEquipmentInternalAuditPage.id);
}),
),
],

@ -23,7 +23,6 @@ class SystemInternalAuditItemView extends StatelessWidget {
@override
Widget build(BuildContext context) {
//TODO need to refactor this code repetation @waseem
log('request details ${requestDetails?.toJson()}');
if (requestData != null) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,

@ -12,6 +12,7 @@ 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/modules/internal_audit_module/models/equipment_internal_audit_data_model.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
@ -23,8 +24,9 @@ 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;
static const String id = "update-system-internal-audit";
//Need to pass system model here.
final EquipmentInternalAuditDataModel ?model;
const UpdateInternalAuditPage({this.model, Key? key}) : super(key: key);
@ -36,12 +38,8 @@ 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;
@ -51,18 +49,6 @@ class _UpdateInternalAuditPageState extends State<UpdateInternalAuditPage> {
@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() {
@ -194,16 +180,6 @@ class _UpdateInternalAuditPageState extends State<UpdateInternalAuditPage> {
@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,

@ -10,6 +10,7 @@ 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/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_form_model.dart';
@ -71,6 +72,47 @@ class InternalAuditProvider extends ChangeNotifier {
return -1;
}
}
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> addEquipmentInternalAudit({
required BuildContext context,
@ -95,6 +137,29 @@ class InternalAuditProvider extends ChangeNotifier {
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;

@ -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),
);
});

@ -33,14 +33,14 @@ 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,
// );
}
// 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]);

Loading…
Cancel
Save