import 'dart:convert'; import 'dart:developer'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:provider/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/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/helper/utils.dart'; import 'package:test_sa/models/generic_attachment_model.dart'; import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/new_models/building.dart'; import 'package:test_sa/models/new_models/floor.dart'; import 'package:test_sa/models/new_models/site.dart'; import 'package:test_sa/models/service_request/supp_engineer_work_orders.dart'; import 'package:test_sa/models/service_request/supplier_details.dart'; import 'package:test_sa/modules/cm_module/cm_request_utils.dart'; import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/modules/demo_module/models/demo_attachment_model.dart'; import 'package:test_sa/modules/demo_module/models/demo_request_model.dart'; import 'package:test_sa/modules/demo_module/provider/demo_period_lookup_provider.dart'; import 'package:test_sa/modules/demo_module/provider/demo_provider.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; import 'package:test_sa/providers/gas_request_providers/site_provider.dart'; import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/providers/work_order/vendor_provider.dart'; import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; import '../../../../../../new_views/common_widgets/default_app_bar.dart'; import '../../models/new_models/department.dart'; import 'models/demo_form_model.dart'; class UpdateDemoRequestView extends StatefulWidget { static const String id = "/update-demo-request"; DemoRequestModel dataModel; UpdateDemoRequestView({Key? key, required this.dataModel}) : super(key: key); @override _UpdateDemoRequestViewState createState() => _UpdateDemoRequestViewState(); } class _UpdateDemoRequestViewState extends State with TickerProviderStateMixin { final List attachments = []; final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); DemoFormModel _demoFormModel = DemoFormModel(); late TextEditingController doctorName; late TextEditingController doctorPhone; late TextEditingController doctorEmail; late TextEditingController assetName; late TextEditingController model; late TextEditingController manufacturer; late TextEditingController itemDesc; late TextEditingController requestDesc; late TextEditingController vendorPhone; late TextEditingController vendorEmail; late SiteProvider siteProvider; late DemoProvider demoProvider; bool isLoading = true; @override void initState() { super.initState(); doctorName = TextEditingController(); doctorPhone = TextEditingController(); doctorEmail = TextEditingController(); assetName = TextEditingController(); model = TextEditingController(); manufacturer = TextEditingController(); itemDesc = TextEditingController(); requestDesc = TextEditingController(); vendorPhone = TextEditingController(); vendorEmail = TextEditingController(); siteProvider = Provider.of(context, listen: false); demoProvider = Provider.of(context, listen: false); WidgetsBinding.instance.addPostFrameCallback((_) { fillData(); }); } void fillData() async { final vendorProvider = Provider.of(context, listen: false); if (vendorProvider.items.isEmpty) { if (mounted) { await vendorProvider.getData(); } } final d = widget.dataModel; if (d.site?.id != null) { _demoFormModel.site = await demoProvider.getSiteData( siteId: d.site?.id, ); _demoFormModel.building = _demoFormModel.site?.buildings?.firstWhere( (e) => e.id == d.building?.id, orElse: () => Building(), ); _demoFormModel.floor = _demoFormModel.building?.floors?.firstWhere( (e) => e.id == d.floor?.id, orElse: () => Floor(), ); _demoFormModel.department = _demoFormModel.floor?.departments?.firstWhere( (e) => e.id == d.department?.id, orElse: () => Department(), ); } doctorName.text = d.doctorName ?? ''; doctorPhone.text = d.doctorContactNumber ?? ''; doctorEmail.text = d.doctorContactEmail ?? ''; assetName.text = d.assetName ?? ''; model.text = d.model ?? ''; manufacturer.text = d.manufacturer ?? ''; itemDesc.text = d.itemDescription ?? ''; requestDesc.text = d.requestDescription ?? ''; vendorPhone.text = d.supplier?.contact ?? d.vendorContactNumber ?? ''; vendorEmail.text = d.supplier?.email ?? d.vendorEmail ?? ''; _demoFormModel ..docName = d.doctorName ..docNumber = d.doctorContactNumber ..docEmail = d.doctorContactEmail ..assetName = d.assetName ..model = d.model ..manufacturer = d.manufacturer ..itemDescription = d.itemDescription ..requestDescription = d.requestDescription ..vendor = d.supplier ..vendorName = d.vendorName ..vendorRepresentativeName = d.vendorRepresentativeName ..vendorEmail = d.vendorEmail ..vendorContactNumber = d.vendorContactNumber; _demoFormModel.id = widget.dataModel.id; _demoFormModel.demoPeriod = widget.dataModel.demoPeriod; if (d.supplier != null) { final supplier = d.supplier; _demoFormModel.vendor = supplier; final selectedVendor = vendorProvider.items.firstWhere( (element) => element.id == supplier?.id, orElse: () => SupplierDetails(), ); _demoFormModel.vendor?.suppPersons = selectedVendor.suppPersons; _demoFormModel.supEngineer = widget.dataModel.suppPerson; _demoFormModel.vendorEmail = supplier?.email; _demoFormModel.vendorContactNumber = supplier?.contact; vendorPhone.text = supplier?.email ?? ''; vendorEmail.text = supplier?.contact ?? ''; } attachments.clear(); if (widget.dataModel.demoAttachments?.isNotEmpty ?? false) { for (final item in widget.dataModel.demoAttachments!) { if ((item.attachmentName ?? '').isNotEmpty) { attachments.add( GenericAttachmentModel(name: item.attachmentName, id: item.id ?? 0, originalName: item.originalName), ); } } } setState(() { isLoading = false; }); } @override Widget build(BuildContext context) { return Scaffold( key: _scaffoldKey, appBar: DefaultAppBar(title: 'Update Request'.addTranslation), body: isLoading ? const CircularProgressIndicator(color: AppColor.primary10).center : Form( key: _formKey, child: Column( children: [ SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ ...siteSection(), 16.height, ...doctorInfoSection(), 16.height, ...assetSection(), 16.height, ...vendorDetailsSection(), 16.height, AttachmentPicker( label: context.translation.attachments, attachment: attachments, buttonColor: AppColor.black10, onlyImages: false, showAsListView: true, buttonIcon: 'image-plus'.toSvgAsset(color: context.isDark ? AppColor.primary10 : AppColor.neutral120), ), ], ).toShadowContainer(context, borderRadius: 20), ).expanded, FooterActionButton.footerContainer( context: context, child: AppFilledButton( buttonColor: AppColor.primary10, label: context.translation.update, onPressed: _update, // buttonColor: AppColor.primary10, ), ), ], ), ), ); } List siteSection() { return [ 'Site Details'.addTranslation.bodyText(context).custom(color: AppColor.black10), 8.height, SingleItemDropDownMenu( context: context, title: context.translation.site, initialValue: _demoFormModel.site, showShadow: false, validator: (value) { if (value == null) return "Please select a site"; return null; }, backgroundColor: AppColor.fieldBgColor(context), showAsBottomSheet: true, onSelect: (value) { _demoFormModel.site = value; setState(() {}); }, ), 8.height, SingleItemDropDownMenu( context: context, title: context.translation.building, initialValue: _demoFormModel.building, showShadow: false, showAsBottomSheet: true, validator: (value) { if (value == null) return "Please select a building"; return null; }, backgroundColor: AppColor.fieldBgColor(context), enabled: _demoFormModel.site?.buildings?.isNotEmpty ?? false, staticData: _demoFormModel.site?.buildings ?? [], onSelect: (value) { _demoFormModel.building = value; _demoFormModel.floor = null; _demoFormModel.department = null; setState(() {}); }, ), 8.height, SingleItemDropDownMenu( context: context, title: context.translation.floor, showShadow: false, showAsBottomSheet: true, initialValue: _demoFormModel.floor, backgroundColor: AppColor.fieldBgColor(context), enabled: _demoFormModel.building?.floors?.isNotEmpty ?? false, staticData: _demoFormModel.building?.floors ?? [], validator: (value) { if (value == null) return "Please select a floor"; return null; }, onSelect: (value) { _demoFormModel.floor = value; _demoFormModel.department = null; setState(() {}); }, ), 8.height, SingleItemDropDownMenu( context: context, title: context.translation.department, showShadow: false, showAsBottomSheet: true, initialValue: _demoFormModel.department, backgroundColor: AppColor.fieldBgColor(context), enabled: _demoFormModel.floor?.departments?.isNotEmpty ?? false, validator: (value) { if (value == null) return "Please select a department"; return null; }, staticData: _demoFormModel.floor?.departments ?? [], onSelect: (value) { _demoFormModel.department = value; _demoFormModel.room = null; setState(() {}); }, ), ]; } List doctorInfoSection() { return [ "Doctor Details".bodyText(context).custom(color: AppColor.black10), 8.height, AppTextFormField( controller: doctorName, labelText: "Name", validator: (value) { if ((value ?? "").isEmpty) return "Mandatory"; return null; }, style: Theme.of(context).textTheme.titleMedium, backgroundColor: AppColor.fieldBgColor(context), labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), showShadow: false, textInputType: TextInputType.text, onChange: (value) { _demoFormModel.docName = value; }, ), 8.height, AppTextFormField( controller: doctorPhone, labelText: "Contact Number", validator: (value) { if ((value ?? "").isEmpty) return "Mandatory"; return null; }, style: Theme.of(context).textTheme.titleMedium, backgroundColor: AppColor.fieldBgColor(context), labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), showShadow: false, textInputType: TextInputType.phone, onChange: (value) { _demoFormModel.docNumber = value; }, ), 8.height, AppTextFormField( controller: doctorEmail, labelText: "Email", validator: (value) { if ((value ?? "").isEmpty) { return "Mandatory"; } else { return Validator.isEmail(value!) ? null : context.translation.emailValidateMessage; } }, style: Theme.of(context).textTheme.titleMedium, backgroundColor: AppColor.fieldBgColor(context), labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), showShadow: false, textInputType: TextInputType.emailAddress, onChange: (value) { _demoFormModel.docEmail = value; }, ), 8.height, AppTextFormField( controller: itemDesc, labelText: "Item Description", validator: (value) { if ((value ?? "").isEmpty) return "Mandatory"; return null; }, style: Theme.of(context).textTheme.titleMedium, backgroundColor: AppColor.fieldBgColor(context), labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), floatingLabelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), showShadow: false, textInputType: TextInputType.text, textInputAction: TextInputAction.next, onChange: (value) { _demoFormModel.itemDescription = value; }, ), 8.height, AppTextFormField( controller: requestDesc, labelText: "Request Description", // validator: (value) { // if ((value ?? "").isEmpty) return "Mandatory"; // return null; // }, style: Theme.of(context).textTheme.titleMedium, backgroundColor: AppColor.fieldBgColor(context), labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), floatingLabelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), showShadow: false, textInputType: TextInputType.text, textInputAction: TextInputAction.next, onChange: (value) { _demoFormModel.requestDescription = value; }, ), ]; } List assetSection() { return [ 'Asset Details'.addTranslation.bodyText(context).custom(color: AppColor.black10), 8.height, AppTextFormField( labelText: "Asset Name", controller: assetName, validator: (value) { if ((value ?? "").isEmpty) return "Mandatory"; return null; }, style: Theme.of(context).textTheme.titleMedium, backgroundColor: AppColor.fieldBgColor(context), labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), floatingLabelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), showShadow: false, textInputType: TextInputType.text, textInputAction: TextInputAction.next, onChange: (value) { _demoFormModel.assetName = value; }, ), 8.height, AppTextFormField( labelText: "Model", controller: model, validator: (value) { if ((value ?? "").isEmpty) return "Mandatory"; return null; }, style: Theme.of(context).textTheme.titleMedium, backgroundColor: AppColor.fieldBgColor(context), labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), floatingLabelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), showShadow: false, textInputType: TextInputType.text, textInputAction: TextInputAction.next, onChange: (value) { _demoFormModel.model = value; }, ), 8.height, AppTextFormField( labelText: "Manufacturer", controller: manufacturer, validator: (value) { if ((value ?? "").isEmpty) return "Mandatory"; return null; }, style: Theme.of(context).textTheme.titleMedium, backgroundColor: AppColor.fieldBgColor(context), labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), floatingLabelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), showShadow: false, textInputType: TextInputType.text, textInputAction: TextInputAction.next, onChange: (value) { _demoFormModel.manufacturer = value; }, ), 8.height, SingleItemDropDownMenu( context: context, height: 56.toScreenHeight, title: "Demo Period", initialValue: _demoFormModel.demoPeriod, showShadow: false, validator: (value) { if (value == null) return "Mandatory"; return null; }, backgroundColor: AppColor.fieldBgColor(context), showAsBottomSheet: true, onSelect: (value) { _demoFormModel.demoPeriod = value; setState(() {}); }, ), ]; } List vendorDetailsSection() { return [ 'Vendor Details'.addTranslation.bodyText(context).custom(color: AppColor.black10), //TODO show this only if supplier id and suppler person id is null.. if (_demoFormModel.vendor == null) ...[ 8.height, Text( '${'Vendor Name'.addTranslation}: ${_demoFormModel.vendorName?.cleanupWhitespace.capitalizeFirstOfEach}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), 8.height, Text( '${'Representative Name'.addTranslation}: ${_demoFormModel.vendorRepresentativeName?.cleanupWhitespace.capitalizeFirstOfEach}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), ], 8.height, SingleItemDropDownMenu( context: context, title: 'Vendor Name'.addTranslation, backgroundColor: AppColor.fieldBgColor(context), initialValue: _demoFormModel.vendor, showAsBottomSheet: true, showShadow: false, showCancel: true, onSelect: (person) { _demoFormModel.vendor = person; _demoFormModel.supEngineer = null; vendorPhone.text = person?.contact ?? ''; vendorEmail.text = person?.email ?? ''; setState(() {}); }, ), 8.height, SingleItemDropDownMenu( context: context, backgroundColor: _demoFormModel.vendor?.suppliername == null ? context.isDark ? AppColor.neutral20 : AppColor.neutral40 : AppColor.fieldBgColor(context), title: "Representative Name".addTranslation, showShadow: false, enabled: _demoFormModel.vendor?.suppPersons?.isNotEmpty ?? false, staticData: _demoFormModel.vendor?.suppPersons, showAsBottomSheet: true, initialValue: _demoFormModel.supEngineer == null ? null : SuppPersons.fromJson(_demoFormModel.supEngineer?.toJson()), onSelect: (suppPerson) { if (suppPerson != null) { _demoFormModel.supEngineer = SuppEngineerWorkOrders.fromJson(suppPerson.toJson()); setState(() {}); } }, ), 8.height, AppTextFormField( controller: vendorPhone, enable: false, labelText: "Contact Number", style: Theme.of(context).textTheme.titleMedium, backgroundColor: AppColor.fieldBgColor(context), labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), showShadow: false, textInputType: TextInputType.phone, textInputAction: TextInputAction.next, onChange: (value) { _demoFormModel.vendorContactNumber = value; }, ), 8.height, AppTextFormField( labelText: "Email", controller: vendorEmail, enable: false, style: Theme.of(context).textTheme.titleMedium, backgroundColor: AppColor.fieldBgColor(context), labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), showShadow: false, textInputType: TextInputType.emailAddress, textInputAction: TextInputAction.next, onChange: (value) { _demoFormModel.vendorEmail = value; }, ), ]; } Future _update() async { FocusScope.of(context).unfocus(); if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); _demoFormModel.demoAttachment = []; for (var item in attachments) { String fileName = CMRequestUtils.isLocalUrl(item.name ?? '') ? ("${item.name ?? ''.split("/").last}|${base64Encode(File(item.name ?? '').readAsBytesSync())}") : item.name ?? ''; //Todo need to pass attachmentType id as well. _demoFormModel.demoAttachment?.add(DemoAttachments(id: item.id, demoRequestId: _demoFormModel.id ?? 0, attachmentName: fileName)); } Utils.showLoading(context); DemoProvider demoProvider = Provider.of(context, listen: false); bool isSuccess = await demoProvider.updateDemoRequest(_demoFormModel.toJson()); Utils.hideLoading(context); if (isSuccess) { Navigator.pop(context, true); } } } }