Asset tranfer api integrated ready to test

design_3.0_task_module_new
WaseemAbbasi22 8 months ago
parent 289d06ff68
commit be8c83cc8f

@ -178,11 +178,16 @@ class URLs {
//device transfer
static get requestDeviceTransfer => "$_baseUrl/AssetTransfer/AddAssetTransfer"; // get
static get updateDeviceTransfer => "$_baseUrl/AssetTransfer/UpdateAssetTransfer"; // get
// static get updateDeviceTransfer => "$_baseUrl/AssetTransfer/UpdateAssetTransfer"; // get
static get getDeviceTransfer => "$_baseUrl/AssetTransfer/GetAssetTransfers"; // get
static get getAssetTransferById => "$_baseUrl/AssetTransfer/GetAssetTransferById"; // get
// static get getAssetTransferById => "$_baseUrl/AssetTransfer/GetAssetTransferById"; // get
static get getAssetTransferStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=406"; // get
//Asset transfer new Apis
static get getAssetTransferById => "$_baseUrl/AssetTransfer/GetAssetTransferNewById"; // get
static get createAssetTransferRequest => "$_baseUrl/AssetTransfer/AddAssetTransferMobileNew";// post
static get updateDeviceTransfer => "$_baseUrl/AssetTransfer/UpdateEngineerAssetTransferNew"; // get
// employee
static get getEmployees => "$_baseUrl/Lookups/GetLookup?lookupEnum=33"; // get
static get getEngineers => "$_baseUrl/Account/GetUserByRoleValue?value=R-6"; // get

@ -6,8 +6,10 @@ 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/extensions/string_extensions.dart';
import 'package:test_sa/models/device/asset.dart';
import 'package:test_sa/models/device/asset_transfer.dart';
import 'package:test_sa/models/service_request/pending_service_request_model.dart';
import 'package:test_sa/models/user.dart';
import '../../../models/hospital.dart';
@ -120,15 +122,27 @@ class AssetTransferProvider extends ChangeNotifier {
}
}
Future<PendingAssetServiceRequest?> checkAssetPendingRequest(int assetId) async {
Response response;
try {
response = await ApiManager.instance.post(URLs.CheckIfAssetHasAnotherServiceRequest + "?assetId=$assetId",body: {});
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {}
return PendingAssetServiceRequest.fromJson(json.decode(response.body)["data"]);
} catch (error) {
"Please Try Again\n$error".addTranslation.showToast;
return null;
}
}
Future<void> createRequest({
required BuildContext context,
required AssetTransfer assetDestination,
required Asset asset,
required AssetTransfer model,
}) async {
Response response;
try {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
response = await ApiManager.instance.post(URLs.requestDeviceTransfer, body: assetDestination.transferBody(asset: asset));
response = await ApiManager.instance.post(URLs.createAssetTransferRequest, body: model.toCreateAssetTransferJson());
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
if (items != null) {
@ -148,29 +162,15 @@ class AssetTransferProvider extends ChangeNotifier {
}
}
Future<int> updateRequest(BuildContext context, {required AssetTransfer assetTransfer, required bool isSender}) async {
Future<int> updateRequest(BuildContext context, {required AssetTransfer model}) async {
Response response;
try {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
response = await ApiManager.instance.put(URLs.updateDeviceTransfer, body: assetTransfer.toJson());
//print(response.body);
// print("${newModel.engSignature}.png");
// response = await post(
// Uri.parse("$host${URLs.updateDeviceTransfer}/$requestId"),
// body: body,
// );
response = await ApiManager.instance.post(URLs.updateDeviceTransfer, body: model.toEngineerUpdateJson());
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
reset();
// Fluttertoast.showToast(msg: context.translation.successfulRequestMessage);
Navigator.of(context).pop();
// oldModel.fromDeviceTransfer(
// DeviceTransfer.fromJson(
// json.decode(utf8.decode(response.bodyBytes))[0]
// )
// );
notifyListeners();
} else {
Fluttertoast.showToast(msg: "${context.translation.failedToCompleteRequest} :${json.decode(response.body)['message']}");
@ -184,8 +184,5 @@ class AssetTransferProvider extends ChangeNotifier {
}
}
bool _isLocalUrl(String? url) {
if (url?.isEmpty ?? true) return false;
return url!.startsWith("/") || url.startsWith("file://") || url.substring(1).startsWith(':\\');
}
}

@ -549,6 +549,8 @@
"attachments": "المرفقات",
"supplierName": "اسم المورد",
"externalEngineerName": "اسم المهندس الخارجي",
"telephone": "الهاتف"
"telephone": "الهاتف",
"transferAsset": "نقل الأصل",
"createAssetTransferRequest": "إنشاء طلب نقل أصل"
}

@ -552,5 +552,7 @@
"attachments": "Attachments",
"supplierName": "Supplier Name",
"externalEngineerName": "External Engineer Name",
"telephone": "Telephone"
"telephone": "Telephone",
"transferAsset": "Transfer Asset",
"createAssetTransferRequest": "Create Asset Transfer Request"
}

@ -2,6 +2,8 @@ import 'package:flutter/src/widgets/framework.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/device/asset.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/new_models/assistant_employee.dart';
import 'package:test_sa/models/ppm/ppm.dart';
import 'package:test_sa/models/timer_model.dart';
@ -11,6 +13,7 @@ class AssetTransfer {
AssetTransfer({
this.id,
this.transferNo,
this.transferType,
this.transferCode,
this.assetId,
this.destSiteId,
@ -44,6 +47,7 @@ class AssetTransfer {
this.receiverTravelingHours,
this.receiverEngSignature,
this.receiverAttachments,
this.attachments,
this.assetNumber,
this.assetName,
this.manufacturerName,
@ -52,6 +56,7 @@ class AssetTransfer {
this.destDepartmentName,
this.destBuildingName,
this.applied,
this.isSender,
this.extensionNo,
this.name,
this.employeeId,
@ -76,14 +81,21 @@ class AssetTransfer {
this.supplierName,
this.senderVisitTimers,
this.receiverVisitTimers,
this.assetTransferEngineerTimers,
this.tbsTimer,
this.timerModelList,
this.assistantEmployees,
this.modelAssistantEmployees,
this.assetTransferAssistantEmployeesReceiver,
this.assetTransferAssistantEmployeesSender,
this.statusValue,
});
AssetTransfer.fromJson(dynamic json) {
id = json['id'];
transferNo = json['transferNo'];
transferCode = json['transferCode'];
transferType = json["transferType"] == null ? null : Lookup.fromJson(json["transferType"]);
assetId = json['assetId'];
destSiteId = json['destSiteId'];
destBuildingId = json['destBuildingId'];
@ -132,6 +144,19 @@ class AssetTransfer {
receiverVisitTimers!.add(VisitTimers.fromJson(v));
});
}
if (json['assetTransferAssistantEmployeesSender'] != null) {
assetTransferAssistantEmployeesSender = [];
json['assetTransferAssistantEmployeesSender'].forEach((v) {
assetTransferAssistantEmployeesSender!.add(AssetTransferAssistantEmployees.fromJson(v));
});
}
if (json['assetTransferAssistantEmployeesReceiver'] != null) {
assetTransferAssistantEmployeesReceiver = [];
json['assetTransferAssistantEmployeesReceiver'].forEach((v) {
assetTransferAssistantEmployeesReceiver!.add(AssetTransferAssistantEmployees.fromJson(v));
});
}
tbsTimer = TimerModel();
// try {
// receiverTimer = TimerModel(startAt: DateTime.tryParse(receiverStartDate ?? ""), endAt: DateTime.tryParse(receiverEndDate ?? ""));
@ -188,6 +213,8 @@ class AssetTransfer {
num? id;
num? transferNo;
String? transferCode;
int? statusValue;
Lookup? transferType;
String? assetSerialNo;
num? assetId;
String? assetNumber;
@ -218,6 +245,7 @@ class AssetTransfer {
String? senderTravelingHours;
String? senderEngSignature;
List<AssetTransferAttachment>? senderAttachments;
List<AssetTransferAttachment>? attachments;
String? receiverAssignedEmployeeId;
num? receiverMachineStatusId;
String? receiverComment;
@ -244,6 +272,7 @@ class AssetTransfer {
String? receiverMachineStatusName;
String? receiverEngSignatureUrl;
bool? applied;
bool? isSender;
dynamic extensionNo;
String? employeeId;
String? name;
@ -252,13 +281,21 @@ class AssetTransfer {
String? modifiedOn;
List<VisitTimers>? senderVisitTimers;
List<VisitTimers>? receiverVisitTimers;
List<VisitTimers>? assetTransferEngineerTimers;
List<TimerModel>? timerModelList = [];
List<AssistantEmployees>? assistantEmployees;
List<AssetTransferAssistantEmployees>? assetTransferAssistantEmployeesSender;
List<AssetTransferAssistantEmployees>? assetTransferAssistantEmployeesReceiver;
AssetTransferAssistantEmployees? modelAssistantEmployees;
TimerModel? tbsTimer = TimerModel();
AssetTransfer copyWith(
{num? id,
num? transferNo,
String? transferCode,
Lookup? transferType,
num? assetId,
num? destSiteId,
num? destBuildingId,
@ -329,6 +366,7 @@ class AssetTransfer {
id: id ?? this.id,
transferNo: transferNo ?? this.transferNo,
transferCode: transferCode ?? this.transferCode,
transferType: transferType ?? this.transferType,
assetId: assetId ?? this.assetId,
destSiteId: destSiteId ?? this.destSiteId,
destBuildingId: destBuildingId ?? this.destBuildingId,
@ -475,6 +513,44 @@ class AssetTransfer {
return map;
}
Map<String, dynamic> toCreateAssetTransferJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['assetId'] = assetId;
map['transferTypeId'] = transferType?.id;
map['destSiteId'] = destSiteId;
map['destSiteId'] = destSiteId;
map['destBuildingId'] = destBuildingId;
map['destFloorId'] = destFloorId;
map['destDepartmentId'] = destDepartmentId;
map['destRoomId'] = destRoomId;
map['comment'] = comment;
if (attachments != null) {
map['attachment'] = attachments!.map((v) => v.toJson()).toList();
}
return map;
}
Map<String, dynamic> toEngineerUpdateJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['statusValue'] = statusValue;
map['isSender'] = isSender;
map['techComment'] = comment;
map['assetTransferAssistantEmployees'] = modelAssistantEmployees;
map['assetTransferEngineerTimers'] = assetTransferEngineerTimers;
if (attachments != null) {
map['attachments'] = attachments!.map((v) => v.toJson()).toList();
}
if (assetTransferEngineerTimers != null) {
map['assetTransferEngineerTimers'] = assetTransferEngineerTimers!.map((v) => v.toJson()).toList();
}
if (modelAssistantEmployees != null) {
map['assetTransferAssistantEmployees'] = [modelAssistantEmployees!.toJson()];
}
return map;
}
Map<String, dynamic> transferBody({Asset? asset}) {
final map = <String, dynamic>{};
map['id'] = 0;
@ -529,6 +605,7 @@ class AssetTransfer {
if (assetTransfer == null) return;
id = assetTransfer.id;
transferNo = assetTransfer.transferNo;
transferType = assetTransfer.transferType;
transferCode = assetTransfer.transferCode;
assetId = assetTransfer.assetId;
destSiteId = assetTransfer.destSiteId;
@ -594,6 +671,8 @@ class AssetTransfer {
manufacturerName = assetTransfer.manufacturerName;
senderVisitTimers = assetTransfer.senderVisitTimers;
receiverVisitTimers = assetTransfer.receiverVisitTimers;
assetTransferAssistantEmployeesReceiver = assetTransfer.assetTransferAssistantEmployeesReceiver;
assetTransferAssistantEmployeesSender = assetTransfer.assetTransferAssistantEmployeesSender;
}
Future<bool> validate(BuildContext context) async {
@ -616,3 +695,42 @@ class AssetTransfer {
return true;
}
}
class AssetTransferAssistantEmployees {
DateTime? startDate;
DateTime? endDate;
double? workingHours;
String? techComment;
String? employeeId;
String? employeeNumber;
String? employeeName;
String? email;
String? mobileNo;
dynamic extension;
AssetTransferAssistantEmployees(
{this.startDate, this.endDate, this.workingHours, this.techComment, this.employeeId, this.employeeName, this.employeeNumber, this.email, this.extension, this.mobileNo});
AssetTransferAssistantEmployees.fromJson(Map<String, dynamic> json) {
startDate = json['startDate'] != null ? DateTime.parse(json['startDate']) : null;
endDate = json['endDate'] != null ? DateTime.parse(json['endDate']) : null;
workingHours = json['workingHours'];
techComment = json['techComment'];
employeeId = json['employeeId'];
employeeNumber = json['employeeNumber'];
employeeName = json['employeeName'];
email = json['email'];
mobileNo = json['mobileNo'];
extension = json['extension'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['startDate'] = startDate?.toIso8601String();
data['endDate'] = endDate?.toIso8601String();
data['workingHours'] = workingHours;
data['techComment'] = techComment;
data['employeeId'] = employeeId;
return data;
}
}

@ -12,8 +12,9 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
final List<Widget>? actions;
final Function? onBackPress;
final bool showHomeActionButton;
final TextStyle? titleStyle;
const DefaultAppBar({this.title, this.onBackPress, this.actions, this.showHomeActionButton = false, Key? key}) : super(key: key);
const DefaultAppBar({this.title, this.onBackPress, this.actions, this.showHomeActionButton = false,this.titleStyle, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -49,7 +50,7 @@ class DefaultAppBar extends StatelessWidget implements PreferredSizeWidget {
10.width,
Text(
title ?? "",
style: AppTextStyles.heading3.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
style: titleStyle??AppTextStyles.heading4.copyWith(fontWeight: FontWeight.w500, color:AppColor.white936 ),
).expanded,
],
),

@ -122,7 +122,7 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
ServiceRequestUtils.calculateAndAssignWorkingHours(
startTime: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate,
endTime: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate,
endTime: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate,
workingHoursController: _workingHoursController,
updateModel: (hours){
requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.workingHours=hours;

@ -1,29 +1,26 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/asset_transfer_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/employee/nurse_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.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/models/device/asset.dart';
import 'package:test_sa/models/device/asset_transfer.dart';
import 'package:test_sa/models/employee.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/device/asset_transfer_attachment.dart';
import 'package:test_sa/models/new_models/department.dart';
import 'package:test_sa/models/new_models/floor.dart';
import 'package:test_sa/models/new_models/room_model.dart';
import 'package:test_sa/models/service_request/pending_service_request_model.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
import 'package:test_sa/providers/ppm_service_provider.dart';
import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/views/pages/user/requests/pending_requests_screen.dart';
import 'package:test_sa/views/widgets/bottom_sheets/pending_request_bottom_sheet.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/status/employee/nurse_menu.dart';
import '../../../models/new_models/building.dart';
import '../../../models/new_models/site.dart';
import '../../../new_views/common_widgets/app_filled_button.dart';
@ -31,7 +28,6 @@ import '../../../new_views/common_widgets/default_app_bar.dart';
import '../../../new_views/common_widgets/single_item_drop_down_menu.dart';
import '../../../providers/gas_request_providers/site_provider.dart';
import '../../../providers/loading_list_notifier.dart';
import '../../widgets/equipment/pick_asset.dart';
class CreateAssetTransferRequest extends StatefulWidget {
static const String id = "/request-device-transfer";
@ -43,25 +39,28 @@ class CreateAssetTransferRequest extends StatefulWidget {
}
class _CreateAssetTransferRequestState extends State<CreateAssetTransferRequest> {
UserProvider? _userProvider;
SettingProvider? _settingProvider;
late AssetTransferProvider _deviceTransferProvider;
final TextEditingController _requestedQuantityController = TextEditingController();
final AssetTransfer _transferModel = AssetTransfer();
final AssetTransfer _transferModel = AssetTransfer(id: 0);
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
final TextEditingController _receiverNameController = TextEditingController(), _commentsController = TextEditingController();
final Asset _assetDestination = Asset();
Asset? _pickedAsset;
Employee? receiverEndUser;
Employee? _selectedNurse;
final List<File> _deviceImages = [];
PendingAssetServiceRequest? pendingAssetServiceRequest;
@override
void setState(VoidCallback fn) {
if (mounted) super.setState(() {});
}
//TODO need to clean the extra logic and code when finilize api from backend..
bool checkPendingRequest = false;
void showPendingRequests() {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => PendingServiceRequestScreen(pendingAssetServiceRequest!)));
}
void _onSubmit() async {
_transferModel.assetId = _pickedAsset?.id;
_transferModel.destSiteId = _assetDestination.site?.id;
@ -69,33 +68,32 @@ class _CreateAssetTransferRequestState extends State<CreateAssetTransferRequest>
_transferModel.destFloorId = _assetDestination.floor?.id;
_transferModel.destDepartmentId = _assetDestination.department?.id;
_transferModel.destRoomId = _assetDestination.room?.id;
_transferModel.receiverEndUserId = _selectedNurse?.id;
if (!_formKey.currentState!.validate() || !(await _transferModel.validate(context))) {
return;
}
_formKey.currentState!.save();
// List<WorkOrderAttachments> attachement = [];
// for (var item in _deviceImages) {
// attachement.add(WorkOrderAttachments(id: 0, name: "${item.path.split("/").last}|${base64Encode(item.readAsBytesSync())}"));
// }
List<AssetTransferAttachment> attachement = [];
for (var item in _deviceImages) {
attachement.add(AssetTransferAttachment(id: 0, attachmentName: "${item.path.split("/").last}|${base64Encode(item.readAsBytesSync())}"));
}
_transferModel.attachments = attachement;
await _deviceTransferProvider.createRequest(context: context, assetDestination: _transferModel, asset: _pickedAsset!);
}
List<Lookup> requestType = [
Lookup(name: 'Internal', value: 1),
Lookup(name: 'External', value: 2),
];
await _deviceTransferProvider.createRequest(
context: context,
model: _transferModel,
);
}
@override
void initState() {
// TODO: need to check parameter with backend.
// _deviceImages.addAll(_serviceRequest.devicePhotos!.map((e) => File(e)).toList());
WidgetsBinding.instance.addPostFrameCallback((_) async {
Provider.of<PpmServiceProvider>(context, listen: false).getDate();
});
super.initState();
}
Lookup selectedRequestType = Lookup(name: 'Internal', value: 1);
@override
void dispose() {
@ -108,12 +106,13 @@ class _CreateAssetTransferRequestState extends State<CreateAssetTransferRequest>
@override
Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context, listen: false);
_settingProvider = Provider.of<SettingProvider>(context, listen: false);
_deviceTransferProvider = Provider.of<AssetTransferProvider>(context, listen: false);
return Scaffold(
key: _scaffoldKey,
appBar: DefaultAppBar(title: context.translation.newTransferRequest),
appBar: DefaultAppBar(
title: context.translation.createAssetTransferRequest,
titleStyle: AppTextStyles.heading3.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),
body: Form(
key: _formKey,
child: SafeArea(
@ -123,14 +122,6 @@ class _CreateAssetTransferRequestState extends State<CreateAssetTransferRequest>
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 16.height,
// PickAsset(
// device: _pickedAsset,
// onPickAsset: (asset) {
// _pickedAsset = asset;
// setState(() {});
// },
// ),
AssetPicker(
device: _pickedAsset,
showLoading: false,
@ -138,50 +129,30 @@ class _CreateAssetTransferRequestState extends State<CreateAssetTransferRequest>
backgroundColor: AppColor.white936,
onPick: (asset) async {
_pickedAsset = asset;
await checkAssetForPendingServiceRequest(asset.id!.toInt());
if (_pickedAsset != null && pendingAssetServiceRequest != null && pendingAssetServiceRequest!.details!.isNotEmpty) {
showPendingRequestBottomSheet();
}
setState(() {});
// pendingAssetServiceRequest = null;
// _serviceRequest.device = asset;
// await checkAssetForPendingServiceRequest(asset.id!.toInt());
// if (pendingAssetServiceRequest != null && pendingAssetServiceRequest!.details!.isNotEmpty) {
// showPendingRequestBottomSheet();
}),
if (pendingAssetServiceRequest != null && pendingAssetServiceRequest!.details!.isNotEmpty) ...[
8.height,
Row(
children: [
const Icon(Icons.warning, color: Color(0xffEE404C), size: 14),
8.width,
Text(
"This asset already have ${pendingAssetServiceRequest!.details!.length} request pending",
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500, color: Color(0xff7D859A), decoration: TextDecoration.underline),
).expanded,
],
).onPress(() {
showPendingRequests();
}),
],
21.height,
context.translation.requestType.bodyText(context).custom(color: AppColor.white936),
10.height,
Wrap(
runSpacing: 8,
spacing: 20,
children: [
for (var element in requestType)
Row(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 24,
height: 24,
child: Radio(
value: element,
activeColor: AppColor.primary10,
fillColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return AppColor.primary10; // Thumb color when selected
}
return Colors.grey; // Thumb color when unselected (grey)
}),
groupValue: selectedRequestType,
onChanged: (state) {
setState(() {
selectedRequestType = element;
});
}),
),
8.width,
Text(element.name ?? '', style: AppTextStyles.tinyFont.copyWith(color: AppColor.neutral120)),
],
)
],
),
8.height,
requestTypeWidget(context),
12.height,
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@ -197,9 +168,6 @@ class _CreateAssetTransferRequestState extends State<CreateAssetTransferRequest>
_assetDestination.building = null;
_assetDestination.floor = null;
_assetDestination.department = null;
_selectedNurse = null;
Provider.of<NurseProvider>(context, listen: false).siteId = value!.id!.toInt();
Provider.of<NurseProvider>(context, listen: false).getData();
setState(() {});
},
).expanded,
@ -257,32 +225,6 @@ class _CreateAssetTransferRequestState extends State<CreateAssetTransferRequest>
],
),
8.height,
// SingleItemDropDownMenu<Rooms, NullableLoadingProvider>(
// context: context,
// title: context.translation.room,
// initialValue: _assetDestination.room,
// backgroundColor:AppColor.neutral100,
// enabled: _assetDestination.department?.rooms?.isNotEmpty ?? false,
// staticData: _assetDestination.department?.rooms ?? [],
// onSelect: (value) {
// _assetDestination.room = value;
// setState(() {});
// },
// ),
// 8.height,
// NurseMenu(
// title: context.translation.receiverName,
// initialValue: _selectedNurse,
//
// enable: _assetDestination.site != null,
// onSelect: (employee) {
// if (employee != null) {
// _selectedNurse = employee;
// setState(() {});
// }
// },
// ),
// 16.height,
AppTextFormField(
controller: _commentsController,
backgroundColor: AppColor.neutral100,
@ -309,9 +251,7 @@ class _CreateAssetTransferRequestState extends State<CreateAssetTransferRequest>
).toShadowContainer(context).paddingOnly(top: 20, start: 16, end: 16),
).expanded,
FooterActionButton.footerContainer(
child: AppFilledButton(buttonColor: AppColor.primary10, label: context.translation.submitRequest, maxWidth: true, onPressed: _onSubmit
// buttonColor: AppColor.primary10,
),
child: AppFilledButton(buttonColor: AppColor.primary10, label: context.translation.submitRequest, maxWidth: true, onPressed: _onSubmit),
),
],
),
@ -319,4 +259,84 @@ class _CreateAssetTransferRequestState extends State<CreateAssetTransferRequest>
),
);
}
Future<void> checkAssetForPendingServiceRequest(int assetId) async {
checkPendingRequest = true;
setState(() {});
pendingAssetServiceRequest = await _deviceTransferProvider.checkAssetPendingRequest(assetId);
await Future.delayed(const Duration(milliseconds: 250));
checkPendingRequest = false;
setState(() {});
}
void showPendingRequestBottomSheet() async {
bool view = (await showModalBottomSheet(
context: context,
isDismissible: false,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(20),
),
),
clipBehavior: Clip.antiAliasWithSaveLayer,
builder: (BuildContext context) => PendingRequestBottomSheet(pendingAssetServiceRequest!, _pickedAsset!),
)) as bool;
if (view) {
showPendingRequests();
}
}
Widget requestTypeWidget(BuildContext context) {
return Consumer<PpmServiceProvider>(builder: (cxt, snapshot, _) {
try {
_transferModel.transferType ??= snapshot.items.first;
} catch (ex) {
print("snapshot.items:${snapshot.items.length}");
}
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
context.translation.requestType.bodyText(context).custom(color: AppColor.white936),
8.height,
Wrap(
runSpacing: 8,
spacing: 8,
children: [
for (var element in snapshot.items)
Row(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 24,
height: 24,
child: Radio(
value: element,
activeColor: AppColor.primary10,
fillColor: WidgetStateColor.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return AppColor.primary10; // Thumb color when selected
}
return Colors.grey; // Thumb color when unselected (grey)
}),
groupValue: _transferModel.transferType,
onChanged: (state) {
_transferModel.transferType = element;
setState(() {});
// });
}),
),
8.width,
Text(element.name ?? '', style: AppTextStyles.tinyFont.copyWith(color: AppColor.neutral120)),
],
)
],
).toShimmer(isShow: snapshot.loading),
],
);
});
}
}

