mark as complete confirmation dialog and new timer added for all type of requests

design_3.0_task_module_new
WaseemAbbasi22 5 months ago
parent 4c88dce72c
commit 4d15dc9dab

@ -105,14 +105,14 @@ class BaseStep extends StatelessWidget {
Color _handleTitleColor(BuildContext context, bool isFinished, bool isActive,
bool isAlreadyReached) {
if (isActive) {
return activeTextColor ?? Theme.of(context).colorScheme.primary;
return activeTextColor;
} else {
if (isFinished) {
return Colors.transparent;
} else if (isAlreadyReached) {
return Colors.transparent;
} else {
return unreachedTextColor ?? Colors.grey.shade400;
return unreachedTextColor;
}
}
}

@ -85,6 +85,7 @@ class DeviceTransfer {
this.receiverVisitTimers,
this.assetTransferEngineerTimers,
this.tbsTimer,
this.deviceTimePicker,
this.timerModelList,
this.assistantEmployees,
this.modelAssistantEmployees,
@ -309,6 +310,7 @@ class DeviceTransfer {
List<AssetTransferContactPerson>? assetTransferContactPersons;
AssetTransferAssistantEmployees? modelAssistantEmployees;
TimerModel? tbsTimer = TimerModel();
TimerModel? deviceTimePicker;
DeviceTransfer copyWith(
{num? id,
@ -382,7 +384,8 @@ class DeviceTransfer {
String? destDepartmentName,
List<VisitTimers>? senderVisitTimers,
List<VisitTimers>? receiverVisitTimers,
TimerModel? tbsTimer}) =>
TimerModel? tbsTimer,
TimerModel? deviceTimePicker}) =>
DeviceTransfer(
id: id ?? this.id,
transferNo: transferNo ?? this.transferNo,
@ -454,6 +457,7 @@ class DeviceTransfer {
senderVisitTimers: senderVisitTimers ?? this.senderVisitTimers,
receiverVisitTimers: receiverVisitTimers ?? this.receiverVisitTimers,
tbsTimer: tbsTimer ?? this.tbsTimer,
deviceTimePicker: deviceTimePicker ?? this.deviceTimePicker,
manufacturerName: manufacturerName ?? this.manufacturerName);
Map<String, dynamic> toJson() {

@ -45,6 +45,7 @@ class GasRefillModel {
this.localEngineerSignature,
this.localNurseSignature,
this.timer,
this.gasRefillTimePicker,
this.timerModelList,
this.gasRefillTimers,
this.gasRefillAttachments,
@ -83,6 +84,7 @@ class GasRefillModel {
Uint8List? localNurseSignature; // Now nullable
Uint8List? localEngineerSignature; // Now nullable
TimerModel? timer = TimerModel();
TimerModel? gasRefillTimePicker;
List<TimerModel>? timerModelList = [];
List<GasRefillTimer>? gasRefillTimers = [];
List<GasRefillAttachments>? gasRefillAttachments;

@ -88,46 +88,47 @@ class TaskData {
TimerModel? taskTimerModel = TimerModel();
double? totalWorkingHours = 0.0;
List<TimerModel>? timerModelList = [];
TaskData({
this.id,
this.statusValue,
this.taskJobNo,
this.userCreated,
this.taskJobContactPersons,
this.taskType,
this.taskJobStatus,
this.asset,
this.site,
this.building,
this.floor,
this.department,
this.room,
this.callComment,
this.taskJobAttachments,
this.assignedEngineer,
this.taskJobAssistantEmployees,
this.modelAssistantEmployees,
this.assistantEmployees,
this.taskJobHistories,
this.installationBuilding,
this.installationFloor,
this.installationDepartment,
this.serialNo,
this.installationDate,
this.completedAction,
this.impactStatus,
this.isUserAcknowledge,
this.typeOfAlert,
this.riskLevel,
this.resource,
this.actionNeeded,
this.alertNo,
this.estimationDeliveryDate,
this.reasonOfFSCA,
this.correctiveActionDescription,
this.evaluatorUser,
});
TimerModel? taskTimePicker;
TaskData(
{this.id,
this.statusValue,
this.taskJobNo,
this.userCreated,
this.taskJobContactPersons,
this.taskType,
this.taskJobStatus,
this.asset,
this.site,
this.building,
this.floor,
this.department,
this.room,
this.callComment,
this.taskJobAttachments,
this.assignedEngineer,
this.taskJobAssistantEmployees,
this.modelAssistantEmployees,
this.assistantEmployees,
this.taskJobHistories,
this.installationBuilding,
this.installationFloor,
this.installationDepartment,
this.serialNo,
this.installationDate,
this.completedAction,
this.impactStatus,
this.isUserAcknowledge,
this.typeOfAlert,
this.riskLevel,
this.resource,
this.actionNeeded,
this.alertNo,
this.estimationDeliveryDate,
this.reasonOfFSCA,
this.correctiveActionDescription,
this.evaluatorUser,
this.taskTimePicker});
TaskData.fromJson(Map<String, dynamic> json) {
id = json['id'];

@ -50,6 +50,7 @@ class PlanPreventiveVisit {
List<PreventiveVisitSuppliers>? preventiveVisitSuppliers;
TimerModel? tbsTimer = TimerModel();
List<TimerModel>? timerModelList = [];
TimerModel? ppMTimePicker;
PlanPreventiveVisit(
{this.id,
@ -91,6 +92,7 @@ class PlanPreventiveVisit {
this.preventiveVisitKits,
this.preventiveVisitTimers,
this.timerModelList,
this.ppMTimePicker,
this.preventiveVisitSuppliers});
PlanPreventiveVisit.fromJson(Map<String, dynamic> json) {

@ -54,6 +54,7 @@ class RecurrentWoData {
double? totalWorkingHours = 0.0;
List<TimerModel>? timerModelList = [];
String? comment;
TimerModel? recurrentWoTimePicker;
RecurrentWoData(
{this.id,
@ -71,6 +72,7 @@ class RecurrentWoData {
this.planRecurrentMedicalTaskRooms,
this.planRecurrentTaskTimers,
this.timerModelList,
this.recurrentWoTimePicker,
this.comment,
this.totalWorkingHours});

@ -17,6 +17,7 @@ import 'package:test_sa/modules/cm_module/views/components/verify_arrival_view.d
import 'package:test_sa/modules/cm_module/views/forms/asset_retired/verify_asset_detail.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/swipe_module/dialoge/acknowledge_work_dialog.dart';
import 'package:test_sa/providers/service_request_providers/reject_reason_provider.dart';
class FooterActionButton {
@ -205,7 +206,24 @@ class FooterActionButton {
buttonColor: AppColor.green70,
onPressed: () {
bool isValid = ServiceRequestBottomSheet.validateAssetSituation(Provider.of<ServiceRequestDetailProvider>(context, listen: false));
if (isValid) ServiceRequestBottomSheet.feedBackBottomSheet(context: context);
if (isValid) {
showDialog(
context: context,
builder: (BuildContext cxt) => AcknowledgeWorkDialog(
message: "Are you sure you want to mark this Work Order as complete ",
confirmButtonText: 'Complete',
cancelButtonText: 'Cancel',
onSave: () async {
int status = await requestDetailProvider.engineerMarkAsFixed(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, feedback: '');
if (status != -1) {
Navigator.of(cxt).pop();
}
},
onDiscard: () {},
),
);
}
// ServiceRequestBottomSheet.feedBackBottomSheet(context: context);
},
),
]

@ -91,6 +91,9 @@ class TimeDurationView extends StatelessWidget {
child: AppTimer(
label: context.translation.workingHours,
timer: TimerModel(),
onPick: (TimerModel ?value){
},
decoration: BoxDecoration(
color: AppColor.background(context),
borderRadius: BorderRadius.circular(10),

@ -50,6 +50,18 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
}
ppmProvider.planPreventiveVisit?.preventiveVisitTimers = ppmProvider.planPreventiveVisit?.preventiveVisitTimers ?? [];
if (ppmProvider.planPreventiveVisit?.ppMTimePicker != null) {
int durationInSecond = ppmProvider.planPreventiveVisit!.ppMTimePicker!.endAt!.difference(ppmProvider.planPreventiveVisit!.ppMTimePicker!.startAt!).inSeconds;
ppmProvider.planPreventiveVisit?.preventiveVisitTimers?.add(
PreventiveVisitTimers(
id: 0,
startDateTime: ppmProvider.planPreventiveVisit?.ppMTimePicker!.startAt!.toIso8601String(), // Handle potential null
endDateTime: ppmProvider.planPreventiveVisit?.ppMTimePicker!.endAt?.toIso8601String(), // Handle potential null
workingHours: ((durationInSecond) / 60 / 60),
),
);
}
ppmProvider.planPreventiveVisit?.timerModelList?.forEach((timer) {
int durationInSecond = timer.endAt!.difference(timer.startAt!).inSeconds;
ppmProvider.planPreventiveVisit?.preventiveVisitTimers?.add(
@ -78,11 +90,10 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
@override
void initState() {
ppmProvider = Provider.of<PpmProvider>(context, listen: false);
_planPreventiveVisit = widget.planPreventiveVisit;
// WidgetsBinding.instance.addPostFrameCallback((_) {
initTabs(_planPreventiveVisit.typeOfService);
initTabs(_planPreventiveVisit.typeOfService);
// });
super.initState();
}
@ -114,9 +125,11 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
backgroundColor: AppColor.neutral110,
appBar: DefaultAppBar(
title: context.translation.preventiveMaintenance,
onWillPopScope:ppmProvider.isReadOnly?null: () {
_onSubmit(status: 0);
},
onWillPopScope: ppmProvider.isReadOnly
? null
: () {
_onSubmit(status: 0);
},
),
key: _scaffoldKey,
body: SafeArea(
@ -234,14 +247,14 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
visible: tabIndex != 0,
child: AppFilledButton(
onPressed: () {
if(ppmProvider.totalTabs == _tabController!.index + 1){
if (ppmProvider.totalTabs == _tabController!.index + 1) {
Navigator.pop(context);
return;
}
_tabController?.animateTo(_tabController!.index + 1);
setState(() {});
_tabController?.animateTo(_tabController!.index + 1);
setState(() {});
},
label:ppmProvider.totalTabs == _tabController!.index + 1? context.translation.close: context.translation.next,
label: ppmProvider.totalTabs == _tabController!.index + 1 ? context.translation.close : context.translation.next,
).expanded,
),
]
@ -250,8 +263,11 @@ class _UpdatePpmState extends State<UpdatePpm> with TickerProviderStateMixin {
],
),
),
).handlePopScope(cxt: context, showPopUp:!ppmProvider.isReadOnly ,onSave: () {
_onSubmit(status: 0);
});
).handlePopScope(
cxt: context,
showPopUp: !ppmProvider.isReadOnly,
onSave: () {
_onSubmit(status: 0);
});
}
}

@ -357,6 +357,11 @@ class _WoInfoFormState extends State<WoInfoForm> {
width: double.infinity,
timer: widget.planPreventiveVisit.tbsTimer,
// enabled: widget.planPreventiveVisit.tbsTimer?.endAt == null,
pickerTimer: widget.planPreventiveVisit.ppMTimePicker,
canPickTime: true,
onPick: (time) {
widget.planPreventiveVisit.ppMTimePicker = time;
},
timerProgress: (isRunning) {},
onChange: (timer) async {
widget.planPreventiveVisit.tbsTimer = timer;

@ -82,6 +82,11 @@ class RecurrentTaskInfoWidget extends StatelessWidget {
color: AppColor.neutral100,
borderRadius: BorderRadius.circular(10),
),
pickerTimer: model?.recurrentWoTimePicker,
canPickTime: true,
onPick: (time) {
model?.recurrentWoTimePicker = time;
},
timerProgress: (isRunning) {},
onChange: (timer) async {
snapshot.updateRecurrentWoTimer(timer: timer);

@ -115,6 +115,18 @@ void _updateTask({required BuildContext context, required int status}) async {
if (validate(model: allRequestsProvider.recurrentWoData!)) {
allRequestsProvider.recurrentWoData?.planRecurrentTaskTimers = allRequestsProvider.recurrentWoData?.planRecurrentTaskTimers ?? [];
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
if (allRequestsProvider.recurrentWoData?.recurrentWoTimePicker != null) {
int durationInSecond = allRequestsProvider.recurrentWoData!.recurrentWoTimePicker!.endAt!.difference(allRequestsProvider.recurrentWoData!.recurrentWoTimePicker!.startAt!).inSeconds;
allRequestsProvider.recurrentWoData?.planRecurrentTaskTimers?.add(
PlanRecurrentTaskTimers(
id: 0,
startTime: allRequestsProvider.recurrentWoData!.recurrentWoTimePicker!.startAt!.toIso8601String(), // Handle potential null
endTime: allRequestsProvider.recurrentWoData!.recurrentWoTimePicker!.endAt?.toIso8601String(), // Handle potential null
workingHours: ((durationInSecond) / 60 / 60),
),
);
}
allRequestsProvider.recurrentWoData?.timerModelList?.forEach((timer) {
int durationInSecond = timer.endAt!.difference(timer.startAt!).inSeconds;
allRequestsProvider.recurrentWoData?.planRecurrentTaskTimers?.add(

@ -190,6 +190,17 @@ class _UpdateTaskRequestState extends State<UpdateTaskRequest> {
attachment.add(TaskJobAttachment(id: 0, name: ServiceRequestUtils.isLocalUrl(item.path) ? "${item.path.split("/").last}|${base64Encode(item.readAsBytesSync())}" : item.path));
}
taskModel?.taskJobAttachments = attachment;
if (taskModel?.taskTimePicker != null) {
int durationInSecond = taskModel!.taskTimePicker!.endAt!.difference(taskModel.taskTimePicker!.startAt!).inSeconds;
taskModel.taskJobActivityEngineerTimers?.add(
TaskJobActivityEngineerTimer(
id: 0,
startDate: taskModel.taskTimePicker!.startAt!.toIso8601String(), // Handle potential null
endDate: taskModel.taskTimePicker!.endAt?.toIso8601String(), // Handle potential null
totalWorkingHour: ((durationInSecond) / 60 / 60),
),
);
}
taskModel?.timerModelList?.forEach((timer) {
int durationInSecond = timer.endAt!.difference(timer.startAt!).inSeconds;
taskModel.taskJobActivityEngineerTimers?.add(
@ -483,6 +494,11 @@ class _UpdateTaskRequestState extends State<UpdateTaskRequest> {
color: AppColor.neutral90,
borderRadius: BorderRadius.circular(10),
),
pickerTimer: taskProvider.taskRequestModel?.taskTimePicker,
canPickTime: true,
onPick: (time) {
taskProvider.taskRequestModel?.taskTimePicker = time;
},
timerProgress: (isRunning) {},
onChange: (timer) async {
taskProvider.updateTaskTimer(timer: timer);

@ -9,11 +9,13 @@ class AcknowledgeWorkDialog extends StatelessWidget {
final String? title;
final String? message;
final String? okTitle;
final String? confirmButtonText;
final String? cancelButtonText;
final VoidCallback onSave;
final VoidCallback onDiscard;
const AcknowledgeWorkDialog(
{Key? key, this.title, this.message = "To prevent the risk of losing your changes, Please confirm Save or Discard", this.okTitle, required this.onSave, required this.onDiscard})
{Key? key, this.title, this.message = "To prevent the risk of losing your changes, Please confirm Save or Discard", this.okTitle, required this.onSave, required this.onDiscard,this.confirmButtonText,this.cancelButtonText})
: super(key: key);
@override
@ -37,7 +39,7 @@ class AcknowledgeWorkDialog extends StatelessWidget {
Row(
children: [
AppFilledButton(
label: "Discard",
label: cancelButtonText?? "Discard",
buttonColor: Colors.white54,
textColor: AppColor.red30,
height: 40,
@ -49,7 +51,7 @@ class AcknowledgeWorkDialog extends StatelessWidget {
).expanded,
16.width,
AppFilledButton(
label: "Save",
label:confirmButtonText?? "Save",
onPressed: () {
Navigator.of(context).pop();
onSave();

@ -58,8 +58,21 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
_formModel.statusValue = status;
_formModel.isSender = widget.isSender;
_formModel.assetTransferAttachments = [];
VisitTimers? deviceTimerPicker;
if (_formModel.deviceTimePicker != null) {
int durationInSecond =
_formModel.deviceTimePicker!.endAt!.difference(_formModel.deviceTimePicker!.startAt!).inSeconds;
deviceTimerPicker = VisitTimers(
id: 0,
startDateTime: _formModel.deviceTimePicker?.startAt?.toIso8601String(),
endDateTime: _formModel.deviceTimePicker?.endAt?.toIso8601String(),
workingHours: ((durationInSecond) / 60 / 60),
);
}
int workingHours = _formModel.tbsTimer?.endAt!.difference(_formModel.tbsTimer!.startAt!).inSeconds ?? 0;
if (widget.isSender) {
_formModel.senderVisitTimers?.add(deviceTimerPicker!);
_formModel.senderVisitTimers?.add(
VisitTimers(
id: 0,
@ -70,6 +83,7 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
);
_formModel.assetTransferEngineerTimers = _formModel.senderVisitTimers;
} else {
_formModel.receiverVisitTimers?.add(deviceTimerPicker!);
_formModel.receiverVisitTimers?.add(
VisitTimers(
id: 0,
@ -275,6 +289,11 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
color: AppColor.neutral100,
borderRadius: BorderRadius.circular(10),
),
pickerTimer: _formModel.deviceTimePicker,
canPickTime: true,
onPick: (time) {
_formModel.deviceTimePicker = time;
},
timerProgress: (isRunning) {},
onChange: (timer) async {
updateTimer(timer: timer);

@ -234,6 +234,11 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
label: context.translation.workingHours,
timer: _formModel.timer,
enabled: _formModel.endDate == null,
pickerTimer: _formModel.gasRefillTimePicker,
canPickTime: true,
onPick: (time) {
_formModel.gasRefillTimePicker = time;
},
onChange: (timer) async {
_formModel.timer = timer;
return true;

@ -111,7 +111,18 @@ class _UpdateGasRefillRequestState extends State<UpdateGasRefillRequest> {
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(
@ -275,8 +286,11 @@ class _UpdateGasRefillRequestState extends State<UpdateGasRefillRequest> {
AppTimer(
label: context.translation.workingHours,
timer: _formModel.timer,
//TODO need to fix this..
// enabled: _formModel.endDate == null,
pickerTimer: _formModel.gasRefillTimePicker,
canPickTime: true,
onPick: (time) {
_formModel.gasRefillTimePicker = time;
},
width: double.infinity,
decoration: BoxDecoration(
color: AppColor.neutral100,

@ -120,7 +120,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
}
_serviceReport.assetType = _assetTypeProvider.statuses?.firstWhere(
(element) => element.value == _serviceReport.callRequest?.assetType,
orElse: null,
orElse: null,
);
return Scaffold(
@ -176,15 +176,16 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
setState(() {
_serviceReport.visitDate = selectedDateTime.toIso8601String();
});
}
}
});
},
},
),
8.height,
AppTimer(
label: context.translation.workingHours,
timer: _serviceReport.timer,
enabled: _serviceReport.endofWorkTime == null,
onPick: (value) {},
onChange: (timer) async {
_serviceReport.timer = timer;
if (timer.startAt != null && timer.endAt != null) {
@ -209,7 +210,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
await _assetTypeProvider.getTypes();
_serviceReport.assetType = _assetTypeProvider.statuses?.firstWhere(
(element) => element.value == _serviceReport.callRequest!.assetType,
orElse: null,
orElse: null,
);
},
child: AppTextFormField(
@ -301,7 +302,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
setState(() {
loanAvailabilityAsset = asset;
});
},
},
),
8.height,
ServiceReportAssistantEmployeeMenu(

@ -104,7 +104,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
_settingProvider = Provider.of<SettingProvider>(context);
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_assetTypeProvider = Provider.of<ServiceStatusProvider>(context);
_serviceReport.assetType = _assetTypeProvider.statuses?.firstWhere((element) => element.value == _callRequestForWorkOrder.assetType, orElse: null);
_serviceReport.assetType = _assetTypeProvider.statuses?.firstWhere((element) => element.value == _callRequestForWorkOrder.assetType, orElse: null);
return Scaffold(
key: _scaffoldKey,
appBar: DefaultAppBar(title: context.translation.updateWorkOrder),
@ -154,9 +154,9 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
setState(() {
_serviceReport.visitDate = selectedDateTime.toIso8601String();
});
}
}
});
},
},
),
8.height,
AppTimer(
@ -167,6 +167,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
_serviceReport.timer = timer;
return true;
},
onPick: (value) {},
),
8.height,
LoadingManager(
@ -178,7 +179,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
await _assetTypeProvider.getTypes();
_serviceReport.assetType = _assetTypeProvider.statuses?.firstWhere(
(element) => element.value == _serviceReport.callRequest?.assetType,
orElse: null,
orElse: null,
);
},
child: AppTextFormField(
@ -270,7 +271,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
setState(() {
loanAvailabilityAsset = asset;
});
},
},
),
if (_serviceReport.assetLoan != null && loanAvailabilityAsset == null)
Card(child: "${context.translation.assetNumber}: ${_serviceReport.assetLoan?.assetNumber}".bodyText(context).paddingAll(16)),

Loading…
Cancel
Save