From 62f6f135bb2768d07fe8a64f12064a8348ec8204 Mon Sep 17 00:00:00 2001 From: nextwo <1234> Date: Tue, 31 Oct 2023 11:37:41 +0300 Subject: [PATCH 1/8] device transfer --- lib/l10n/app_ar.arb | 7 + lib/l10n/app_en.arb | 7 + lib/models/device/asset_transfer.dart | 158 ++++++++++ .../device_transfer_details.dart | 272 ++++++++++-------- .../track_device_transfer.dart | 49 +--- .../update_device_transfer.dart | 235 ++++++++------- .../user/gas_refill/request_gas_refill.dart | 25 +- .../device_trancfer/device_transfer_item.dart | 171 ++++------- 8 files changed, 508 insertions(+), 416 deletions(-) diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index 733a78aa..40a33feb 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -271,6 +271,13 @@ "requestedThrough" : "الطلب عبر", "typeOfRequest" : "نوع الطلب", "assetDetails" : "تفاصيل الجهاز", + "deviceTransfer" : "نقل جهاز ", + "deviceTransferRequest" : "طلب نقل جهاز ", + "deviceTransferDetails" : "تفاصيل نقل جهاز ", + "transferDetails" : "تفاصيل النقل" , + "senderDetails" : "تفاصيل المرسل", + "receiverDetails" : "تفاصيل المستقبل", + "assetDetails" : "تفاصيل الجهاز", "searchBy" : "إبحث بـ", "searchByDesc" : "إبحث بأي من المعايير التالية", "location" : "الموقع", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index b7ac86ab..f8965cc2 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -276,6 +276,13 @@ "receiverDetails" : "Receiver Details", "requestedThrough" : "Requested Through", "typeOfRequest" : "Type of Request", + "deviceTransfer" : "Device Transfer", + "deviceTransferRequest" : "Device Transfer Request", + "deviceTransferDetails" : "Device Transfer Details", + "transferDetails" : "Transfer Details" , + "senderDetails" :"Sender Details", + "receiverDetails" :"Receiver Details", + "typeOfRequest" : "Type of Request", "searchBy" : "Search by", "searchByDesc" : "Search by any of the following criteria", "location" : "Location", diff --git a/lib/models/device/asset_transfer.dart b/lib/models/device/asset_transfer.dart index 26df8df4..827830a5 100644 --- a/lib/models/device/asset_transfer.dart +++ b/lib/models/device/asset_transfer.dart @@ -39,6 +39,32 @@ class AssetTransfer { this.receiverTravelingHours, this.receiverEngSignature, this.receiverAttachments, + this.assetNumber, + this.assetName, + this.manufacturerName, + this.modelName, + this.assetSerialNo, + this.destDepartmentName, + this.destBuildingName, + this.applied, + this.createdOn, + this.destFloorName, + this.destSiteName, + this.manufacturerId, + this.modelId, + this.modifiedOn, + this.receiverAssignedEmployeeName, + this.receiverEngSignatureUrl, + this.receiverMachineStatusName, + this.senderAssignedEmployeeName, + this.senderBuildingName, + this.senderDepartmentName, + this.senderEngSignatureUrl, + this.senderFloorName, + this.senderMachineStatusName, + this.senderSiteName, + this.supplierId, + this.supplierName }); AssetTransfer.fromJson(dynamic json) { @@ -84,11 +110,44 @@ class AssetTransfer { receiverAttachments.add(AssetTransferAttachment.fromJson(v)); }); } + assetNumber= json['assetNumber']; + assetName= json['assetName']; + manufacturerName= json['manufacturerName']; + modelName= json['modelName']; + assetSerialNo= json['assetSerialNo']; + destDepartmentName= json['destDepartmentName']; + destBuildingName= json['destBuildingName']; + applied= json['applied']; + createdOn= json['createdOn']; + destFloorName= json['destFloorName']; + destSiteName= json['destSiteName']; + manufacturerId= json['manufacturerId']; + modelId= json['modelId']; + modifiedOn= json['modifiedOn']; + receiverAssignedEmployeeName= json['receiverAssignedEmployeeName']; + receiverEngSignatureUrl= json['receiverEngSignatureUrl']; + receiverMachineStatusName= json['receiverMachineStatusName']; + senderAssignedEmployeeName= json['senderAssignedEmployeeName']; + senderBuildingName= json['senderBuildingName']; + senderDepartmentName= json['senderDepartmentName']; + senderEngSignatureUrl= json['senderEngSignatureUrl']; + senderFloorName= json['senderFloorName']; + senderMachineStatusName= json['senderMachineStatusName']; + senderSiteName= json['senderSiteName']; + supplierId= json['supplierId']; + supplierName= json['supplierName']; } num id; num transferNo; String transferCode; + String assetSerialNo; num assetId; + String assetNumber; + String assetName; + int modelId; + String modelName; + int manufacturerId; + String manufacturerName; num destSiteId; num destBuildingId; num destFloorId; @@ -117,6 +176,26 @@ class AssetTransfer { String receiverTravelingHours; String receiverEngSignature; List receiverAttachments; + num supplierId; + String supplierName; + String destSiteName; + String destBuildingName; + String destFloorName; + String destDepartmentName; + String senderSiteName; + String senderBuildingName; + String senderFloorName; + String senderDepartmentName; + String senderAssignedEmployeeName; + String senderMachineStatusName; + String senderEngSignatureUrl; + String receiverAssignedEmployeeName; + String receiverMachineStatusName; + String receiverEngSignatureUrl; + bool applied; + String createdOn; + String modifiedOn; + AssetTransfer copyWith({ num id, num transferNo, @@ -150,6 +229,33 @@ class AssetTransfer { String receiverTravelingHours, String receiverEngSignature, List receiverAttachments, + num supplierId, + String supplierName, + String destSiteName, + String destBuildingName, + String destFloorName, + String destDepartmentNam, + String senderSiteName, + String senderBuildingName, + String senderFloorName, + String senderDepartmentName, + String senderAssignedEmployeeName, + String senderMachineStatusName, + String senderEngSignatureUrl, + String receiverAssignedEmployeeName, + String receiverMachineStatusName, + String receiverEngSignatureUrl, + bool applied, + String createdOn, + String modifiedOn, + String assetSerialNo, + String assetNumber, + String assetName, + int modelId, + String modelName, + int manufacturerId, + String manufacturerName, + String destDepartmentName }) => AssetTransfer( id: id ?? this.id, @@ -184,6 +290,32 @@ class AssetTransfer { receiverTravelingHours: receiverTravelingHours ?? this.receiverTravelingHours, receiverEngSignature: receiverEngSignature ?? this.receiverEngSignature, receiverAttachments: receiverAttachments ?? this.receiverAttachments, + supplierId : supplierId?? this.supplierId, + supplierName: supplierName??this.supplierName, + destSiteName: destSiteName??this.destSiteName, + destBuildingName: destBuildingName?? this.destBuildingName, + destFloorName: destFloorName??this.destFloorName, + destDepartmentName: destDepartmentName?? this.destDepartmentName, + senderSiteName: senderSiteName??this.senderSiteName, + senderBuildingName: senderBuildingName??this.senderBuildingName, + senderFloorName: senderFloorName??this.senderFloorName, + senderDepartmentName: senderDepartmentName??this.senderDepartmentName, + senderAssignedEmployeeName: senderAssignedEmployeeName??this.senderAssignedEmployeeName, + senderMachineStatusName: senderMachineStatusName??this.senderMachineStatusName, + senderEngSignatureUrl: senderEngSignatureUrl??this.senderEngSignatureUrl, + receiverAssignedEmployeeName: receiverAssignedEmployeeName?? this.receiverAssignedEmployeeName, + receiverMachineStatusName: receiverMachineStatusName??this.receiverMachineStatusName, + receiverEngSignatureUrl: receiverEngSignatureUrl??this.receiverEngSignatureUrl, + applied: applied??this.applied, + createdOn: createdOn?? this.createdOn, + modifiedOn: modifiedOn??this.modifiedOn, + assetSerialNo:assetSerialNo??this.assetSerialNo, + assetNumber:assetNumber??this.assetNumber, + assetName:assetName??this.assetName, + modelId:modelId??this.modelId, + modelName:modelName??this.modelName, + manufacturerId:manufacturerId??this.manufacturerId, + manufacturerName:manufacturerName??this.manufacturerName ); Map toJson() { final map = {}; @@ -223,6 +355,32 @@ class AssetTransfer { if (receiverAttachments != null) { map['receiverAttachments'] = receiverAttachments.map((v) => v.toJson()).toList(); } + map["supplierId"] = supplierId; + map["supplierName"] =supplierName; + map["destSiteName"] =destSiteName; + map["destBuildingName"] =destBuildingName; + map["destFloorName"] =destFloorName; + map["destDepartmentName"] =destDepartmentName; + map["senderSiteName"] =senderSiteName; + map["senderBuildingName"] = senderBuildingName; + map["senderFloorName"] = senderFloorName; + map["senderDepartmentName"] = senderDepartmentName; + map["senderAssignedEmployeeName"] = senderAssignedEmployeeName; + map["senderMachineStatusName"] = senderMachineStatusName; + map["senderEngSignatureUrl"] = senderEngSignatureUrl; + map["receiverAssignedEmployeeName"] = receiverAssignedEmployeeName; + map["receiverMachineStatusName"] = receiverMachineStatusName; + map["receiverEngSignatureUrl"] = receiverEngSignatureUrl; + map["applied"] = applied; + map["createdOn"] = createdOn; + map["modifiedOn"] = modifiedOn; + map["assetSerialNo"] =assetSerialNo; + map["assetNumber"] =assetNumber; + map["assetName"] =assetName; + map["modelId"] =modelId; + map["modelName"] =modelName; + map["manufacturerId"] =manufacturerId; + map["manufacturerName"] =manufacturerName; return map; } diff --git a/lib/views/pages/device_transfer/device_transfer_details.dart b/lib/views/pages/device_transfer/device_transfer_details.dart index 09b9fe99..d0e568ab 100644 --- a/lib/views/pages/device_transfer/device_transfer_details.dart +++ b/lib/views/pages/device_transfer/device_transfer_details.dart @@ -1,19 +1,28 @@ import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/localization/localization.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/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/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/sizing.dart'; +import 'package:test_sa/views/pages/device_transfer/update_device_transfer.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_small_button.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/requests/info_row.dart'; +import '../../../extensions/text_extensions.dart'; import '../../../models/enums/user_types.dart'; +import '../../../new_views/app_style/app_color.dart'; +import '../../../new_views/common_widgets/default_app_bar.dart'; +import '../../widgets/requests/request_status.dart'; class DeviceTransferDetails extends StatefulWidget { final AssetTransfer model; @@ -26,8 +35,6 @@ class DeviceTransferDetails extends StatefulWidget { class _DeviceTransferDetailsState extends State { AssetTransfer _model; - bool _isSender = false; - bool _isReceiver = false; UserProvider _userProvider; bool _isLoading = false; final GlobalKey _formKey = GlobalKey(); @@ -46,6 +53,7 @@ class _DeviceTransferDetailsState extends State { @override Widget build(BuildContext context) { return Scaffold( + appBar: DefaultAppBar(title: context.translation.deviceTransferDetails), key: _scaffoldKey, body: SafeArea( child: FutureBuilder( @@ -55,8 +63,6 @@ class _DeviceTransferDetailsState extends State { return const ALoading(); } else { _userProvider = Provider.of(context); - // _isSender = _userProvider.user.userID == _model.sender?.userId; - // _isReceiver = _userProvider.user.userID == _model.receiver?.userId; return Form( key: _formKey, child: LoadingManager( @@ -66,129 +72,74 @@ class _DeviceTransferDetailsState extends State { onRefresh: () async {}, child: Column( children: [ - Container( - color: Theme.of(context).colorScheme.primary, - padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), - child: Row( - children: [ - const ABackButton(), - Expanded( - child: Center( - child: Text( - context.translation.details, - style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic), - ), - ), - ), - const SizedBox(width: 58), - ], - ), - ), - Expanded( - child: SingleChildScrollView( - padding: EdgeInsets.all(16 * AppStyle.getScaleFactor(context)), - child: Column( + _buildDetailsCard( + Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - RequestInfoRow( - title: "Transfer Id", - info: "_model.title?.toString()", - ), - RequestInfoRow( - title: context.translation.assetName, - info: "_model.device.assetName", - ), - RequestInfoRow( - title: context.translation.assetSN, - info: "_model.device.serialNumber", - ), - RequestInfoRow( - title: context.translation.assetNumber, - info: "_model.device.number", - ), - RequestInfoRow( - title: context.translation.destinationSite, - info: "_model.device.destSiteName", - ), - RequestInfoRow( - title: context.translation.building, - info: " _model.device.destBuildingName", - ), - RequestInfoRow( - title: context.translation.floor, - info: "_model.device.destFloor", - ), - RequestInfoRow( - title: context.translation.department, - info: "_model.device.destDepartmentName", - ), - RequestInfoRow( - title: context.translation.room, - info: "_model.device.destRoom", - ), - RequestInfoRow( - title: context.translation.actions, - info: "", - ), - const SizedBox(height: 8), Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Expanded( - child: Text("Sender", style: Theme.of(context).textTheme.headline6), + Row( + children: [ + /// TBD + StatusLabel( + label: "", + id: 0, + textColor: AColors.getPriorityStatusTextColor(0), + backgroundColor: AColors.getPriorityStatusColor(0)), + 8.width, + /// TBD + StatusLabel(label: '', textColor: AColors.getRequestStatusTextColor(0), backgroundColor: AColors.getRequestStatusColor(0)), + ], ), - if (_userProvider.user?.type == UsersTypes.engineer) - ASmallButton( - text: context.translation.edit, - // onPressed: (_isSender) - // ? (_model.sender.status?.name == "Closed" - // ? null - // : () { - // Navigator.of(context).push(MaterialPageRoute( - // builder: (_) => UpdateDeviceTransfer( - // model: _model, - // isSender: true, - // ))); - // }) - // : null, - ), + 1.width.expanded, + Text(widget.model.createdOn != null ?widget.model.createdOn.toServiceRequestCardFormat:"", textAlign: TextAlign.end, style: AppTextStyles.tinyFont.copyWith(color: const Color(0xFF3B3D4A))), ], ), - const SizedBox(height: 12), - // DeviceTransferInfoSection( - // info: _model.sender, - // isSender: true, - // ), - const SizedBox(height: 8), - Row( + 8.height, + Text(context.translation.transferDetails, style: AppTextStyles.heading5.copyWith(color: const Color(0xFF3B3D4A))), + 8.height, + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: Text("Receiver", style: Theme.of(context).textTheme.headline6), - ), - if (_userProvider.user?.type == UsersTypes.engineer) - ASmallButton( - text: context.translation.edit, - // onPressed: (_isReceiver) - // ? (_model.receiver.status?.name == "Closed" - // ? null - // : () { - // Navigator.of(context).push(MaterialPageRoute( - // builder: (_) => UpdateDeviceTransfer( - // model: _model, - // isSender: false, - // ))); - // }) - // : null, - ), + _buildTextWidget('${context.translation.assetName} : ${_model.assetName}'), + _buildTextWidget('${context.translation.assetNumber} : ${_model.assetNumber}'), + _buildTextWidget('${context.translation.model} : ${_model.modelName}'), + _buildTextWidget('${context.translation.sn} : ${_model.assetSerialNo}'), ], ), - const SizedBox(height: 12), - // DeviceTransferInfoSection( - // info: _model.receiver, - // isSender: false, - // ), + 8.height, ], - ), - ), + ).paddingAll(14) + ), + // sender card + _buildCard( + isSender: true, + site: _model.senderSiteName??"", + /// TBD + unit: _model.senderDepartmentName??"", + comment: _model.senderComment??"", + /// TBD + statusLabel: StatusLabel( + label: _model.senderMachineStatusName??"", + id: _model.senderMachineStatusId, + textColor: AColors.getRequestStatusTextColor(_model.senderMachineStatusId), + backgroundColor: AColors.getRequestStatusColor(_model.senderMachineStatusId)), + ), + // receiver card + _buildCard( + isSender: false, + site: _model.destSiteName??"", + /// TBD + unit: _model.destDepartmentName??"", + comment: _model.receiverComment??"", + /// TBD + statusLabel: StatusLabel( + label: _model.receiverMachineStatusName??"", + id: _model.receiverMachineStatusId, + textColor: AColors.getRequestStatusTextColor(_model.receiverMachineStatusId), + backgroundColor: AColors.getRequestStatusColor(_model.receiverMachineStatusId)), ), ], ), @@ -200,4 +151,93 @@ class _DeviceTransferDetailsState extends State { ), ); } + + _buildDetailsCard(Widget widget){ + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), + ), + child: widget, + ).paddingOnly(top: 14, start: 14, end: 14); + } + + _buildTextWidget(String text){ + return Text( + text, style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ); + } + + _buildCard({@required String site, @required String unit, @required String comment, @required bool isSender, StatusLabel statusLabel}){ + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + statusLabel??Container(), + 8.height, + Text(isSender?context.translation.senderDetails:context.translation.receiverDetails, + style: AppTextStyles.heading5.copyWith(color: const Color(0xFF3B3D4A))), + ], + ), + if (_userProvider.user?.type == UsersTypes.engineer) + CircleAvatar( + radius: 25, + backgroundColor: AppColor.neutral30, + child: CircleAvatar( + radius: 24, + backgroundColor: Colors.white, + child: Padding( + padding: const EdgeInsets.only(left: 3.0), + child: SvgPicture.asset('assets/images/update.svg'), + ), + ), + ).onPress( + isSender ? _model.senderMachineStatusName == "Closed" + ? null + : () { + Navigator.of(context).push(MaterialPageRoute( + builder: (_) => UpdateDeviceTransfer( + model: _model, + isSender: isSender, + ))); + } + : _model.receiverMachineStatusName == "Closed" + ? null + : () { + Navigator.of(context).push(MaterialPageRoute( + builder: (_) => UpdateDeviceTransfer( + model: _model, + isSender: isSender, + ))); + }), + + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildTextWidget('${context.translation.site} : $site'), + _buildTextWidget('${context.translation.unite} : $unit'), + 8.height, + const Divider(color: Color(0xFFEAF1F4), height: 1, thickness: 1), + 8.height, + _buildTextWidget(comment), + ], + ), + 8.height, + ], + ).paddingAll(14), + ).paddingOnly(top: 14, start: 14, end: 14); + } + } diff --git a/lib/views/pages/device_transfer/track_device_transfer.dart b/lib/views/pages/device_transfer/track_device_transfer.dart index 769b682b..012a7040 100644 --- a/lib/views/pages/device_transfer/track_device_transfer.dart +++ b/lib/views/pages/device_transfer/track_device_transfer.dart @@ -3,11 +3,13 @@ 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/views/app_style/colors.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/device_trancfer/device_transfer_list.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; +import '../../../new_views/common_widgets/default_app_bar.dart'; import '../../widgets/buttons/app_icon_button.dart'; class TrackDeviceTransferPage extends StatefulWidget { @@ -31,6 +33,7 @@ class _TrackDeviceTransferPageState extends State with _settingProvider = Provider.of(context); return Scaffold( + appBar: DefaultAppBar(title: context.translation.deviceTransfer), body: SafeArea( child: LoadingManager( isLoading: _deviceTransferProvider.isLoading, @@ -47,52 +50,6 @@ class _TrackDeviceTransferPageState extends State with children: [ Column( children: [ - Container( - color: AColors.primaryColor, - padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), - child: Column( - children: [ - Row( - children: [ - const ABackButton(), - Expanded( - child: Center( - child: Text( - "Asset Transfer", - style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic), - ), - ), - ), - AIconButton( - iconData: Icons.search, - color: AColors.secondaryColor, - buttonSize: 42, - backgroundColor: AColors.white, - onPressed: () async { - // DeviceTransferSearch temp = await showModalBottomSheet( - // context: context, - // isScrollControlled: true, - // builder: (context) { - // return AssetTransferSearchDialog(initialSearchValue: _deviceTransferProvider.deviceTransferSearch); - // }, - // ); - // if (temp != null) { - // _deviceTransferProvider.deviceTransferSearch = temp; - // _deviceTransferProvider.reset(); - // setState(() {}); - // await _deviceTransferProvider.getRequests( - // user: _userProvider.user, - // host: _settingProvider.host, - // ); - // } - }, - ), - const SizedBox(width: 16), - ], - ), - ], - ), - ), Expanded( child: DeviceTransferList( nextPage: _deviceTransferProvider.nextPage, diff --git a/lib/views/pages/device_transfer/update_device_transfer.dart b/lib/views/pages/device_transfer/update_device_transfer.dart index 588075f4..c9babbc4 100644 --- a/lib/views/pages/device_transfer/update_device_transfer.dart +++ b/lib/views/pages/device_transfer/update_device_transfer.dart @@ -7,12 +7,14 @@ import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/models/device/asset_transfer.dart'; import 'package:test_sa/models/subtitle.dart'; +import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; import '../../../../controllers/localization/localization.dart'; +import '../../../new_views/common_widgets/default_app_bar.dart'; class UpdateDeviceTransfer extends StatefulWidget { final AssetTransfer model; @@ -90,133 +92,120 @@ class _UpdateDeviceTransferState extends State { _settingProvider = Provider.of(context); _deviceTransferProvider = Provider.of(context, listen: false); return Scaffold( + appBar: DefaultAppBar(title: context.translation.updateRequest), key: _scaffoldKey, - body: Form( - key: _formKey, - child: SafeArea( - child: LoadingManager( - isLoading: _isLoading, - isFailedLoading: false, - stateCode: 200, - onRefresh: () async {}, - child: SingleChildScrollView( - padding: EdgeInsets.all(12 * AppStyle.getScaleFactor(context)), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Center( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - "Edit Transfer Asset", - style: Theme.of(context).textTheme.headline5.copyWith(color: Theme.of(context).primaryColor, fontSize: 28, fontWeight: FontWeight.bold), - ), + body: SafeArea( + child: LoadingManager( + isLoading: _isLoading, + isFailedLoading: false, + stateCode: 200, + onRefresh: () async {}, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SingleChildScrollView( + padding: EdgeInsets.all(12 * AppStyle.getScaleFactor(context)), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ASubTitle("Comment"), + const SizedBox( + height: 4, ), - ), - const SizedBox( - height: 8, - ), - ASubTitle("Comment"), - - const SizedBox( - height: 4, - ), - // ATextFormField( - // initialValue: _formModel?.comment, - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // textInputType: TextInputType.text, - // onSaved: (value) { - // _formModel.comment = value; - // }, - // ), - const SizedBox( - height: 8, - ), - ASubTitle(context.translation.travelingHours), - const SizedBox( - height: 4, - ), - // ATextFormField( - // initialValue: _formModel?.travelingHours, - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // textInputType: TextInputType.number, - // onSaved: (value) { - // _formModel.travelingHours = value; - // }, - // ), - const SizedBox( - height: 16, - ), - ASubTitle(context.translation.workingHours), - const SizedBox(height: 8), - Row( - children: [ - // Expanded( - // child: AppTimer( - // timer: _formModel.timer, - // onChange: (timer) async { - // _formModel.timer = timer; - // _formModel.workingHours = (((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0"; - // return true; - // }, - // ), - // ), - ], - ), - const SizedBox(height: 16), - ASubTitle(context.translation.status), - const SizedBox( - height: 4, - ), - // AssetStatusMenu( - // initialValue: _formModel.status, - // onSelect: (status) { - // if (status == null) return; - // _formModel.status = status; - // setState(() {}); - // }, - // ), - const SizedBox( - height: 16, - ), - // MultiFilesPicker( - // label: "Attachments", - // files: _formModel.attachments, - // ), - const SizedBox( - height: 16, - ), - const ASubTitle("Signature"), - // if(_validate && _formModel.signature == null) - // ASubTitle(_subtitle.requiredWord,color: Colors.red,), - const SizedBox( - height: 4, - ), - // ESignature( - // oldSignature: widget.isSender ? widget.model.sender.engSignature : widget.model.receiver.engSignature, - // newSignature: _signature, - // onSaved: (signature) { - // _signature = signature; - // if (signature == null || signature.isEmpty) return; - // _formModel.engSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - // // base64Encode(signature); - // }, - // ), - Padding( - padding: const EdgeInsets.all(16.0), - child: AButton( - text: context.translation.update, - onPressed: _update, + // ATextFormField( + // initialValue: _formModel?.comment, + // textAlign: TextAlign.center, + // style: Theme.of(context).textTheme.subtitle1, + // textInputType: TextInputType.text, + // onSaved: (value) { + // _formModel.comment = value; + // }, + // ), + const SizedBox( + height: 8, + ), + ASubTitle(context.translation.travelingHours), + const SizedBox( + height: 4, + ), + // ATextFormField( + // initialValue: _formModel?.travelingHours, + // textAlign: TextAlign.center, + // style: Theme.of(context).textTheme.subtitle1, + // textInputType: TextInputType.number, + // onSaved: (value) { + // _formModel.travelingHours = value; + // }, + // ), + const SizedBox( + height: 16, + ), + ASubTitle(context.translation.workingHours), + const SizedBox(height: 8), + Row( + children: [ + // Expanded( + // child: AppTimer( + // timer: _formModel.timer, + // onChange: (timer) async { + // _formModel.timer = timer; + // _formModel.workingHours = (((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0"; + // return true; + // }, + // ), + // ), + ], + ), + const SizedBox(height: 16), + ASubTitle(context.translation.status), + const SizedBox( + height: 4, ), - ), - const SizedBox( - height: 100, - ) - ], + // AssetStatusMenu( + // initialValue: _formModel.status, + // onSelect: (status) { + // if (status == null) return; + // _formModel.status = status; + // setState(() {}); + // }, + // ), + const SizedBox( + height: 16, + ), + // MultiFilesPicker( + // label: "Attachments", + // files: _formModel.attachments, + // ), + const SizedBox( + height: 16, + ), + const ASubTitle("Signature"), + // if(_validate && _formModel.signature == null) + // ASubTitle(_subtitle.requiredWord,color: Colors.red,), + const SizedBox( + height: 4, + ), + // ESignature( + // oldSignature: widget.isSender ? widget.model.sender.engSignature : widget.model.receiver.engSignature, + // newSignature: _signature, + // onSaved: (signature) { + // _signature = signature; + // if (signature == null || signature.isEmpty) return; + // _formModel.engSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + // // base64Encode(signature); + // }, + // ), + ], + ), + ), + Padding( + padding: const EdgeInsets.all(16.0), + child: AppFilledButton( + label: context.translation.update, + onPressed: _update, + ), ), - ), + ], ), ), ), diff --git a/lib/views/pages/user/gas_refill/request_gas_refill.dart b/lib/views/pages/user/gas_refill/request_gas_refill.dart index 38151083..4608f8f3 100644 --- a/lib/views/pages/user/gas_refill/request_gas_refill.dart +++ b/lib/views/pages/user/gas_refill/request_gas_refill.dart @@ -13,6 +13,7 @@ import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/lookup.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/views/app_style/sizing.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart'; @@ -199,11 +200,11 @@ class _RequestGasRefillState extends State { isFailedLoading: false, stateCode: 200, onRefresh: () async {}, - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( + child: Column( + //mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SingleChildScrollView( + child: Column( children: [ Container( width: MediaQuery.of(context).size.width, @@ -278,13 +279,13 @@ class _RequestGasRefillState extends State { }, ), ], - ).paddingAll(16), - AButton( - text: widget.gasRefillModel == null ? context.translation.submit : context.translation.update, - onPressed:()async{_onSubmit.call(context);}, - ).paddingAll(16), - ], - ), + ).paddingAll(16) + ).expanded, + AppFilledButton( + label: widget.gasRefillModel == null ? context.translation.submit : context.translation.update, + onPressed:()async{_onSubmit.call(context);}, + ).paddingAll(16), + ], ) ), ), diff --git a/lib/views/widgets/device_trancfer/device_transfer_item.dart b/lib/views/widgets/device_trancfer/device_transfer_item.dart index 8c9f4b9f..1bda58d1 100644 --- a/lib/views/widgets/device_trancfer/device_transfer_item.dart +++ b/lib/views/widgets/device_trancfer/device_transfer_item.dart @@ -1,13 +1,15 @@ import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:test_sa/controllers/localization/localization.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/widget_extensions.dart'; import 'package:test_sa/models/device/asset_transfer.dart'; -import 'package:test_sa/models/subtitle.dart'; -import 'package:test_sa/models/user.dart'; import 'package:test_sa/views/app_style/sizing.dart'; +import '../../../extensions/text_extensions.dart'; +import '../../app_style/colors.dart'; +import '../requests/request_status.dart'; + class DeviceTransferItem extends StatelessWidget { final int index; final AssetTransfer item; @@ -17,21 +19,18 @@ class DeviceTransferItem extends StatelessWidget { @override Widget build(BuildContext context) { - User _user = Provider.of(context, listen: false).user; - Color itemColor = index % 2 == 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary; - Color onItemColor = index % 2 != 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary; return Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: ElevatedButton( - style: ElevatedButton.styleFrom( - padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8), - backgroundColor: itemColor, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), + style: ElevatedButton.styleFrom( + elevation: 0, + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 8), + backgroundColor: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), + ), ), - ), - //padding: EdgeInsets.symmetric(vertical: 8,horizontal: 8), onPressed: () { onPressed(item); }, @@ -39,115 +38,49 @@ class DeviceTransferItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + /// TBD + StatusLabel( + label: '', + id: 0, + textColor: AColors.getPriorityStatusTextColor(0), + backgroundColor: AColors.getPriorityStatusColor(0)), + 8.width, + /// TBD + StatusLabel(label: '', textColor: AColors.getRequestStatusTextColor(0), backgroundColor: AColors.getRequestStatusColor(0)), + 1.width.expanded, + Text(item.createdOn != null ?item.createdOn.toServiceRequestCardFormat:"", textAlign: TextAlign.end, style: AppTextStyles.tinyFont.copyWith(color: const Color(0xFF3B3D4A))), + ], + ), + 8.height, + Text(context.translation.deviceTransferRequest, style: AppTextStyles.heading5.copyWith(color: const Color(0xFF3B3D4A))), + Text( + '${context.translation.from} : ${item.senderAssignedEmployeeName}', + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + Text( + '${context.translation.to} : ${item.receiverAssignedEmployeeName}', + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + 8.height, + Row( + mainAxisSize: MainAxisSize.min, children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - /*item.title ??*/ "-----", - style: Theme.of(context).textTheme.headline6.copyWith(color: onItemColor, fontSize: 16, fontWeight: FontWeight.bold), - ), - Divider( - color: onItemColor, - ), - Text( - /*item.asset?.number ??*/ "-----", - style: Theme.of(context).textTheme.headline6.copyWith(color: onItemColor, fontSize: 16, fontWeight: FontWeight.bold), - ), - Divider( - color: onItemColor, - ), - Text( - /*item.asset.assetName ??*/ "", - style: Theme.of(context).textTheme.headline6.copyWith(color: onItemColor, fontSize: 16, fontWeight: FontWeight.bold), - ), - Divider( - color: onItemColor, - ), - Row( - children: [ - Expanded( - child: Text( - context.translation.from, - style: Theme.of(context).textTheme.subtitle2.copyWith( - color: onItemColor, - ), - ), - ), - // StatusLabel( - // backgroundColor: AColors.getRequestStatusColor(item.sender.status?.id), - // label: item.sender.status?.name, - // ) - ], - ), - //const SizedBox(height: 8,), - // Row( - // children: [ - // Expanded( - // child: Text( - // item.sender.client.name, - // style: Theme.of(context).textTheme.subtitle2.copyWith( - // color: onItemColor, - // ), - // ), - // ), - // ], - // ), - // if (item.sender.department.id != null) - // Text( - // item.sender.department.name, - // style: Theme.of(context).textTheme.bodySmall.copyWith( - // color: onItemColor, - // ), - // ), - Divider( - color: onItemColor, - ), - // Row( - // children: [ - // Expanded( - // child: Text( - // context.translation.to, - // style: Theme.of(context).textTheme.subtitle2.copyWith( - // color: onItemColor, - // ), - // ), - // ), - // StatusLabel( - // backgroundColor: AColors.getRequestStatusColor(item.receiver.status?.id), - // label: item.receiver.status?.name, - // ) - // ], - // ), - // //const SizedBox(height: 8,), - // Row( - // children: [ - // Expanded( - // child: Text( - // item.receiver.client.name, - // style: Theme.of(context).textTheme.subtitle2.copyWith( - // color: onItemColor, - // ), - // ), - // ), - // ], - // ), - // if (item.receiver.department.id != null) - // Text( - // item.receiver.department.name, - // style: Theme.of(context).textTheme.bodySmall.copyWith( - // color: onItemColor, - // ), - // ), - //Divider(color: onItemColor,), - ], - ), + Text( + 'View Details', + style: AppTextStyles.bodyText.copyWith(color: const Color(0xFF4A8DB7)), ), + 4.width, + const Icon( + Icons.arrow_forward, + color: Color(0xFF4A8DB7), + size: 14, + ) ], ), ], - ), + ) ), ); } From 8b7aa8235d2bef6c66984d2616b9ece338ba1f0b Mon Sep 17 00:00:00 2001 From: zaid_daoud Date: Wed, 1 Nov 2023 11:30:28 +0300 Subject: [PATCH 2/8] Update Service Request DONE --- .../api/service_requests_provider.dart | 1 + .../requests/create_service_request_page.dart | 4 + .../requests/first_action_bottom_sheet.dart | 2 +- .../requests/service_request_details.dart | 4 +- .../requests/update_service_request_page.dart | 163 +++++++++++++++++- lib/views/widgets/equipment/pick_asset.dart | 48 +++--- 6 files changed, 191 insertions(+), 31 deletions(-) diff --git a/lib/controllers/providers/api/service_requests_provider.dart b/lib/controllers/providers/api/service_requests_provider.dart index e3428ed3..6331eec6 100644 --- a/lib/controllers/providers/api/service_requests_provider.dart +++ b/lib/controllers/providers/api/service_requests_provider.dart @@ -233,6 +233,7 @@ class ServiceRequestsProvider extends ChangeNotifier { } Future updateRequest({ + @required BuildContext context, @required User user, @required ServiceRequest request, }) async { diff --git a/lib/views/pages/user/requests/create_service_request_page.dart b/lib/views/pages/user/requests/create_service_request_page.dart index c04d69d3..56d92c41 100644 --- a/lib/views/pages/user/requests/create_service_request_page.dart +++ b/lib/views/pages/user/requests/create_service_request_page.dart @@ -186,6 +186,10 @@ class CreateServiceRequestPageState extends State { controller: _commentController, labelText: context.translation.comments, suffixIcon: "warning".toSvgAsset(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20, width: 24).paddingOnly(end: 16), + initialValue: _serviceRequest.callComments, + onSaved: (text) { + _serviceRequest.callComments = text; + }, ), 8.height, RecordSound( diff --git a/lib/views/pages/user/requests/first_action_bottom_sheet.dart b/lib/views/pages/user/requests/first_action_bottom_sheet.dart index fcccef91..af0d539c 100644 --- a/lib/views/pages/user/requests/first_action_bottom_sheet.dart +++ b/lib/views/pages/user/requests/first_action_bottom_sheet.dart @@ -108,7 +108,7 @@ class _FirstActionBottomSheetState extends State { loading: snapshot.isLoading, onPressed: () async { _formKey.currentState.save(); - await snapshot.updateRequest(user: userProvider.user, request: _serviceRequest); + await snapshot.updateRequest(context: context, user: userProvider.user, request: _serviceRequest); Navigator.pop(context); }, ), diff --git a/lib/views/pages/user/requests/service_request_details.dart b/lib/views/pages/user/requests/service_request_details.dart index 20bdb790..0ce5b97c 100644 --- a/lib/views/pages/user/requests/service_request_details.dart +++ b/lib/views/pages/user/requests/service_request_details.dart @@ -93,9 +93,9 @@ class ServiceRequestDetailsPage extends StatelessWidget { Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ - if (_userProvider.user.type == UsersTypes.engineer) + if (_userProvider.user.type == UsersTypes.normal_user) "edit".toSvgAsset(width: 48).onPress(() { - Navigator.push(context, MaterialPageRoute(builder: (context) => const UpdateServiceRequestPage())); + Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateServiceRequestPage(serviceRequest: serviceRequest))); }), if (_userProvider.user.type == UsersTypes.engineer) 16.height, Text(serviceRequest.date.toServiceRequestCardFormat, textAlign: TextAlign.end, style: AppTextStyles.tinyFont.copyWith(color: const Color(0xFF3B3D4A))), diff --git a/lib/views/pages/user/requests/update_service_request_page.dart b/lib/views/pages/user/requests/update_service_request_page.dart index 1e4b0cc3..d7fe80b5 100644 --- a/lib/views/pages/user/requests/update_service_request_page.dart +++ b/lib/views/pages/user/requests/update_service_request_page.dart @@ -1,20 +1,173 @@ +import 'dart:convert'; +import 'dart:io'; + import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/service_requests_provider.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/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; -class UpdateServiceRequestPage extends StatelessWidget { +import '../../../../models/lookup.dart'; +import '../../../../new_views/app_style/app_color.dart'; +import '../../../../new_views/common_widgets/app_filled_button.dart'; +import '../../../../new_views/common_widgets/app_text_form_field.dart'; +import '../../../../new_views/common_widgets/single_item_drop_down_menu.dart'; +import '../../../../providers/service_request_providers/equipment_status_provider.dart'; +import '../../../../providers/service_request_providers/priority_provider.dart'; +import '../../../../providers/service_request_providers/requested_through_provider.dart'; +import '../../../../providers/service_request_providers/type_of_request_provider.dart'; +import '../../../widgets/equipment/pick_asset.dart'; +import '../../../widgets/images/multi_image_picker.dart'; +import '../../../widgets/sound/record_sound.dart'; + +class UpdateServiceRequestPage extends StatefulWidget { static const String id = "/update_service_request_page"; - const UpdateServiceRequestPage({Key key}) : super(key: key); + final ServiceRequest serviceRequest; + const UpdateServiceRequestPage({Key key, this.serviceRequest}) : super(key: key); + + @override + State createState() => _UpdateServiceRequestPageState(); +} + +class _UpdateServiceRequestPageState extends State { + final GlobalKey _formKey = GlobalKey(); + TextEditingController _commentController; + List _deviceImages = []; + UserProvider _userProvider; + + @override + void initState() { + super.initState(); + _deviceImages = widget.serviceRequest.devicePhotos.map((e) => File(e)).toList(); + _commentController = TextEditingController(text: widget.serviceRequest.callComments ?? ""); + } + + @override + void dispose() { + _commentController.dispose(); + super.dispose(); + } @override Widget build(BuildContext context) { + _userProvider = Provider.of(context, listen: false); return Scaffold( appBar: DefaultAppBar(title: context.translation.updateServiceRequest), body: SafeArea( - child: Column( - children: [], - ), + child: Form( + key: _formKey, + child: Column( + children: [ + SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + PickAsset( + editable: false, + device: widget.serviceRequest.device, + onPickAsset: (asset) { + widget.serviceRequest.device = asset; + setState(() {}); + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + title: context.translation.priority, + initialValue: widget.serviceRequest?.priority, + onSelect: (value) { + widget.serviceRequest.priority = value; + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + title: context.translation.equipmentStatus, + initialValue: widget.serviceRequest?.defectType, + onSelect: (value) { + widget.serviceRequest.defectType = value; + }, + ), + 8.height, + Consumer(builder: (context, snapshot, _) { + return SingleItemDropDownMenu( + context: context, + enabled: false, + title: context.translation.requestedThrough, + initialValue: snapshot.items?.firstWhere((element) => element.value == 3, orElse: () => null), + ); + }), + 8.height, + SingleItemDropDownMenu( + context: context, + title: context.translation.typeOfRequest, + initialValue: widget.serviceRequest?.type, + onSelect: (value) { + widget.serviceRequest.type = value; + }, + ), + 8.height, + MultiFilesPicker( + label: context.translation.attachImage, + onlyImages: true, + files: _deviceImages, + ), + ((widget.serviceRequest.devicePhotos?.isNotEmpty ?? false) ? 16 : 8).height, + Align( + alignment: AlignmentDirectional.centerStart, + child: context.translation.callComments.heading5(context), + ), + 8.height, + AppTextFormField( + controller: _commentController, + labelText: context.translation.comments, + initialValue: widget.serviceRequest.callComments, + suffixIcon: "warning".toSvgAsset(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20, width: 24).paddingOnly(end: 16), + onSaved: (text) { + widget.serviceRequest.callComments = text; + }, + ), + 8.height, + RecordSound( + onRecord: (audio) { + widget.serviceRequest.audio = audio; + }, + enabled: widget.serviceRequest == null ? true : false, + ), + 16.height, + ], + ), + ).expanded, + AppFilledButton(onPressed: _submit, label: context.translation.submitRequest), + ], + ), + ).paddingOnly(start: 16, end: 16, bottom: 24, top: 16), ), ); } + + Future _submit() async { + widget.serviceRequest?.requestedThrough = Provider.of(context, listen: false).items?.firstWhere((element) => element.value == 3, orElse: () => null); + if (_formKey.currentState.validate() && await widget.serviceRequest.validateNewRequest(context)) { + _formKey.currentState.save(); + widget.serviceRequest.devicePhotos = _deviceImages.map((e) => _isLocalUrl(e.path) ? "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}" : e.path).toList(); + if (widget.serviceRequest.audio != null) { + if (_isLocalUrl(widget.serviceRequest.audio)) { + final File file = File(widget.serviceRequest.audio); + widget.serviceRequest.audio = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}"; + } + } + await Provider.of(context, listen: false).updateRequest(context: context, user: _userProvider.user, request: widget.serviceRequest); + } + } + + bool _isLocalUrl(String url) { + if (url?.isEmpty != false) return false; + return url.startsWith("/") || url.startsWith("file://") || url.substring(1).startsWith(':\\'); + } } diff --git a/lib/views/widgets/equipment/pick_asset.dart b/lib/views/widgets/equipment/pick_asset.dart index e3cddf2b..756deff6 100644 --- a/lib/views/widgets/equipment/pick_asset.dart +++ b/lib/views/widgets/equipment/pick_asset.dart @@ -12,36 +12,38 @@ import '../../../new_views/common_widgets/asset_info_card.dart'; class PickAsset extends StatelessWidget { final Function(Asset) onPickAsset; final Asset device; + final bool editable; - const PickAsset({Key key, this.device, this.onPickAsset}) : super(key: key); + const PickAsset({Key key, this.editable = true, this.device, this.onPickAsset}) : super(key: key); @override Widget build(BuildContext context) { return Column( children: [ - Container( - decoration: BoxDecoration( - color: Theme.of(context).cardColor, - borderRadius: BorderRadius.circular(10), - boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)], + if (editable) + Container( + decoration: BoxDecoration( + color: Theme.of(context).cardColor, + borderRadius: BorderRadius.circular(10), + boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)], + ), + padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight), + child: Row( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + context.translation.device.tinyFont(context).custom(color: context.isDark ? AppColor.neutral40 : AppColor.neutral50), + context.translation.pickAsset.bodyText(context).custom(color: context.isDark ? AppColor.neutral40 : AppColor.neutral50), + ], + ).onPress(() async { + Asset device = await Navigator.of(context).pushNamed(SingleDevicePicker.id) as Asset; + onPickAsset(device); + }).expanded, + "qr".toSvgAsset(height: 24, fit: BoxFit.fitHeight, color: context.isDark ? AppColor.primary40 : AppColor.primary70), + ], + ), ), - padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight), - child: Row( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - context.translation.device.tinyFont(context).custom(color: context.isDark ? AppColor.neutral40 : AppColor.neutral50), - context.translation.pickAsset.bodyText(context).custom(color: context.isDark ? AppColor.neutral40 : AppColor.neutral50), - ], - ).onPress(() async { - Asset device = await Navigator.of(context).pushNamed(SingleDevicePicker.id) as Asset; - onPickAsset(device); - }).expanded, - "qr".toSvgAsset(height: 24, fit: BoxFit.fitHeight, color: context.isDark ? AppColor.primary40 : AppColor.primary70), - ], - ), - ), if (device != null) AssetInfoCard(asset: device).paddingOnly(top: 8), ], ); From c3d6643ead4e9202a309e73991a10467e0063773 Mon Sep 17 00:00:00 2001 From: zaid_daoud Date: Wed, 1 Nov 2023 11:46:54 +0300 Subject: [PATCH 3/8] Enhancements --- .../providers/api/service_requests_provider.dart | 6 +----- .../user/requests/create_service_request_page.dart | 6 +----- .../user/requests/first_action_bottom_sheet.dart | 2 +- .../user/requests/update_service_request_page.dart | 11 +++++------ 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/lib/controllers/providers/api/service_requests_provider.dart b/lib/controllers/providers/api/service_requests_provider.dart index 6331eec6..9c18b46d 100644 --- a/lib/controllers/providers/api/service_requests_provider.dart +++ b/lib/controllers/providers/api/service_requests_provider.dart @@ -232,11 +232,7 @@ class ServiceRequestsProvider extends ChangeNotifier { } } - Future updateRequest({ - @required BuildContext context, - @required User user, - @required ServiceRequest request, - }) async { + Future updateRequest({@required User user, @required ServiceRequest request}) async { isLoading = true; notifyListeners(); Map serviceRequest = await getServiceRequestById(requestId: request.id) ?? ""; diff --git a/lib/views/pages/user/requests/create_service_request_page.dart b/lib/views/pages/user/requests/create_service_request_page.dart index 56d92c41..fbad447e 100644 --- a/lib/views/pages/user/requests/create_service_request_page.dart +++ b/lib/views/pages/user/requests/create_service_request_page.dart @@ -171,11 +171,7 @@ class CreateServiceRequestPageState extends State { }, ), 8.height, - MultiFilesPicker( - label: context.translation.attachImage, - onlyImages: true, - files: _deviceImages, - ), + MultiFilesPicker(label: context.translation.attachImage, files: _deviceImages), ((_serviceRequest.devicePhotos?.isNotEmpty ?? false) ? 16 : 8).height, Align( alignment: AlignmentDirectional.centerStart, diff --git a/lib/views/pages/user/requests/first_action_bottom_sheet.dart b/lib/views/pages/user/requests/first_action_bottom_sheet.dart index af0d539c..fcccef91 100644 --- a/lib/views/pages/user/requests/first_action_bottom_sheet.dart +++ b/lib/views/pages/user/requests/first_action_bottom_sheet.dart @@ -108,7 +108,7 @@ class _FirstActionBottomSheetState extends State { loading: snapshot.isLoading, onPressed: () async { _formKey.currentState.save(); - await snapshot.updateRequest(context: context, user: userProvider.user, request: _serviceRequest); + await snapshot.updateRequest(user: userProvider.user, request: _serviceRequest); Navigator.pop(context); }, ), diff --git a/lib/views/pages/user/requests/update_service_request_page.dart b/lib/views/pages/user/requests/update_service_request_page.dart index d7fe80b5..9af6081f 100644 --- a/lib/views/pages/user/requests/update_service_request_page.dart +++ b/lib/views/pages/user/requests/update_service_request_page.dart @@ -15,6 +15,7 @@ import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import '../../../../models/lookup.dart'; import '../../../../new_views/app_style/app_color.dart'; import '../../../../new_views/common_widgets/app_filled_button.dart'; +import '../../../../new_views/common_widgets/app_lazy_loading.dart'; import '../../../../new_views/common_widgets/app_text_form_field.dart'; import '../../../../new_views/common_widgets/single_item_drop_down_menu.dart'; import '../../../../providers/service_request_providers/equipment_status_provider.dart'; @@ -112,11 +113,7 @@ class _UpdateServiceRequestPageState extends State { }, ), 8.height, - MultiFilesPicker( - label: context.translation.attachImage, - onlyImages: true, - files: _deviceImages, - ), + MultiFilesPicker(label: context.translation.attachImage, files: _deviceImages), ((widget.serviceRequest.devicePhotos?.isNotEmpty ?? false) ? 16 : 8).height, Align( alignment: AlignmentDirectional.centerStart, @@ -162,7 +159,9 @@ class _UpdateServiceRequestPageState extends State { widget.serviceRequest.audio = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}"; } } - await Provider.of(context, listen: false).updateRequest(context: context, user: _userProvider.user, request: widget.serviceRequest); + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + await Provider.of(context, listen: false).updateRequest(user: _userProvider.user, request: widget.serviceRequest); + Navigator.of(context).pop(); } } From daa427bac2a514050ca53b9e8d9f210b1864fc68 Mon Sep 17 00:00:00 2001 From: zaid_daoud Date: Wed, 1 Nov 2023 14:36:18 +0300 Subject: [PATCH 4/8] Update Work Order Screen DONE --- .../api/service_requests_provider.dart | 70 +- lib/l10n/app_ar.arb | 3 +- lib/l10n/app_en.arb | 3 +- .../requests/update_service_request_page.dart | 2 +- .../work_order/create_service_report.dart | 1 + .../work_order/edit_service_report.dart | 1166 +++-------------- ...report.dart => update_service_report.dart} | 27 +- .../work_order/work_order_details_page.dart | 4 +- .../work_order/work_orders_list_page.dart | 4 +- .../widgets/e_signature/e_signature.dart | 18 +- 10 files changed, 209 insertions(+), 1089 deletions(-) rename lib/views/pages/user/requests/work_order/{future_service_report.dart => update_service_report.dart} (53%) diff --git a/lib/controllers/providers/api/service_requests_provider.dart b/lib/controllers/providers/api/service_requests_provider.dart index 9c18b46d..41c75d37 100644 --- a/lib/controllers/providers/api/service_requests_provider.dart +++ b/lib/controllers/providers/api/service_requests_provider.dart @@ -461,42 +461,28 @@ class ServiceRequestsProvider extends ChangeNotifier { } } - Future updateServiceReport({ - @required ServiceReport report, - String host, - User user, - ServiceRequest request, - }) async { + Future updateServiceReport(BuildContext context, {@required ServiceReport report}) async { Response response; - //Map body = report.toMap(request); - // body["uid"] = user.id; - // body["token"] = user.token; - // body["job_id"] = request.id; - // body["report_id"] = request.reportID; - // try { + report.callRequest = CallRequest(id: report.callRequest.id); Map body = report.toJson(); - - /// todo [zaid] : don't forget to add [request] data to [body] - // Map body = report.toMap(request); - // body["uid"] = user.id; - // body["token"] = user.token; - response = await ApiManager.instance.put(URLs.updateServiceReport, body: body); - // response = await post( - // Uri.parse( - // host+URLs.updateServiceReport), - // body: body, - // ); - // stateCode = response.statusCode; - - if (response.statusCode >= 200 && response.statusCode < 300) { - reset(); - notifyListeners(); + try { + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + response = await ApiManager.instance.put(URLs.updateServiceReport, body: body); + if (response.statusCode >= 200 && response.statusCode < 300) { + reset(); + notifyListeners(); + Fluttertoast.showToast(msg: context.translation.successfulRequestMessage); + Navigator.of(context).pop(); + } else { + Fluttertoast.showToast(msg: "${context.translation.failedToCompleteRequest}"); + } + Navigator.of(context).pop(); + return response.statusCode; + } catch (e) { + print(e); + Navigator.of(context).pop(); + return -1; } - return response.statusCode; - // } catch (error) { - // print(error); - // return -1; - // } } Future updateWorkOrderDetails({@required SearchWorkOrder workOrder}) async { @@ -560,28 +546,20 @@ class ServiceRequestsProvider extends ChangeNotifier { } } - Future getSingleServiceReport({ - @required int reportId, - @required String host, - @required User user, - @required AppLocalizations subtitle, - }) async { + Future getSingleServiceReport(BuildContext context, {@required int reportId}) async { Response response; try { - response = await ApiManager.instance.get( - URLs.getServiceReport + "?workOrderId=$reportId", - ); + response = await ApiManager.instance.get(URLs.getServiceReport + "?workOrderId=$reportId"); } catch (error) { - throw (HttpStatusManger.getStatusMessage(status: -1, subtitle: subtitle)); + throw (context.translation.failedToCompleteRequest); } // If the call to the server was successful, parse the JSON. if (response.statusCode >= 200 && response.statusCode < 300) { // If the call to the server was successful, parse the JSON. - /// todo [zaid]: check [reportId] below - return ServiceReport.fromJson(json.decode(response.body)["data"] /*, reportId*/); + return ServiceReport.fromJson(json.decode(response.body)["data"]); } else { - throw (HttpStatusManger.getStatusMessage(status: response.statusCode, subtitle: subtitle)); + throw (("${context.translation.failedToCompleteRequest} ${jsonDecode(response.body)["message"]}")); } } diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index 3a197653..20102d21 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -295,5 +295,6 @@ "assistantEmployee" : "موظف مساعد", "assignAssistant" : "تعيين مساعد", "partNo" : "الجزء رقم", - "engSign" : "توقيع المهندس" + "engSign" : "توقيع المهندس", + "updateWorkOrder" : "تعديل طلب العمل" } \ No newline at end of file diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 77f11ce2..5233fb33 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -299,5 +299,6 @@ "assistantEmployee" : "Assistant Employee", "assignAssistant" : "Assign Assistant", "partNo" : "Part No.", - "engSign" : "Engineer Signature" + "engSign" : "Engineer Signature", + "updateWorkOrder" : "Update Work Order" } \ No newline at end of file diff --git a/lib/views/pages/user/requests/update_service_request_page.dart b/lib/views/pages/user/requests/update_service_request_page.dart index 9af6081f..d7e7a395 100644 --- a/lib/views/pages/user/requests/update_service_request_page.dart +++ b/lib/views/pages/user/requests/update_service_request_page.dart @@ -140,7 +140,7 @@ class _UpdateServiceRequestPageState extends State { ], ), ).expanded, - AppFilledButton(onPressed: _submit, label: context.translation.submitRequest), + AppFilledButton(onPressed: _submit, label: context.translation.updateRequest), ], ), ).paddingOnly(start: 16, end: 16, bottom: 24, top: 16), diff --git a/lib/views/pages/user/requests/work_order/create_service_report.dart b/lib/views/pages/user/requests/work_order/create_service_report.dart index d1e5956d..4383e6ff 100644 --- a/lib/views/pages/user/requests/work_order/create_service_report.dart +++ b/lib/views/pages/user/requests/work_order/create_service_report.dart @@ -208,6 +208,7 @@ class _CreateServiceReportState extends State with TickerPr ), 8.height, MultiFilesPicker(label: context.translation.attachImage, files: _files), + 8.height, ESignature( title: context.translation.engSign, oldSignature: _serviceReport.engSignature, diff --git a/lib/views/pages/user/requests/work_order/edit_service_report.dart b/lib/views/pages/user/requests/work_order/edit_service_report.dart index 8915d49e..34d2c562 100644 --- a/lib/views/pages/user/requests/work_order/edit_service_report.dart +++ b/lib/views/pages/user/requests/work_order/edit_service_report.dart @@ -1,33 +1,36 @@ +import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; -import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; import 'package:test_sa/controllers/providers/api/service_requests_provider.dart'; -import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_types_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/controllers/validator/validator.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/service_request/service_report.dart'; import 'package:test_sa/models/service_request/service_request.dart'; -import 'package:test_sa/views/app_style/colors.dart'; -import 'package:test_sa/views/app_style/sizing.dart'; -import 'package:test_sa/views/widgets/app_text_form_field.dart'; -import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; -import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; -import 'package:test_sa/views/widgets/status/report/service_report_equipment_status.dart'; -import 'package:test_sa/views/widgets/status/report/service_report_fault_description.dart'; import 'package:test_sa/views/widgets/status/report/service_report_last_call.dart'; -import 'package:test_sa/views/widgets/status/report/service_report_reasons.dart'; -import 'package:test_sa/views/widgets/status/report/service_report_repair_location.dart'; -import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; +import '../../../../../attachment.dart'; +import '../../../../../models/lookup.dart'; +import '../../../../../models/service_request/spare_parts.dart'; import '../../../../../models/service_request/wo_call_request.dart'; +import '../../../../../new_views/common_widgets/app_filled_button.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 '../../../../../providers/loading_list_notifier.dart'; +import '../../../../../providers/work_order/reason_provider.dart'; +import '../../../../../providers/work_order/service_type_provider.dart'; +import '../../../../widgets/date_and_time/date_picker.dart'; +import '../../../../widgets/e_signature/e_signature.dart'; import '../../../../widgets/images/multi_image_picker.dart'; +import '../../../../widgets/status/report/service_report_assistant_employee_menu.dart'; class EditServiceReport extends StatefulWidget { static final String id = "/edit-service-report"; @@ -44,35 +47,31 @@ class _EditServiceReportState extends State with TickerProvid UserProvider _userProvider; SettingProvider _settingProvider; ServiceRequestsProvider _serviceRequestsProvider; - - bool _validate = false; + List _spareParts = []; ServiceReport _serviceReport; bool _isLoading = false; - bool _showCommentField = false; - - List _images = []; + List _files = []; final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); - TextEditingController _faultController = TextEditingController(); - TextEditingController _workPreformedController = TextEditingController(); - + final TextEditingController _faultController = TextEditingController(); + final TextEditingController _workPreformedController = TextEditingController(); ServiceStatusProvider _assetTypeProvider; - CallRequest _callRequestForWorkOrder; @override void initState() { _serviceReport = widget.report; - // _images = widget.report?.files?.map((e) => File(e))?.toList(); + _files = widget.report?.attachmentsWorkOrder?.map((e) => File(e.name))?.toList(); + _spareParts = _serviceReport.sparePartsWorkOrders.map((e) => e.sparePart).toList(); super.initState(); } void getRequestForWorkOrder() async { _isLoading = true; setState(() {}); - _callRequestForWorkOrder = await _serviceRequestsProvider.getCallRequestForWorkOrder(callId: widget.request.id); - // _serviceReport.engineer = Engineer.fromJson(_callRequestForWorkOrder?.assignedEmployee?.toJson()); - await _assetTypeProvider.getTypes(user: _userProvider.user, host: _settingProvider.host); + _callRequestForWorkOrder = await _serviceRequestsProvider?.getCallRequestForWorkOrder(callId: widget.request.id); + _serviceReport.assignedEmployee = _callRequestForWorkOrder?.assignedEmployee; + await _assetTypeProvider?.getTypes(user: _userProvider.user, host: _settingProvider.host); _isLoading = false; setState(() {}); } @@ -89,18 +88,14 @@ class _EditServiceReportState extends State with TickerProvid _userProvider = Provider.of(context); _settingProvider = Provider.of(context); _serviceRequestsProvider = Provider.of(context); - _assetTypeProvider = Provider.of(context); if (_callRequestForWorkOrder == null) { getRequestForWorkOrder(); } - _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), body: SafeArea( child: LoadingManager( isLoading: _isLoading, @@ -109,990 +104,143 @@ class _EditServiceReportState extends State with TickerProvid onRefresh: () async {}, child: Form( key: _formKey, - child: Stack( + child: Column( children: [ - ListView( - padding: const EdgeInsets.all(16), - children: [ - const SizedBox(height: 16), - Center( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Text( - context.translation.editServiceReport, - style: Theme.of(context).textTheme.headline5.copyWith(color: AColors.cyan, fontSize: 28, fontWeight: FontWeight.bold), - ), + SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Card( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + widget.request.hospitalName.heading5(context), + 8.height, + "${context.translation.assetNo}: ${widget.request.deviceNumber}".bodyText(context), + "${context.translation.callId}: ${widget.request.requestCode}".bodyText(context), + ], + ).paddingAll(16), ), - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ASubTitle("Caller Info"), - const SizedBox(height: 8), - Container( - width: double.infinity, - padding: const EdgeInsets.all(16), - margin: const EdgeInsets.symmetric(vertical: 16), - decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: const [ - BoxShadow( - color: AColors.grey, - offset: Offset(0, -1), - ) - ]), - child: Wrap( - direction: Axis.vertical, - spacing: 10, - children: [ - ASubTitle( - "${context.translation.callId}: ${widget.request.requestCode}", - font: 14, - ), - ASubTitle( - "${context.translation.assetNumber}: ${widget.request.deviceNumber}", - font: 14, - ), - widget.request.deviceSerialNumber == null - ? const SizedBox() - : ASubTitle( - "${context.translation.deviceSN}: ${widget.request.deviceSerialNumber}", - font: 14, - ), - Text( - "${context.translation.customer}: ${widget.request.hospitalName}", - style: Theme.of(context).textTheme.subtitle1.copyWith( - fontWeight: FontWeight.bold, - fontSize: 12, - ), - textScaleFactor: AppStyle.getScaleFactor(context), - ) - ], - ), - ), - const SizedBox(height: 8), - ASubTitle("Work Order Details"), - const SizedBox(height: 8), - Container( - width: double.infinity, - padding: const EdgeInsets.all(16), - margin: const EdgeInsets.symmetric(vertical: 16), - decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: const [ - BoxShadow( - color: AColors.grey, - offset: Offset(0, -1), - ) - ]), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // Report type and Reasons - // Row( - // children: [ - // // Report Status - // // Expanded( - // // child: Column( - // // crossAxisAlignment: CrossAxisAlignment.start, - // // children: [ - // // ASubTitle(context.translation.reportType), - // // _validate && _serviceReport.type == null - // // ? ASubTitle( - // // context.translation.requiredWord, - // // color: Colors.red, - // // ) - // // : const SizedBox.shrink(), - // // const SizedBox( - // // height: 4, - // // ), - // // ServiceReportTypeMenu( - // // initialValue: _serviceReport.type, - // // onSelect: (status) { - // // _serviceReport.type = status; - // // }, - // // ), - // // ], - // // ), - // // ), - // // const SizedBox( - // // width: 8, - // // ), - // // visit date - // Expanded( - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // ASubTitle(context.translation.visitDate), - // _validate && _serviceReport.visitDate == null - // ? ASubTitle( - // context.translation.requiredWord, - // color: Colors.red, - // ) - // : const SizedBox.shrink(), - // Row( - // children: [ - // Expanded( - // child: ADatePicker( - // date: _serviceReport.visitDate, - // from: DateTime.now().subtract(const Duration(days: 365)), - // to: DateTime.now().add(const Duration(days: 365)), - // onDatePicker: (date) { - // _serviceReport.visitDate = date; - // setState(() {}); - // }, - // ), - // ), - // ], - // ), - // ], - // ), - // ), - // ], - // ), - // const SizedBox( - // height: 8, - // ), - // device sn - // Visibility( - // visible: widget.request.deviceSerialNumber == null, - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // ASubTitle(context.translation.deviceSN), - // _validate && _serviceReport.device?.id == null - // ? ASubTitle( - // context.translation.requiredWord, - // color: Colors.red, - // ) - // : const SizedBox.shrink(), - // AutoCompleteDeviceField( - // hospitalId: widget.request.hospitalId, - // initialValue: _serviceReport.device, - // onPick: (id) { - // _serviceReport.device.id = id; - // }, - // ), - // const SizedBox(height: 8), - // ], - // ), - // ), - const SizedBox(height: 8), - ASubTitle(context.translation.assetType), - _validate && _serviceReport.assetType == null - ? ASubTitle( - context.translation.requiredWord, - color: Colors.red, - ) - : const SizedBox.shrink(), - const SizedBox( - height: 4, - ), - LoadingManager( - isLoading: _assetTypeProvider.isLoading, - isFailedLoading: _assetTypeProvider.statuses == null, - stateCode: _assetTypeProvider.stateCode, - onRefresh: () async { - _assetTypeProvider.reset(); - await _assetTypeProvider.getTypes(user: _userProvider.user, host: _settingProvider.host); - _serviceReport?.assetType = _assetTypeProvider.statuses?.firstWhere( - (element) => element.value == _callRequestForWorkOrder.assetType, - orElse: () => null, - ); - }, - child: ATextFormField( - initialValue: _serviceReport?.assetType?.name ?? "NULL", - textAlign: TextAlign.center, - enable: false, - style: Theme.of(context).textTheme.titleMedium, - ), - ), - // ServiceAssetTypeMenu( - // initialValue: _serviceReport.assetType, - // onSelect: (status) { - // _serviceReport.assetType = status; - // }, - // ), - const SizedBox( - height: 8, - ), - Row( - children: [ - // report status - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // ASubTitle(context.translation.reportStatus), - ASubTitle("Equipment Status"), - _validate && _serviceReport.equipmentStatus == null - ? ASubTitle( - context.translation.requiredWord, - color: Colors.red, - ) - : const SizedBox.shrink(), - const SizedBox( - height: 4, - ), - // ServiceReportStatusMenu( - // report: _serviceReport, - // request: widget.request, - // onSelect: (status) { - // _serviceReport.status = status; - // }, - // ), - ServiceReportEquipmentStatusMenu( - report: _serviceReport, - request: widget.request, - onSelect: (status) { - _serviceReport.equipmentStatus = status; - }, - ) - ], - ), - ), - const SizedBox( - width: 8, - ), - // Provider.of(context).isLoading == null - // ? const SizedBox.shrink(): - // Call's last Situation - Consumer( - builder: (_, provider, __) { - if (provider.isLoading == null) return const SizedBox.shrink(); - return Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ASubTitle(context.translation.callLastSituation), - _validate && _serviceReport.calllastSituation == null - ? ASubTitle( - context.translation.requiredWord, - color: Colors.red, - ) - : const SizedBox.shrink(), - const SizedBox(height: 4), - ServiceReportLastCallsMenu( - report: _serviceReport, - onSelect: (status) { - if (status?.value == 12 || _serviceReport.calllastSituation?.value == 12) { - _serviceReport.calllastSituation = status; - setState(() {}); - } else { - _serviceReport.calllastSituation = status; - setState(() {}); - } - }, - ), - ], - ), - ); - }, - ), - ], - ), - const SizedBox( - height: 8, - ), - const ASubTitle("Return to Service"), - // Row( - // children: [ - // Expanded( - // child: ADatePicker( - // date: _serviceReport.returnToService, - // from: DateTime.now().subtract(const Duration(days: 365)), - // to: DateTime.now().add(const Duration(days: 365)), - // onDatePicker: (date) { - // _serviceReport.returnToService = date; - // setState(() {}); - // }, - // ), - // ), - // ], - // ), - if (_serviceReport?.calllastSituation?.value == 2) - Column( - children: [ - const SizedBox( - height: 8, - ), - ATextFormField( - initialValue: _serviceReport?.reviewComment, - hintText: "Vendor Name", - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.titleMedium, - textInputType: TextInputType.multiline, - onSaved: (value) { - _serviceReport.reviewComment = value; - }, - ), - const SizedBox( - height: 8, - ), - ATextFormField( - initialValue: _serviceReport?.reviewComment, - hintText: "Vendor Engineer", - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.titleMedium, - textInputType: TextInputType.multiline, - onSaved: (value) { - _serviceReport.reviewComment = value; - }, - ), - ], - ), - if (_showCommentField) - const SizedBox( - height: 8, - ), - if (_showCommentField) - ATextFormField( - initialValue: _serviceReport?.reviewComment, - hintText: "Review Comment", - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.titleMedium, - textInputType: TextInputType.multiline, - onSaved: (value) { - _serviceReport.reviewComment = value; - }, - ), - - SizedBox( - height: 8 * AppStyle.getScaleFactor(context), - ), - // const ASubTitle("Assign Employee"), - // const SizedBox( - // height: 8, - // ), - // _validate && _serviceReport.engineer == null - // ? ASubTitle( - // context.translation.requiredWord, - // color: Colors.red, - // ) - // : const SizedBox.shrink(), - // const SizedBox( - // height: 4, - // ), - // EngineersMenu( - // initialValue: _serviceReport.engineer, - // onSelect: (engineer) { - // _serviceReport.engineer = engineer; - // }, - // ), - // const SizedBox( - // height: 8, - // ), - // Report status and Service Type - // Row( - // children: [ - // // report status - // Expanded( - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // ASubTitle(context.translation.reportStatus), - // _validate && _serviceReport.equipmentStatus == null - // ? ASubTitle( - // context.translation.requiredWord, - // color: Colors.red, - // ) - // : const SizedBox.shrink(), - // const SizedBox( - // height: 4, - // ), - // ServiceReportStatusMenu( - // report: _serviceReport, - // request: widget.request, - // onSelect: (status) { - // _serviceReport.equipmentStatus = status; - // }, - // ), - // ], - // ), - // ), - // const SizedBox( - // width: 8, - // ), - // Consumer( - // builder: (_, provider, __) { - // if (provider.isLoading == null) return const SizedBox.shrink(); - // return Expanded( - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // ASubTitle(context.translation.callLastSituation), - // _validate && _serviceReport.callLastSituation == null - // ? ASubTitle( - // context.translation.requiredWord, - // color: Colors.red, - // ) - // : const SizedBox.shrink(), - // const SizedBox( - // height: 4, - // ), - // ServiceReportLastCallsMenu( - // report: _serviceReport, - // onSelect: (status) { - // if (status?.value == 12 || _serviceReport.callLastSituation?.value == 12) { - // _serviceReport.callLastSituation = status; - // setState(() {}); - // } else { - // _serviceReport.callLastSituation = status; - // } - // }, - // ), - // ], - // ), - // ); - // }, - // ), - // ], - // ), - const SizedBox( - height: 8, - ), - // invoice number & code - _serviceReport.calllastSituation?.value != 12 - ? const SizedBox.shrink() - : Row( - children: [ - // Expanded( - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // ASubTitle(context.translation.invoiceNumber), - // const SizedBox( - // height: 8, - // ), - // ATextFormField( - // initialValue: _serviceReport?.invoiceNumber, - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // validator: (value) => Validator.hasValue(value) ? null : context.translation.requiredWord, - // textInputType: TextInputType.number, - // onSaved: (value) { - // _serviceReport.invoiceNumber = value; - // }, - // ), - // ], - // ), - // ), - const SizedBox( - width: 8, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ASubTitle(context.translation.invoiceCode), - const SizedBox( - height: 4, - ), - // ATextFormField( - // initialValue: _serviceReport?.invoiceCode, - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // validator: (value) => Validator.hasValue(value) ? null : context.translation.requiredWord, - // textInputType: TextInputType.text, - // onSaved: (value) { - // _serviceReport.invoiceCode = value; - // }, - // ), - ], - ), - ), - ], - ), - - // const SizedBox(height: 8,), - // Row( - // children: [ - // ASubTitle(context.translation.faultDescription), - // Expanded( - // child: SizedBox( - // height: 32 * AppStyle.getScaleFactor(context), - // child: SpeechToTextButton( - // controller: _faultController, - // mini: true, - // ), - // ), - // ), - // ], - // ), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: _serviceReport?.faultDescriptionId, - // textAlign: TextAlign.center, - // controller: _faultController, - // style: Theme.of(context).textTheme.subtitle1, - // validator: (value) => - // Validator.hasValue(value) - // ? null : context.translation.requiredWord, - // textInputType: TextInputType.multiline, - // onSaved: (value){ - // _serviceReport.faultDescriptionId = value; - // }, - // ), - // const SizedBox(height: 8,), - // Row( - // children: [ - // ASubTitle(context.translation.workPreformed), - // Expanded( - // child: SizedBox( - // height: 32 * AppStyle.getScaleFactor(context), - // child: SpeechToTextButton( - // controller: _workPreformedController, - // mini: true, - // ), - // ), - // ), - // ], - // ), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: _serviceReport?.workPreformed, - // textAlign: TextAlign.center, - // controller: _workPreformedController, - // style: Theme.of(context).textTheme.subtitle1, - // validator: (value) => - // Validator.hasValue(value) - // ? null : context.translation.requiredWord, - // textInputType: TextInputType.multiline, - // onSaved: (value){ - // _serviceReport.workPreformed = value; - // }, - // ), - // const SizedBox(height: 8,), - const SizedBox(height: 8), - ASubTitle(context.translation.workingHours), - const SizedBox(height: 8), - // Row( - // children: [ - // Expanded( - // child: AppTimer( - // timer: _serviceReport.timer, - // enabled: false, - // // onChange: (timer) async { - // // _serviceReport.timer = timer; - // // _serviceReport.workingHours = num.tryParse((((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0"); - // // return true; - // // }, - // ), - // ), - // ], - // ), - const SizedBox(height: 16), - if (_showCommentField) - const SizedBox( - height: 8, - ), - if (_showCommentField) - ATextFormField( - initialValue: _serviceReport?.reviewComment, - hintText: "Review Comment", - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.titleMedium, - textInputType: TextInputType.multiline, - onSaved: (value) { - _serviceReport.reviewComment = value; - }, - ), - SizedBox( - height: 8 * AppStyle.getScaleFactor(context), - ), - const SizedBox(height: 8), - ASubTitle(context.translation.faultDescription), - const SizedBox( - height: 4, - ), - ServiceReportFaultDescription( - requestId: widget.request?.id, - initialValue: _serviceReport.faultDescription, - onSelect: (status) { - _serviceReport.faultDescription = status; - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - if (mounted) setState(() {}); - }); - }, - ), - const SizedBox(height: 8), - const ASubTitle("Solutions"), - const SizedBox(height: 4), - ATextFormField( - initialValue: "_serviceReport?.workPreformed", - textAlign: TextAlign.center, - enable: false, - hintText: _serviceReport.faultDescription?.workPerformed ?? "", - controller: _workPreformedController, - style: Theme.of(context).textTheme.subtitle1, - validator: (value) => Validator.hasValue(value) ? null : context.translation.requiredWord, - textInputType: TextInputType.multiline, - onSaved: (value) { - // _serviceReport.workPreformed = value; - }, - ), - const SizedBox(height: 4), - ASubTitle("Failure Reason"), - const SizedBox( - height: 4, - ), - ServiceReportReasonsMenu( - initialValue: _serviceReport.reason, - onSelect: (status) { - _serviceReport.reason = status; - }, - ), - const SizedBox( - height: 8, - ), - ASubTitle(context.translation.attachImage), - const SizedBox( - height: 4, - ), - MultiFilesPicker( - label: "", - files: _images, - ), - // AMiniOneImagePicker( - // //error: _validate && _serviceReport.image == null, - // image: _image, - // onPick: (image) { - // _image = image; - // _serviceReport.image = base64Encode(image.readAsBytesSync()); - // }, - // ), - const SizedBox( - height: 8, - ), - const SizedBox(height: 8), - ASubTitle(context.translation.repairLocation), - const SizedBox(height: 4), - ServiceReportRepairLocation( - initialValue: _serviceReport.repairLocation, - onSelect: (status) { - _serviceReport.repairLocation = status; - }, - ), - const SizedBox(height: 16), - ASubTitle("Travel Expenses"), - const SizedBox( - height: 4, - ), - ATextFormField( - initialValue: " _serviceReport?.travelingExpense?.toString()", - hintText: context.translation.travelingExpense, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.titleMedium, - textInputType: TextInputType.number, - onSaved: (value) { - // if (value != null && value.isEmpty) { - // _serviceReport.travelingExpense = num.tryParse(_serviceReport?.travelingExpense?.toString() ?? "") ?? 0; - // } else - // _serviceReport.travelingExpense = num.tryParse(value) ?? 0; - }, - ), - - const SizedBox(height: 8), - ASubTitle(context.translation.travelingHours), - const SizedBox(height: 4), - ATextFormField( - initialValue: _serviceReport?.travelingHours?.toString(), - textAlign: TextAlign.center, - hintText: "i.e 3, 3.5, 4", - style: Theme.of(context).textTheme.subtitle1, - // validator: (value) => - // Validator.isNumeric(value) - // ? null : context.translation.requiredWord, - textInputType: TextInputType.number, - onSaved: (value) { - _serviceReport.travelingHours = double.tryParse(value) ?? 0.0; - }, - ), - // Traveling Hours & Working Hours - // Row( - // children: [ - // Expanded( - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // ASubTitle(context.translation.workingHours), - // const SizedBox( - // height: 8, - // ), - // Row( - // children: [ - // Expanded( - // child: AppTimer( - // timer: _serviceReport.timer, - // onChange: (timer) async { - // _serviceReport.timer = timer; - // return true; - // }, - // ), - // ), - // ], - // ), - // // ATextFormField( - // // initialValue: _serviceReport?.workHours, - // // textAlign: TextAlign.center, - // // hintText: "i.e 3, 3.5, 4", - // // style: Theme.of(context).textTheme.subtitle1, - // // validator: (value) => - // // Validator.isNumeric(value) - // // ? null : context.translation.requiredWord, - // // textInputType: TextInputType.number, - // // onSaved: (value){ - // // _serviceReport.workHours = value; - // // }, - // // ), - // ], - // ), - // ), - // // const SizedBox(width: 8,), - // // Expanded( - // // child: Column( - // // crossAxisAlignment: CrossAxisAlignment.start, - // // children: [ - // // ASubTitle(context.translation.travelingHours), - // // const SizedBox(height: 4,), - // // ATextFormField( - // // initialValue: _serviceReport?.travelingHours, - // // textAlign: TextAlign.center, - // // hintText: "i.e 3, 3.5, 4", - // // style: Theme.of(context).textTheme.subtitle1, - // // validator: (value) => - // // Validator.isNumeric(value) - // // ? null : context.translation.requiredWord, - // // textInputType: TextInputType.number, - // // onSaved: (value){ - // // _serviceReport.travelingHours = value; - // // }, - // // ), - // // ], - // // ), - // // ), - // ], - // ), - // const SizedBox( - // height: 8, - // ), - // Operating Hours and Job Sheet Number - // Row( - // children: [ - // Expanded( - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // ASubTitle(context.translation.operatingHours), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: _serviceReport?.operatingHours, - // textAlign: TextAlign.center, - // hintText: "i.e 3, 3.5, 4", - // style: Theme.of(context).textTheme.subtitle1, - // validator: (value) => - // Validator.isNumeric(value) - // ? null : context.translation.requiredWord, - // textInputType: TextInputType.number, - // onSaved: (value){ - // _serviceReport.operatingHours = value; - // }, - // ), - // ], - // ), - // ), - // const SizedBox(width: 8,), - // Expanded( - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // ASubTitle(context.translation.jobSheetNumber), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: _serviceReport?.jobSheetNumber, - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // textInputType: TextInputType.name, - // onSaved: (value){ - // _serviceReport.jobSheetNumber = value; - // }, - // ), - // ], - // ), - // ), - // ], - // ), - //const SizedBox(height: 8,), - - const SizedBox(height: 8), - const ASubTitle("Technical comment"), - const SizedBox(height: 4), - ATextFormField( - initialValue: _serviceReport?.comment, - hintText: "Technical Comment", - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.titleMedium, - textInputType: TextInputType.multiline, - onSaved: (value) { - _serviceReport.comment = value; - }, - ), - const SizedBox(height: 8), - const ASubTitle("Nurse Signature"), - // ESignature( - // oldSignature: _serviceReport.signatureNurse, - // newSignature: _serviceReport.localNurseSignature, - // onSaved: (signature) { - // if (signature == null || signature.isEmpty) { - // return; - // } - // _serviceReport.localNurseSignature = signature; - // _serviceReport.signatureNurse = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - // }, - // ), - // const SizedBox( - // height: 8, - // ), - // const ASubTitle("Engineer Signature"), - // ESignature( - // oldSignature: _serviceReport.signatureEngineer, - // newSignature: _serviceReport.localNurseSignature, - // onSaved: (signature) { - // if (signature == null || signature.isEmpty) { - // return; - // } - // _serviceReport.localNurseSignature = signature; - // _serviceReport.signatureEngineer = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - // }, - // ), - const SizedBox( - height: 8, - ), - // Part Number and Quantity - ], - ), - ), - ], - ), - ASubTitle("Spare Parts"), - Container( - width: double.infinity, - padding: const EdgeInsets.all(16), - margin: const EdgeInsets.symmetric(vertical: 16), - decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [ - BoxShadow( - color: AColors.grey, - offset: Offset(0, -1), - ) - ]), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - // Row( - // children: [ - // Expanded( - // flex: 3, - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // ASubTitle(context.translation.partNumberName), - // _validate && _serviceReport.parts == null - // ? ASubTitle( - // context.translation.requiredWord, - // color: Colors.red, - // ) - // : const SizedBox.shrink(), - // const SizedBox( - // height: 4, - // ), - // AutoCompletePartsField( - // assetId: _serviceReport?.device?.id, - // onPick: (part) { - // _serviceReport.parts.add(part); - // setState(() {}); - // }, - // ), - // ], - // ), - // ), - // ], - // ), - SizedBox( - height: 8 * AppStyle.getScaleFactor(context), - ), - Row( - children: [ - Expanded(flex: 3, child: Text(context.translation.number)), - Expanded(flex: 1, child: Text(context.translation.quantity)), - ], - ), - // Column( - // children: List.generate(_serviceReport.parts.length, (index) { - // Part _part = _serviceReport.parts[index]; - // return PartItem( - // part: _part, - // onDelete: (part) { - // _serviceReport.parts.remove(part); - // setState(() {}); - // }, - // ); - // }), - // ), - const SizedBox( - height: 16, - ), - ], + 8.height, + ADatePicker( + label: context.translation.visitDate, + date: DateTime.tryParse(_serviceReport.visitDate ?? ""), + onDatePicker: (date) { + _serviceReport.visitDate = date?.toIso8601String(); + // setState(() {}); + }, ), - ), - AButton( - text: context.translation.update, - onPressed: () async { - if (_serviceReport?.workingHours == null) { - await Fluttertoast.showToast(msg: "Working Hours Timer Isn't Started"); - return; - } - _validate = true; - // if (!_formKey.currentState.validate()) { - // setState(() {}); - // return; - // } - // print("jere124"); - // if (!_serviceReport.validate()) { - // setState(() {}); - // return; - // } - // print("jere14"); - _formKey.currentState.save(); - - _isLoading = true; - setState(() {}); - // _serviceReport.files = _images.map((e) => _isLocalUrl(e.path) ? "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}" : e.path).toList(); - int status = await _serviceRequestsProvider.updateServiceReport(user: _userProvider.user, host: _settingProvider.host, report: _serviceReport, request: widget.request); - _isLoading = false; - setState(() {}); - if (status >= 200 && status < 300) { - Fluttertoast.showToast( - msg: context.translation.successfulRequestMessage, - ); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - } else { - String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: context.translation); - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text(errorMessage), - )); - } - }, - ), - ], + 8.height, + AppTextFormField( + labelText: context.translation.workingHours, + textInputType: TextInputType.number, + initialValue: _serviceReport.workingHours?.toString(), + onSaved: (text) { + _serviceReport.workingHours = num.tryParse(text ?? ""); + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + title: context.translation.reason, + initialValue: _serviceReport.reason, + onSelect: (value) { + _serviceReport.reason = value; + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + title: context.translation.serviceType, + onSelect: (value) {}, + ), + 8.height, + ServiceReportLastCallsMenu( + report: _serviceReport, + title: context.translation.callLastSituation, + parentId: widget.request.id, + onSelect: (status) { + _serviceReport.calllastSituation = status; + }, + ), + 8.height, + ServiceReportAssistantEmployeeMenu( + title: context.translation.assignAssistant, + assetId: _serviceReport.callRequest?.asset?.id, + initialValue: (_serviceReport.assistantEmployees?.isNotEmpty ?? false) ? _serviceReport.assistantEmployees?.first : null, + onSelect: (employee) { + _serviceReport.assistantEmployees = [employee.copyWith(id: 0)]; + }, + ), + 8.height, + SingleItemDropDownMenu( + context: context, + title: context.translation.partNo, + staticData: _spareParts, + initialValue: (_serviceReport.sparePartsWorkOrders?.isNotEmpty ?? false) ? _serviceReport.sparePartsWorkOrders.first.sparePart : null, + onSelect: (part) { + _serviceReport.sparePartsWorkOrders.clear(); + _serviceReport.sparePartsWorkOrders.add(SparePartsWorkOrders(id: 0, sparePart: part, qty: 0)); + // setState(() {}); + }, + ), + 8.height, + AppTextFormField( + labelText: context.translation.quantity, + textInputType: TextInputType.number, + enable: _serviceReport.sparePartsWorkOrders.isNotEmpty, + initialValue: (_serviceReport.sparePartsWorkOrders?.isNotEmpty ?? false) ? _serviceReport.sparePartsWorkOrders.first.qty?.toString() : null, + onSaved: (text) { + if (_serviceReport.sparePartsWorkOrders?.isNotEmpty ?? false) { + _serviceReport.sparePartsWorkOrders.first.qty = num.tryParse(text ?? ""); + } + }, + ), + 8.height, + MultiFilesPicker(label: context.translation.attachImage, files: _files), + 8.height, + ESignature( + title: context.translation.engSign, + oldSignature: _serviceReport.engSignature, + newSignature: _serviceReport.localEngSignature, + onSaved: (signature) { + // if (signature == null || signature.isEmpty) { + // setState(() {}); + // return; + // } + _serviceReport.localEngSignature = signature; + _serviceReport.engSignature = signature != null ? "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}" : null; + }, + ), + 24.height, + ], + ), + ).expanded, + AppFilledButton( + label: context.translation.updateRequest, + onPressed: () async { + if ((!_formKey.currentState.validate()) || (!(await _serviceReport.validate(context)))) { + setState(() {}); + return; + } + _formKey.currentState.save(); + _serviceReport.attachmentsWorkOrder ??= []; + if (_files.isEmpty) _serviceReport.attachmentsWorkOrder = []; + try { + for (var file in _files) { + _serviceReport.attachmentsWorkOrder.add(Attachment(id: 0, name: "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}")); + } + } catch (error) { + print(error); + } + await _serviceRequestsProvider.updateServiceReport(context, report: _serviceReport); + }, ), - const ABackButton(), ], - ), + ).paddingAll(16), ), ), ), ); } - - bool _isLocalUrl(String url) { - if (url?.isEmpty != false) return false; - return url.startsWith("/") || url.startsWith("file://") || url.substring(1).startsWith(':\\'); - } } diff --git a/lib/views/pages/user/requests/work_order/future_service_report.dart b/lib/views/pages/user/requests/work_order/update_service_report.dart similarity index 53% rename from lib/views/pages/user/requests/work_order/future_service_report.dart rename to lib/views/pages/user/requests/work_order/update_service_report.dart index 937262b4..fb8bcee7 100644 --- a/lib/views/pages/user/requests/work_order/future_service_report.dart +++ b/lib/views/pages/user/requests/work_order/update_service_report.dart @@ -1,9 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; import 'package:test_sa/controllers/providers/api/service_requests_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/models/service_request/search_work_order.dart'; import 'package:test_sa/models/service_request/service_report.dart'; import 'package:test_sa/models/service_request/service_request.dart'; @@ -12,29 +8,23 @@ import 'package:test_sa/views/widgets/loaders/failed_loading.dart'; import 'edit_service_report.dart'; -class FutureServiceReport extends StatefulWidget { +class UpdateServiceReport extends StatefulWidget { final ServiceRequest request; final SearchWorkOrder workOrder; - const FutureServiceReport({Key key, this.request, this.workOrder}) : super(key: key); + const UpdateServiceReport({Key key, this.request, this.workOrder}) : super(key: key); @override - _FutureServiceReportState createState() => _FutureServiceReportState(); + _UpdateServiceReportState createState() => _UpdateServiceReportState(); } -class _FutureServiceReportState extends State { - UserProvider _userProvider; - SettingProvider _settingProvider; - +class _UpdateServiceReportState extends State { @override Widget build(BuildContext context) { - _userProvider = Provider.of(context); - _settingProvider = Provider.of(context); - - ServiceRequestsProvider().getSingleServiceReport(reportId: widget.workOrder.id, user: _userProvider.user, host: _settingProvider.host, subtitle: context.translation); + ServiceRequestsProvider().getSingleServiceReport(context, reportId: widget.workOrder.id); return Scaffold( body: FutureBuilder( - future: ServiceRequestsProvider().getSingleServiceReport(reportId: widget.workOrder.id, user: _userProvider.user, host: _settingProvider.host, subtitle: context.translation), + future: ServiceRequestsProvider().getSingleServiceReport(context, reportId: widget.workOrder.id), builder: (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasError) { return FailedLoading( @@ -45,10 +35,7 @@ class _FutureServiceReportState extends State { ); } if (snapshot.connectionState == ConnectionState.done) { - return EditServiceReport( - report: snapshot.data, - request: widget.request, - ); + return EditServiceReport(report: snapshot.data, request: widget.request); } return const Center(child: ALoading()); }, diff --git a/lib/views/pages/user/requests/work_order/work_order_details_page.dart b/lib/views/pages/user/requests/work_order/work_order_details_page.dart index efc0c920..cd9d9ab1 100644 --- a/lib/views/pages/user/requests/work_order/work_order_details_page.dart +++ b/lib/views/pages/user/requests/work_order/work_order_details_page.dart @@ -14,7 +14,7 @@ import '../../../../../controllers/providers/api/user_provider.dart'; import '../../../../../models/enums/user_types.dart'; import '../../../../../models/service_request/search_work_order.dart'; import '../../../../widgets/requests/request_status.dart'; -import 'future_service_report.dart'; +import 'update_service_report.dart'; class WorkOrderDetailsPage extends StatelessWidget { static const String id = "/work_order_details_page"; @@ -79,7 +79,7 @@ class WorkOrderDetailsPage extends StatelessWidget { AppFilledButton( onPressed: () { Navigator.of(context).push( - MaterialPageRoute(builder: (_) => FutureServiceReport(request: serviceRequest, workOrder: workOrder)), + MaterialPageRoute(builder: (_) => UpdateServiceReport(request: serviceRequest, workOrder: workOrder)), ); }, label: context.translation.updateRequest, diff --git a/lib/views/pages/user/requests/work_order/work_orders_list_page.dart b/lib/views/pages/user/requests/work_order/work_orders_list_page.dart index 744e7a11..2f7ea3e6 100644 --- a/lib/views/pages/user/requests/work_order/work_orders_list_page.dart +++ b/lib/views/pages/user/requests/work_order/work_orders_list_page.dart @@ -14,7 +14,7 @@ import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/pages/user/requests/work_order/create_service_report.dart'; -import 'package:test_sa/views/pages/user/requests/work_order/future_service_report.dart'; +import 'package:test_sa/views/pages/user/requests/work_order/update_service_report.dart'; import 'package:test_sa/views/pages/user/requests/work_order/work_order_details_page.dart'; import 'package:test_sa/views/widgets/requests/request_status.dart'; @@ -86,7 +86,7 @@ class WorkOrderListPage extends StatelessWidget { if (_userProvider.user.type == UsersTypes.engineer && serviceRequest.statusValue != 5 && serviceRequest.statusValue != 3) "edit".toSvgAsset(height: 48, width: 48).onPress(() { Navigator.of(context).push( - MaterialPageRoute(builder: (_) => FutureServiceReport(request: serviceRequest, workOrder: workOrders[index])), + MaterialPageRoute(builder: (_) => UpdateServiceReport(request: serviceRequest, workOrder: workOrders[index])), ); }) ], diff --git a/lib/views/widgets/e_signature/e_signature.dart b/lib/views/widgets/e_signature/e_signature.dart index 3ed11050..2fbf9e6a 100644 --- a/lib/views/widgets/e_signature/e_signature.dart +++ b/lib/views/widgets/e_signature/e_signature.dart @@ -6,6 +6,9 @@ import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; +import '../../app_style/sizing.dart'; +import '../loaders/image_loader.dart'; + class ESignature extends StatefulWidget { final String oldSignature; final Uint8List newSignature; @@ -35,7 +38,7 @@ class _ESignatureState extends State { if (widget.newSignature != null) { signature = widget.newSignature; } else if (widget.oldSignature != null || signature != null) { - signature = widget.oldSignature.codeUnits; + signature = Uint8List.fromList(widget.oldSignature.codeUnits); } super.initState(); } @@ -50,12 +53,13 @@ class _ESignatureState extends State { Widget build(BuildContext context) { return Column( children: [ - // if (widget.oldSignature != null || signature != null) - // Container( - // width: MediaQuery.of(context).size.width, - // padding: const EdgeInsets.only(bottom: 8), - // height: 90 * AppStyle.getScaleFactor(context), - // child: signature != null ? Image.memory(signature) : ImageLoader(boxFit: BoxFit.contain, url: widget.oldSignature)), + if (widget.oldSignature != null || signature != null) + Container( + width: MediaQuery.of(context).size.width, + padding: const EdgeInsets.only(bottom: 8), + height: 90 * AppStyle.getScaleFactor(context), + child: signature != null ? Image.memory(signature) : ImageLoader(boxFit: BoxFit.contain, url: widget.oldSignature), + ), FormField(onSaved: (_) async { widget.onSaved(signature); }, builder: (FormFieldState state) { From 8b63cee7c58f803e38272b38835963c200f7d7dc Mon Sep 17 00:00:00 2001 From: zaid_daoud Date: Wed, 1 Nov 2023 14:40:46 +0300 Subject: [PATCH 5/8] Update Work Order Screen DONE --- lib/views/widgets/e_signature/e_signature.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/views/widgets/e_signature/e_signature.dart b/lib/views/widgets/e_signature/e_signature.dart index 2fbf9e6a..e21a51a0 100644 --- a/lib/views/widgets/e_signature/e_signature.dart +++ b/lib/views/widgets/e_signature/e_signature.dart @@ -37,8 +37,6 @@ class _ESignatureState extends State { void initState() { if (widget.newSignature != null) { signature = widget.newSignature; - } else if (widget.oldSignature != null || signature != null) { - signature = Uint8List.fromList(widget.oldSignature.codeUnits); } super.initState(); } From 57abce1b75fdd671f1320ef5776d996b5ecab009 Mon Sep 17 00:00:00 2001 From: nextwo <1234> Date: Wed, 1 Nov 2023 14:43:54 +0300 Subject: [PATCH 6/8] device transfer --- lib/l10n/app_ar.arb | 3 +- lib/l10n/app_en.arb | 3 +- lib/models/device/asset_transfer.dart | 63 ++++++ .../device_transfer_details.dart | 12 +- .../update_device_transfer.dart | 189 ++++++++++-------- .../user/gas_refill/request_gas_refill.dart | 36 +--- .../device_trancfer/device_transfer_item.dart | 12 +- 7 files changed, 187 insertions(+), 131 deletions(-) diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index 102bb310..1a532274 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -300,5 +300,6 @@ "assistantEmployee" : "موظف مساعد", "assignAssistant" : "تعيين مساعد", "partNo" : "الجزء رقم", - "engSign" : "توقيع المهندس" + "engSign" : "توقيع المهندس", + "requesterName" : "اسم الطالب" } \ No newline at end of file diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index d0261e24..2d930a7c 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -305,5 +305,6 @@ "assistantEmployee" : "Assistant Employee", "assignAssistant" : "Assign Assistant", "partNo" : "Part No.", - "engSign" : "Engineer Signature" + "engSign" : "Engineer Signature", + "requesterName" : "Requester Name" } \ No newline at end of file diff --git a/lib/models/device/asset_transfer.dart b/lib/models/device/asset_transfer.dart index 827830a5..46fe292d 100644 --- a/lib/models/device/asset_transfer.dart +++ b/lib/models/device/asset_transfer.dart @@ -425,6 +425,69 @@ class AssetTransfer { return map; } + fromDetails(AssetTransfer assetTransfer){ + + id= assetTransfer.id; + transferNo=assetTransfer.transferNo; + transferCode= assetTransfer.transferCode; + assetId=assetTransfer.assetId; + destSiteId= assetTransfer.destSiteId; + destBuildingId=assetTransfer.destBuildingId; + destFloorId=assetTransfer.destFloorId; + destDepartmentId= assetTransfer.destDepartmentId; + destRoom=assetTransfer.destRoom; + senderSiteId=assetTransfer.senderSiteId; + senderBuildingId=assetTransfer.senderBuildingId; + senderFloorId=assetTransfer.senderFloorId; + senderDepartmentId=assetTransfer.senderDepartmentId; + senderRoom=assetTransfer.senderRoom; + senderAssignedEmployeeId= assetTransfer.senderAssignedEmployeeId; + senderMachineStatusId=assetTransfer.senderMachineStatusId; + senderComment=assetTransfer.senderComment; + senderStartDate= assetTransfer.senderStartDate; + senderEndDate= assetTransfer.senderEndDate; + senderWorkingHours= assetTransfer.senderWorkingHours; + senderTravelingHours= assetTransfer.senderTravelingHours; + senderEngSignature=assetTransfer.senderEngSignature; + senderAttachments=assetTransfer.senderAttachments; + receiverAssignedEmployeeId=assetTransfer.receiverAssignedEmployeeId; + receiverMachineStatusId= assetTransfer.receiverMachineStatusId; + receiverComment= assetTransfer.receiverComment; + receiverStartDate=assetTransfer.receiverStartDate; + receiverEndDate= assetTransfer.receiverEndDate; + receiverWorkingHours= assetTransfer.receiverWorkingHours; + receiverTravelingHours= assetTransfer.receiverTravelingHours; + receiverEngSignature= assetTransfer.receiverEngSignature; + receiverAttachments=assetTransfer.receiverAttachments; + supplierId =assetTransfer.supplierId; + supplierName=assetTransfer.supplierName; + destSiteName=assetTransfer.destSiteName; + destBuildingName=assetTransfer.destBuildingName; + destFloorName=assetTransfer.destFloorName; + destDepartmentName=assetTransfer.destDepartmentName; + senderSiteName=assetTransfer.senderSiteName; + senderBuildingName=assetTransfer.senderBuildingName; + senderFloorName=assetTransfer.senderFloorName; + senderDepartmentName=assetTransfer.senderDepartmentName; + senderAssignedEmployeeName=assetTransfer.senderAssignedEmployeeName; + senderMachineStatusName= assetTransfer.senderMachineStatusName; + senderEngSignatureUrl= assetTransfer.senderEngSignatureUrl; + receiverAssignedEmployeeName=assetTransfer.receiverAssignedEmployeeName; + receiverMachineStatusName=assetTransfer.receiverMachineStatusName; + receiverEngSignatureUrl=assetTransfer.receiverEngSignatureUrl; + applied=assetTransfer.applied; + createdOn= assetTransfer.createdOn; + modifiedOn= assetTransfer.modifiedOn; + assetSerialNo=assetTransfer.assetSerialNo; + assetNumber=assetTransfer.assetNumber; + assetName=assetTransfer.assetName; + modelId=assetTransfer.modelId; + modelName=assetTransfer.modelName; + manufacturerId=assetTransfer.manufacturerId; + manufacturerName=assetTransfer.manufacturerName; + } + + Future validate(BuildContext context) async { if (assetId == null) { await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.device}"); diff --git a/lib/views/pages/device_transfer/device_transfer_details.dart b/lib/views/pages/device_transfer/device_transfer_details.dart index d0e568ab..e17e3abf 100644 --- a/lib/views/pages/device_transfer/device_transfer_details.dart +++ b/lib/views/pages/device_transfer/device_transfer_details.dart @@ -83,14 +83,14 @@ class _DeviceTransferDetailsState extends State { Row( children: [ /// TBD - StatusLabel( - label: "", - id: 0, - textColor: AColors.getPriorityStatusTextColor(0), - backgroundColor: AColors.getPriorityStatusColor(0)), + // StatusLabel( + // label: "", + // id: 0, + // textColor: AColors.getPriorityStatusTextColor(0), + // backgroundColor: AColors.getPriorityStatusColor(0)), 8.width, /// TBD - StatusLabel(label: '', textColor: AColors.getRequestStatusTextColor(0), backgroundColor: AColors.getRequestStatusColor(0)), + //StatusLabel(label: '', textColor: AColors.getRequestStatusTextColor(0), backgroundColor: AColors.getRequestStatusColor(0)), ], ), 1.width.expanded, diff --git a/lib/views/pages/device_transfer/update_device_transfer.dart b/lib/views/pages/device_transfer/update_device_transfer.dart index c9babbc4..c8b54328 100644 --- a/lib/views/pages/device_transfer/update_device_transfer.dart +++ b/lib/views/pages/device_transfer/update_device_transfer.dart @@ -5,6 +5,8 @@ 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/widget_extensions.dart'; import 'package:test_sa/models/device/asset_transfer.dart'; import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; @@ -14,7 +16,14 @@ import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; import '../../../../controllers/localization/localization.dart'; +import '../../../controllers/validator/validator.dart'; +import '../../../extensions/text_extensions.dart'; +import '../../../models/lookup.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 '../../../providers/gas_request_providers/gas_status_provider.dart'; +import '../../widgets/e_signature/e_signature.dart'; class UpdateDeviceTransfer extends StatefulWidget { final AssetTransfer model; @@ -34,7 +43,7 @@ class _UpdateDeviceTransferState extends State { Uint8List _signature; AssetTransferProvider _deviceTransferProvider; final TextEditingController _requestedQuantityController = TextEditingController(); - // final DeviceTransferInfo _formModel = DeviceTransferInfo(attachments: []); + final AssetTransfer _formModel = AssetTransfer(); final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); @@ -76,7 +85,7 @@ class _UpdateDeviceTransferState extends State { @override void initState() { - // _formModel.fromDetails(widget.isSender ? widget.model.sender : widget.model.receiver, withSignature: false); + _formModel.fromDetails(widget.model); super.initState(); } @@ -101,103 +110,84 @@ class _UpdateDeviceTransferState extends State { stateCode: 200, onRefresh: () async {}, child: Column( - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SingleChildScrollView( padding: EdgeInsets.all(12 * AppStyle.getScaleFactor(context)), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - ASubTitle("Comment"), - const SizedBox( - height: 4, + _buildCard(), + 8.height, + AppTextFormField( + initialValue: widget.isSender? _formModel.senderTravelingHours:_formModel.receiverTravelingHours, + labelText: context.translation.travelingHours, + onSaved:(value){ + widget.isSender? _formModel.senderTravelingHours + : _formModel.receiverTravelingHours= value; + //_formModel?.workingHours = double.tryParse(value); + // _formModel.travelingHours = value; + }, + textInputType: TextInputType.number, + validator: (value) => Validator.isNumeric(value) ? null : "allow numbers only", ), - // ATextFormField( - // initialValue: _formModel?.comment, - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // textInputType: TextInputType.text, - // onSaved: (value) { - // _formModel.comment = value; - // }, - // ), - const SizedBox( - height: 8, - ), - ASubTitle(context.translation.travelingHours), - const SizedBox( - height: 4, - ), - // ATextFormField( - // initialValue: _formModel?.travelingHours, - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // textInputType: TextInputType.number, - // onSaved: (value) { - // _formModel.travelingHours = value; - // }, - // ), - const SizedBox( - height: 16, - ), - ASubTitle(context.translation.workingHours), - const SizedBox(height: 8), - Row( - children: [ - // Expanded( - // child: AppTimer( - // timer: _formModel.timer, - // onChange: (timer) async { + 8.height, + AppTextFormField( + labelText: context.translation.workingHours, + initialValue: widget.isSender?_formModel.senderWorkingHours:_formModel.receiverWorkingHours, + onSaved:(value){ + widget.isSender? + _formModel?.senderWorkingHours = value:_formModel?.receiverWorkingHours = value; // _formModel.timer = timer; // _formModel.workingHours = (((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0"; - // return true; - // }, - // ), - // ), - ], - ), - const SizedBox(height: 16), - ASubTitle(context.translation.status), - const SizedBox( - height: 4, + }, + textInputType: TextInputType.number, + validator: (value) => Validator.isNumeric(value) ? null : "allow numbers only", ), - // AssetStatusMenu( - // initialValue: _formModel.status, - // onSelect: (status) { - // if (status == null) return; - // _formModel.status = status; - // setState(() {}); - // }, - // ), - const SizedBox( - height: 16, + 8.height, + ///TBD + Consumer(builder: (context, snapshot, _){ + return SingleItemDropDownMenu( + context: context, + title: context.translation.reportStatus, + initialValue: snapshot.items?.firstWhere((element) => element.name == (widget.isSender?_formModel.senderMachineStatusName:_formModel.receiverMachineStatusName), orElse: () => null), + onSelect: (value) { + if(widget.isSender) { + _formModel.senderMachineStatusName=value.name; + _formModel.senderMachineStatusId=value.value; + }else{ + _formModel.receiverMachineStatusName=value.name; + _formModel.receiverMachineStatusId=value.value; + } + setState(() {}); + }, + ); + }), + 8.height, + AppTextFormField( + initialValue: widget.isSender?_formModel.senderComment:_formModel.receiverComment, + labelText: context.translation.comments, + textInputType: TextInputType.multiline, + alignLabelWithHint: true, + onSaved: (value){ + widget.isSender? + _formModel.senderComment = value:_formModel.receiverComment; + }, ), - // MultiFilesPicker( - // label: "Attachments", - // files: _formModel.attachments, - // ), - const SizedBox( - height: 16, + 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; + // _formModel.engSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + // base64Encode(signature); + }, ), - const ASubTitle("Signature"), - // if(_validate && _formModel.signature == null) - // ASubTitle(_subtitle.requiredWord,color: Colors.red,), - const SizedBox( - height: 4, - ), - // ESignature( - // oldSignature: widget.isSender ? widget.model.sender.engSignature : widget.model.receiver.engSignature, - // newSignature: _signature, - // onSaved: (signature) { - // _signature = signature; - // if (signature == null || signature.isEmpty) return; - // _formModel.engSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - // // base64Encode(signature); - // }, - // ), ], ), - ), + ).expanded, Padding( padding: const EdgeInsets.all(16.0), child: AppFilledButton( @@ -211,4 +201,33 @@ class _UpdateDeviceTransferState extends State { ), ); } + + _buildCard(){ + return Container( + width: MediaQuery.of(context).size.width, + decoration: ShapeDecoration( + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(15), + ), + shadows: const [BoxShadow(color: Color(0x07000000), blurRadius: 14, offset: Offset(0, 0), spreadRadius: 0)], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(context.translation.transferDetails, style: AppTextStyles.heading5.copyWith(color: const Color(0xFF3B3D4A))), + 8.height, + Text( + '${context.translation.assetName}: ${_formModel.assetName}', + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + ///TBD + Text( + '${context.translation.requesterName}: ', + style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), + ), + ], + ).paddingAll(16), + ); + } } diff --git a/lib/views/pages/user/gas_refill/request_gas_refill.dart b/lib/views/pages/user/gas_refill/request_gas_refill.dart index 4608f8f3..2d4c4908 100644 --- a/lib/views/pages/user/gas_refill/request_gas_refill.dart +++ b/lib/views/pages/user/gas_refill/request_gas_refill.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; @@ -14,20 +13,8 @@ import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/lookup.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/views/app_style/sizing.dart'; -import 'package:test_sa/views/widgets/app_text_form_field.dart'; -import 'package:test_sa/views/widgets/buttons/app_button.dart'; -import 'package:test_sa/views/widgets/gas_refill/building_type_menu.dart'; -import 'package:test_sa/views/widgets/gas_refill/department_type_menu.dart'; -import 'package:test_sa/views/widgets/gas_refill/floor_type_menu.dart'; -import 'package:test_sa/views/widgets/gas_refill/gas_refill_create_details_item.dart'; -import 'package:test_sa/views/widgets/hospitals/hospital_auto_complete_field_new.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; -import 'package:test_sa/views/widgets/status/gas_refill/gas_cylinder_size.dart'; -import 'package:test_sa/views/widgets/status/gas_refill/gas_cylinder_type.dart'; -import 'package:test_sa/views/widgets/status/gas_refill/gas_status.dart'; -import 'package:test_sa/views/widgets/status/gas_refill/gas_type.dart'; -import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; + import '../../../../controllers/providers/api/hospitals_provider.dart'; import '../../../../extensions/text_extensions.dart'; @@ -70,7 +57,7 @@ class _RequestGasRefillState extends State { void initState() { super.initState(); if (widget.gasRefillModel != null) { - _formModel = widget.gasRefillModel; + _formModel.fromGasRefillModel(widget.gasRefillModel); } } @@ -84,22 +71,7 @@ class _RequestGasRefillState extends State { if (!(await _addNewModel(context))) return; } - //_isLoading = true; setState(() {}); - // if (widget.gasRefillModel != null) { - // if (!(await _formModel.validate(context))) { - // _isLoading = false; - // setState(() {}); - // return; - // } - // } - //if(!(_formKey.currentState.validate())) return; - // if (_gasRefillProvider.department?.name == null) { - // ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Select department"))); - // _isLoading = false; - // setState(() {}); - // return; - // } int status = widget.gasRefillModel == null ? null /*await _gasRefillProvider.createModel( @@ -201,7 +173,6 @@ class _RequestGasRefillState extends State { stateCode: 200, onRefresh: () async {}, child: Column( - //mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SingleChildScrollView( child: Column( @@ -220,6 +191,7 @@ class _RequestGasRefillState extends State { children: [ Text(context.translation.gasRefill, style: AppTextStyles.heading5.copyWith(color: const Color(0xFF3B3D4A))), 8.height, + /// TBD Text( 'Gas Request:', style: AppTextStyles.bodyText.copyWith(color: Color(0xFF757575)), @@ -253,7 +225,7 @@ class _RequestGasRefillState extends State { SingleItemDropDownMenu( context: context, title: context.translation.reportStatus, - initialValue: _formModel.status, + initialValue: widget.gasRefillModel.status, onSelect: (value) { _formModel.status=value; }, diff --git a/lib/views/widgets/device_trancfer/device_transfer_item.dart b/lib/views/widgets/device_trancfer/device_transfer_item.dart index 1bda58d1..0972d197 100644 --- a/lib/views/widgets/device_trancfer/device_transfer_item.dart +++ b/lib/views/widgets/device_trancfer/device_transfer_item.dart @@ -41,14 +41,14 @@ class DeviceTransferItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ /// TBD - StatusLabel( - label: '', - id: 0, - textColor: AColors.getPriorityStatusTextColor(0), - backgroundColor: AColors.getPriorityStatusColor(0)), + // StatusLabel( + // label: '', + // id: 0, + // textColor: AColors.getPriorityStatusTextColor(0), + // backgroundColor: AColors.getPriorityStatusColor(0)), 8.width, /// TBD - StatusLabel(label: '', textColor: AColors.getRequestStatusTextColor(0), backgroundColor: AColors.getRequestStatusColor(0)), + //StatusLabel(label: '', textColor: AColors.getRequestStatusTextColor(0), backgroundColor: AColors.getRequestStatusColor(0)), 1.width.expanded, Text(item.createdOn != null ?item.createdOn.toServiceRequestCardFormat:"", textAlign: TextAlign.end, style: AppTextStyles.tinyFont.copyWith(color: const Color(0xFF3B3D4A))), ], From 9c43eab5db04fbb27700efa3405b7025e67d5fbf Mon Sep 17 00:00:00 2001 From: nextwo <1234> Date: Wed, 1 Nov 2023 16:07:55 +0300 Subject: [PATCH 7/8] device transfer --- .../api/asset_transfer_provider.dart | 85 +------- lib/models/device/asset_transfer.dart | 2 + .../device_transfer_details.dart | 28 ++- .../update_device_transfer.dart | 203 +++++++++--------- 4 files changed, 131 insertions(+), 187 deletions(-) diff --git a/lib/controllers/providers/api/asset_transfer_provider.dart b/lib/controllers/providers/api/asset_transfer_provider.dart index bdf388ba..c53cbc91 100644 --- a/lib/controllers/providers/api/asset_transfer_provider.dart +++ b/lib/controllers/providers/api/asset_transfer_provider.dart @@ -150,92 +150,11 @@ class AssetTransferProvider extends ChangeNotifier { } Future updateRequest({ - @required String host, - @required User user, - @required bool isSender, - @required int requestId, - @required AssetTransfer oldModel, - @required AssetTransfer newModel, + @required AssetTransfer assetTransfer, }) async { - Map body = { - "id": oldModel.id, - // "assetId": oldModel.device.id ?? "", - // "senderSiteId": oldModel.sender.client.id, - // "destSiteId": oldModel.receiver.client.id, - // "destDepartmentId": oldModel.receiver.department.id, - }; - - if (isSender) { - body.addAll({ - // "senderSiteId": newModel.client.id, - // "senderDepartmentId": newModel.department.id, - // "senderAssignedEmployeeId": newModel.userId, - // "senderMachineStatusId": newModel.status.id, - // "senderComment": newModel.comment, - // "senderWorkingHours": newModel.workingHours, - // "senderStartDate": newModel.timer?.startAt?.toIso8601String(), - // "senderEndDate": newModel.timer?.endAt?.toIso8601String(), - // "senderTravelingHours": newModel.travelingHours, - // "senderEngSignature": newModel.engSignature, - // if (newModel?.attachments?.isNotEmpty ?? false) - // "senderAttachments": - // newModel?.attachments?.map((file) => {"attachmentName": _isLocalUrl(file.path) ? ("${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}") : file.path})?.toList(), - // "destSiteId": oldModel.receiver.client?.id, - // "destDepartmentId": oldModel.receiver.department?.id, - // "destBuildingId": oldModel.device?.destBuildingId, - // "destFloorId": oldModel.device?.destFloorId, - // "destRoom": oldModel.device?.destRoom, - // "receiverAssignedEmployeeId": oldModel.receiver.userId, - // "receiverMachineStatusId": oldModel.receiver.status.id ?? "", - // "receiverComment": oldModel.receiver.comment, - // "receiverWorkingHours": oldModel.receiver.workingHours, - // "receiverStartDate": oldModel.receiver.timer?.startAt?.toIso8601String(), - // "receiverEndDate": oldModel.receiver.timer?.endAt?.toIso8601String(), - // "receiverTravelingHours": oldModel.receiver?.travelingHours, - // "receiverEngSignature": oldModel.receiver?.engSignature, - // if (oldModel.receiver?.attachments?.isNotEmpty ?? false) - // "receiverAttachments": oldModel.receiver?.attachments - // ?.map((file) => {"attachmentName": _isLocalUrl(file.path) ? ("${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}") : file.path}) - // ?.toList(), - }); - } else { - body.addAll({ - // "senderSiteId": oldModel.sender.client.id, - // "senderDepartmentId": oldModel.sender.department.id, - // "senderAssignedEmployeeId": oldModel.sender.userId, - // "senderMachineStatusId": oldModel.sender.status.id, - // "senderComment": oldModel.sender.comment, - // "senderWorkingHours": oldModel.sender.workingHours, - // "senderStartDate": oldModel.sender.timer?.startAt?.toIso8601String(), - // "senderEndDate": oldModel.sender.timer?.endAt?.toIso8601String(), - // "senderTravelingHours": oldModel.sender?.travelingHours, - // "senderEngSignature": oldModel.sender?.engSignature, - // if (oldModel.sender?.attachments?.isNotEmpty ?? false) - // "senderAttachments": - // oldModel.sender?.attachments?.map((file) => {"attachmentName": _isLocalUrl(file.path) ? ("${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}") : file.path})?.toList(), - // "destSiteId": newModel.client?.id, - // "destDepartmentId": newModel.department?.id, - // "destBuildingId": oldModel.device?.destBuildingId, - // "destFloorId": oldModel.device?.destFloorId, - // "destRoom": oldModel.device?.destRoom, - // "receiverAssignedEmployeeId": newModel.userId, - // "receiverMachineStatusId": newModel.status?.id ?? "", - // "receiverComment": newModel.comment, - // "receiverWorkingHours": newModel.workingHours, - // "receiverStartDate": newModel.timer?.startAt?.toIso8601String(), - // "receiverEndDate": newModel.timer?.endAt?.toIso8601String(), - // "receiverTravelingHours": newModel.travelingHours, - // "receiverEngSignature": newModel.engSignature, - // if (newModel?.attachments?.isNotEmpty ?? false) - // "receiverAttachments": - // newModel?.attachments?.map((file) => {"attachmentName": _isLocalUrl(file.path) ? ("${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}") : file.path})?.toList(), - }); - } - //body.addAll(newModel.toJson(isSender)); - log(body?.toString()); Response response; try { - response = await ApiManager.instance.put(URLs.updateDeviceTransfer, body: body); + response = await ApiManager.instance.put(URLs.updateDeviceTransfer, body: assetTransfer.toJson()); print(response.body); // print("${newModel.engSignature}.png"); diff --git a/lib/models/device/asset_transfer.dart b/lib/models/device/asset_transfer.dart index 46fe292d..790dda43 100644 --- a/lib/models/device/asset_transfer.dart +++ b/lib/models/device/asset_transfer.dart @@ -425,6 +425,8 @@ class AssetTransfer { return map; } + + fromDetails(AssetTransfer assetTransfer){ id= assetTransfer.id; diff --git a/lib/views/pages/device_transfer/device_transfer_details.dart b/lib/views/pages/device_transfer/device_transfer_details.dart index e17e3abf..b378496d 100644 --- a/lib/views/pages/device_transfer/device_transfer_details.dart +++ b/lib/views/pages/device_transfer/device_transfer_details.dart @@ -121,11 +121,11 @@ class _DeviceTransferDetailsState extends State { unit: _model.senderDepartmentName??"", comment: _model.senderComment??"", /// TBD - statusLabel: StatusLabel( - label: _model.senderMachineStatusName??"", + statusLabel: _model.senderMachineStatusName != null? StatusLabel( + label: _model.senderMachineStatusName, id: _model.senderMachineStatusId, - textColor: AColors.getRequestStatusTextColor(_model.senderMachineStatusId), - backgroundColor: AColors.getRequestStatusColor(_model.senderMachineStatusId)), + textColor: AColors.getRequestStatusTextColor(getIdstatus(_model.senderMachineStatusName)), + backgroundColor: AColors.getRequestStatusColor(getIdstatus(_model.senderMachineStatusName))):null, ), // receiver card _buildCard( @@ -135,11 +135,11 @@ class _DeviceTransferDetailsState extends State { unit: _model.destDepartmentName??"", comment: _model.receiverComment??"", /// TBD - statusLabel: StatusLabel( + statusLabel: _model.receiverMachineStatusName != null ? StatusLabel( label: _model.receiverMachineStatusName??"", id: _model.receiverMachineStatusId, - textColor: AColors.getRequestStatusTextColor(_model.receiverMachineStatusId), - backgroundColor: AColors.getRequestStatusColor(_model.receiverMachineStatusId)), + textColor: AColors.getRequestStatusTextColor(getIdstatus(_model.receiverMachineStatusName)), + backgroundColor: AColors.getRequestStatusColor(getIdstatus(_model.receiverMachineStatusName))):null, ), ], ), @@ -239,5 +239,19 @@ class _DeviceTransferDetailsState extends State { ).paddingAll(14), ).paddingOnly(top: 14, start: 14, end: 14); } + + int getIdstatus(String status){ + switch(status){ + case "Closed": + return 3 ; + break; + case "Open": + return 1 ; + break; + case "In Progress": + return 2; + break; + } +} } diff --git a/lib/views/pages/device_transfer/update_device_transfer.dart b/lib/views/pages/device_transfer/update_device_transfer.dart index c8b54328..49ec90d0 100644 --- a/lib/views/pages/device_transfer/update_device_transfer.dart +++ b/lib/views/pages/device_transfer/update_device_transfer.dart @@ -1,5 +1,8 @@ +import 'dart:convert'; + 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'; @@ -57,7 +60,7 @@ class _UpdateDeviceTransferState extends State { // return false; // } _validate = true; - if (!_formKey.currentState.validate()) { + if (!(_formKey.currentState.validate())) { setState(() {}); return false; } @@ -65,17 +68,17 @@ class _UpdateDeviceTransferState extends State { _isLoading = true; setState(() {}); - // int status = await _deviceTransferProvider.updateRequest( - // user: _userProvider.user, host: _settingProvider.host, requestId: widget.model.id, isSender: widget.isSender, newModel: _formModel, oldModel: widget.model); - // _isLoading = false; - // setState(() {}); - // if (status >= 200 && status < 300) { - // Fluttertoast.showToast( - // msg: context.translation.successfulRequestMessage, - // ); - // _validate = false; - // Navigator.of(context).pop(); - // } + int status = await _deviceTransferProvider.updateRequest( + assetTransfer: _formModel); + _isLoading = false; + setState(() {}); + if (status >= 200 && status < 300) { + Fluttertoast.showToast( + msg: context.translation.successfulRequestMessage, + ); + _validate = false; + Navigator.of(context).pop(); + } } // @override @@ -109,93 +112,99 @@ class _UpdateDeviceTransferState extends State { isFailedLoading: false, stateCode: 200, onRefresh: () async {}, - child: Column( - children: [ - SingleChildScrollView( - padding: EdgeInsets.all(12 * AppStyle.getScaleFactor(context)), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _buildCard(), - 8.height, - AppTextFormField( - initialValue: widget.isSender? _formModel.senderTravelingHours:_formModel.receiverTravelingHours, - labelText: context.translation.travelingHours, - onSaved:(value){ - widget.isSender? _formModel.senderTravelingHours - : _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, - AppTextFormField( - labelText: context.translation.workingHours, - initialValue: widget.isSender?_formModel.senderWorkingHours:_formModel.receiverWorkingHours, - onSaved:(value){ - widget.isSender? - _formModel?.senderWorkingHours = value:_formModel?.receiverWorkingHours = value; - // _formModel.timer = timer; - // _formModel.workingHours = (((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0"; - }, - textInputType: TextInputType.number, - validator: (value) => Validator.isNumeric(value) ? null : "allow numbers only", - ), - 8.height, - ///TBD - Consumer(builder: (context, snapshot, _){ - return SingleItemDropDownMenu( - context: context, - title: context.translation.reportStatus, - initialValue: snapshot.items?.firstWhere((element) => element.name == (widget.isSender?_formModel.senderMachineStatusName:_formModel.receiverMachineStatusName), orElse: () => null), - onSelect: (value) { - if(widget.isSender) { - _formModel.senderMachineStatusName=value.name; - _formModel.senderMachineStatusId=value.value; - }else{ - _formModel.receiverMachineStatusName=value.name; - _formModel.receiverMachineStatusId=value.value; - } - setState(() {}); + child: Form( + key: _formKey, + child: Column( + children: [ + SingleChildScrollView( + padding: EdgeInsets.all(12 * AppStyle.getScaleFactor(context)), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildCard(), + 8.height, + AppTextFormField( + initialValue: widget.isSender? _formModel.senderTravelingHours:_formModel.receiverTravelingHours, + labelText: context.translation.travelingHours, + onSaved:(value){ + widget.isSender? _formModel.senderTravelingHours + : _formModel.receiverTravelingHours= value; + //_formModel?.workingHours = double.tryParse(value); + // _formModel.travelingHours = value; }, - ); - }), - 8.height, - AppTextFormField( - initialValue: widget.isSender?_formModel.senderComment:_formModel.receiverComment, - labelText: context.translation.comments, - textInputType: TextInputType.multiline, - alignLabelWithHint: true, - onSaved: (value){ - widget.isSender? - _formModel.senderComment = value:_formModel.receiverComment; - }, - ), - 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; - // _formModel.engSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - // base64Encode(signature); - }, - ), - ], - ), - ).expanded, - Padding( - padding: const EdgeInsets.all(16.0), - child: AppFilledButton( - label: context.translation.update, - onPressed: _update, + textInputType: TextInputType.number, + validator: (value) => Validator.isNumeric(value) ? null : "allow numbers only", + ), + 8.height, + AppTextFormField( + labelText: context.translation.workingHours, + initialValue: widget.isSender?_formModel.senderWorkingHours:_formModel.receiverWorkingHours, + onSaved:(value){ + widget.isSender? + _formModel?.senderWorkingHours = value:_formModel?.receiverWorkingHours = value; + // _formModel.timer = timer; + // _formModel.workingHours = (((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0"; + }, + textInputType: TextInputType.number, + validator: (value) => Validator.isNumeric(value) ? null : "allow numbers only", + ), + 8.height, + ///TBD + Consumer(builder: (context, snapshot, _){ + return SingleItemDropDownMenu( + context: context, + title: context.translation.reportStatus, + initialValue: snapshot.items?.firstWhere((element) => element.name == (widget.isSender?_formModel.senderMachineStatusName:_formModel.receiverMachineStatusName), orElse: () => null), + onSelect: (value) { + if(widget.isSender) { + _formModel.senderMachineStatusName=value.name; + _formModel.senderMachineStatusId=value.id; + print("${value.id}"); + }else{ + _formModel.receiverMachineStatusName=value.name; + _formModel.receiverMachineStatusId=value.id; + } + setState(() {}); + }, + ); + }), + 8.height, + AppTextFormField( + initialValue: widget.isSender?_formModel.senderComment:_formModel.receiverComment, + labelText: context.translation.comments, + textInputType: TextInputType.multiline, + alignLabelWithHint: true, + onSaved: (value){ + widget.isSender? + _formModel.senderComment = value:_formModel.receiverComment=value; + }, + ), + 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)}"; + + base64Encode(signature); + }, + ), + ], + ), + ).expanded, + Padding( + padding: const EdgeInsets.all(16.0), + child: AppFilledButton( + label: context.translation.update, + onPressed: _update, + ), ), - ), - ], + ], + ), ), ), ), From 3c91abf47d38b0b6110ea1d40489bb59b560e80b Mon Sep 17 00:00:00 2001 From: zaid_daoud Date: Thu, 2 Nov 2023 08:38:55 +0300 Subject: [PATCH 8/8] Enhancement on Signature --- .../widgets/e_signature/e_signature.dart | 205 +++++++++--------- 1 file changed, 100 insertions(+), 105 deletions(-) diff --git a/lib/views/widgets/e_signature/e_signature.dart b/lib/views/widgets/e_signature/e_signature.dart index e21a51a0..6aa8ca6a 100644 --- a/lib/views/widgets/e_signature/e_signature.dart +++ b/lib/views/widgets/e_signature/e_signature.dart @@ -6,7 +6,6 @@ import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; -import '../../app_style/sizing.dart'; import '../loaders/image_loader.dart'; class ESignature extends StatefulWidget { @@ -49,115 +48,111 @@ class _ESignatureState extends State { @override Widget build(BuildContext context) { - return Column( - children: [ - if (widget.oldSignature != null || signature != null) + return FormField(onSaved: (_) async { + widget.onSaved(signature); + }, builder: (FormFieldState state) { + return Column( + children: [ Container( width: MediaQuery.of(context).size.width, - padding: const EdgeInsets.only(bottom: 8), - height: 90 * AppStyle.getScaleFactor(context), - child: signature != null ? Image.memory(signature) : ImageLoader(boxFit: BoxFit.contain, url: widget.oldSignature), - ), - FormField(onSaved: (_) async { - widget.onSaved(signature); - }, builder: (FormFieldState state) { - return Column( - children: [ - Container( - width: MediaQuery.of(context).size.width, - padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: _editable ? const BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10)) : BorderRadius.circular(10), - boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, + padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: _editable ? const BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10)) : BorderRadius.circular(10), + boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - widget.title.tinyFont(context).paddingOnly(top: 8), - (!_editable - ? "edit".toSvgAsset(width: 48).paddingOnly(top: 8) - : Container( - width: 48.toScreenWidth, - height: 48.toScreenWidth, - decoration: BoxDecoration(borderRadius: BorderRadius.circular(100), border: Border.all(color: AppColor.neutral30)), - padding: const EdgeInsets.all(11), - margin: const EdgeInsets.only(top: 8), - child: "done".toSvgAsset(width: 26), - )) - .onPress(() async { - if (_editable) { - signature = await _controller.toPngBytes(); - if (widget.onChange != null) { - widget.onChange(signature); - } - } - _editable = !_editable; - setState(() {}); - }), - ], - ), - AbsorbPointer( - absorbing: !_editable, - child: Signature( - controller: _controller, - height: 135.toScreenHeight, - width: MediaQuery.of(context).size.width - 64.toScreenWidth, - backgroundColor: Colors.transparent, - ), - ), + widget.title.tinyFont(context).paddingOnly(top: 8), + (!_editable + ? "edit".toSvgAsset(width: 48).paddingOnly(top: 8) + : Container( + width: 48.toScreenWidth, + height: 48.toScreenWidth, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(100), border: Border.all(color: AppColor.neutral30)), + padding: const EdgeInsets.all(11), + margin: const EdgeInsets.only(top: 8), + child: "done".toSvgAsset(width: 26), + )) + .onPress(() async { + if (_editable) { + signature = await _controller.toPngBytes(); + if (widget.onChange != null) { + widget.onChange(signature); + } + } + _editable = !_editable; + setState(() {}); + }), ], ), + (widget.oldSignature != null || signature != null || !_editable) + ? Container( + height: 135.toScreenHeight, + width: MediaQuery.of(context).size.width, + padding: const EdgeInsets.only(bottom: 8), + child: signature != null ? Image.memory(signature) : ImageLoader(boxFit: BoxFit.contain, url: widget.oldSignature), + ) + : AbsorbPointer( + absorbing: !_editable, + child: Signature( + controller: _controller, + height: 135.toScreenHeight, + width: MediaQuery.of(context).size.width - 64.toScreenWidth, + backgroundColor: Colors.transparent, + ), + ), + ], + ), + ), + if (_editable) + Container( + decoration: const BoxDecoration( + color: AppColor.neutral30, + borderRadius: BorderRadius.only(bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), ), - if (_editable) - Container( - decoration: const BoxDecoration( - color: AppColor.neutral30, - borderRadius: BorderRadius.only(bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10)), - ), - child: Row( - children: [ - "clear".toSvgAsset(width: 14).paddingOnly(start: 16).onPress(() { - _controller.clear(); - }), - 35.width, - "back".toSvgAsset(width: 17).onPress(() { - _controller.undo(); - }), - 27.width, - "redo".toSvgAsset(width: 17).onPress(() { - _controller.redo(); - }), - // IconButton( - // onPressed: () { - // _unpaint = !_unpaint; - // setState(() {}); - // }, - // icon: Icon( - // _unpaint ? Icons.draw : Icons.ac_unit, - // color: _unpaint ? AColors.orange : null, - // )), - // const Spacer(), - // IconButton( - // onPressed: () async { - // signature = await _controller.toPngBytes(); - // if (widget.onChange != null) { - // widget.onChange(signature); - // } - // setState(() {}); - // }, - // icon: const Icon(Icons.check)), - ], - ).paddingOnly(top: 12, bottom: 12), - ) - ], - ); - }), - ], - ); + child: Row( + children: [ + "clear".toSvgAsset(width: 14).paddingOnly(start: 16).onPress(() { + _controller.clear(); + }), + 35.width, + "back".toSvgAsset(width: 17).onPress(() { + _controller.undo(); + }), + 27.width, + "redo".toSvgAsset(width: 17).onPress(() { + _controller.redo(); + }), + // IconButton( + // onPressed: () { + // _unpaint = !_unpaint; + // setState(() {}); + // }, + // icon: Icon( + // _unpaint ? Icons.draw : Icons.ac_unit, + // color: _unpaint ? AColors.orange : null, + // )), + // const Spacer(), + // IconButton( + // onPressed: () async { + // signature = await _controller.toPngBytes(); + // if (widget.onChange != null) { + // widget.onChange(signature); + // } + // setState(() {}); + // }, + // icon: const Icon(Icons.check)), + ], + ).paddingOnly(top: 12, bottom: 12), + ) + ], + ); + }); } }