@ -1,3 +1,5 @@
//older code.
// import 'dart:convert';
// import 'dart:io';
//
@ -332,41 +334,32 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/asset_transfer_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_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/widget_extensions.dart';
import 'package:test_sa/models/device/asset_transfer.dart';
import 'package:test_sa/models/device/asset_transfer_attachment.dart';
import 'package:test_sa/models/new_models/work_order_detail_model.dart';
import 'package:test_sa/models/new_models/assigned_employee.dart';
import 'package:test_sa/models/new_models/assistant_employee.dart';
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/providers/asset_transfer/asset_transfer_status_provider.dart';
import 'package:test_sa/service_request_latest/service_request_detail_provider.dart';
import 'package:test_sa/service_request_latest/utilities/service_request_utils.dart';
import 'package:test_sa/service_request_latest/views/forms/maintenance_request/components/assistant_employee_card.dart';
import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.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/status/report/service_report_assistant_employee_menu.dart';
import '../../../extensions/text_extensions.dart';
import '../../../models/lookup.dart';
import '../../../models/ppm/ppm.dart';
import '../../../new_views/app_style/app_color.dart';
import '../../../new_views/common_widgets/app_text_form_field.dart';
import '../../../new_views/common_widgets/default_app_bar.dart';
import '../../../new_views/common_widgets/single_item_drop_down_menu.dart';
import '../../widgets/e_signature/e_signature.dart';
import '../../widgets/timer/app_timer.dart';
class UpdateDeviceTransfer extends StatefulWidget {
@ -381,10 +374,7 @@ class UpdateDeviceTransfer extends StatefulWidget {
class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
final bool _isLoading = false;
bool _validate = false;
late UserProvider _userProvider;
late SettingProvider _settingProvider;
Uint8List? _signature;
late AssetTransferProvider _deviceTransferProvider;
final TextEditingController _requestedQuantityController = TextEditingController();
final AssetTransfer _formModel = AssetTransfer();
@ -393,27 +383,7 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
List<File> _files = [];
_update() async {
if (widget.isSender) {
_formModel.senderVisitTimers?.add(
VisitTimers(
id: 0,
startDateTime: _formModel.tbsTimer?.startAt?.toIso8601String(),
endDateTime: _formModel.tbsTimer?.endAt?.toIso8601String(),
workingHours: ((_formModel.tbsTimer?.durationInSecond ?? 0) / 60 / 60),
),
);
} else {
_formModel.receiverVisitTimers?.add(
VisitTimers(
id: 0,
startDateTime: _formModel.tbsTimer?.startAt?.toIso8601String(),
endDateTime: _formModel.tbsTimer?.endAt?.toIso8601String(),
workingHours: ((_formModel.tbsTimer?.durationInSecond ?? 0) / 60 / 60),
),
);
}
_update({required int status}) async {
if (_formModel.tbsTimer?.startAt == null) {
await Fluttertoast.showToast(msg: "Working Hours Required");
return false;
@ -422,19 +392,38 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
await Fluttertoast.showToast(msg: "Please Stop The Timer");
return false;
}
_validate = true;
if (!(_formKey.currentState!.validate())) {
setState(() {});
return false;
}
_formKey.currentState!.save();
_formModel.statusValue = status;
_formModel.isSender = widget.isSender;
if (widget.isSender) {
_formModel.senderAttachments = [];
_formModel.senderVisitTimers?.add(
VisitTimers(
id: 0,
startDateTime: _formModel.tbsTimer?.startAt?.toIso8601String(),
endDateTime: _formModel.tbsTimer?.endAt?.toIso8601String(),
workingHours: ((_formModel.tbsTimer?.durationInSecond ?? 0) / 60 / 60),
),
);
_formModel.assetTransferEngineerTimers = _formModel.senderVisitTimers;
} else {
_formModel.receiverAttachments = [];
_formModel.receiverVisitTimers?.add(
VisitTimers(
id: 0,
startDateTime: _formModel.tbsTimer?.startAt?.toIso8601String(),
endDateTime: _formModel.tbsTimer?.endAt?.toIso8601String(),
workingHours: ((_formModel.tbsTimer?.durationInSecond ?? 0) / 60 / 60),
),
);
_formModel.assetTransferEngineerTimers = _formModel.receiverVisitTimers;
}
try {
for (var file in _files) {
String attachmentName = file.path;
@ -442,17 +431,19 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
attachmentName = file.path.split("/").last;
attachmentName = "$attachmentName|${base64Encode(file.readAsBytesSync())}";
}
if (widget.isSender) {
_formModel.senderAttachments!.add(AssetTransferAttachment(id: 0, attachmentName: attachmentName));
_formModel.attachments = _formModel.senderAttachments;
} else {
_formModel.receiverAttachments!.add(AssetTransferAttachment(id: 0, attachmentName: attachmentName));
_formModel.attachments = _formModel.receiverAttachments;
}
}
} catch (error) {
print(error);
}
await _deviceTransferProvider.updateRequest(context, assetTransfer: _formModel, isSender: widget.isSender);
await _deviceTransferProvider.updateRequest(context, model: _formModel);
}
@override
@ -478,20 +469,16 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
@override
Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_deviceTransferProvider = Provider.of<AssetTransferProvider>(context, listen: false);
double totalWorkingHours = widget.isSender
? (widget.model.senderVisitTimers?.fold(0.0, (sum, item) => (sum ?? 0) + DateTime.parse(item.endDateTime!).difference(DateTime.parse(item.startDateTime!)).inSeconds) ?? 0)
: (widget.model.receiverVisitTimers?.fold(0.0, (sum, item) => (sum ?? 0) + DateTime.parse(item.endDateTime!).difference(DateTime.parse(item.startDateTime!)).inSeconds) ?? 0);
bool isTimerEnable = widget.isSender
? (!(_formModel.senderMachineStatusName?.toLowerCase().contains("close") ?? false) || !(_formModel.senderMachineStatusName?.toLowerCase().contains("complete") ?? false))
: (!(_formModel.receiverMachineStatusName?.toLowerCase().contains("close") ?? false) || !(_formModel.receiverMachineStatusName?.toLowerCase().contains("complete") ?? false));
return Scaffold(
appBar: DefaultAppBar(title: context.translation.updateRequest),
appBar: DefaultAppBar(title: context.translation.transferAsset),
key: _scaffoldKey,
body: SafeArea(
child: LoadingManager(
@ -510,56 +497,12 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// _buildCard(),
// 8.height,
// AppTextFormField(
// initialValue: widget.isSender ? _formModel.senderTravelingHours ?? "" : _formModel.receiverTravelingHours ?? "",
// labelText: context.translation.travelingHours,
// onChange: (text) {
// widget.isSender ? _formModel.senderTravelingHours = text : _formModel.receiverTravelingHours = text;
// },
// onSaved: (value) {
// widget.isSender ? _formModel.senderTravelingHours = value : _formModel.receiverTravelingHours = value;
// //_formModel?.workingHours = double.tryParse(value);
// // _formModel.travelingHours = value;
// },
// textInputType: TextInputType.number,
// //validator: (value) => Validator.isNumeric(value) ? null : "allow numbers only",
// ),
// 8.height,
// if (totalWorkingHours > 0.0) ...[
// Container(
// height: 50.toScreenHeight,
// padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth),
// alignment: Alignment.centerLeft,
// decoration: BoxDecoration(
// color: context.isDark ? AppColor.neutral40 : AppColor.background(context),
// borderRadius: BorderRadius.circular(10),
// boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
// ),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// Text(
// "Total Working Time",
// style: Theme.of(context).textTheme.bodySmall?.copyWith(color: context.isDark ? null : AppColor.neutral20, fontWeight: FontWeight.w500),
// ),
// Text(
// " ${formatDuration(totalWorkingHours.round())}",
// style: Theme.of(context).textTheme.bodyLarge,
// ),
// ],
// ),
// ),
// 8.height,
// ],
_timerWidget(context, totalWorkingHours, isTimerEnable),
8.height,
AppTextFormField(
initialValue: widget.isSender ? _formModel.senderComment ?? "" : _formModel.receiverComment ?? "",
labelText: context.translation.comments,
labelText: context.translation.technicalComment,
labelStyle: AppTextStyles.tinyFont.copyWith(color: AppColor.neutral20),
textInputType: TextInputType.multiline,
backgroundColor: AppColor.neutral100,
showShadow: false,
@ -568,43 +511,6 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
widget.isSender ? _formModel.senderComment = value : _formModel.receiverComment = value;
},
),
// AppTimer(
// label: context.translation.workingHours,
// timer: _formModel.tbsTimer,
// enabled: isTimerEnable,
// // enabled: widget.isSender ? _formModel.senderEndDate == null : (_formModel?.receiverMachineStatusName?.toLowerCase()?.contains("close") ?? false),
// timerProgress: (isRunning) {
// isTimerRunning = isRunning;
// },
// onChange: (timer) async {
// _formModel.tbsTimer = timer;
// return true;
// },
// ),
// 8.height,
// Consumer<AssetTransferStatusProvider>(builder: (context, snapshot, _) {
// return SingleItemDropDownMenu<Lookup, AssetTransferStatusProvider>(
// context: context,
// title: widget.isSender ? "Status Sender" : "Status Receiver", //,context.translation.reportStatus,
// initialValue:snapshot.items.isNotEmpty?
// snapshot.items.firstWhere((element) => element.name == (widget.isSender ? _formModel.senderMachineStatusName : _formModel.receiverMachineStatusName), orElse: null):null,
// onSelect: (value) {
// if (value?.value == 4) {
// "Status cannot be change to ${value?.name}.".addTranslation.showToast;
// setState(() {});
// return;
// }
// if (widget.isSender) {
// _formModel.senderMachineStatusName = value?.name;
// _formModel.senderMachineStatusId = value?.id;
// } else {
// _formModel.receiverMachineStatusName = value?.name;
// _formModel.receiverMachineStatusId = value?.id;
// }
// setState(() {});
// },
// );
// }),
8.height,
MultiFilesPicker(
label: context.translation.attachFiles,
@ -614,32 +520,33 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.neutral120),
),
8.height,
// 8.height,
// ESignature(
// title: "Signature",
// oldSignature: widget.isSender ? widget.model.senderEngSignature : widget.model.receiverEngSignature,
// newSignature: _signature,
// onSaved: (signature) {
// _signature = signature;
// if (signature == null || signature.isEmpty) return;
// widget.isSender
// ? _formModel.senderEngSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"
// : _formModel.receiverEngSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
// },
// ),
],
).toShadowContainer(context),
16.height,
const AssistantEmployeeCard().toShadowContainer(context, paddingObject: const EdgeInsets.symmetric(horizontal: 16)),
AssistantEmployeeCard(
isSender: widget.isSender,
formModel: _formModel,
).toShadowContainer(context, paddingObject: const EdgeInsets.symmetric(horizontal: 16)),
],
),
).expanded,
Padding(
padding: const EdgeInsets.all(16.0),
child: AppFilledButton(
label: context.translation.update,
onPressed: _update,
FooterActionButton.footerContainer(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
AppFilledButton(
label: context.translation.save,
buttonColor: AppColor.white60,
textColor: AppColor.black10,
onPressed: () => _update(status: 0),
).expanded,
12.width,
AppFilledButton(
label: context.translation.complete,
buttonColor: AppColor.primary10,
onPressed: () => _update(status: 1),
).expanded,
],
),
),
],
@ -659,18 +566,6 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
// notifyListeners();
}
_buildCard() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
context.translation.transferDetails.heading5(context),
8.height,
'${context.translation.assetName}: ${_formModel.assetName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context),
'${context.translation.requesterName}: ${_formModel.receiverEndUserName?.cleanupWhitespace.capitalizeFirstOfEach ?? ""}'.bodyText(context),
],
).toShadowContainer(context);
}
Widget _timerWidget(BuildContext context, double totalWorkingHours, bool isTimerEnable) {
return Column(
mainAxisSize: MainAxisSize.min,
@ -708,46 +603,27 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
],
);
}
String formatDuration(int seconds) {
int hours = seconds ~/ 3600;
int minutes = (seconds % 3600) ~/ 60;
int remainingSeconds = seconds % 60;
String formattedDuration = '';
if (hours > 0) {
formattedDuration += '$hours hour${hours > 1 ? 's' : ''} ';
}
if (minutes > 0) {
formattedDuration += '$minutes minute${minutes > 1 ? 's' : ''} ';
}
if (remainingSeconds > 0) {
formattedDuration += '$remainingSeconds second${remainingSeconds > 1 ? 's' : ''} ';
}
if (formattedDuration.isEmpty) {
formattedDuration = 'Less than a second';
}
return formattedDuration.trim();
}
}
class AssistantEmployeeCard extends StatefulWidget {
const AssistantEmployeeCard({super.key});
bool? isSender = false;
AssetTransfer? formModel;
AssistantEmployeeCard({super.key, this.isSender, this.formModel});
@override
State<AssistantEmployeeCard> createState() => _AssistantEmployeeCardState();
}
class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
bool status = false;
final TextEditingController _workingHoursController = TextEditingController(text: '');
bool isCurrentUserIsAssistantEmp = false;
bool isExpanded = false;
List<AssetTransferAssistantEmployees> employeeList = [];
AssistantEmployees selectedEmployee = AssistantEmployees();
@override
void initState() {
// TODO: implement initState
WidgetsBinding.instance.addPostFrameCallback((_) {
getInitialData();
});
@ -755,202 +631,171 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
}
Future<void> getInitialData() async {
final user = Provider.of<UserProvider>(context, listen: false).user!;
ServiceRequestDetailProvider requestDetailProvider = Provider.of<ServiceRequestDetailProvider>(context, listen: false);
isCurrentUserIsAssistantEmp = (user.userID != requestDetailProvider.currentWorkOrder?.data?.assignedEmployee?.userId);
// if (isCurrentUserIsAssistantEmp) {
// // _subWorkOrders.assistantEmployees = [widget.workOrder.assistantEmployees?.first?.copyWith(id: 0)];
// }
if (widget.isSender!) {
employeeList = widget.formModel!.assetTransferAssistantEmployeesSender ?? [];
} else {
employeeList = widget.formModel!.assetTransferAssistantEmployeesReceiver ?? [];
}
widget.formModel?.modelAssistantEmployees = employeeList.isNotEmpty ? employeeList[0] : AssetTransferAssistantEmployees();
AssignedEmployee? assignedUser = AssignedEmployee(
id: employeeList[0].employeeId,
name: employeeList[0].employeeName,
);
selectedEmployee = AssistantEmployees(userId: assignedUser.id, user: assignedUser);
}
@override
void dispose() {
// TODO: implement dispose
_workingHoursController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Consumer<ServiceRequestDetailProvider>(builder: (context, requestDetailProvider, child) {
return Column(
children: [
SizedBox(
height: 56.toScreenHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
context.translation.assistantEmployee.heading6(context).custom(color: AppColor.black10),
Icon(isExpanded ? Icons.keyboard_arrow_up_rounded : Icons.keyboard_arrow_down_rounded),
],
),
).onPress(() {
setState(() {
isExpanded = !isExpanded;
});
}),
isExpanded
? Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ServiceReportAssistantEmployeeMenu(
title: context.translation.select,
backgroundColor: AppColor.neutral100,
// assetId: requestDetailProvider.currentWorkOrder!.data!.asset!.id!,
// initialValue: (requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees?.isNotEmpty ?? false)
// ? requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees?.first
// : null,
initialValue: null,
assetId: 23,
//TODO add check...
// enable: !isCurrentUserIsAssistantEmp,
onSelect: (employee) {
if (employee == null) {
requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = [];
} else {
requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = [employee.copyWith(id: 0)];
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.user = AssignedEmployee(userId: employee.user?.id, userName: employee.user?.name);
}
},
),
8.height,
Row(
mainAxisSize: MainAxisSize.min,
children: [
ADatePicker(
label: context.translation.startTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
// Handle the selected date and time here.
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
ServiceRequestUtils.calculateAndAssignWorkingHours(
startTime: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate,
endTime: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate,
workingHoursController: _workingHoursController,
updateModel: (hours) {
requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.workingHours = hours;
});
}
});
},
).expanded,
8.width,
ADatePicker(
label: context.translation.endTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
// Handle the selected date and time here.
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
if (requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate != null &&
selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.startDate!)) {
"End Date time must be greater then start date".showToast;
return;
}
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
ServiceRequestUtils.calculateAndAssignWorkingHours(
startTime: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate,
endTime: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate,
workingHoursController: _workingHoursController,
updateModel: (hours) {
requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.workingHours = hours;
});
return Column(
children: [
SizedBox(
height: 56.toScreenHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
context.translation.assistantEmployee.heading6(context).custom(color: AppColor.black10),
Icon(isExpanded ? Icons.keyboard_arrow_up_rounded : Icons.keyboard_arrow_down_rounded),
],
),
).onPress(() {
setState(() {
isExpanded = !isExpanded;
});
}),
isExpanded
? Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ServiceReportAssistantEmployeeMenu(
title: context.translation.select,
backgroundColor: AppColor.neutral100,
assetId: widget.formModel?.assetId ?? 0,
initialValue: selectedEmployee,
onSelect: (employee) {
if (employee == null) {
widget.formModel?.assistantEmployees = [];
} else {
widget.formModel?.assistantEmployees = [employee.copyWith(id: 0)];
widget.formModel?.modelAssistantEmployees?.employeeId = employee.user?.id;
}
},
),
8.height,
Row(
mainAxisSize: MainAxisSize.min,
children: [
ADatePicker(
label: context.translation.startTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: widget.formModel?.modelAssistantEmployees?.startDate,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
// Handle the selected date and time here.
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
widget.formModel?.modelAssistantEmployees?.startDate = selectedDateTime;
ServiceRequestUtils.calculateAndAssignWorkingHours(
startTime: widget.formModel?.modelAssistantEmployees?.startDate,
endTime: widget.formModel?.modelAssistantEmployees?.endDate,
workingHoursController: _workingHoursController,
updateModel: (hours) {
widget.formModel?.modelAssistantEmployees?.workingHours = hours;
});
setState(() {});
}
});
},
).expanded,
8.width,
ADatePicker(
label: context.translation.endTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: widget.formModel?.modelAssistantEmployees?.endDate,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
if (widget.formModel?.modelAssistantEmployees?.startDate != null && selectedDateTime.isBefore(widget.formModel!.modelAssistantEmployees!.startDate!)) {
"End Date time must be greater then start date".showToast;
return;
}
});
},
).expanded,
],
),
8.height,
AppTextFormField(
labelText: context.translation.workingHours,
backgroundColor: AppColor.neutral80,
controller: _workingHoursController,
suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16),
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.workingHours != null
? requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.workingHours.toString()
: '',
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
enable: false,
showShadow: false,
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
AppTextFormField(
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment,
labelText: context.translation.technicalComment,
backgroundColor: AppColor.neutral100,
showShadow: false,
labelStyle: AppTextStyles.textFieldLabelStyle,
alignLabelWithHint: true,
textInputType: TextInputType.multiline,
onChange: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = value;
},
onSaved: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = value;
},
),
16.height,
],
)
: const SizedBox(),
],
);
});
widget.formModel?.modelAssistantEmployees?.endDate = selectedDateTime;
ServiceRequestUtils.calculateAndAssignWorkingHours(
startTime: widget.formModel?.modelAssistantEmployees?.startDate,
endTime: widget.formModel?.modelAssistantEmployees?.endDate,
workingHoursController: _workingHoursController,
updateModel: (hours) {
widget.formModel?.modelAssistantEmployees?.workingHours = hours;
});
setState(() {});
}
});
},
).expanded,
],
),
8.height,
AppTextFormField(
labelText: context.translation.workingHours,
backgroundColor: AppColor.neutral80,
controller: _workingHoursController,
suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16),
initialValue: widget.formModel?.modelAssistantEmployees?.workingHours != null ? widget.formModel?.modelAssistantEmployees?.workingHours.toString() : '',
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
enable: false,
showShadow: false,
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
AppTextFormField(
initialValue: widget.formModel?.modelAssistantEmployees?.techComment,
labelText: context.translation.technicalComment,
backgroundColor: AppColor.neutral100,
showShadow: false,
labelStyle: AppTextStyles.textFieldLabelStyle,
alignLabelWithHint: true,
textInputType: TextInputType.multiline,
onChange: (value) {
widget.formModel?.modelAssistantEmployees?.techComment = value;
},
onSaved: (value) {
widget.formModel?.modelAssistantEmployees?.techComment = value;
},
),
16.height,
],
)
: const SizedBox(),
],
);
}
// //TODO move this to some common place....@waseem
// double calculateWorkingHours(DateTime? startTime, DateTime? endTime) {
// if (startTime != null && endTime != null) {
// Duration difference = endTime.difference(startTime);
// int hours = difference.inHours;
// int minutes = difference.inMinutes % 60;
// return hours.toDouble();
// } else {
// return -1;
// }
// }
//
// assignWorkingHours({required RequestDetailProvider requestDetailProvider}) {
// double hours = calculateWorkingHours(
// requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate, requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate);
// if (hours != -1) {
// _workingHoursController.text = hours.toString();
// requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.workingHours = hours;
// }
// }
}

@ -104,11 +104,7 @@ void _updateTask({required BuildContext context, required int status}) async {
if (validate(model: allRequestsProvider.recurrentWoData!)) {
allRequestsProvider.recurrentWoData?.planRecurrentTaskTimers = allRequestsProvider.recurrentWoData?.planRecurrentTaskTimers ?? [];
DateTime? startTime = allRequestsProvider.recurrentWoData?.recurrentWoTimerModel?.startAt;
DateTime? endTime = allRequestsProvider.recurrentWoData?.recurrentWoTimerModel?.endAt;
// final duration = (endTime?.difference(startTime!));
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
allRequestsProvider.recurrentWoData?.timerModelList?.forEach((timer) {
int durationInSecond = timer.endAt!.difference(timer.startAt!).inSeconds;
allRequestsProvider.recurrentWoData?.planRecurrentTaskTimers?.add(

Loading…
Cancel
Save