internal audit api's implementation in progress
parent
81dd799672
commit
81dd189025
@ -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,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue