import 'package:fcs/domain/entities/package.dart'; import 'package:fcs/domain/entities/user.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/package/model/package_model.dart'; import 'package:fcs/pages/user_search/user_search.dart'; import 'package:fcs/pages/widgets/barcode_scanner.dart'; import 'package:fcs/pages/widgets/input_text.dart'; import 'package:fcs/pages/widgets/local_app_bar.dart'; import 'package:fcs/pages/widgets/multi_img_controller.dart'; import 'package:fcs/pages/widgets/multi_img_file.dart'; import 'package:fcs/pages/widgets/progress.dart'; import 'package:flutter/material.dart'; import 'package:flutter_vector_icons/flutter_vector_icons.dart'; import 'package:provider/provider.dart'; class ReceivingEditor extends StatefulWidget { final Package? package; const ReceivingEditor({super.key, this.package}); @override _ReceivingEditorState createState() => _ReceivingEditorState(); } class _ReceivingEditorState extends State { Package package = Package(); bool _isLoading = false; late bool _isNew; User? _consignee; final _receiveFormKey = GlobalKey(); TextEditingController _trackingIDCtl = new TextEditingController(); TextEditingController _remarkCtl = new TextEditingController(); MultiImgController _multiImgController = MultiImgController(); @override void initState() { super.initState(); _isNew = widget.package == null; if (!_isNew) { package = widget.package!; _trackingIDCtl.text = package.trackingID!; _remarkCtl.text = package.remark!; _multiImgController.setImageUrls = package.photoUrls; _consignee = User( fcsID: package.fcsID, name: package.userName, phoneNumber: package.phoneNumber); } else { package = Package(); } _trackingIDCtl.addListener(() { var text = _trackingIDCtl.text; if (text.contains(RegExp(r'[a-z ]'))) { text = text.toUpperCase().replaceAll(" ", ""); _trackingIDCtl.value = _trackingIDCtl.value.copyWith( text: text, selection: TextSelection(baseOffset: text.length, extentOffset: text.length), ); } }); } @override Widget build(BuildContext context) { final trackingIDBox = Container( padding: EdgeInsets.only(left: 6), child: Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ Expanded( child: InputText( iconData: MaterialCommunityIcons.barcode_scan, labelTextKey: "receiving.tracking.id", controller: _trackingIDCtl, autovalidateMode: AutovalidateMode.onUserInteraction, validator: (value) { if (value == null || value.isEmpty) { return "invalid tracking ID"; } return null; }, )), InkWell( onTap: _scan, child: Padding( padding: const EdgeInsets.all(8.0), child: Column( children: [ Icon( MaterialCommunityIcons.barcode_scan, color: primaryColor, ), Text("Scan") ], ), ), ), ], )); final remarkBox = InputText( labelTextKey: 'receiving.remark', iconData: Entypo.new_message, controller: _remarkCtl); final img = MultiImageFile( enabled: true, controller: _multiImgController, title: "Receiving", ); final createButton = fcsButton( context, getLocalString(context, 'receiving.create_btn'), callack: _save, ); final updateButton = fcsButton( context, getLocalString(context, 'receiving.update_btn'), callack: _save, ); final consigneeBox = userSearchBox(context, lableKey: 'box.consignee.title', icon: MaterialCommunityIcons.account_arrow_left, rowMainAxisAlignment: MainAxisAlignment.spaceBetween, user: _consignee, onSearch: () => searchUser(context, onUserSelect: (u) { setState(() { _consignee = u; }); }, popPage: true)); return LocalProgress( inAsyncCall: _isLoading, child: Scaffold( appBar: LocalAppBar( labelKey: _isNew ? "receiving.create" : "receiving.update", backgroundColor: Colors.white, labelColor: primaryColor, arrowColor: primaryColor, onBack: () { if (isDataChanged()) { showConfirmDialog(context, "back.button_confirm", () { Navigator.of(context).pop(); }); } else { Navigator.of(context).pop(); } }, ), body: Padding( padding: const EdgeInsets.only(left: 12.0, right: 12), child: Form( key: _receiveFormKey, child: ListView( children: [ trackingIDBox, SizedBox( height: 10, ), remarkBox, Divider(), img, Divider(), SizedBox( height: 10, ), consigneeBox, SizedBox(height: 20), _isNew ? createButton : updateButton, SizedBox( height: 10, ), ], ), ), ), )); } _scan() async { // PermissionStatus permission = // await PermissionHandler().checkPermissionStatus(PermissionGroup.camera); // if (permission != PermissionStatus.granted) { // Map permissions = // await PermissionHandler() // .requestPermissions([PermissionGroup.camera]); // if (permissions[PermissionGroup.camera] != PermissionStatus.granted) { // showMsgDialog(context, "Error", "Camera permission is not granted"); // return null; // } // } try { String? barcode = await scanBarcode(); if (barcode != null) { setState(() { _trackingIDCtl.text = barcode; }); } } catch (e) { print('error: $e'); } } _save() async { Package _p = Package(trackingID: _trackingIDCtl.text, remark: _remarkCtl.text); // if (_p.trackingID == null || _p.trackingID == "") { // showMsgDialog(context, "Error", "Invalid tracking ID!"); // return; // } if (!_receiveFormKey.currentState!.validate()) { return; } if (_consignee == null) { showMsgDialog(context, "Error", "Please select consignee"); return; } setState(() { _isLoading = true; }); PackageModel packageModel = Provider.of(context, listen: false); try { if (_isNew) { await packageModel.createReceiving( _consignee!, _p, _multiImgController.getAddedFile); } else { _p.id = widget.package!.id; _p.photoUrls = package.photoUrls; await packageModel.updateReceiving( _consignee!, _p, _multiImgController.getAddedFile, _multiImgController.getDeletedUrl); } Navigator.pop(context); } catch (e) { showMsgDialog(context, "Error", e.toString()); } finally { setState(() { _isLoading = false; }); } } isDataChanged() { if (_isNew) { return _trackingIDCtl.text != "" || _remarkCtl.text != "" || _consignee != null || _multiImgController.getAddedFile.isNotEmpty; } else { var package = Package( trackingID: _trackingIDCtl.text, remark: _remarkCtl.text, fcsID: _consignee!.fcsID, photoUrls: widget.package!.photoUrls); return widget.package!.isChangedForEditReceiving(package) || _multiImgController.getAddedFile.isNotEmpty || _multiImgController.getDeletedUrl.isNotEmpty; } } }