import 'dart:convert'; import 'dart:io'; import 'package:flutter/cupertino.dart'; 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/dashboard_latest/dashboard_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/enums/user_types.dart'; import 'package:test_sa/models/helper_data_models/workorder/work_order_helper_models.dart'; import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/service_request/pending_service_request_model.dart'; import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import 'package:test_sa/providers/service_request_providers/equipment_status_provider.dart'; import 'package:test_sa/providers/service_request_providers/priority_provider.dart'; import 'package:test_sa/providers/service_request_providers/requested_through_provider.dart'; import 'package:test_sa/providers/service_request_providers/type_of_request_provider.dart'; import 'package:test_sa/cm_module/service_request_detail_provider.dart'; import 'package:test_sa/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/views/pages/user/requests/pending_requests_screen.dart'; import 'package:test_sa/views/widgets/bottom_sheets/pending_request_bottom_sheet.dart'; import 'package:test_sa/views/widgets/equipment/asset_picker.dart'; import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/sound/TextSpeechRecordWidget.dart'; import '../../../../../../new_views/common_widgets/default_app_bar.dart'; class CreateNewRequest extends StatefulWidget { static const String id = "/create-new-request"; const CreateNewRequest({Key? key}) : super(key: key); @override _CreateNewRequestState createState() => _CreateNewRequestState(); } //TODO remove unnecessary code class _CreateNewRequestState extends State with TickerProviderStateMixin { late TextEditingController _commentController; late UserProvider _userProvider; late SettingProvider _settingProvider; late ServiceRequestsProvider _serviceRequestsProvider; late ServiceRequestDetailProvider _requestDetailProvider; late ServiceRequest _serviceRequest; final List _deviceImages = []; final bool _isLoading = false; final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); bool isFirstActionSubmitted = false; String text = ''; DateTime? _dateTime; bool _showDatePicker = false; PendingAssetServiceRequest? pendingAssetServiceRequest; @override void initState() { super.initState(); _commentController = TextEditingController(); _userProvider = Provider.of(context, listen: false); _serviceRequestsProvider = Provider.of(context, listen: false); _requestDetailProvider = Provider.of(context, listen: false); getInitialData(); if (_serviceRequestsProvider.currentSelectedRequest != null) { _serviceRequest = _serviceRequestsProvider.currentSelectedRequest!; _deviceImages.addAll(_serviceRequest.devicePhotos!.map((e) => File(e)).toList()); _showDatePicker = _serviceRequest.firstAction != null && _serviceRequest.firstAction?.name == "Need a visit"; if (_showDatePicker && _serviceRequest.visitDate != null) { _dateTime = DateTime.tryParse(_serviceRequest.visitDate!); } } else { _serviceRequest = ServiceRequest(); } isFirstActionSubmitted = _serviceRequest.firstAction != null; // _isLoading = true; } Future getInitialData() async { WidgetsBinding.instance.addPostFrameCallback((_) async { if(Provider.of(context, listen: false).showPriority) { await Provider.of(context, listen: false).getDate(); } await Provider.of(context, listen: false).getDate(); await Provider.of(context, listen: false).getDate(); await Provider.of(context, listen: false).getDate(); }); } @override void dispose() { // TODO: implement dispose _commentController.dispose(); super.dispose(); } bool _isLocalUrl(String url) { if (url.isEmpty != false) return false; return url.startsWith("/") || url.startsWith("file://") || url.substring(1).startsWith(':\\'); } @override Widget build(BuildContext context) { return Scaffold( key: _scaffoldKey, appBar: DefaultAppBar(title: context.translation.createWorkOrder), body: Consumer(builder: (context, serviceRequestProvider, child) { return SafeArea( child: LoadingManager( isLoading: _isLoading, isFailedLoading: false, stateCode: 200, onRefresh: () async {}, child: Form( key: _formKey, child: Column( children: [ SingleChildScrollView( child: Column( children: [ Card( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ scanAssetButton(), if (pendingAssetServiceRequest != null && pendingAssetServiceRequest!.details!.isNotEmpty) ...[ 8.height, Row( children: [ const Icon(Icons.warning, color: Color(0xffEE404C), size: 14), 8.width, Text( "This asset already have ${pendingAssetServiceRequest!.details!.length} request pending", style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500, color: Color(0xff7D859A), decoration: TextDecoration.underline), ).expanded, ], ).onPress(() { showPendingRequests(); }), ], if (Provider.of(context, listen: false).showPriority) ...[ 16.height, highPriorityWidget(), ], 16.height, assetStatusWidget(context), 24.height, MultiFilesPicker( label: context.translation.attachImage, files: _deviceImages, buttonColor: AppColor.black10, onlyImages: false, buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.neutral120), ), ], ).paddingOnly(start: 13, end: 13, top: 15, bottom: 16), ).paddingAll(16), commentWidget(serviceRequest: _serviceRequest), ], ), ).expanded, FooterActionButton.footerContainer( child: AppFilledButton( // label: context.translation.submitRequest, buttonColor: AppColor.primary10, label: // (pendingAssetServiceRequest != null && (pendingAssetServiceRequest!.details?.isNotEmpty ?? false)) // ? context.translation.duplicateRequest : // @FM said show create work order button text to create request not duplicate request context.translation.createWorkOrder, onPressed: checkPendingRequest ? null : _submit, // buttonColor: AppColor.primary10, ), ), ], ), ), ), ); }), ); } Widget assetStatusWidget(BuildContext context) { return Consumer(builder: (cxt, snapshot, _) { try { _serviceRequest.defectType ??= snapshot.items.first; } catch (ex) { print("snapshot.items:${snapshot.items.length}"); } return Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ context.translation.assetStatus.bodyText(context).custom(color: AppColor.black20), 8.height, Wrap( runSpacing: 8, spacing: 8, children: [ for (var element in snapshot.items) Row( mainAxisSize: MainAxisSize.min, children: [ SizedBox( width: 24, height: 24, child: Radio( value: element, activeColor: AppColor.primary10, fillColor: WidgetStateColor.resolveWith((states) { if (states.contains(WidgetState.selected)) { return AppColor.primary10; // Thumb color when selected } return Colors.grey; // Thumb color when unselected (grey) }), groupValue: _serviceRequest.defectType, onChanged: (state) { setState(() { _serviceRequest.defectType = element; }); }), ), 8.width, Text(element.name ?? '', style: AppTextStyles.tinyFont.copyWith(color: AppColor.neutral120)), ], ) ], ).toShimmer(isShow: snapshot.loading), ], ); }); } Widget scanAssetButton() { return AssetPicker( device: _serviceRequest.device, showLoading: checkPendingRequest, borderColor: AppColor.black20, onPick: (asset) async { pendingAssetServiceRequest = null; _serviceRequest.device = asset; await checkAssetForPendingServiceRequest(asset.id!.toInt()); if (pendingAssetServiceRequest != null && pendingAssetServiceRequest!.details!.isNotEmpty) { showPendingRequestBottomSheet(); } }, ); } Widget highPriorityWidget() { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ context.translation.highPriority.bodyText(context).custom(color: AppColor.black20), Consumer(builder: (cxt, snapshot, _) { if (snapshot.items.isNotEmpty) { _serviceRequest.priority ??= snapshot.items.firstWhere((element) => element.value == 0, orElse: () => Lookup()); } return CupertinoSwitch( thumbColor: _serviceRequest.priority?.value != 0 ? AppColor.red70 : AppColor.neutral10, activeColor: AppColor.red30.withOpacity(0.4), value: _serviceRequest.priority?.value != 0, onChanged: (state) { if (state) { _serviceRequest.priority = snapshot.items.firstWhere((element) => element.value == 1, orElse: null); } else { _serviceRequest.priority = snapshot.items.firstWhere((element) => element.value == 0, orElse: null); } setState(() {}); }).toShimmer(isShow: snapshot.loading); }), ], ); } Widget commentWidget({required ServiceRequest? serviceRequest}) { return TextSpeechRecordWidget( initialMessage: serviceRequest?.callComments ?? '', onMessageChange: (message) { serviceRequest?.callComments = message; }, onRecord: (audio) { serviceRequest?.audio = audio; }, enabled: serviceRequest == null ? true : false, ).paddingOnly(start: 16, end: 16, bottom: 16); } bool checkPendingRequest = false; void showPendingRequests() { Navigator.of(context).push(MaterialPageRoute(builder: (_) => PendingServiceRequestScreen(pendingAssetServiceRequest!))); } void showPendingRequestBottomSheet() async { bool view = (await showModalBottomSheet( context: context, isDismissible: false, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical( top: Radius.circular(20), ), ), clipBehavior: Clip.antiAliasWithSaveLayer, builder: (BuildContext context) => PendingRequestBottomSheet(pendingAssetServiceRequest!, _serviceRequest.device!), )) as bool; if (view) { showPendingRequests(); } } Future checkAssetForPendingServiceRequest(int assetId) async { checkPendingRequest = true; setState(() {}); pendingAssetServiceRequest = await _serviceRequestsProvider.checkAssetPendingRequest(assetId); await Future.delayed(const Duration(milliseconds: 250)); checkPendingRequest = false; setState(() {}); } Future _submit() async { _serviceRequest.requestedThrough = Provider.of(context, listen: false).items.firstWhere((element) => element.value == 3, orElse: null); _serviceRequest.type = Provider.of(context, listen: false).items.firstWhere((element) => element.value == 1, orElse: null); if (_formKey.currentState!.validate() && await _serviceRequest.validateNewRequest(context)) { _formKey.currentState!.save(); // bool canSubmitRequest = await checkAssetForPendingServiceRequest(_serviceRequest.device.id); // if (!canSubmitRequest) { // return; // } // _serviceRequest.devicePhotos = _deviceImages.map((e) => _isLocalUrl(e.path) ? "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}" : e.path).toList(); if (_serviceRequest.audio != null) { if (_isLocalUrl(_serviceRequest.audio!)) { final File file = File(_serviceRequest.audio!); _serviceRequest.audio = "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}"; } } List attachement = []; for (var item in _deviceImages) { attachement.add(WorkOrderAttachments(id: 0, name: "${item.path.split("/").last}|${base64Encode(item.readAsBytesSync())}")); } _requestDetailProvider.workOrderHelperModel = WorkOrderHelperModel( assetId: _serviceRequest.device?.id, priorityId: _serviceRequest.priority?.id, equipmentStatusId: _serviceRequest.defectType?.id, voiceNote: _serviceRequest.audio, workOrderAttachments: attachement, comments: _serviceRequest.callComments, //add attachments also... ); showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); int status = await _requestDetailProvider.createWorkOrder(); if (status == 200) { DashBoardProvider dashBoardProvider = Provider.of(context, listen: false); dashBoardProvider.refreshDashboard(context: context, userType: UsersTypes.nurse); Navigator.pop(context); Navigator.pop(context); } else { Navigator.pop(context); } // await _serviceRequestsProvider.createRequest( // context: context, // user: _userProvider.user!, // host: _settingProvider.host!, // serviceRequest: _serviceRequest, // ); } } }