diff --git a/assets/local/localization_en.json b/assets/local/localization_en.json index 760f992..3fe3957 100644 --- a/assets/local/localization_en.json +++ b/assets/local/localization_en.json @@ -323,5 +323,16 @@ "Shipping_addresses Start ================================================================":"", "shipping_addresses": "ADDRESSES", - "Shipping_addresses End ================================================================":"" + "Shipping_addresses End ================================================================":"", + + "Receiving Start ================================================================":"", + "receiving.title":"Receiving", + "receiving.new":"New Receiving", + "receiving.tracking.id":"Tracking ID", + "receiving.remark":"Remark", + "receiving.fcs.id":"FCS ID", + "receiving.name":"Customer Name", + "receiving.phone":"Phone Number", + "receiving.create_btn":"Complete receiving", + "Receiving End ================================================================":"" } \ No newline at end of file diff --git a/assets/local/localization_mu.json b/assets/local/localization_mu.json index 3188a33..90786b9 100644 --- a/assets/local/localization_mu.json +++ b/assets/local/localization_mu.json @@ -323,5 +323,16 @@ "Shipping_addresses Start ================================================================":"", "shipping_addresses": "လိပ်စာများ", - "Shipping_addresses End ================================================================":"" + "Shipping_addresses End ================================================================":"", + + "Receiving Start ================================================================":"", + "receiving.title":"လက်ခံခြင်းများ", + "receiving.new":"လက်ခံခြင်းအသစ်", + "receiving.tracking.id":"Tracking ID", + "receiving.remark":"မှတ်ချက်", + "receiving.fcs.id":"FCS ID", + "receiving.name":"နာမည်", + "receiving.phone":"ဖုန်းနံပါတ်", + "receiving.create_btn":"လက်ခံမည်", + "Receiving End ================================================================":"" } \ No newline at end of file diff --git a/lib/pages/main/home_page.dart b/lib/pages/main/home_page.dart index 95a807a..e0e1bab 100644 --- a/lib/pages/main/home_page.dart +++ b/lib/pages/main/home_page.dart @@ -19,6 +19,7 @@ import 'package:fcs/pages/main/model/language_model.dart'; import 'package:fcs/pages/main/model/main_model.dart'; import 'package:fcs/pages/package/package_list.dart'; import 'package:fcs/pages/rates/shipment_rates.dart'; +import 'package:fcs/pages/receiving/receiving_list.dart'; import 'package:fcs/pages/shipment/shipment_list.dart'; import 'package:fcs/pages/staff/staff_list.dart'; import 'package:fcs/pages/widgets/task_button.dart'; @@ -203,6 +204,11 @@ class _HomePageState extends State { btnCallback: () => Navigator.of(context).push( CupertinoPageRoute(builder: (context) => PackageList()))); + final receivingBtn = TaskButton("receiving.title", + icon: Octicons.package, + btnCallback: () => Navigator.of(context).push( + CupertinoPageRoute(builder: (context) => ReceivingList()))); + final boxesBtn = TaskButton("boxes.name", icon: MaterialCommunityIcons.package, btnCallback: () => @@ -283,6 +289,7 @@ class _HomePageState extends State { user.hasStaffs() ? widgets.add(staffBtn) : ""; widgets.add(shipmentCostBtn); user.hasPackages() ? widgets.add(packagesBtn) : ""; + user.hasPackages() ? widgets.add(receivingBtn) : ""; true ? widgets.add(boxesBtn) : ""; true ? widgets.add(deliveryBtn) : ""; user.hasCustomers() ? widgets.add(customersBtn) : ""; diff --git a/lib/pages/receiving/receiving_list.dart b/lib/pages/receiving/receiving_list.dart new file mode 100644 index 0000000..402f10f --- /dev/null +++ b/lib/pages/receiving/receiving_list.dart @@ -0,0 +1,116 @@ +import 'package:fcs/domain/entities/package.dart'; +import 'package:fcs/helpers/theme.dart'; +import 'package:fcs/localization/app_translations.dart'; +import 'package:fcs/pages/main/model/main_model.dart'; +import 'package:fcs/pages/package/model/package_model.dart'; +import 'package:fcs/pages/package/package_info.dart'; +import 'package:fcs/pages/package/package_new.dart'; +import 'package:fcs/pages/package_search/package_serach.dart'; +import 'package:fcs/pages/widgets/bottom_up_page_route.dart'; +import 'package:fcs/pages/widgets/local_text.dart'; +import 'package:fcs/pages/widgets/progress.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'receiving_list_row.dart'; +import 'receiving_new.dart'; + +class ReceivingList extends StatefulWidget { + @override + _ReceivingListState createState() => _ReceivingListState(); +} + +class _ReceivingListState extends State { + bool _isLoading = false; + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + var packageModel = Provider.of(context); + bool isCustomer = context.select((MainModel m) => m.isCustomer()); + + return LocalProgress( + inAsyncCall: _isLoading, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + leading: new IconButton( + icon: new Icon(CupertinoIcons.back), + onPressed: () => Navigator.of(context).pop(), + ), + backgroundColor: primaryColor, + title: LocalText( + context, + "receiving.title", + fontSize: 20, + color: Colors.white, + ), + actions: [ + isCustomer + ? Container() + : IconButton( + icon: Icon( + Icons.search, + color: Colors.white, + ), + iconSize: 30, + onPressed: () => searchPackage(context, + callbackPackageSelect: _searchCallback), + ), + ], + ), + floatingActionButton: isCustomer + ? Container() + : FloatingActionButton.extended( + onPressed: () { + _newReceiving(); + }, + icon: Icon(Icons.add), + label: Text( + AppTranslations.of(context).text("receiving.new")), + backgroundColor: primaryColor, + ), + body: new ListView.separated( + separatorBuilder: (context, index) => Divider( + color: Colors.black, + ), + scrollDirection: Axis.vertical, + padding: EdgeInsets.only(top: 15), + shrinkWrap: true, + itemCount: packageModel.packages.length, + itemBuilder: (BuildContext context, int index) { + return ReceivingListRow( + key: ValueKey(packageModel.packages[index].id), + package: packageModel.packages[index], + ); + })), + ); + } + + _newReceiving() { + Navigator.push( + context, + BottomUpPageRoute(ReceivingNew()), + ); + } + + _searchCallback(Package package) async { + var packageModel = Provider.of(context, listen: false); + Package _package = await packageModel.getPackage(package.id); + if (_package == null) return; + Navigator.push( + context, + BottomUpPageRoute(PackageInfo(package: _package)), + ); + } +} diff --git a/lib/pages/receiving/receiving_list_row.dart b/lib/pages/receiving/receiving_list_row.dart new file mode 100644 index 0000000..435622d --- /dev/null +++ b/lib/pages/receiving/receiving_list_row.dart @@ -0,0 +1,88 @@ +import 'package:fcs/domain/entities/package.dart'; +import 'package:fcs/pages/package/package_info.dart'; +import 'package:fcs/pages/main/util.dart'; +import 'package:fcs/pages/widgets/bottom_up_page_route.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +typedef CallbackPackageSelect(Package package); + +class ReceivingListRow extends StatelessWidget { + final Package package; + final CallbackPackageSelect callbackPackageSelect; + final double dotSize = 15.0; + final DateFormat dateFormat = new DateFormat("dd MMM yyyy"); + + ReceivingListRow({Key key, this.package, this.callbackPackageSelect}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.only(left: 15, right: 15), + child: InkWell( + onTap: () { + if (callbackPackageSelect != null) { + callbackPackageSelect(package); + return; + } + Navigator.push( + context, + BottomUpPageRoute(PackageInfo(package: package)), + ); + }, + child: Row( + children: [ + Expanded( + child: new Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: new Row( + children: [ + new Expanded( + child: new Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: new Text( + package.id == null ? '' : package.trackingID, + style: new TextStyle( + fontSize: 15.0, color: Colors.black), + ), + ), + Padding( + padding: const EdgeInsets.only(left: 8.0), + child: new Text( + package.market == null ? '' : package.market, + style: new TextStyle( + fontSize: 15.0, color: Colors.black), + ), + ), + ], + ), + ), + ], + ), + ), + ), + Column( + children: [ + Padding( + padding: const EdgeInsets.all(3.0), + child: getStatus(package.currentStatus), + ), + Padding( + padding: const EdgeInsets.all(0), + child: new Text( + dateFormat.format(package.currentStatusDate), + style: new TextStyle(fontSize: 15.0, color: Colors.grey), + ), + ), + ], + ) + ], + ), + ), + ); + } +} diff --git a/lib/pages/receiving/receiving_new.dart b/lib/pages/receiving/receiving_new.dart new file mode 100644 index 0000000..e583ac1 --- /dev/null +++ b/lib/pages/receiving/receiving_new.dart @@ -0,0 +1,196 @@ +import 'package:barcode_scan/barcode_scan.dart'; +import 'package:fcs/domain/entities/package.dart'; +import 'package:fcs/domain/entities/user.dart'; +import 'package:fcs/helpers/theme.dart'; +import 'package:fcs/pages/user_search/user_serach.dart'; +import 'package:fcs/pages/main/util.dart'; +import 'package:fcs/pages/widgets/display_text.dart'; +import 'package:fcs/pages/widgets/fcs_id_icon.dart'; +import 'package:fcs/pages/widgets/input_text.dart'; +import 'package:fcs/pages/widgets/local_text.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_icons/flutter_icons.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:provider/provider.dart'; + +typedef void FindCallBack(); + +class ReceivingNew extends StatefulWidget { + const ReceivingNew(); + @override + _ReceivingNewState createState() => _ReceivingNewState(); +} + +class _ReceivingNewState extends State { + bool _isLoading = false; + User user; + TextEditingController _transcationIDCtl = new TextEditingController(); + TextEditingController _remarkCtl = new TextEditingController(); + MultiImgController multiImgController = MultiImgController(); + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + var fcsIDBox = Row( + children: [ + Expanded( + child: DisplayText( + text: user != null ? user.fcsID : "", + labelTextKey: "receiving.fcs.id", + icon: FcsIDIcon(), + )), + IconButton( + icon: Icon(Icons.search, color: primaryColor), + onPressed: () => searchUser(context, callbackUserSelect: (u) { + setState(() { + this.user = u; + }); + })), + ], + ); + + final trackingIDBox = Container( + padding: EdgeInsets.only(left: 6), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: InputText( + labelTextKey: "receiving.tracking.id", + controller: _transcationIDCtl, + )), + IconButton( + icon: Icon(MaterialCommunityIcons.barcode_scan, + color: primaryColor), + onPressed: _scan, + ), + ], + )); + + final remarkBox = InputText( + labelTextKey: 'receiving.remark', + iconData: Entypo.new_message, + controller: _remarkCtl); + final img = MultiImageFile( + enabled: true, + controller: multiImgController, + title: "Receipt File", + ); + final namebox = DisplayText( + text: user != null ? user.name : "", + labelTextKey: "receiving.name", + iconData: Icons.person, + ); + final phoneNumberBox = DisplayText( + text: user != null ? user.phoneNumber : "", + labelTextKey: "receiving.phone", + iconData: Icons.phone, + ); + + final createButton = fcsButton( + context, + getLocalString(context, 'receiving.create_btn'), + callack: _create, + ); + + return LocalProgress( + inAsyncCall: _isLoading, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + leading: new IconButton( + icon: new Icon(Icons.close, color: primaryColor, size: 30), + onPressed: () => Navigator.of(context).pop(), + ), + shadowColor: Colors.transparent, + backgroundColor: Colors.white, + title: LocalText( + context, + "receiving.new", + fontSize: 20, + color: primaryColor, + ), + ), + body: Padding( + padding: const EdgeInsets.only(left: 12.0, right: 12), + child: ListView( + children: [ + trackingIDBox, + SizedBox( + height: 10, + ), + img, + remarkBox, + SizedBox( + height: 10, + ), + fcsIDBox, + phoneNumberBox, + namebox, + SizedBox( + height: 20, + ), + createButton, + 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 BarcodeScanner.scan(); + if (barcode != null) { + setState(() { + _transcationIDCtl.text = barcode; + }); + } + } catch (e) { + print('error: $e'); + } + } + + _create() async { + if (user == null) { + showMsgDialog(context, "Error", "Invalid user!"); + return; + } + setState(() { + _isLoading = true; + }); + // PackageModel packageModel = + // Provider.of(context, listen: false); + try { + // await packageModel.createPackages(user, packages); + Navigator.pop(context); + } catch (e) { + showMsgDialog(context, "Error", e.toString()); + } finally { + setState(() { + _isLoading = false; + }); + } + } +}