diff --git a/assets/local/localization_en.json b/assets/local/localization_en.json index c218354..c3fa161 100644 --- a/assets/local/localization_en.json +++ b/assets/local/localization_en.json @@ -291,6 +291,7 @@ "box.carton_size.title":"Carton Sizes", "box.carton_size_remove.confirm":"Remove this carton size?", "box.carton_size.name":"Name", + "box.cargo_total_title":"Edit Total Weight", "Boxes End ================================================================":"", "Delivery Start ================================================================":"", diff --git a/assets/local/localization_mu.json b/assets/local/localization_mu.json index fb5080b..91dd517 100644 --- a/assets/local/localization_mu.json +++ b/assets/local/localization_mu.json @@ -291,6 +291,7 @@ "box.carton_size.title":"သေတ္တာ အရွယ်အစားများ", "box.carton_size_remove.confirm":"Remove this carton size?", "box.carton_size.name":"နာမည်", + "box.cargo_total_title":"စုစုပေါင်းအလေးချိန် ပြုပြင်မည်", "Boxes End ================================================================":"", "Delivery Start ================================================================":"", diff --git a/lib/domain/entities/cargo_type.dart b/lib/domain/entities/cargo_type.dart index 7247ce0..6534d71 100644 --- a/lib/domain/entities/cargo_type.dart +++ b/lib/domain/entities/cargo_type.dart @@ -3,6 +3,7 @@ class CargoType { String name; double rate; double weight; + bool isChecked; double get calAmount => (calRate ?? 0) * (calWeight ?? 0); @@ -19,13 +20,15 @@ class CargoType { calRate: map['cal_rate']?.toDouble() ?? 0, ); } - CargoType( - {this.id, - this.name, - this.rate, - this.weight, - this.calWeight, - this.calRate}); + CargoType({ + this.id, + this.name, + this.rate, + this.weight, + this.calWeight, + this.calRate, + this.isChecked = false, + }); Map toMap() { return { diff --git a/lib/domain/entities/package.dart b/lib/domain/entities/package.dart index 70f9af2..e03c814 100644 --- a/lib/domain/entities/package.dart +++ b/lib/domain/entities/package.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:fcs/domain/vo/delivery_address.dart'; import 'package:fcs/domain/vo/shipment_status.dart'; @@ -36,42 +38,47 @@ class Package { DateTime arrivedDate; DeliveryAddress deliveryAddress; + //for packages in processing + List photoFiles; + int get amount => rate != null && weight != null ? rate * weight : 0; String get packageNumber => shipmentNumber + "-" + receiverNumber + " #" + boxNumber; double get price => rate.toDouble() * weight; - Package( - {this.id, - this.trackingID, - this.userID, - this.userName, - this.fcsID, - this.phoneNumber, - this.shipmentNumber, - this.senderFCSID, - this.senderName, - this.receiverFCSID, - this.receiverName, - this.receiverNumber, - this.receiverAddress, - this.boxNumber, - this.rate, - this.weight, - this.packageType, - this.pickUpID, - this.remark, - this.status, - this.arrivedDate, - this.cargoDesc, - this.market, - this.shipmentHistory, - this.currentStatusDate, - this.photoUrls, - this.desc, - this.deliveryAddress, - this.isChecked = false}); + Package({ + this.id, + this.trackingID, + this.userID, + this.userName, + this.fcsID, + this.phoneNumber, + this.shipmentNumber, + this.senderFCSID, + this.senderName, + this.receiverFCSID, + this.receiverName, + this.receiverNumber, + this.receiverAddress, + this.boxNumber, + this.rate, + this.weight, + this.packageType, + this.pickUpID, + this.remark, + this.status, + this.arrivedDate, + this.cargoDesc, + this.market, + this.shipmentHistory, + this.currentStatusDate, + this.photoUrls, + this.desc, + this.deliveryAddress, + this.isChecked = false, + this.photoFiles, + }); factory Package.fromMap(Map map, String docID) { var _currentStatusDate = (map['status_date'] as Timestamp); diff --git a/lib/pages/carton/cargo_type_addtion.dart b/lib/pages/carton/cargo_type_addtion.dart new file mode 100644 index 0000000..64dff27 --- /dev/null +++ b/lib/pages/carton/cargo_type_addtion.dart @@ -0,0 +1,116 @@ +import 'package:fcs/domain/entities/cargo_type.dart'; +import 'package:fcs/helpers/theme.dart'; +import 'package:fcs/pages/main/util.dart'; +import 'package:fcs/pages/rates/model/shipment_rate_model.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'; + +class CargoTypeAddition extends StatefulWidget { + @override + _CargoTypeAdditionState createState() => _CargoTypeAdditionState(); +} + +class _CargoTypeAdditionState extends State { + bool _isLoading = false; + + List cargos = []; + + @override + void initState() { + super.initState(); + cargos = + Provider.of(context, listen: false).rate.cargoTypes; + cargos.forEach((p) => p.isChecked = false); + } + + @override + void dispose() { + super.dispose(); + } + + List showcargoTypeList(BuildContext context) { + return this.cargos.map((c) { + return new ListTile( + contentPadding: EdgeInsets.all(0), + title: InkWell( + onTap: () { + setState(() { + c.isChecked = c.isChecked == null ? true : !c.isChecked; + }); + }, + child: new Row( + children: [ + new Checkbox( + value: c.isChecked == null ? false : c.isChecked, + activeColor: primaryColor, + onChanged: (bool value) { + setState(() { + c.isChecked = value; + }); + }), + new Text( + c.name, + style: TextStyle(fontSize: 15.0, color: primaryColor), + ), + ], + ), + )); + }).toList(); + } + + @override + Widget build(BuildContext context) { + final saveBtn = fcsButton( + context, + getLocalString(context, 'box.cargo.save.btn'), + callack: () { + this.cargos.forEach((p) => p.weight = 0.00); + List _cargos = + this.cargos.where((c) => c.isChecked).toList(); + Navigator.pop(context, _cargos); + }, + ); + return LocalProgress( + inAsyncCall: _isLoading, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + leading: new IconButton( + icon: + new Icon(CupertinoIcons.back, color: primaryColor, size: 30), + onPressed: () => Navigator.of(context).pop(), + ), + shadowColor: Colors.transparent, + backgroundColor: Colors.white, + title: LocalText( + context, + "cargo.form.title", + fontSize: 20, + color: primaryColor, + )), + body: Container( + padding: EdgeInsets.all(18), + child: ListView( + shrinkWrap: true, + children: [ + Column( + children: showcargoTypeList(context), + ), + SizedBox(height: 30), + saveBtn, + SizedBox(height: 20), + ], + ), + ), + ), + ); + } + + // List cargoTypeList() { + // return this.privileges.where((p) => p.isChecked).map((p) => p.id).toList(); + // } + +} diff --git a/lib/pages/carton/cargo_type_editor.dart b/lib/pages/carton/cargo_type_editor.dart index b73f73b..78c4b32 100644 --- a/lib/pages/carton/cargo_type_editor.dart +++ b/lib/pages/carton/cargo_type_editor.dart @@ -31,7 +31,7 @@ class _CargoTypeEditorState extends State { super.initState(); if (widget.cargo != null) { _cargo = widget.cargo; - _weightController.text = _cargo.weight.toString(); + _weightController.text = _cargo.weight.toStringAsFixed(2); } else { _loadDefalut(); } diff --git a/lib/pages/carton/carton_cargo_table.dart b/lib/pages/carton/carton_cargo_table.dart index 3b49332..8778547 100644 --- a/lib/pages/carton/carton_cargo_table.dart +++ b/lib/pages/carton/carton_cargo_table.dart @@ -6,11 +6,12 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'cargo_type_editor.dart'; +import 'total_weight_edit.dart'; typedef OnAdd(CargoType cargoType); typedef OnRemove(CargoType cargoType); -class CargoTable extends StatelessWidget { +class CargoTable extends StatefulWidget { final List cargoTypes; final OnAdd onAdd; final OnRemove onRemove; @@ -18,6 +19,12 @@ class CargoTable extends StatelessWidget { const CargoTable({Key key, this.cargoTypes, this.onAdd, this.onRemove}) : super(key: key); + @override + _CargoTableState createState() => _CargoTableState(); +} + +class _CargoTableState extends State { + double totalWeight = 0; @override Widget build(BuildContext context) { return MyDataTable( @@ -43,12 +50,14 @@ class CargoTable extends StatelessWidget { } List getCargoRows(BuildContext context) { - if (cargoTypes == null) { + if (widget.cargoTypes == null) { return []; } - double total = 0; - var rows = cargoTypes.map((c) { - total += c.weight; + + double _total = 0; + var rows = widget.cargoTypes.map((c) { + _total += c.weight; + return MyDataRow( onSelectChanged: (bool selected) async { CargoType cargo = await Navigator.push( @@ -57,7 +66,7 @@ class CargoTable extends StatelessWidget { builder: (context) => CargoTypeEditor( cargo: c, ))); - if (onAdd != null) onAdd(cargo); + if (widget.onAdd != null) widget.onAdd(cargo); }, cells: [ MyDataCell(new Text( @@ -68,9 +77,8 @@ class CargoTable extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - Text(c.weight == null ? "0" : c.weight.toString(), - style: textStyle), - onRemove == null + Text(c.weight.toStringAsFixed(2), style: textStyle), + widget.onRemove == null ? SizedBox( width: 50, ) @@ -80,7 +88,93 @@ class CargoTable extends StatelessWidget { color: primaryColor, ), onPressed: () { - if (onRemove != null) onRemove(c); + if (widget.onRemove != null) widget.onRemove(c); + }) + ], + ), + ), + ], + ); + }).toList(); + + var totalRow = MyDataRow( + onSelectChanged: (bool selected) async { + double _t = await Navigator.of(context).push(CupertinoPageRoute( + builder: (context) => TotalWeightEdit(totalWeight: totalWeight))); + if (_t == null) return; + setState(() { + totalWeight = _t; + }); + }, + cells: [ + MyDataCell(Align( + alignment: Alignment.centerRight, + child: LocalText( + context, + "shipment.cargo.total", + color: Colors.black87, + fontWeight: FontWeight.bold, + ), + )), + MyDataCell( + Padding( + padding: const EdgeInsets.only(right: 48.0), + child: Align( + alignment: Alignment.centerRight, + child: Text(totalWeight.toStringAsFixed(2), + style: TextStyle(fontWeight: FontWeight.bold))), + ), + ), + ], + ); + rows.add(totalRow); + return rows; + } + + double getRemainBalance(double total) { + double _r = this.totalWeight < total ? 0 : this.totalWeight - total; + return _r; + } + + List _getCargoRows(BuildContext context) { + if (widget.cargoTypes == null) { + return []; + } + double total = 0; + var rows = widget.cargoTypes.map((c) { + total += c.weight; + return MyDataRow( + onSelectChanged: (bool selected) async { + CargoType cargo = await Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => CargoTypeEditor( + cargo: c, + ))); + if (widget.onAdd != null) widget.onAdd(cargo); + }, + cells: [ + MyDataCell(new Text( + c.name == null ? "" : c.name, + style: textStyle, + )), + MyDataCell( + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Text(c.weight == null ? "0" : c.weight.toStringAsFixed(2), + style: textStyle), + widget.onRemove == null + ? SizedBox( + width: 50, + ) + : IconButton( + icon: Icon( + Icons.remove_circle, + color: primaryColor, + ), + onPressed: () { + if (widget.onRemove != null) widget.onRemove(c); }) ], ), @@ -106,7 +200,7 @@ class CargoTable extends StatelessWidget { padding: const EdgeInsets.only(right: 48.0), child: Align( alignment: Alignment.centerRight, - child: Text(total.toString(), + child: Text(total.toStringAsFixed(2), style: TextStyle(fontWeight: FontWeight.bold))), ), ), diff --git a/lib/pages/carton/carton_editor.dart b/lib/pages/carton/carton_editor.dart index 9ec5068..878ad41 100644 --- a/lib/pages/carton/carton_editor.dart +++ b/lib/pages/carton/carton_editor.dart @@ -3,31 +3,21 @@ import 'package:fcs/domain/entities/carton.dart'; import 'package:fcs/domain/entities/cargo_type.dart'; import 'package:fcs/domain/entities/carton_size.dart'; import 'package:fcs/domain/entities/fcs_shipment.dart'; -import 'package:fcs/domain/entities/market.dart'; import 'package:fcs/domain/entities/package.dart'; import 'package:fcs/domain/entities/user.dart'; import 'package:fcs/domain/vo/delivery_address.dart'; import 'package:fcs/helpers/theme.dart'; -import 'package:fcs/localization/app_translations.dart'; import 'package:fcs/pages/carton/carton_cargo_table.dart'; -import 'package:fcs/pages/carton/carton_mix_table.dart'; import 'package:fcs/pages/carton/carton_package_table.dart'; import 'package:fcs/pages/carton_size/carton_size_list.dart'; import 'package:fcs/pages/delivery_address/delivery_address_list.dart'; import 'package:fcs/pages/delivery_address/delivery_address_row.dart'; -import 'package:fcs/pages/delivery_address/model/delivery_address_model.dart'; import 'package:fcs/pages/fcs_shipment/model/fcs_shipment_model.dart'; -import 'package:fcs/pages/main/model/language_model.dart'; -import 'package:fcs/pages/main/model/main_model.dart'; import 'package:fcs/pages/main/util.dart'; -import 'package:fcs/pages/market/model/market_model.dart'; import 'package:fcs/pages/package/model/package_model.dart'; -import 'package:fcs/pages/package/tracking_id_page.dart'; import 'package:fcs/pages/rates/model/shipment_rate_model.dart'; import 'package:fcs/pages/user_search/user_serach.dart'; -import 'package:fcs/pages/widgets/bottom_up_page_route.dart'; import 'package:fcs/pages/widgets/defalut_delivery_address.dart'; -import 'package:fcs/pages/widgets/delivery_address_selection.dart'; import 'package:fcs/pages/widgets/display_text.dart'; import 'package:fcs/pages/widgets/fcs_id_icon.dart'; import 'package:fcs/pages/widgets/length_picker.dart'; @@ -36,19 +26,17 @@ import 'package:fcs/pages/widgets/local_dropdown.dart'; import 'package:fcs/pages/widgets/local_radio_buttons.dart'; import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_title.dart'; -import 'package:fcs/pages/widgets/my_data_table.dart'; import 'package:fcs/pages/widgets/progress.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_icons/flutter_icons.dart'; import 'package:provider/provider.dart'; +import 'cargo_type_addtion.dart'; import 'cargo_type_editor.dart'; import 'model/carton_model.dart'; import '../carton_size/model/carton_size_model.dart'; import 'widgets.dart'; -const MANAGE_CARTONSIZE = "Manage Carton Size"; - class CartonEditor extends StatefulWidget { final Carton box; CartonEditor({this.box}); @@ -102,9 +90,9 @@ class _CartonEditorState extends State { cargoTypes: [], packages: [], ); - _lengthController.text = "12"; - _widthController.text = "12"; - _heightController.text = "12"; + _lengthController.text = ""; + _widthController.text = ""; + _heightController.text = ""; _isNew = true; _selectedCartonType = carton_from_packages; _loadFcsShipments(); @@ -212,53 +200,60 @@ class _CartonEditorState extends State { labelTextKey: "box.mix.carton", iconData: MaterialCommunityIcons.package, ); - var fcsShipmentsBox = LocalDropdown( - callback: (v) { - setState(() { - _fcsShipment = v; - }); - _loadMixCartons(); - }, - labelKey: "shipment.pack.fcs.shipment", - iconData: Ionicons.ios_airplane, - display: (u) => u.shipmentNumber, - selectedValue: _fcsShipment, - values: _fcsShipments, - ); + var fcsShipmentsBox = Container( + padding: EdgeInsets.only(top: 10), + child: LocalDropdown( + callback: (v) { + setState(() { + _fcsShipment = v; + }); + _loadMixCartons(); + }, + labelKey: "shipment.pack.fcs.shipment", + iconData: Ionicons.ios_airplane, + display: (u) => u.shipmentNumber, + selectedValue: _fcsShipment, + values: _fcsShipments, + )); - var mixCartonsBox = LocalDropdown( - callback: (v) { - setState(() { - _mixCarton = v; - }); - }, - labelKey: "box.mix.carton", - iconData: MaterialCommunityIcons.package, - display: (u) => u.cartonNumber, - selectedValue: _mixCarton, - values: _mixCartons, - ); + var mixCartonsBox = Container( + padding: EdgeInsets.only(top: 10), + child: LocalDropdown( + callback: (v) { + setState(() { + _mixCarton = v; + }); + }, + labelKey: "box.mix.carton", + iconData: MaterialCommunityIcons.package, + display: (u) => u.cartonNumber, + selectedValue: _mixCarton, + values: _mixCartons, + )); - final fcsIDBox = Row( - children: [ - Expanded( - child: DisplayText( - text: _user?.fcsID ?? "", - labelTextKey: "box.fcs.id", - icon: FcsIDIcon(), - )), - _isNew - ? IconButton( - icon: Icon(Icons.search, color: primaryColor), - onPressed: () => searchUser(context, callbackUserSelect: (u) { - setState(() { - this._user = u; - _loadPackages(); - }); - })) - : Container(), - ], - ); + final fcsIDBox = Container( + padding: EdgeInsets.only(top: 10), + child: Row( + children: [ + Expanded( + child: DisplayText( + text: _user?.fcsID ?? "", + labelTextKey: "box.fcs.id", + icon: FcsIDIcon(), + )), + _isNew + ? IconButton( + icon: Icon(Icons.search, color: primaryColor), + onPressed: () => + searchUser(context, callbackUserSelect: (u) { + setState(() { + this._user = u; + _loadPackages(); + }); + })) + : Container(), + ], + )); final namebox = DisplayText( text: _user?.name ?? "", @@ -269,14 +264,17 @@ class _CartonEditorState extends State { final lengthBox = LengthPicker( controller: _lengthController, lableKey: "box.length", + isReadOnly: true, ); final widthBox = LengthPicker( controller: _widthController, lableKey: "box.width", + isReadOnly: true, ); final heightBox = LengthPicker( controller: _heightController, lableKey: "box.height", + isReadOnly: true, ); final dimBox = Row( @@ -293,7 +291,7 @@ class _CartonEditorState extends State { ); final shipmentWeightBox = DisplayText( - text: shipmentWeight != null ? shipmentWeight.toStringAsFixed(0) : "", + text: shipmentWeight != null ? shipmentWeight.toStringAsFixed(2) : "", labelTextKey: "box.shipment_weight", iconData: MaterialCommunityIcons.weight, ); @@ -326,9 +324,17 @@ class _CartonEditorState extends State { color: primaryColor, ), onPressed: () async { - CargoType cargo = await Navigator.push(context, - CupertinoPageRoute(builder: (context) => CargoTypeEditor())); - _addCargo(cargo); + // CargoType cargo = await Navigator.push(context, + // CupertinoPageRoute(builder: (context) => CargoTypeEditor())); + // _addCargo(cargo); + List cargos = await Navigator.push>( + context, + CupertinoPageRoute(builder: (context) => CargoTypeAddition())); + if (cargos == null) return; + setState(() { + _carton.cargoTypes.clear(); + _carton.cargoTypes.addAll(cargos); + }); }), ); @@ -414,7 +420,7 @@ class _CartonEditorState extends State { ? Container() : LocalTitle(textKey: "box.dimension"), isSmallBag ? Container() : cartonSizeDropdown(), - // isSmallBag ? Container() : dimBox, + isSmallBag ? Container() : dimBox, isSmallBag ? Container() : shipmentWeightBox, LocalTitle(textKey: "box.delivery_address"), DefaultDeliveryAddress( @@ -445,16 +451,13 @@ class _CartonEditorState extends State { ); } - String selectedCatonSize; + CartonSize selectedCatonSize; Widget cartonSizeDropdown() { List _cartonSizes = - Provider.of(context).cartonSizes; - - List cartonSizes = _cartonSizes.map((e) => e.name).toList(); - cartonSizes.insert(0, MANAGE_CARTONSIZE); + Provider.of(context).getCartonSizes; return Padding( - padding: const EdgeInsets.only(top: 10, bottom: 10), + padding: const EdgeInsets.only(top: 10), child: Row( children: [ Padding( @@ -474,7 +477,7 @@ class _CartonEditorState extends State { fontSize: 16, ), ), - DropdownButton( + DropdownButton( isDense: true, value: selectedCatonSize, style: TextStyle(color: Colors.black, fontSize: 14), @@ -482,25 +485,31 @@ class _CartonEditorState extends State { height: 1, color: Colors.grey, ), - onChanged: (String newValue) { + onChanged: (CartonSize newValue) { setState(() { - if (newValue == MANAGE_CARTONSIZE) { + if (newValue.name == MANAGE_CARTONSIZE) { selectedCatonSize = null; _manageCartonSize(); return; } selectedCatonSize = newValue; + _widthController.text = + selectedCatonSize.width.toString(); + _heightController.text = + selectedCatonSize.height.toString(); + _lengthController.text = + selectedCatonSize.length.toString(); }); }, isExpanded: true, - items: - cartonSizes.map>((String value) { - return DropdownMenuItem( + items: _cartonSizes + .map>((CartonSize value) { + return DropdownMenuItem( value: value, - child: Text(value ?? "", + child: Text(value.name ?? "", overflow: TextOverflow.ellipsis, style: TextStyle( - color: value == MANAGE_CARTONSIZE + color: value.name == MANAGE_CARTONSIZE ? secondaryColor : primaryColor)), ); diff --git a/lib/pages/carton/carton_info.dart b/lib/pages/carton/carton_info.dart index 37daf5c..0cea278 100644 --- a/lib/pages/carton/carton_info.dart +++ b/lib/pages/carton/carton_info.dart @@ -177,7 +177,7 @@ class _CartonInfoState extends State { ); final shipmentWeightBox = DisplayText( - text: shipmentWeight != null ? shipmentWeight.toStringAsFixed(0) : "", + text: shipmentWeight != null ? shipmentWeight.toStringAsFixed(2) : "", labelTextKey: "box.shipment_weight", iconData: MaterialCommunityIcons.weight, ); diff --git a/lib/pages/carton/carton_list_row.dart b/lib/pages/carton/carton_list_row.dart index 54c4a7e..7e5cf27 100644 --- a/lib/pages/carton/carton_list_row.dart +++ b/lib/pages/carton/carton_list_row.dart @@ -78,7 +78,7 @@ class CartonListRow extends StatelessWidget { child: Row( children: [ new Text( - "${box.actualWeight?.toString() ?? ''} lb", + "${box.actualWeight?.toStringAsFixed(2) ?? ''} lb", style: new TextStyle(fontSize: 15.0, color: Colors.grey), ), diff --git a/lib/pages/carton/total_weight_edit.dart b/lib/pages/carton/total_weight_edit.dart new file mode 100644 index 0000000..614e0d5 --- /dev/null +++ b/lib/pages/carton/total_weight_edit.dart @@ -0,0 +1,86 @@ +import 'package:fcs/helpers/theme.dart'; +import 'package:fcs/pages/widgets/input_text.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:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:fcs/pages/main/util.dart'; + +typedef void ProfileCallback(); + +class TotalWeightEdit extends StatefulWidget { + final double totalWeight; + + const TotalWeightEdit({Key key, this.totalWeight}) : super(key: key); + @override + _TotalWeightEditState createState() => _TotalWeightEditState(); +} + +class _TotalWeightEditState extends State { + final TextEditingController totalController = new TextEditingController(); + bool _loading = false; + + @override + void initState() { + super.initState(); + totalController.text = widget.totalWeight.toStringAsFixed(2); + } + + @override + Widget build(BuildContext context) { + final totalInputBox = InputText( + labelTextKey: 'shipment.cargo.total', + iconData: FontAwesomeIcons.weightHanging, + textInputType: TextInputType.number, + controller: totalController); + + final saveBtn = + fcsButton(context, getLocalString(context, "btn.save"), callack: _save); + + return LocalProgress( + inAsyncCall: _loading, + child: Scaffold( + appBar: AppBar( + centerTitle: true, + title: LocalText( + context, + "box.cargo_total_title", + fontSize: 20, + color: primaryColor, + ), + backgroundColor: Colors.white, + shadowColor: Colors.transparent, + leading: IconButton( + icon: Icon( + CupertinoIcons.back, + size: 35, + color: primaryColor, + ), + onPressed: () => Navigator.of(context).pop(), + ), + ), + body: ListView( + padding: EdgeInsets.all(18), + children: [totalInputBox, SizedBox(height: 30), saveBtn], + ), + ), + ); + } + + _save() async { + setState(() { + _loading = true; + }); + try { + double total = double.parse(totalController.text, (s) => 0); + Navigator.pop(context, total); + } catch (e) { + showMsgDialog(context, "Error", e.toString()); + } finally { + setState(() { + _loading = false; + }); + } + } +} diff --git a/lib/pages/carton_size/carton_size_editor.dart b/lib/pages/carton_size/carton_size_editor.dart index 75a7fe9..6c4d51d 100644 --- a/lib/pages/carton_size/carton_size_editor.dart +++ b/lib/pages/carton_size/carton_size_editor.dart @@ -31,12 +31,14 @@ class _CartonSizeEditorState extends State { bool _isLoading = false; CartonSize _cartonSize; + bool _isNew; @override void initState() { super.initState(); if (widget.cartonSize != null) { _cartonSize = widget.cartonSize; + _isNew = false; _nameController.text = _cartonSize.name; _widthController.text = _cartonSize.width.toString(); _heightController.text = _cartonSize.height.toString(); @@ -45,6 +47,7 @@ class _CartonSizeEditorState extends State { _lengthController.text = "12"; _widthController.text = "12"; _heightController.text = "12"; + _isNew = true; } } @@ -104,9 +107,20 @@ class _CartonSizeEditorState extends State { double w = double.parse(_widthController.text, (s) => 0); double h = double.parse(_heightController.text, (s) => 0); - CartonSize _cartonSize = CartonSize( - name: _nameController.text, length: l, width: w, height: h); - await cartonSizeModel.addCartonSize(_cartonSize); + if (_isNew) { + CartonSize _cartonSize = CartonSize( + name: _nameController.text, length: l, width: w, height: h); + await cartonSizeModel.addCartonSize(_cartonSize); + } else { + CartonSize _cartonSize = CartonSize( + id: widget.cartonSize.id, + name: _nameController.text, + length: l, + width: w, + height: h); + await cartonSizeModel.updateCartonSize(_cartonSize); + } + Navigator.pop(context); } catch (e) { showMsgDialog(context, "Error", e.toString()); diff --git a/lib/pages/carton_size/carton_size_list.dart b/lib/pages/carton_size/carton_size_list.dart index 1485a4a..98a2687 100644 --- a/lib/pages/carton_size/carton_size_list.dart +++ b/lib/pages/carton_size/carton_size_list.dart @@ -29,34 +29,38 @@ class _CartonSizeListState extends State { BuildContext context, List cartonSizes) { return cartonSizes.map((p) { return new ListTile( + onTap: () { + Navigator.of(context).push(CupertinoPageRoute( + builder: (context) => CartonSizeEditor(cartonSize: p))); + }, title: new Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - new Text( - p.name, - style: TextStyle(fontSize: 15.0), + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + new Text( + p.name, + style: TextStyle(fontSize: 15.0), + ), + Padding( + padding: const EdgeInsets.only(top: 8.0), + child: new Text( + "(L${p.length}xW${p.width}xH${p.height})", + style: new TextStyle(color: Colors.grey), + ), + ), + SizedBox(height: 15) + ], ), - Padding( - padding: const EdgeInsets.only(top: 8.0), - child: new Text( - "(L${p.length}xW${p.width}xH${p.height})", - style: new TextStyle(color: Colors.grey), - ), - ), - SizedBox(height: 15) - ], - ), - ), - Spacer(), - IconButton( - icon: Icon(Icons.remove, color: primaryColor), - onPressed: () => _remove(p), - ) - ], - )); + ), + Spacer(), + IconButton( + icon: Icon(Icons.remove, color: primaryColor), + onPressed: () => _remove(p), + ) + ], + )); }).toList(); } diff --git a/lib/pages/carton_size/model/carton_size_model.dart b/lib/pages/carton_size/model/carton_size_model.dart index 76038bc..a42d0e3 100644 --- a/lib/pages/carton_size/model/carton_size_model.dart +++ b/lib/pages/carton_size/model/carton_size_model.dart @@ -5,12 +5,19 @@ import 'package:fcs/domain/entities/carton_size.dart'; import 'package:fcs/pages/main/model/base_model.dart'; import 'package:logging/logging.dart'; +const MANAGE_CARTONSIZE = "Manage Carton Size"; + class CartonSizeModel extends BaseModel { List cartonSizes = []; final log = Logger('CartonSizeModel'); StreamSubscription listener; + List get getCartonSizes { + var _cartonSizes = new List.from(cartonSizes); + return _cartonSizes..insert(0, CartonSize(name: MANAGE_CARTONSIZE)); + } + void initUser(user) { super.initUser(user); cartonSizes = [ @@ -32,5 +39,7 @@ class CartonSizeModel extends BaseModel { Future addCartonSize(CartonSize cartonSize) async {} + Future updateCartonSize(CartonSize cartonSize) async {} + Future deleteCartonSize(String id) async {} } diff --git a/lib/pages/processing/model/processing_model.dart b/lib/pages/processing/model/processing_model.dart index fec5b56..e5782c8 100644 --- a/lib/pages/processing/model/processing_model.dart +++ b/lib/pages/processing/model/processing_model.dart @@ -24,14 +24,7 @@ class ProcessingModel extends BaseModel { processings = []; } - Future createProcessing(Processing carton) {} + Future createProcessing(Processing processing) {} - Future updateProcessing(Processing carton) {} - - Future createPackage(Package package, List files) {} - - Future updatePackage( - Package package, List files, List deletedUrls) {} - - Future deletePackage(String id) {} + Future updateProcessing(Processing processing) {} } diff --git a/lib/pages/processing/package_editor.dart b/lib/pages/processing/package_editor.dart index 6197327..e997eca 100644 --- a/lib/pages/processing/package_editor.dart +++ b/lib/pages/processing/package_editor.dart @@ -3,7 +3,6 @@ import 'package:fcs/domain/entities/package.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/pages/market/market_editor.dart'; import 'package:fcs/pages/market/model/market_model.dart'; -import 'package:fcs/pages/package/model/package_model.dart'; import 'package:fcs/pages/package/tracking_id_page.dart'; import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/widgets/barcode_scanner.dart'; @@ -18,8 +17,6 @@ import 'package:flutter_icons/flutter_icons.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; -import 'model/processing_model.dart'; - class PackageEditor extends StatefulWidget { final Package package; PackageEditor({this.package}); @@ -36,7 +33,7 @@ class _PackageEditorState extends State { bool _isLoading = false; bool _isNew; MultiImgController multiImgController = MultiImgController(); - Package _package; + Package _package = Package(); @override void initState() { @@ -45,10 +42,11 @@ class _PackageEditorState extends State { _isNew = false; _package = widget.package; _trackingIDCtl.text = _package.trackingID; - multiImgController.setImageUrls = _package.photoUrls; + selectedMarket = _package.market ?? ""; _descCtl.text = _package.desc; _remarkCtl.text = _package.remark; + multiImgController.setImageFiles = _package.photoFiles; } else { _isNew = true; } @@ -259,26 +257,20 @@ class _PackageEditorState extends State { } _selectPackage() async { - Package package = Package(); - package.id = _package.id; - package.trackingID = _package.trackingID; - package.market = selectedMarket; - package.desc = _descCtl.text; - package.remark = _remarkCtl.text; setState(() { _isLoading = true; }); - ProcessingModel processingModel = - Provider.of(context, listen: false); + try { - if (_isNew) { - await processingModel.createPackage( - package, multiImgController.getAddedFile); - } else { - await processingModel.updatePackage(package, - multiImgController.getAddedFile, multiImgController.getDeletedUrl); - } - Navigator.pop(context, true); + this._package.trackingID = _trackingIDCtl.text; + this._package.market = selectedMarket; + this._package.desc = _descCtl.text; + this._package.remark = _remarkCtl.text; + this._package.photoFiles = _isNew + ? multiImgController.getAddedFile + : multiImgController.getUpdatedFile; + + Navigator.pop(context, this._package); } catch (e) { showMsgDialog(context, "Error", e.toString()); } finally { diff --git a/lib/pages/processing/processing_editor_old.dart b/lib/pages/processing/processing_edit_editor.dart similarity index 96% rename from lib/pages/processing/processing_editor_old.dart rename to lib/pages/processing/processing_edit_editor.dart index e521dc3..839d6a1 100644 --- a/lib/pages/processing/processing_editor_old.dart +++ b/lib/pages/processing/processing_edit_editor.dart @@ -8,7 +8,6 @@ import 'package:fcs/pages/package/model/package_model.dart'; import 'package:fcs/pages/package/tracking_id_page.dart'; import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/user_search/user_serach.dart'; -import 'package:fcs/pages/widgets/bottom_up_page_route.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'; @@ -22,15 +21,15 @@ import 'package:flutter_icons/flutter_icons.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; -class ProcessingEditor extends StatefulWidget { +class ProcessingEditEditor extends StatefulWidget { final Package package; - ProcessingEditor({this.package}); + ProcessingEditEditor({this.package}); @override - _ProcessingEditorState createState() => _ProcessingEditorState(); + _ProcessingEditEditorState createState() => _ProcessingEditEditorState(); } -class _ProcessingEditorState extends State { +class _ProcessingEditEditorState extends State { TextEditingController _remarkCtl = new TextEditingController(); TextEditingController _descCtl = new TextEditingController(); diff --git a/lib/pages/processing/processing_editor.dart b/lib/pages/processing/processing_editor.dart index a8c317c..6021019 100644 --- a/lib/pages/processing/processing_editor.dart +++ b/lib/pages/processing/processing_editor.dart @@ -1,12 +1,8 @@ -import 'dart:io'; - import 'package:fcs/domain/entities/package.dart'; import 'package:fcs/domain/entities/processing.dart'; import 'package:fcs/domain/entities/user.dart'; import 'package:fcs/helpers/theme.dart'; -import 'package:fcs/pages/carton/carton_package_table.dart'; import 'package:fcs/pages/main/util.dart'; -import 'package:fcs/pages/package/model/package_model.dart'; import 'package:fcs/pages/user_search/user_serach.dart'; import 'package:fcs/pages/widgets/display_text.dart'; import 'package:fcs/pages/widgets/fcs_id_icon.dart'; @@ -50,13 +46,6 @@ class _ProcesingEditorState extends State { name: processing.shipperName, phoneNumber: processing.shipperPhoneNumber); packages = processing.packages; - } else { - packages = [ - Package(trackingID: "REC 4", market: "New Market"), - Package(trackingID: "REC 3", market: "Macy"), - Package(trackingID: "REC 2", market: "New Market"), - Package(trackingID: "REC 1", market: "New Market") - ]; } } @@ -157,10 +146,12 @@ class _ProcesingEditorState extends State { color: primaryColor, ), onPressed: () async { - Navigator.push( + Package _package = await Navigator.push( context, CupertinoPageRoute(builder: (context) => PackageEditor()), ); + _addPackage(_package); + // _savePackage(_package); }), ], ), @@ -172,12 +163,6 @@ class _ProcesingEditorState extends State { callack: _save, ); - final updateButton = fcsButton( - context, - getLocalString(context, 'processing.edit.complete.btn'), - callack: _save, - ); - return LocalProgress( inAsyncCall: _isLoading, child: Scaffold( @@ -219,7 +204,7 @@ class _ProcesingEditorState extends State { SizedBox( height: 20, ), - _isNew ? createButton : updateButton, + createButton, SizedBox( height: 10, ), @@ -238,9 +223,14 @@ class _ProcesingEditorState extends State { ), ), child: InkWell( - onTap: () { - Navigator.of(context).push(CupertinoPageRoute( - builder: (context) => PackageEditor(package: p))); + onTap: () async { + Package _package = await Navigator.of(context).push( + CupertinoPageRoute( + builder: (context) => PackageEditor(package: p))); + // setState(() { + // _savePackage(_package); + // }); + _savePackage(_package); }, child: Row( children: [ @@ -276,7 +266,7 @@ class _ProcesingEditorState extends State { ), IconButton( icon: Icon(Icons.remove, color: primaryColor), - onPressed: () => _remove(p), + onPressed: () => _removePackage(p), ) ], ), @@ -289,30 +279,22 @@ class _ProcesingEditorState extends State { }).toList(); } - _remove(Package package) { - if (package == null) { - showMsgDialog(context, "Esrror", "Invalid package!"); - return; - } - showConfirmDialog(context, "processing.package.delete_confirm", - () => _removePackage(package)); + _addPackage(Package package) { + if (package == null) return; + + this.packages.add(package); + setState(() {}); } - _removePackage(Package package) async { - setState(() { - _isLoading = true; - }); - ProcessingModel processingModel = - Provider.of(context, listen: false); - try { - await processingModel.deletePackage(package.id); - } catch (e) { - showMsgDialog(context, "Error", e.toString()); - } finally { - setState(() { - _isLoading = false; - }); - } + _savePackage(Package package) { + if (package == null) return; + setState(() {}); + } + + _removePackage(Package package) { + if (package == null) return; + this.packages.removeWhere((p) => p.trackingID == package.trackingID); + setState(() {}); } _save() async { diff --git a/lib/pages/processing/processing_info.dart b/lib/pages/processing/processing_info.dart index cc3c71a..55aab36 100644 --- a/lib/pages/processing/processing_info.dart +++ b/lib/pages/processing/processing_info.dart @@ -16,7 +16,7 @@ import 'package:flutter_icons/flutter_icons.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; -import 'processing_editor_old.dart'; +import 'processing_edit_editor.dart'; final DateFormat dateFormat = DateFormat("d MMM yyyy"); @@ -179,7 +179,7 @@ class _ProcessingInfoState extends State { bool deleted = await Navigator.push( context, CupertinoPageRoute( - builder: (context) => ProcessingEditor( + builder: (context) => ProcessingEditEditor( package: widget.package, ))); if (deleted ?? false) { diff --git a/lib/pages/rates/discount_by weight_list.dart b/lib/pages/rates/discount_by weight_list.dart index 84ee955..73b7467 100644 --- a/lib/pages/rates/discount_by weight_list.dart +++ b/lib/pages/rates/discount_by weight_list.dart @@ -82,7 +82,8 @@ class _DiscountByWeightListState extends State { discountByWeight: discountByWeight))); }, child: Container( - child: _row("${discountByWeight.weight.toString()} lb", + child: _row( + "${discountByWeight.weight.toStringAsFixed(2)} lb", "\$ " + discountByWeight.discount.toString()), ), ); diff --git a/lib/pages/rates/discount_by_weight_editor.dart b/lib/pages/rates/discount_by_weight_editor.dart index c271183..018c942 100644 --- a/lib/pages/rates/discount_by_weight_editor.dart +++ b/lib/pages/rates/discount_by_weight_editor.dart @@ -31,7 +31,7 @@ class _DiscountByWeightEditorState extends State { super.initState(); if (widget.discountByWeight != null) { _discountByWeight = widget.discountByWeight; - _weightController.text = _discountByWeight.weight.toString(); + _weightController.text = _discountByWeight.weight.toStringAsFixed(2); _discountController.text = _discountByWeight.discount.toString(); _isNew = false; } else { diff --git a/lib/pages/rates/shipment_rates.dart b/lib/pages/rates/shipment_rates.dart index f5f6a8a..aa351a6 100644 --- a/lib/pages/rates/shipment_rates.dart +++ b/lib/pages/rates/shipment_rates.dart @@ -196,8 +196,8 @@ class _ShipmentRatesState extends State { if (discounts == null) return []; return discounts.map((d) { return Container( - child: _row( - "${d.weight.toString()} lb", "\$ " + d.discount.toString(), ''), + child: _row("${d.weight.toStringAsFixed(2)} lb", + "\$ " + d.discount.toString(), ''), ); }).toList(); } diff --git a/lib/pages/rates/shipment_rates_edit.dart b/lib/pages/rates/shipment_rates_edit.dart index 286be1c..6fa144d 100644 --- a/lib/pages/rates/shipment_rates_edit.dart +++ b/lib/pages/rates/shipment_rates_edit.dart @@ -37,7 +37,7 @@ class _ShipmentRatesEditState extends State { Provider.of(context, listen: false); Rate rate = shipmentRateModel.rate; - _minWeight.text = rate.freeDeliveryWeight?.toString() ?? ""; + _minWeight.text = rate.freeDeliveryWeight?.toStringAsFixed(2) ?? ""; _deliveryFee.text = rate.deliveryFee?.toString() ?? ""; _volumetricRatio.text = rate.volumetricRatio?.toString() ?? ""; } diff --git a/lib/pages/shipment/box_row.dart b/lib/pages/shipment/box_row.dart index 3568be2..5b41300 100644 --- a/lib/pages/shipment/box_row.dart +++ b/lib/pages/shipment/box_row.dart @@ -101,7 +101,7 @@ class BoxRow extends StatelessWidget { Padding( padding: const EdgeInsets.only(left: 8.0), child: new Text( - "Actual Weight:${box.actualWeight.toString()}lb", + "Actual Weight:${box.actualWeight.toStringAsFixed(2)}lb", style: new TextStyle(fontSize: 14.0, color: Colors.grey), ), ), diff --git a/lib/pages/shipment/shipment_box_editor.dart b/lib/pages/shipment/shipment_box_editor.dart index 9b974f3..5d0b46d 100644 --- a/lib/pages/shipment/shipment_box_editor.dart +++ b/lib/pages/shipment/shipment_box_editor.dart @@ -232,7 +232,7 @@ class _ShipmentBoxEditorState extends State { Row( mainAxisAlignment: MainAxisAlignment.end, children: [ - Text(c.weight == null ? "0" : c.weight.toString(), + Text(c.weight == null ? "0" : c.weight.toStringAsFixed(2), style: textStyle), IconButton( icon: Icon( @@ -265,7 +265,7 @@ class _ShipmentBoxEditorState extends State { padding: const EdgeInsets.only(right: 48.0), child: Align( alignment: Alignment.centerRight, - child: Text(total.toString(), + child: Text(total.toStringAsFixed(2), style: TextStyle(fontWeight: FontWeight.bold))), ), ), diff --git a/lib/pages/widgets/multi_img_controller.dart b/lib/pages/widgets/multi_img_controller.dart index 1e10c7e..84654da 100644 --- a/lib/pages/widgets/multi_img_controller.dart +++ b/lib/pages/widgets/multi_img_controller.dart @@ -5,6 +5,7 @@ import 'display_image_source.dart'; class MultiImgController { List imageUrls = []; + List imageFiles = []; List addedFiles = []; List removedFiles = []; @@ -29,6 +30,22 @@ class MultiImgController { } } + set setImageFiles(List imageFiles) { + if (imageFiles == null) { + return; + } + + fileContainers.clear(); + + this.imageFiles = imageFiles; + imageFiles.forEach((e) { + fileContainers.add(DisplayImageSource(file: e)); + }); + if (callback != null) { + callback(); + } + } + void onChange(CallBack callBack) { this.callback = callBack; } @@ -51,11 +68,22 @@ class MultiImgController { if (imageUrls.contains(fileContainer.url)) { removedFiles.add(fileContainer); } + + if (imageFiles.contains(fileContainer.file)) { + this.imageFiles.remove(fileContainer.file); + } + if (callback != null) { callback(); } } + List get getUpdatedFile { + List _addfiles = getAddedFile; + this.imageFiles.addAll(_addfiles); + return this.imageFiles; + } + List get getAddedFile { return addedFiles.map((e) => e.file).toList(); }