Merge remote-tracking branch 'tzw/master'
This commit is contained in:
@@ -64,8 +64,9 @@ class Carton {
|
|||||||
// String get packageNumber =>
|
// String get packageNumber =>
|
||||||
// shipmentNumber + "-" + receiverNumber + " #" + boxNumber;
|
// shipmentNumber + "-" + receiverNumber + " #" + boxNumber;
|
||||||
|
|
||||||
double get actualWeight =>
|
double get actualWeight => cargoTypes == null
|
||||||
cargoTypes == null ? 0 : cargoTypes.fold(0, (p, e) => e.weight + p);
|
? 0
|
||||||
|
: cargoTypes.fold(0, (p, e) => e.weight + p);
|
||||||
|
|
||||||
int getShipmentWeight(double volumetricRatio) {
|
int getShipmentWeight(double volumetricRatio) {
|
||||||
if (length == null ||
|
if (length == null ||
|
||||||
@@ -114,8 +115,8 @@ class Carton {
|
|||||||
|
|
||||||
double total = 0;
|
double total = 0;
|
||||||
cargoTypes.forEach((e) {
|
cargoTypes.forEach((e) {
|
||||||
double r =
|
double r = e.rate -
|
||||||
e.rate - (discountByWeight != null ? (discountByWeight.discount) : 0);
|
(discountByWeight != null ? (discountByWeight.discount) : 0);
|
||||||
double amount = e.weight * r;
|
double amount = e.weight * r;
|
||||||
total += amount;
|
total += amount;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ class Rate {
|
|||||||
return discountByWeights.firstWhere((e) => e.weight < weight);
|
return discountByWeights.firstWhere((e) => e.weight < weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
CargoType? get defaultCargoType => cargoTypes == null
|
CargoType get defaultCargoType => cargoTypes.firstWhere((e) => e.name == "General");
|
||||||
? null
|
|
||||||
: cargoTypes.firstWhere((e) => e.name == "General");
|
|
||||||
|
|
||||||
Rate(
|
Rate(
|
||||||
{this.deliveryFee = 0,
|
{this.deliveryFee = 0,
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class _CargoTableState extends State<CargoTable> {
|
|||||||
}
|
}
|
||||||
double total = 0;
|
double total = 0;
|
||||||
var rows = widget.cargoTypes!.map((c) {
|
var rows = widget.cargoTypes!.map((c) {
|
||||||
total += c.weight!;
|
total += c.weight;
|
||||||
return MyDataRow(
|
return MyDataRow(
|
||||||
onSelectChanged: (bool selected) async {},
|
onSelectChanged: (bool selected) async {},
|
||||||
cells: [
|
cells: [
|
||||||
@@ -81,7 +81,7 @@ class _CargoTableState extends State<CargoTable> {
|
|||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
MyDataCell(
|
MyDataCell(
|
||||||
Text(c.weight == null ? "0" : c.weight!.toStringAsFixed(2),
|
Text(c.weight == null ? "0" : c.weight.toStringAsFixed(2),
|
||||||
style: textStyle),
|
style: textStyle),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class _CargoTypeAdditionState extends State<CargoTypeAddition> {
|
|||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
c.isChecked = !c.isChecked!;
|
c.isChecked = !c.isChecked;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
@@ -71,7 +71,7 @@ class _CargoTypeAdditionState extends State<CargoTypeAddition> {
|
|||||||
activeColor: primaryColor,
|
activeColor: primaryColor,
|
||||||
onChanged: (bool? check) {
|
onChanged: (bool? check) {
|
||||||
setState(() {
|
setState(() {
|
||||||
c.isChecked = check;
|
c.isChecked = check ?? false;
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
new Text(c.name ?? '', style: textStyle),
|
new Text(c.name ?? '', style: textStyle),
|
||||||
@@ -88,9 +88,9 @@ class _CargoTypeAdditionState extends State<CargoTypeAddition> {
|
|||||||
getLocalString(context, 'box.cargo.select.btn'),
|
getLocalString(context, 'box.cargo.select.btn'),
|
||||||
callack: () {
|
callack: () {
|
||||||
List<CargoType> _cargos =
|
List<CargoType> _cargos =
|
||||||
this.cargos.where((c) => c.isChecked!).toList();
|
this.cargos.where((c) => c.isChecked).toList();
|
||||||
List<CargoType> _scargos =
|
List<CargoType> _scargos =
|
||||||
this.specialCargos.where((c) => c.isChecked!).toList();
|
this.specialCargos.where((c) => c.isChecked).toList();
|
||||||
_cargos.addAll(_scargos);
|
_cargos.addAll(_scargos);
|
||||||
Navigator.pop(context, _cargos);
|
Navigator.pop(context, _cargos);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class _CargoTypeEditorState extends State<CargoTypeEditor> {
|
|||||||
super.initState();
|
super.initState();
|
||||||
if (widget.cargo != null) {
|
if (widget.cargo != null) {
|
||||||
_cargo = widget.cargo;
|
_cargo = widget.cargo;
|
||||||
_weightController.text = _cargo!.weight!.toStringAsFixed(2);
|
_weightController.text = _cargo!.weight.toStringAsFixed(2);
|
||||||
} else {
|
} else {
|
||||||
_loadDefalut();
|
_loadDefalut();
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ class _CargoTypeEditorState extends State<CargoTypeEditor> {
|
|||||||
_loadDefalut() {
|
_loadDefalut() {
|
||||||
ShipmentRateModel shipmentRateModel =
|
ShipmentRateModel shipmentRateModel =
|
||||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||||
_cargo = shipmentRateModel.rate.defaultCargoType.clone();
|
_cargo = shipmentRateModel.rate.defaultCargoType?.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class _CargoTableState extends State<CargoTable> {
|
|||||||
cargoTypes = widget.cargoTypes;
|
cargoTypes = widget.cargoTypes;
|
||||||
if (!widget.isNew!) {
|
if (!widget.isNew!) {
|
||||||
totalWeight =
|
totalWeight =
|
||||||
cargoTypes!.fold(0, (previous, current) => previous + current.weight!);
|
cargoTypes!.fold(0, (previous, current) => previous + current.weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
super.initState();
|
super.initState();
|
||||||
@@ -86,7 +86,7 @@ class _CargoTableState extends State<CargoTable> {
|
|||||||
cells: [
|
cells: [
|
||||||
MyDataCell(
|
MyDataCell(
|
||||||
new Text(
|
new Text(
|
||||||
c.name ??'',
|
c.name ?? '',
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -144,7 +144,7 @@ class _CargoTableState extends State<CargoTable> {
|
|||||||
context: context,
|
context: context,
|
||||||
builder: (_) => DialogInput(
|
builder: (_) => DialogInput(
|
||||||
label: "cargo.weight",
|
label: "cargo.weight",
|
||||||
value: c.weight!.toStringAsFixed(2)));
|
value: c.weight.toStringAsFixed(2)));
|
||||||
|
|
||||||
if (_t == null) return;
|
if (_t == null) return;
|
||||||
setState(() {
|
setState(() {
|
||||||
@@ -162,7 +162,7 @@ class _CargoTableState extends State<CargoTable> {
|
|||||||
borderRadius: BorderRadius.all(Radius.circular(5.0)),
|
borderRadius: BorderRadius.all(Radius.circular(5.0)),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
c.weight == null ? "0.00" : c.weight!.toStringAsFixed(2),
|
c.weight == null ? "0.00" : c.weight.toStringAsFixed(2),
|
||||||
style: textStyle),
|
style: textStyle),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -252,11 +252,10 @@ class _CargoTableState extends State<CargoTable> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CargoType? autoCalWeight(List<CargoType> cargoTypes, double total) {
|
CargoType? autoCalWeight(List<CargoType> cargoTypes, double total) {
|
||||||
if ((cargoTypes?.length ?? 0) == 0 || total == 0) return null;
|
|
||||||
List<CargoType> noWeight = cargoTypes.where((c) => c.weight == 0).toList();
|
List<CargoType> noWeight = cargoTypes.where((c) => c.weight == 0).toList();
|
||||||
if (noWeight.length != 1) return null;
|
if (noWeight.length != 1) return null;
|
||||||
|
|
||||||
var _existing =
|
double _existing =
|
||||||
cargoTypes.fold(0, (previous, current) => previous + current.weight);
|
cargoTypes.fold(0, (previous, current) => previous + current.weight);
|
||||||
|
|
||||||
noWeight[0].weight = total - _existing;
|
noWeight[0].weight = total - _existing;
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import 'package:fcs/domain/entities/cargo_type.dart';
|
import 'package:fcs/domain/entities/cargo_type.dart';
|
||||||
import 'package:fcs/helpers/theme.dart';
|
import 'package:fcs/helpers/theme.dart';
|
||||||
import 'package:fcs/pages/main/util.dart';
|
|
||||||
import 'package:fcs/pages/widgets/local_text.dart';
|
import 'package:fcs/pages/widgets/local_text.dart';
|
||||||
import 'package:fcs/pages/widgets/my_data_table.dart';
|
import 'package:fcs/pages/widgets/my_data_table.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'cargo_type_editor.dart';
|
|
||||||
import 'total_weight_edit.dart';
|
import 'total_weight_edit.dart';
|
||||||
|
|
||||||
typedef OnAdd(CargoType cargoType);
|
typedef OnAdd(CargoType cargoType);
|
||||||
@@ -68,7 +66,7 @@ class _CargoTableState extends State<CargoTable> {
|
|||||||
double _total = 0;
|
double _total = 0;
|
||||||
|
|
||||||
var rows = widget.cargoTypes!.map((c) {
|
var rows = widget.cargoTypes!.map((c) {
|
||||||
_total += c.weight!;
|
_total += c.weight;
|
||||||
return MyDataRow(
|
return MyDataRow(
|
||||||
onSelectChanged: (bool selected) async {},
|
onSelectChanged: (bool selected) async {},
|
||||||
cells: [
|
cells: [
|
||||||
@@ -88,7 +86,7 @@ class _CargoTableState extends State<CargoTable> {
|
|||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
Text(c.weight!.toStringAsFixed(2), style: textStyle),
|
Text(c.weight.toStringAsFixed(2), style: textStyle),
|
||||||
widget.onRemove == null
|
widget.onRemove == null
|
||||||
? SizedBox(
|
? SizedBox(
|
||||||
width: 50,
|
width: 50,
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class _CartonEditorState extends State<CartonEditor> {
|
|||||||
TextEditingController _widthController = new TextEditingController();
|
TextEditingController _widthController = new TextEditingController();
|
||||||
TextEditingController _heightController = new TextEditingController();
|
TextEditingController _heightController = new TextEditingController();
|
||||||
TextEditingController _lengthController = new TextEditingController();
|
TextEditingController _lengthController = new TextEditingController();
|
||||||
DeliveryAddress _deliveryAddress = new DeliveryAddress();
|
DeliveryAddress? _deliveryAddress = new DeliveryAddress();
|
||||||
List<CargoType> _cargoTypes = [];
|
List<CargoType> _cargoTypes = [];
|
||||||
|
|
||||||
Carton? _carton;
|
Carton? _carton;
|
||||||
@@ -151,12 +151,12 @@ class _CartonEditorState extends State<CartonEditor> {
|
|||||||
PackageModel packageModel =
|
PackageModel packageModel =
|
||||||
Provider.of<PackageModel>(context, listen: false);
|
Provider.of<PackageModel>(context, listen: false);
|
||||||
List<Package> packages = await packageModel.getPackages(
|
List<Package> packages = await packageModel.getPackages(
|
||||||
_user!.id, [package_processed_status, package_packed_status]);
|
_user!.id!, [package_processed_status, package_packed_status]);
|
||||||
if (_isNew) {
|
if (_isNew) {
|
||||||
String? prevCompare;
|
String? prevCompare;
|
||||||
packages.forEach((p) {
|
packages.forEach((p) {
|
||||||
String compare =
|
String compare = (p.deliveryAddress?.fullName ?? "") +
|
||||||
(p.deliveryAddress.fullName) + (p.deliveryAddress.phoneNumber);
|
(p.deliveryAddress?.phoneNumber ?? "");
|
||||||
if (prevCompare != null && compare == prevCompare) {
|
if (prevCompare != null && compare == prevCompare) {
|
||||||
p.isChecked = true;
|
p.isChecked = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -195,9 +195,9 @@ class _CartonEditorState extends State<CartonEditor> {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
_calShipmentWeight() {
|
_calShipmentWeight() {
|
||||||
double l = double.parse(_lengthController.text, (s) => 0);
|
double l = double.parse(_lengthController.text);
|
||||||
double w = double.parse(_widthController.text, (s) => 0);
|
double w = double.parse(_widthController.text);
|
||||||
double h = double.parse(_heightController.text, (s) => 0);
|
double h = double.parse(_heightController.text);
|
||||||
setState(() {
|
setState(() {
|
||||||
shipmentWeight = l * w * h / volumetricRatio;
|
shipmentWeight = l * w * h / volumetricRatio;
|
||||||
});
|
});
|
||||||
@@ -757,7 +757,7 @@ class _CartonEditorState extends State<CartonEditor> {
|
|||||||
.map<DropdownMenuItem<CartonSize>>((CartonSize value) {
|
.map<DropdownMenuItem<CartonSize>>((CartonSize value) {
|
||||||
return DropdownMenuItem<CartonSize>(
|
return DropdownMenuItem<CartonSize>(
|
||||||
value: value,
|
value: value,
|
||||||
child: Text(value.name,
|
child: Text(value.name ?? "",
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: value.name == MANAGE_CARTONSIZE
|
color: value.name == MANAGE_CARTONSIZE
|
||||||
@@ -863,7 +863,7 @@ class _CartonEditorState extends State<CartonEditor> {
|
|||||||
);
|
);
|
||||||
if (_c == null) return;
|
if (_c == null) return;
|
||||||
var cartonModel = Provider.of<CartonModel>(context, listen: false);
|
var cartonModel = Provider.of<CartonModel>(context, listen: false);
|
||||||
Carton _carton = await cartonModel.getCarton(_c.id);
|
Carton _carton = await cartonModel.getCarton(_c.id ?? "");
|
||||||
if (isFromPackages) {
|
if (isFromPackages) {
|
||||||
_cartons.add(_carton);
|
_cartons.add(_carton);
|
||||||
}
|
}
|
||||||
@@ -935,13 +935,13 @@ class _CartonEditorState extends State<CartonEditor> {
|
|||||||
showMsgDialog(context, "Error", "Expect at least one cargo type");
|
showMsgDialog(context, "Error", "Expect at least one cargo type");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_cargoTypes.where((c) => c.weight! <= 0).isNotEmpty) {
|
if (_cargoTypes.where((c) => c.weight <= 0).isNotEmpty) {
|
||||||
showMsgDialog(context, "Error", "Invalid cargo weight");
|
showMsgDialog(context, "Error", "Invalid cargo weight");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
double l = double.parse(_lengthController.text, (s) => 0);
|
double l = double.parse(_lengthController.text);
|
||||||
double w = double.parse(_widthController.text, (s) => 0);
|
double w = double.parse(_widthController.text);
|
||||||
double h = double.parse(_heightController.text, (s) => 0);
|
double h = double.parse(_heightController.text);
|
||||||
if ((l <= 0 || w <= 0 || h <= 0) && (isFromPackages || isFromCartons)) {
|
if ((l <= 0 || w <= 0 || h <= 0) && (isFromPackages || isFromCartons)) {
|
||||||
showMsgDialog(context, "Error", "Invalid dimension");
|
showMsgDialog(context, "Error", "Invalid dimension");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import 'package:fcs/domain/constants.dart';
|
import 'package:fcs/domain/constants.dart';
|
||||||
import 'package:fcs/domain/entities/cargo_type.dart';
|
|
||||||
import 'package:fcs/domain/entities/carton.dart';
|
import 'package:fcs/domain/entities/carton.dart';
|
||||||
import 'package:fcs/domain/entities/carton_size.dart';
|
|
||||||
import 'package:fcs/domain/entities/package.dart';
|
import 'package:fcs/domain/entities/package.dart';
|
||||||
import 'package:fcs/domain/vo/delivery_address.dart';
|
import 'package:fcs/domain/vo/delivery_address.dart';
|
||||||
import 'package:fcs/helpers/theme.dart';
|
import 'package:fcs/helpers/theme.dart';
|
||||||
@@ -43,7 +41,7 @@ class CartonInfo extends StatefulWidget {
|
|||||||
class _CartonInfoState extends State<CartonInfo> {
|
class _CartonInfoState extends State<CartonInfo> {
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
Carton? _box;
|
Carton? _box;
|
||||||
DeliveryAddress _deliveryAddress = new DeliveryAddress();
|
DeliveryAddress? _deliveryAddress = new DeliveryAddress();
|
||||||
TextEditingController _widthController = new TextEditingController();
|
TextEditingController _widthController = new TextEditingController();
|
||||||
TextEditingController _heightController = new TextEditingController();
|
TextEditingController _heightController = new TextEditingController();
|
||||||
TextEditingController _lengthController = new TextEditingController();
|
TextEditingController _lengthController = new TextEditingController();
|
||||||
@@ -80,7 +78,7 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
_widthController.text = _box!.width.toString();
|
_widthController.text = _box!.width.toString();
|
||||||
_heightController.text = _box!.height.toString();
|
_heightController.text = _box!.height.toString();
|
||||||
_lengthController.text = _box!.length.toString();
|
_lengthController.text = _box!.length.toString();
|
||||||
_cartonSizeController.text = _box!.cartonSizeName;
|
_cartonSizeController.text = _box!.cartonSizeName ?? "";
|
||||||
_deliveryAddress = _box!.deliveryAddress;
|
_deliveryAddress = _box!.deliveryAddress;
|
||||||
isMixBox = _box!.cartonType == carton_mix_box;
|
isMixBox = _box!.cartonType == carton_mix_box;
|
||||||
isFromShipments = _box!.cartonType == carton_from_shipments;
|
isFromShipments = _box!.cartonType == carton_from_shipments;
|
||||||
@@ -101,7 +99,7 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
c.width == _box!.width &&
|
c.width == _box!.width &&
|
||||||
c.height == _box!.height) {
|
c.height == _box!.height) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_cartonSizeController.text = c.name;
|
_cartonSizeController.text = c.name ?? "";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -114,7 +112,8 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
return;
|
return;
|
||||||
PackageModel packageModel =
|
PackageModel packageModel =
|
||||||
Provider.of<PackageModel>(context, listen: false);
|
Provider.of<PackageModel>(context, listen: false);
|
||||||
List<Package> packages = await packageModel.getPackages(_box!.userID, [
|
List<Package> packages =
|
||||||
|
await packageModel.getPackages(_box!.userID ?? "", [
|
||||||
package_processed_status,
|
package_processed_status,
|
||||||
package_packed_status,
|
package_packed_status,
|
||||||
package_shipped_status,
|
package_shipped_status,
|
||||||
@@ -145,9 +144,9 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_calShipmentWeight() {
|
_calShipmentWeight() {
|
||||||
double l = double.parse(_lengthController.text, (s) => 0);
|
double l = double.parse(_lengthController.text);
|
||||||
double w = double.parse(_widthController.text, (s) => 0);
|
double w = double.parse(_widthController.text);
|
||||||
double h = double.parse(_heightController.text, (s) => 0);
|
double h = double.parse(_heightController.text);
|
||||||
setState(() {
|
setState(() {
|
||||||
shipmentWeight = l * w * h / volumetricRatio;
|
shipmentWeight = l * w * h / volumetricRatio;
|
||||||
});
|
});
|
||||||
@@ -167,8 +166,9 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
final cartonTypeBox = LocalRadioButtons(
|
final cartonTypeBox = LocalRadioButtons(
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
values: cartonModel.cartonTypesInfo,
|
values: cartonModel.cartonTypesInfo,
|
||||||
selectedValue:
|
selectedValue: (_box!.isShipmentCarton ?? false)
|
||||||
_box!.isShipmentCarton ? carton_from_shipments : _box!.cartonType);
|
? carton_from_shipments
|
||||||
|
: _box!.cartonType);
|
||||||
final shipmentBox = DisplayText(
|
final shipmentBox = DisplayText(
|
||||||
text: _box!.fcsShipmentNumber,
|
text: _box!.fcsShipmentNumber,
|
||||||
labelTextKey: "box.fcs_shipment_num",
|
labelTextKey: "box.fcs_shipment_num",
|
||||||
@@ -416,7 +416,7 @@ class _CartonInfoState extends State<CartonInfo> {
|
|||||||
);
|
);
|
||||||
if (updated ?? false) {
|
if (updated ?? false) {
|
||||||
var cartonModel = Provider.of<CartonModel>(context, listen: false);
|
var cartonModel = Provider.of<CartonModel>(context, listen: false);
|
||||||
var c = await cartonModel.getCarton(widget.box!.id);
|
var c = await cartonModel.getCarton(widget.box!.id ?? "");
|
||||||
setState(() {
|
setState(() {
|
||||||
_box = c;
|
_box = c;
|
||||||
_loadPackages();
|
_loadPackages();
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import 'package:intl/intl.dart';
|
|||||||
import 'carton_info.dart';
|
import 'carton_info.dart';
|
||||||
|
|
||||||
class CartonListRow extends StatelessWidget {
|
class CartonListRow extends StatelessWidget {
|
||||||
final Carton? box;
|
final Carton box;
|
||||||
CartonListRow({Key? key, this.box}) : super(key: key);
|
CartonListRow({Key? key, required this.box}) : super(key: key);
|
||||||
|
|
||||||
final double dotSize = 15.0;
|
final double dotSize = 15.0;
|
||||||
final DateFormat dateFormat = new DateFormat("dd MMM yyyy");
|
final DateFormat dateFormat = new DateFormat("dd MMM yyyy");
|
||||||
@@ -47,7 +47,7 @@ class CartonListRow extends StatelessWidget {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 8.0),
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
child: new Text(
|
child: new Text(
|
||||||
box!.cartonNumber ,
|
box.cartonNumber ?? "",
|
||||||
style: new TextStyle(
|
style: new TextStyle(
|
||||||
fontSize: 15.0, color: Colors.black),
|
fontSize: 15.0, color: Colors.black),
|
||||||
),
|
),
|
||||||
@@ -55,7 +55,7 @@ class CartonListRow extends StatelessWidget {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 10.0, top: 10),
|
padding: const EdgeInsets.only(left: 10.0, top: 10),
|
||||||
child: new Text(
|
child: new Text(
|
||||||
box!.userName,
|
box.userName ?? "",
|
||||||
style: new TextStyle(
|
style: new TextStyle(
|
||||||
fontSize: 15.0, color: Colors.grey),
|
fontSize: 15.0, color: Colors.grey),
|
||||||
),
|
),
|
||||||
@@ -71,14 +71,14 @@ class CartonListRow extends StatelessWidget {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(0),
|
padding: const EdgeInsets.all(0),
|
||||||
child: getStatus(box!.status == null ? "" : box!.status),
|
child: getStatus(box.status ?? ""),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 8.0, top: 5, bottom: 5),
|
padding: const EdgeInsets.only(left: 8.0, top: 5, bottom: 5),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
new Text(
|
new Text(
|
||||||
"${box!.cartonWeight.toStringAsFixed(2)} lb",
|
"${box.cartonWeight?.toStringAsFixed(2)} lb",
|
||||||
style:
|
style:
|
||||||
new TextStyle(fontSize: 15.0, color: Colors.grey),
|
new TextStyle(fontSize: 15.0, color: Colors.grey),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class CartonMixTable extends StatelessWidget {
|
|||||||
? [Container()]
|
? [Container()]
|
||||||
: cartons!.asMap().entries.map((p) {
|
: cartons!.asMap().entries.map((p) {
|
||||||
return Container(
|
return Container(
|
||||||
color: p.value.isChecked
|
color: (p.value.isChecked ?? false)
|
||||||
? Colors.grey.withOpacity(0.2)
|
? Colors.grey.withOpacity(0.2)
|
||||||
: Colors.grey.shade50.withOpacity(0.2),
|
: Colors.grey.shade50.withOpacity(0.2),
|
||||||
child: Container(
|
child: Container(
|
||||||
@@ -60,7 +60,7 @@ class CartonMixTable extends StatelessWidget {
|
|||||||
}),
|
}),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: new Text(
|
child: new Text(
|
||||||
p.value.cartonNumber,
|
p.value.cartonNumber ?? "",
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
)),
|
)),
|
||||||
new Text(
|
new Text(
|
||||||
|
|||||||
@@ -70,15 +70,15 @@ class CartonPackageTable extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
p.value.trackingID,
|
p.value.trackingID ?? "",
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
p.value.deliveryAddress.fullName,
|
p.value.deliveryAddress?.fullName ?? "",
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
p.value.deliveryAddress.phoneNumber,
|
p.value.deliveryAddress?.phoneNumber ?? "",
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -88,7 +88,7 @@ class CartonPackageTable extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
new Text(
|
new Text(
|
||||||
p.value.desc,
|
p.value.desc ?? "",
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
),
|
),
|
||||||
new Text(
|
new Text(
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import 'package:intl/intl.dart';
|
|||||||
typedef OnRemove(Carton carton);
|
typedef OnRemove(Carton carton);
|
||||||
|
|
||||||
class CartonRow extends StatelessWidget {
|
class CartonRow extends StatelessWidget {
|
||||||
final Carton? box;
|
final Carton box;
|
||||||
final OnRemove? onRemove;
|
final OnRemove? onRemove;
|
||||||
CartonRow({Key? key, this.box, this.onRemove}) : super(key: key);
|
CartonRow({Key? key, required this.box, this.onRemove}) : super(key: key);
|
||||||
|
|
||||||
final double dotSize = 15.0;
|
final double dotSize = 15.0;
|
||||||
final DateFormat dateFormat = new DateFormat("dd MMM yyyy");
|
final DateFormat dateFormat = new DateFormat("dd MMM yyyy");
|
||||||
@@ -45,7 +45,7 @@ class CartonRow extends StatelessWidget {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 8.0),
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
child: new Text(
|
child: new Text(
|
||||||
box!.cartonNumber,
|
box.cartonNumber ?? "",
|
||||||
style: new TextStyle(
|
style: new TextStyle(
|
||||||
fontSize: 15.0, color: Colors.black),
|
fontSize: 15.0, color: Colors.black),
|
||||||
),
|
),
|
||||||
@@ -53,7 +53,7 @@ class CartonRow extends StatelessWidget {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 10.0, top: 10),
|
padding: const EdgeInsets.only(left: 10.0, top: 10),
|
||||||
child: new Text(
|
child: new Text(
|
||||||
box!.userName,
|
box.userName ?? "",
|
||||||
style: new TextStyle(
|
style: new TextStyle(
|
||||||
fontSize: 15.0, color: Colors.grey),
|
fontSize: 15.0, color: Colors.grey),
|
||||||
),
|
),
|
||||||
@@ -75,16 +75,16 @@ class CartonRow extends StatelessWidget {
|
|||||||
color: primaryColor,
|
color: primaryColor,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (onRemove != null) onRemove!(box!);
|
if (onRemove != null) onRemove!(box);
|
||||||
}),
|
}),
|
||||||
box!.actualWeight == 0
|
box.actualWeight == 0
|
||||||
? Container()
|
? Container()
|
||||||
: Padding(
|
: Padding(
|
||||||
padding: const EdgeInsets.only(left: 8.0, bottom: 5),
|
padding: const EdgeInsets.only(left: 8.0, bottom: 5),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
new Text(
|
new Text(
|
||||||
"${box!.actualWeight.toStringAsFixed(2)} lb",
|
"${box.actualWeight.toStringAsFixed(2)} lb",
|
||||||
style: new TextStyle(
|
style: new TextStyle(
|
||||||
fontSize: 15.0, color: Colors.grey),
|
fontSize: 15.0, color: Colors.grey),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import 'package:logging/logging.dart';
|
|||||||
|
|
||||||
class CartonModel extends BaseModel {
|
class CartonModel extends BaseModel {
|
||||||
List<Carton> _boxes = [];
|
List<Carton> _boxes = [];
|
||||||
PaginatorListener? cartonsByFilter;
|
late PaginatorListener<Carton> cartonsByFilter;
|
||||||
|
|
||||||
final log = Logger('CartonModel');
|
final log = Logger('CartonModel');
|
||||||
List<Carton> get boxes => _selectedIndex == 1
|
List<Carton> get boxes => _selectedIndex == 1
|
||||||
@@ -24,8 +24,8 @@ class CartonModel extends BaseModel {
|
|||||||
int _selectedIndexFilter = 1;
|
int _selectedIndexFilter = 1;
|
||||||
bool isLoading = false;
|
bool isLoading = false;
|
||||||
|
|
||||||
StreamSubscription<QuerySnapshot> listener;
|
StreamSubscription<QuerySnapshot>? listener;
|
||||||
StreamSubscription<QuerySnapshot> cartonListener;
|
StreamSubscription<QuerySnapshot>? cartonListener;
|
||||||
static List<ShipmentStatus> statusHistory = [
|
static List<ShipmentStatus> statusHistory = [
|
||||||
ShipmentStatus(status: "Packed", date: DateTime(2020, 6, 1), done: true),
|
ShipmentStatus(status: "Packed", date: DateTime(2020, 6, 1), done: true),
|
||||||
ShipmentStatus(status: "Shipped", date: DateTime(2020, 6, 5), done: false),
|
ShipmentStatus(status: "Shipped", date: DateTime(2020, 6, 5), done: false),
|
||||||
@@ -101,7 +101,7 @@ class CartonModel extends BaseModel {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void privilegeChanged() {
|
void privilegeChanged() {
|
||||||
if (user != null || !user.hasCarton()) {
|
if (user != null || !user!.hasCarton()) {
|
||||||
_initData();
|
_initData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,12 +119,12 @@ class CartonModel extends BaseModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadBoxes() async {
|
Future<void> _loadBoxes() async {
|
||||||
if (user == null || !user.hasCarton()) return;
|
if (user == null || !user!.hasCarton()) return;
|
||||||
String path = "/$cartons_collection/";
|
String path = "/$cartons_collection/";
|
||||||
if (listener != null) listener.cancel();
|
if (listener != null) listener!.cancel();
|
||||||
_boxes = [];
|
_boxes = [];
|
||||||
try {
|
try {
|
||||||
listener = Firestore.instance
|
listener = FirebaseFirestore.instance
|
||||||
.collection("$path")
|
.collection("$path")
|
||||||
.where("status",
|
.where("status",
|
||||||
whereIn: [carton_packed_status, carton_shipped_status])
|
whereIn: [carton_packed_status, carton_shipped_status])
|
||||||
@@ -133,9 +133,10 @@ class CartonModel extends BaseModel {
|
|||||||
.snapshots()
|
.snapshots()
|
||||||
.listen((QuerySnapshot snapshot) {
|
.listen((QuerySnapshot snapshot) {
|
||||||
_boxes.clear();
|
_boxes.clear();
|
||||||
_boxes = snapshot.documents.map((documentSnapshot) {
|
_boxes = snapshot.docs.map((documentSnapshot) {
|
||||||
var s = Carton.fromMap(
|
var s = Carton.fromMap(
|
||||||
documentSnapshot.data, documentSnapshot.documentID);
|
documentSnapshot.data() as Map<String, dynamic>,
|
||||||
|
documentSnapshot.id);
|
||||||
return s;
|
return s;
|
||||||
}).toList();
|
}).toList();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@@ -146,18 +147,18 @@ class CartonModel extends BaseModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadCartonsByFilter(String orderName) async {
|
Future<void> _loadCartonsByFilter(String orderName) async {
|
||||||
if (user == null || !user.hasCarton()) return null;
|
if (user == null || !user!.hasCarton()) return null;
|
||||||
String path = "/$cartons_collection";
|
String path = "/$cartons_collection";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Query listenerQuery = Firestore.instance
|
Query listenerQuery = FirebaseFirestore.instance
|
||||||
.collection("$path")
|
.collection("$path")
|
||||||
.where("carton_type", whereIn: [
|
.where("carton_type", whereIn: [
|
||||||
carton_from_packages,
|
carton_from_packages,
|
||||||
carton_from_cartons
|
carton_from_cartons
|
||||||
]).where("status", isEqualTo: carton_packed_status);
|
]).where("status", isEqualTo: carton_packed_status);
|
||||||
|
|
||||||
Query pageQuery = Firestore.instance
|
Query pageQuery = FirebaseFirestore.instance
|
||||||
.collection("$path")
|
.collection("$path")
|
||||||
.where("carton_type",
|
.where("carton_type",
|
||||||
whereIn: [carton_from_packages, carton_from_cartons])
|
whereIn: [carton_from_packages, carton_from_cartons])
|
||||||
@@ -171,10 +172,10 @@ class CartonModel extends BaseModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Paginator _getDelivered() {
|
Paginator? _getDelivered() {
|
||||||
if (user == null || !user.hasCarton()) return null;
|
if (user == null || !user!.hasCarton()) return null;
|
||||||
|
|
||||||
var pageQuery = Firestore.instance
|
var pageQuery = FirebaseFirestore.instance
|
||||||
.collection("/$cartons_collection")
|
.collection("/$cartons_collection")
|
||||||
.where("is_delivered", isEqualTo: true)
|
.where("is_delivered", isEqualTo: true)
|
||||||
.where("is_deleted", isEqualTo: false);
|
.where("is_deleted", isEqualTo: false);
|
||||||
@@ -185,10 +186,10 @@ class CartonModel extends BaseModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> loadMore() async {
|
Future<void> loadMore() async {
|
||||||
if (_delivered.ended || selectedIndex == 1) return;
|
if (_delivered == null && _delivered!.ended || selectedIndex == 1) return;
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
await _delivered.load(onFinished: () {
|
await _delivered!.load(onFinished: () {
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
});
|
});
|
||||||
@@ -196,7 +197,7 @@ class CartonModel extends BaseModel {
|
|||||||
|
|
||||||
Future<void> refresh() async {
|
Future<void> refresh() async {
|
||||||
if (selectedIndex == 1) return;
|
if (selectedIndex == 1) return;
|
||||||
await _delivered.refresh(onFinished: () {
|
await _delivered?.refresh(onFinished: () {
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -207,69 +208,62 @@ class CartonModel extends BaseModel {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
logout() async {
|
logout() async {
|
||||||
if (listener != null) await listener.cancel();
|
if (listener != null) await listener!.cancel();
|
||||||
if (cartonListener != null) await cartonListener.cancel();
|
if (cartonListener != null) await cartonListener!.cancel();
|
||||||
if (_delivered != null) _delivered.close();
|
if (_delivered != null) _delivered!.close();
|
||||||
if (cartonsByFilter != null) cartonsByFilter.close();
|
if (cartonsByFilter != null) cartonsByFilter.close();
|
||||||
_boxes = [];
|
_boxes = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Carton>> getCartons(String shipmentID) async {
|
Future<List<Carton>> getCartons(String shipmentID) async {
|
||||||
String path = "/$cartons_collection";
|
String path = "/$cartons_collection";
|
||||||
var querySnap = await Firestore.instance
|
var querySnap = await FirebaseFirestore.instance
|
||||||
.collection(path)
|
.collection(path)
|
||||||
.where("shipment_id", isEqualTo: shipmentID)
|
.where("shipment_id", isEqualTo: shipmentID)
|
||||||
.getDocuments();
|
.get();
|
||||||
return querySnap.documents
|
return querySnap.docs.map((e) => Carton.fromMap(e.data(), e.id)).toList();
|
||||||
.map((e) => Carton.fromMap(e.data, e.documentID))
|
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Carton>> getCartonsByFcsShipment(String fcsShipmentID) async {
|
Future<List<Carton>> getCartonsByFcsShipment(String fcsShipmentID) async {
|
||||||
String path = "/$cartons_collection";
|
String path = "/$cartons_collection";
|
||||||
var querySnap = await Firestore.instance
|
var querySnap = await FirebaseFirestore.instance
|
||||||
.collection(path)
|
.collection(path)
|
||||||
.where("fcs_shipment_id", isEqualTo: fcsShipmentID)
|
.where("fcs_shipment_id", isEqualTo: fcsShipmentID)
|
||||||
.where("is_deleted", isEqualTo: false)
|
.where("is_deleted", isEqualTo: false)
|
||||||
.getDocuments();
|
.get();
|
||||||
return querySnap.documents
|
return querySnap.docs.map((e) => Carton.fromMap(e.data(), e.id)).toList();
|
||||||
.map((e) => Carton.fromMap(e.data, e.documentID))
|
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Carton>> getCartonsForInvoice(
|
Future<List<Carton>> getCartonsForInvoice(
|
||||||
String fcsShipmentID, String userID) async {
|
String fcsShipmentID, String userID) async {
|
||||||
String path = "/$cartons_collection";
|
String path = "/$cartons_collection";
|
||||||
var querySnap = await Firestore.instance
|
var querySnap = await FirebaseFirestore.instance
|
||||||
.collection(path)
|
.collection(path)
|
||||||
.where("fcs_shipment_id", isEqualTo: fcsShipmentID)
|
.where("fcs_shipment_id", isEqualTo: fcsShipmentID)
|
||||||
.where("user_id", isEqualTo: userID)
|
.where("user_id", isEqualTo: userID)
|
||||||
.where("is_deleted", isEqualTo: false)
|
.where("is_deleted", isEqualTo: false)
|
||||||
.where("is_invoiced", isEqualTo: false)
|
.where("is_invoiced", isEqualTo: false)
|
||||||
.getDocuments();
|
.get();
|
||||||
List<Carton> cartons = querySnap.documents
|
List<Carton> cartons =
|
||||||
.map((e) => Carton.fromMap(e.data, e.documentID))
|
querySnap.docs.map((e) => Carton.fromMap(e.data(), e.id)).toList();
|
||||||
.toList();
|
|
||||||
return cartons;
|
return cartons;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Carton>> getMixCartonsByFcsShipment(String fcsShipmentID) async {
|
Future<List<Carton>> getMixCartonsByFcsShipment(String fcsShipmentID) async {
|
||||||
String path = "/$cartons_collection";
|
String path = "/$cartons_collection";
|
||||||
var querySnap = await Firestore.instance
|
var querySnap = await FirebaseFirestore.instance
|
||||||
.collection(path)
|
.collection(path)
|
||||||
.where("fcs_shipment_id", isEqualTo: fcsShipmentID)
|
.where("fcs_shipment_id", isEqualTo: fcsShipmentID)
|
||||||
.where("carton_type", isEqualTo: carton_mix_box)
|
.where("carton_type", isEqualTo: carton_mix_box)
|
||||||
.where("is_deleted", isEqualTo: false)
|
.where("is_deleted", isEqualTo: false)
|
||||||
.getDocuments();
|
.get();
|
||||||
return querySnap.documents
|
return querySnap.docs.map((e) => Carton.fromMap(e.data(), e.id)).toList();
|
||||||
.map((e) => Carton.fromMap(e.data, e.documentID))
|
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Carton> getCarton(String id) async {
|
Future<Carton> getCarton(String id) async {
|
||||||
String path = "/$cartons_collection";
|
String path = "/$cartons_collection";
|
||||||
var snap = await Firestore.instance.collection(path).document(id).get();
|
var snap = await FirebaseFirestore.instance.collection(path).doc(id).get();
|
||||||
return Carton.fromMap(snap.data, snap.documentID);
|
return Carton.fromMap(snap.data() as Map<String, dynamic>, snap.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Carton> createCarton(Carton carton) {
|
Future<Carton> createCarton(Carton carton) {
|
||||||
|
|||||||
@@ -8,12 +8,9 @@ import 'package:fcs/domain/vo/delivery_address.dart';
|
|||||||
import 'package:fcs/helpers/theme.dart';
|
import 'package:fcs/helpers/theme.dart';
|
||||||
import 'package:fcs/pages/carton_size/carton_size_list.dart';
|
import 'package:fcs/pages/carton_size/carton_size_list.dart';
|
||||||
import 'package:fcs/pages/carton_size/model/carton_size_model.dart';
|
import 'package:fcs/pages/carton_size/model/carton_size_model.dart';
|
||||||
import 'package:fcs/pages/delivery_address/model/delivery_address_model.dart';
|
|
||||||
import 'package:fcs/pages/main/util.dart';
|
import 'package:fcs/pages/main/util.dart';
|
||||||
import 'package:fcs/pages/rates/model/shipment_rate_model.dart';
|
|
||||||
import 'package:fcs/pages/widgets/defalut_delivery_address.dart';
|
import 'package:fcs/pages/widgets/defalut_delivery_address.dart';
|
||||||
import 'package:fcs/pages/widgets/delivery_address_selection.dart';
|
import 'package:fcs/pages/widgets/delivery_address_selection.dart';
|
||||||
import 'package:fcs/pages/widgets/display_text.dart';
|
|
||||||
import 'package:fcs/pages/widgets/length_picker.dart';
|
import 'package:fcs/pages/widgets/length_picker.dart';
|
||||||
import 'package:fcs/pages/widgets/local_button.dart';
|
import 'package:fcs/pages/widgets/local_button.dart';
|
||||||
import 'package:fcs/pages/widgets/local_text.dart';
|
import 'package:fcs/pages/widgets/local_text.dart';
|
||||||
@@ -45,7 +42,7 @@ class _PackageCartonEditorState extends State<PackageCartonEditor> {
|
|||||||
|
|
||||||
Carton? _carton;
|
Carton? _carton;
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
DeliveryAddress _deliveryAddress = new DeliveryAddress();
|
DeliveryAddress? _deliveryAddress = new DeliveryAddress();
|
||||||
List<CargoType> _cargoTypes = [];
|
List<CargoType> _cargoTypes = [];
|
||||||
CartonSize? selectedCatonSize;
|
CartonSize? selectedCatonSize;
|
||||||
bool isFromPackages = false;
|
bool isFromPackages = false;
|
||||||
@@ -263,7 +260,7 @@ class _PackageCartonEditorState extends State<PackageCartonEditor> {
|
|||||||
.map<DropdownMenuItem<CartonSize>>((CartonSize value) {
|
.map<DropdownMenuItem<CartonSize>>((CartonSize value) {
|
||||||
return DropdownMenuItem<CartonSize>(
|
return DropdownMenuItem<CartonSize>(
|
||||||
value: value,
|
value: value,
|
||||||
child: Text(value.name,
|
child: Text(value.name ?? "",
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: value.name == MANAGE_CARTONSIZE
|
color: value.name == MANAGE_CARTONSIZE
|
||||||
@@ -354,7 +351,7 @@ class _PackageCartonEditorState extends State<PackageCartonEditor> {
|
|||||||
Navigator.pop(context, _c);
|
Navigator.pop(context, _c);
|
||||||
} else {
|
} else {
|
||||||
await cartonModel.updateCarton(carton);
|
await cartonModel.updateCarton(carton);
|
||||||
Carton _c = await cartonModel.getCarton(_carton!.id);
|
Carton _c = await cartonModel.getCarton(_carton!.id!);
|
||||||
Navigator.pop(context, _c);
|
Navigator.pop(context, _c);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ Widget getCartonNumberStatus(BuildContext context, Carton carton) {
|
|||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 8.0),
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
child: Chip(label: Text(carton.status)),
|
child: Chip(label: Text(carton.status??"")),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,27 +5,15 @@ import 'package:flutter_vector_icons/flutter_vector_icons.dart';
|
|||||||
|
|
||||||
import 'carton_search.dart';
|
import 'carton_search.dart';
|
||||||
|
|
||||||
class CartonListRow extends StatefulWidget {
|
class CartonListRow extends StatelessWidget {
|
||||||
final CallbackCartonSelect? callbackCartonSelect;
|
final CallbackCartonSelect? callbackCartonSelect;
|
||||||
final Carton? carton;
|
final Carton carton;
|
||||||
|
|
||||||
// const CartonListRow({this.carton, this.callbackCartonSelect});
|
// const CartonListRow({this.carton, this.callbackCartonSelect});
|
||||||
CartonListRow(
|
CartonListRow({Key? key, required this.carton, this.callbackCartonSelect})
|
||||||
{Key? key, this.carton, this.callbackCartonSelect})
|
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
|
||||||
_CartonListRowState createState() => _CartonListRowState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _CartonListRowState extends State<CartonListRow> {
|
|
||||||
final double dotSize = 15.0;
|
final double dotSize = 15.0;
|
||||||
Carton? _carton;
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
this._carton = widget.carton;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -38,8 +26,7 @@ class _CartonListRowState extends State<CartonListRow> {
|
|||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
if (widget.callbackCartonSelect != null)
|
if (callbackCartonSelect != null) callbackCartonSelect!(carton);
|
||||||
widget.callbackCartonSelect!(widget.carton!);
|
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
@@ -64,7 +51,7 @@ class _CartonListRowState extends State<CartonListRow> {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 8.0),
|
padding: const EdgeInsets.only(left: 8.0),
|
||||||
child: new Text(
|
child: new Text(
|
||||||
_carton!.cartonNumber,
|
carton.cartonNumber ?? "",
|
||||||
style: new TextStyle(
|
style: new TextStyle(
|
||||||
fontSize: 15.0, color: Colors.black),
|
fontSize: 15.0, color: Colors.black),
|
||||||
),
|
),
|
||||||
@@ -72,7 +59,7 @@ class _CartonListRowState extends State<CartonListRow> {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(left: 10.0, top: 10),
|
padding: const EdgeInsets.only(left: 10.0, top: 10),
|
||||||
child: new Text(
|
child: new Text(
|
||||||
_carton!.userName,
|
carton.userName ?? "",
|
||||||
style: new TextStyle(
|
style: new TextStyle(
|
||||||
fontSize: 15.0, color: Colors.grey),
|
fontSize: 15.0, color: Colors.grey),
|
||||||
),
|
),
|
||||||
@@ -86,7 +73,7 @@ class _CartonListRowState extends State<CartonListRow> {
|
|||||||
child: Row(
|
child: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
new Text(
|
new Text(
|
||||||
"${_carton!.cartonWeight.toStringAsFixed(2)} lb",
|
"${carton.cartonWeight?.toStringAsFixed(2)} lb",
|
||||||
style: new TextStyle(
|
style: new TextStyle(
|
||||||
fontSize: 15.0, color: Colors.grey),
|
fontSize: 15.0, color: Colors.grey),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class _CartonSizeEditorState extends State<CartonSizeEditor> {
|
|||||||
if (widget.cartonSize != null) {
|
if (widget.cartonSize != null) {
|
||||||
_cartonSize = widget.cartonSize;
|
_cartonSize = widget.cartonSize;
|
||||||
_isNew = false;
|
_isNew = false;
|
||||||
_nameController.text = _cartonSize!.name;
|
_nameController.text = _cartonSize!.name ?? "";
|
||||||
_widthController.text = _cartonSize!.width.toString();
|
_widthController.text = _cartonSize!.width.toString();
|
||||||
_heightController.text = _cartonSize!.height.toString();
|
_heightController.text = _cartonSize!.height.toString();
|
||||||
_lengthController.text = _cartonSize!.length.toString();
|
_lengthController.text = _cartonSize!.length.toString();
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class _CartonSizeListState extends State<CartonSizeList> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
new Text(
|
new Text(
|
||||||
p.name,
|
p.name ?? "",
|
||||||
style: TextStyle(fontSize: 15.0),
|
style: TextStyle(fontSize: 15.0),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
@@ -135,7 +135,7 @@ class _CartonSizeListState extends State<CartonSizeList> {
|
|||||||
CartonSizeModel cartonSizeModel =
|
CartonSizeModel cartonSizeModel =
|
||||||
Provider.of<CartonSizeModel>(context, listen: false);
|
Provider.of<CartonSizeModel>(context, listen: false);
|
||||||
try {
|
try {
|
||||||
await cartonSizeModel.deleteCartonSize(cartonSize.id);
|
await cartonSizeModel.deleteCartonSize(cartonSize.id!);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showMsgDialog(context, "Error", e.toString());
|
showMsgDialog(context, "Error", e.toString());
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class CartonSizeModel extends BaseModel {
|
|||||||
List<CartonSize> cartonSizes = [];
|
List<CartonSize> cartonSizes = [];
|
||||||
final log = Logger('CartonSizeModel');
|
final log = Logger('CartonSizeModel');
|
||||||
|
|
||||||
StreamSubscription<QuerySnapshot> listener;
|
StreamSubscription<QuerySnapshot>? listener;
|
||||||
|
|
||||||
List<CartonSize> get getCartonSizes {
|
List<CartonSize> get getCartonSizes {
|
||||||
var _cartonSizes = new List<CartonSize>.from(cartonSizes);
|
var _cartonSizes = new List<CartonSize>.from(cartonSizes);
|
||||||
@@ -27,17 +27,18 @@ class CartonSizeModel extends BaseModel {
|
|||||||
|
|
||||||
Future<void> _loadCartonSizes() async {
|
Future<void> _loadCartonSizes() async {
|
||||||
try {
|
try {
|
||||||
if (listener != null) listener.cancel();
|
if (listener != null) listener!.cancel();
|
||||||
|
|
||||||
listener = Firestore.instance
|
listener = FirebaseFirestore.instance
|
||||||
.collection(
|
.collection(
|
||||||
"/$config_collection/$setting_doc_id/$carton_sizes_collection")
|
"/$config_collection/$setting_doc_id/$carton_sizes_collection")
|
||||||
.snapshots()
|
.snapshots()
|
||||||
.listen((QuerySnapshot snapshot) {
|
.listen((QuerySnapshot snapshot) {
|
||||||
cartonSizes.clear();
|
cartonSizes.clear();
|
||||||
cartonSizes = snapshot.documents.map((documentSnapshot) {
|
cartonSizes = snapshot.docs.map((documentSnapshot) {
|
||||||
var c = CartonSize.fromMap(
|
var c = CartonSize.fromMap(
|
||||||
documentSnapshot.data, documentSnapshot.documentID);
|
documentSnapshot.data() as Map<String, dynamic>,
|
||||||
|
documentSnapshot.id);
|
||||||
return c;
|
return c;
|
||||||
}).toList();
|
}).toList();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@@ -49,7 +50,7 @@ class CartonSizeModel extends BaseModel {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
logout() async {
|
logout() async {
|
||||||
if (listener != null) await listener.cancel();
|
if (listener != null) await listener!.cancel();
|
||||||
cartonSizes = [];
|
cartonSizes = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import 'package:fcs/helpers/theme.dart';
|
|||||||
import 'package:fcs/pages/package/package_info.dart';
|
import 'package:fcs/pages/package/package_info.dart';
|
||||||
import 'package:fcs/pages/main/util.dart';
|
import 'package:fcs/pages/main/util.dart';
|
||||||
import 'package:fcs/pages/widgets/fcs_id_icon.dart';
|
import 'package:fcs/pages/widgets/fcs_id_icon.dart';
|
||||||
import 'package:fcs/pages/widgets/local_text.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
@@ -14,18 +13,18 @@ typedef CallbackOnViewDetail();
|
|||||||
class Bubble extends StatelessWidget {
|
class Bubble extends StatelessWidget {
|
||||||
Bubble(
|
Bubble(
|
||||||
{this.message,
|
{this.message,
|
||||||
this.date,
|
required this.date,
|
||||||
this.delivered,
|
required this.delivered,
|
||||||
this.isMine,
|
required this.isMine,
|
||||||
this.sender,
|
this.sender,
|
||||||
this.isSystem,
|
required this.isSystem,
|
||||||
this.isCustomer,
|
required this.isCustomer,
|
||||||
this.showDate,
|
required this.showDate,
|
||||||
this.callbackOnViewDetail});
|
this.callbackOnViewDetail});
|
||||||
|
|
||||||
final CallbackOnViewDetail callbackOnViewDetail;
|
final CallbackOnViewDetail? callbackOnViewDetail;
|
||||||
final DateTime date;
|
final DateTime date;
|
||||||
final String message, sender;
|
final String? message, sender;
|
||||||
final bool delivered, isMine, isSystem, isCustomer, showDate;
|
final bool delivered, isMine, isSystem, isCustomer, showDate;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -84,7 +83,7 @@ class Bubble extends StatelessWidget {
|
|||||||
fontWeight: FontWeight.bold)))
|
fontWeight: FontWeight.bold)))
|
||||||
]
|
]
|
||||||
: [
|
: [
|
||||||
Text(isCustomer ? "FCS Team" : sender,
|
Text(isCustomer ? "FCS Team" : sender ?? "",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.black38,
|
color: Colors.black38,
|
||||||
fontSize: 10.0,
|
fontSize: 10.0,
|
||||||
@@ -102,8 +101,8 @@ class Bubble extends StatelessWidget {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(right: 48.0),
|
padding: EdgeInsets.only(right: 48.0),
|
||||||
child: Text(message,
|
child: Text(message ?? "",
|
||||||
style: hasUnicode(message)
|
style: hasUnicode(message ?? "")
|
||||||
? newLabelStyleMM(color: primaryColor)
|
? newLabelStyleMM(color: primaryColor)
|
||||||
: newLabelStyle(color: primaryColor))),
|
: newLabelStyle(color: primaryColor))),
|
||||||
Positioned(
|
Positioned(
|
||||||
@@ -130,6 +129,6 @@ class Bubble extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_viewDetail() {
|
_viewDetail() {
|
||||||
if (callbackOnViewDetail != null) callbackOnViewDetail();
|
if (callbackOnViewDetail != null) callbackOnViewDetail!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,14 +21,17 @@ import 'package:provider/provider.dart';
|
|||||||
import 'bubble.dart';
|
import 'bubble.dart';
|
||||||
|
|
||||||
class MessageDetail extends StatelessWidget {
|
class MessageDetail extends StatelessWidget {
|
||||||
final String receiverName;
|
final String? receiverName;
|
||||||
final String receiverID;
|
final String? receiverID;
|
||||||
final MessageModel messageModel;
|
final MessageModel messageModel;
|
||||||
final TextEditingController textEditingController = TextEditingController();
|
final TextEditingController textEditingController = TextEditingController();
|
||||||
final ScrollController listScrollController = ScrollController();
|
final ScrollController listScrollController = ScrollController();
|
||||||
|
|
||||||
MessageDetail(
|
MessageDetail(
|
||||||
{Key key, this.messageModel, this.receiverName, this.receiverID})
|
{Key? key,
|
||||||
|
required this.messageModel,
|
||||||
|
this.receiverName,
|
||||||
|
this.receiverID})
|
||||||
: super(key: key) {
|
: super(key: key) {
|
||||||
listScrollController.addListener(() {
|
listScrollController.addListener(() {
|
||||||
if (listScrollController.offset >=
|
if (listScrollController.offset >=
|
||||||
@@ -44,7 +47,7 @@ class MessageDetail extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
String userID = Provider.of<MessageModel>(context).user.id;
|
String userID = Provider.of<MessageModel>(context).user?.id ?? "";
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
@@ -96,8 +99,8 @@ class MessageDetail extends StatelessWidget {
|
|||||||
Widget buildBubble(Message msg, String userID, bool showDate,
|
Widget buildBubble(Message msg, String userID, bool showDate,
|
||||||
CallbackOnViewDetail callback) {
|
CallbackOnViewDetail callback) {
|
||||||
return Bubble(
|
return Bubble(
|
||||||
message: msg.message,
|
message: msg.message ?? "",
|
||||||
date: msg.date,
|
date: msg.date!,
|
||||||
delivered: true,
|
delivered: true,
|
||||||
sender: msg.senderName,
|
sender: msg.senderName,
|
||||||
isMine: msg.senderID == userID || msg.receiverID == receiverID,
|
isMine: msg.senderID == userID || msg.receiverID == receiverID,
|
||||||
@@ -117,8 +120,8 @@ class MessageDetail extends StatelessWidget {
|
|||||||
child: Container(
|
child: Container(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
onSubmitted: (value) {
|
onSubmitted: (value) {
|
||||||
Provider.of<MessageModel>(context, listen: false)
|
Provider.of<MessageModel>(context, listen: false).sendMessage(
|
||||||
.sendMessage(textEditingController.text, receiverID);
|
textEditingController.text, receiverID ?? "");
|
||||||
textEditingController.text = "";
|
textEditingController.text = "";
|
||||||
},
|
},
|
||||||
style: TextStyle(color: primaryColor, fontSize: 15.0),
|
style: TextStyle(color: primaryColor, fontSize: 15.0),
|
||||||
@@ -152,8 +155,8 @@ class MessageDetail extends StatelessWidget {
|
|||||||
child: IconButton(
|
child: IconButton(
|
||||||
icon: Icon(Icons.send),
|
icon: Icon(Icons.send),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Provider.of<MessageModel>(context, listen: false)
|
Provider.of<MessageModel>(context, listen: false).sendMessage(
|
||||||
.sendMessage(textEditingController.text, receiverID);
|
textEditingController.text, receiverID ?? "");
|
||||||
textEditingController.text = "";
|
textEditingController.text = "";
|
||||||
},
|
},
|
||||||
color: primaryColor,
|
color: primaryColor,
|
||||||
@@ -165,7 +168,8 @@ class MessageDetail extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border(top: BorderSide(color: Colors.grey[700], width: 0.5)),
|
border:
|
||||||
|
Border(top: BorderSide(color: Colors.grey.shade700, width: 0.5)),
|
||||||
color: Colors.white),
|
color: Colors.white),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -176,7 +180,7 @@ class MessageDetail extends StatelessWidget {
|
|||||||
message.messageID != "") {
|
message.messageID != "") {
|
||||||
PackageModel packageModel =
|
PackageModel packageModel =
|
||||||
Provider.of<PackageModel>(context, listen: false);
|
Provider.of<PackageModel>(context, listen: false);
|
||||||
Package p = await packageModel.getPackage(message.messageID);
|
Package p = await packageModel.getPackage(message.messageID!);
|
||||||
if (p == null) return;
|
if (p == null) return;
|
||||||
Navigator.push<bool>(context,
|
Navigator.push<bool>(context,
|
||||||
CupertinoPageRoute(builder: (context) => PackageInfo(package: p)));
|
CupertinoPageRoute(builder: (context) => PackageInfo(package: p)));
|
||||||
@@ -186,7 +190,7 @@ class MessageDetail extends StatelessWidget {
|
|||||||
message.messageID != "") {
|
message.messageID != "") {
|
||||||
MainModel mainModel = Provider.of<MainModel>(context, listen: false);
|
MainModel mainModel = Provider.of<MainModel>(context, listen: false);
|
||||||
|
|
||||||
if (mainModel.user.isCustomer()) {
|
if (mainModel.user?.isCustomer() ?? false) {
|
||||||
Navigator.push<bool>(
|
Navigator.push<bool>(
|
||||||
context, CupertinoPageRoute(builder: (context) => Profile()));
|
context, CupertinoPageRoute(builder: (context) => Profile()));
|
||||||
} else {
|
} else {
|
||||||
@@ -202,7 +206,7 @@ class MessageDetail extends StatelessWidget {
|
|||||||
message.messageID != "") {
|
message.messageID != "") {
|
||||||
ShipmentModel shipmentModel =
|
ShipmentModel shipmentModel =
|
||||||
Provider.of<ShipmentModel>(context, listen: false);
|
Provider.of<ShipmentModel>(context, listen: false);
|
||||||
Shipment s = await shipmentModel.getShipment(message.messageID);
|
Shipment s = await shipmentModel.getShipment(message.messageID!);
|
||||||
if (s == null) return;
|
if (s == null) return;
|
||||||
await Navigator.push<bool>(
|
await Navigator.push<bool>(
|
||||||
context,
|
context,
|
||||||
|
|||||||
@@ -10,45 +10,46 @@ import 'package:logging/logging.dart';
|
|||||||
class MessageModel extends BaseModel {
|
class MessageModel extends BaseModel {
|
||||||
final log = Logger('MessageModel');
|
final log = Logger('MessageModel');
|
||||||
|
|
||||||
List<Message> messages;
|
List<Message> messages = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
logout() async {
|
logout() async {
|
||||||
if (listener != null) await listener.cancel();
|
if (listener != null) await listener!.cancel();
|
||||||
messages = [];
|
messages = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
Query query;
|
late Query query;
|
||||||
DocumentSnapshot prevSnap;
|
DocumentSnapshot? prevSnap;
|
||||||
bool isEnded;
|
late bool isEnded;
|
||||||
bool isLoading;
|
late bool isLoading;
|
||||||
String userID;
|
String? userID;
|
||||||
StreamSubscription<QuerySnapshot> listener;
|
StreamSubscription<QuerySnapshot>? listener;
|
||||||
|
|
||||||
static const int rowPerLoad = 20;
|
static const int rowPerLoad = 20;
|
||||||
void initQuery(String? userID) {
|
void initQuery(String? userID) {
|
||||||
if(userID == null)return;
|
if (userID == null) return;
|
||||||
this.messages = [];
|
this.messages = [];
|
||||||
this.userID = userID;
|
this.userID = userID;
|
||||||
this.prevSnap = null;
|
this.prevSnap = null;
|
||||||
query = Firestore.instance
|
query = FirebaseFirestore.instance
|
||||||
.collection("$user_collection/$userID/$messages_collection")
|
.collection("$user_collection/$userID/$messages_collection")
|
||||||
.orderBy('date', descending: true);
|
.orderBy('date', descending: true);
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> load() async {
|
Future<void> load() async {
|
||||||
|
if (prevSnap == null) return;
|
||||||
Query _query =
|
Query _query =
|
||||||
prevSnap != null ? query.startAfterDocument(prevSnap) : query;
|
prevSnap != null ? query.startAfterDocument(prevSnap!) : query;
|
||||||
QuerySnapshot snapshot =
|
QuerySnapshot snapshot =
|
||||||
await _query.limit(rowPerLoad).getDocuments(source: Source.server);
|
await _query.limit(rowPerLoad).get(GetOptions(source: Source.server));
|
||||||
|
|
||||||
int count = snapshot.documents.length;
|
int count = snapshot.docs.length;
|
||||||
isEnded = count < rowPerLoad;
|
isEnded = count < rowPerLoad;
|
||||||
prevSnap = count > 0 ? snapshot.documents[count - 1] : prevSnap;
|
prevSnap = count > 0 ? snapshot.docs[count - 1] : prevSnap;
|
||||||
|
|
||||||
snapshot.documents.forEach((e) {
|
snapshot.docs.forEach((e) {
|
||||||
messages.add(Message.fromMap(e.data, e.documentID));
|
messages.add(Message.fromMap(e.data() as Map<String, dynamic>, e.id));
|
||||||
if (messages.length == 1) {
|
if (messages.length == 1) {
|
||||||
_initListener(e);
|
_initListener(e);
|
||||||
}
|
}
|
||||||
@@ -57,20 +58,22 @@ class MessageModel extends BaseModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _initListener(DocumentSnapshot snap) {
|
void _initListener(DocumentSnapshot snap) {
|
||||||
if (listener != null) listener.cancel();
|
if (listener != null) listener!.cancel();
|
||||||
|
|
||||||
listener = Firestore.instance
|
listener = FirebaseFirestore.instance
|
||||||
.collection("$user_collection/$userID/$messages_collection")
|
.collection("$user_collection/$userID/$messages_collection")
|
||||||
.endBeforeDocument(snap)
|
.endBeforeDocument(snap)
|
||||||
.orderBy('date', descending: true)
|
.orderBy('date', descending: true)
|
||||||
.snapshots(includeMetadataChanges: true)
|
.snapshots(includeMetadataChanges: true)
|
||||||
.listen((qs) {
|
.listen((qs) {
|
||||||
qs.documentChanges.forEach((c) {
|
qs.docChanges.forEach((c) {
|
||||||
switch (c.type) {
|
switch (c.type) {
|
||||||
case DocumentChangeType.added:
|
case DocumentChangeType.added:
|
||||||
log.info("added!! $c");
|
log.info("added!! $c");
|
||||||
messages.insert(
|
messages.insert(
|
||||||
0, Message.fromMap(c.document.data, c.document.documentID));
|
0,
|
||||||
|
Message.fromMap(
|
||||||
|
c.doc.data() as Map<String, dynamic>, c.doc.id));
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
break;
|
break;
|
||||||
case DocumentChangeType.modified:
|
case DocumentChangeType.modified:
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ class ContactPage extends StatefulWidget {
|
|||||||
class _ContactPageState extends State<ContactPage> {
|
class _ContactPageState extends State<ContactPage> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Setting setting = Provider.of<MainModel>(context).setting;
|
Setting? setting = Provider.of<MainModel>(context).setting;
|
||||||
|
if (setting == null) return Container();
|
||||||
bool isEditable = context.select((MainModel m) => m.contactEditable());
|
bool isEditable = context.select((MainModel m) => m.contactEditable());
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@@ -61,14 +62,14 @@ class _ContactPageState extends State<ContactPage> {
|
|||||||
children: [
|
children: [
|
||||||
itemTitle(context, "contact.callus"),
|
itemTitle(context, "contact.callus"),
|
||||||
contactItem(context, setting.usaContactNumber, CupertinoIcons.phone,
|
contactItem(context, setting.usaContactNumber, CupertinoIcons.phone,
|
||||||
onTap: () => _call(setting.usaContactNumber),
|
onTap: () => _call(setting.usaContactNumber ?? ""),
|
||||||
labelKey: "contact.usa.phone"),
|
labelKey: "contact.usa.phone"),
|
||||||
contactItem(
|
contactItem(
|
||||||
context,
|
context,
|
||||||
setting.mmContactNumber,
|
setting.mmContactNumber,
|
||||||
CupertinoIcons.phone,
|
CupertinoIcons.phone,
|
||||||
onTap: () => _call(
|
onTap: () => _call(
|
||||||
setting.mmContactNumber,
|
setting.mmContactNumber ?? "",
|
||||||
),
|
),
|
||||||
labelKey: "contact.mm.phone",
|
labelKey: "contact.mm.phone",
|
||||||
),
|
),
|
||||||
@@ -90,7 +91,7 @@ class _ContactPageState extends State<ContactPage> {
|
|||||||
context,
|
context,
|
||||||
setting.emailAddress,
|
setting.emailAddress,
|
||||||
CupertinoIcons.mail,
|
CupertinoIcons.mail,
|
||||||
onTap: () => _email(setting.emailAddress),
|
onTap: () => _email(setting.emailAddress ?? ""),
|
||||||
labelKey: "contact.fcs.email",
|
labelKey: "contact.fcs.email",
|
||||||
),
|
),
|
||||||
itemTitle(context, "contact.visitus"),
|
itemTitle(context, "contact.visitus"),
|
||||||
@@ -98,7 +99,7 @@ class _ContactPageState extends State<ContactPage> {
|
|||||||
context,
|
context,
|
||||||
setting.facebookLink,
|
setting.facebookLink,
|
||||||
FontAwesomeIcons.facebook,
|
FontAwesomeIcons.facebook,
|
||||||
onTap: () => _opencontactItem(setting.facebookLink),
|
onTap: () => _opencontactItem(setting.facebookLink ?? ""),
|
||||||
labelKey: "contact.facebook",
|
labelKey: "contact.facebook",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class _CustomerEditorState extends State<CustomerEditor> {
|
|||||||
)),
|
)),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(Icons.open_in_new, color: primaryColor),
|
icon: Icon(Icons.open_in_new, color: primaryColor),
|
||||||
onPressed: () => call(context, widget.customer!.phoneNumber)),
|
onPressed: () => call(context, widget.customer?.phoneNumber ?? "")),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ class _CustomerEditorState extends State<CustomerEditor> {
|
|||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
widget.customer!.name,
|
widget.customer?.name ?? "",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
color: primaryColor,
|
color: primaryColor,
|
||||||
@@ -119,7 +119,7 @@ class _CustomerEditorState extends State<CustomerEditor> {
|
|||||||
CustomerModel customerModel =
|
CustomerModel customerModel =
|
||||||
Provider.of<CustomerModel>(context, listen: false);
|
Provider.of<CustomerModel>(context, listen: false);
|
||||||
try {
|
try {
|
||||||
await customerModel.acceptRequest(widget.customer!.id);
|
await customerModel.acceptRequest(widget.customer?.id ?? "");
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showMsgDialog(context, "Error", e.toString());
|
showMsgDialog(context, "Error", e.toString());
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ class _CustomerListState extends State<CustomerList> {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(top: 2.0),
|
padding: const EdgeInsets.only(top: 2.0),
|
||||||
child: new Text(
|
child: new Text(
|
||||||
customer.name,
|
customer.name ?? "",
|
||||||
style: new TextStyle(
|
style: new TextStyle(
|
||||||
fontSize: 20.0, color: primaryColor),
|
fontSize: 20.0, color: primaryColor),
|
||||||
),
|
),
|
||||||
@@ -171,7 +171,7 @@ class _CustomerListState extends State<CustomerList> {
|
|||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(right: 5),
|
padding: const EdgeInsets.only(right: 5),
|
||||||
child: _status(customer.status),
|
child: _status(customer.status ?? ""),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(right: 5),
|
padding: const EdgeInsets.only(right: 5),
|
||||||
@@ -222,17 +222,17 @@ class _CustomerListState extends State<CustomerList> {
|
|||||||
)))
|
)))
|
||||||
.then((value) {
|
.then((value) {
|
||||||
if (customer.fcsUnseenCount > 0) {
|
if (customer.fcsUnseenCount > 0) {
|
||||||
messageModel.seenMessages(customer.id, false);
|
messageModel.seenMessages(customer.id ?? "", false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (customer.fcsUnseenCount > 0) {
|
if (customer.fcsUnseenCount > 0) {
|
||||||
messageModel.seenMessages(customer.id, false);
|
messageModel.seenMessages(customer.id ?? "", false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_share(User user) async {
|
_share(User user) async {
|
||||||
MainModel mainModel = Provider.of<MainModel>(context, listen: false);
|
MainModel mainModel = Provider.of<MainModel>(context, listen: false);
|
||||||
String appUrl = mainModel.setting.appUrl;
|
String appUrl = mainModel.setting?.appUrl ?? "";
|
||||||
final RenderBox? box = context.findRenderObject() as RenderBox;
|
final RenderBox? box = context.findRenderObject() as RenderBox;
|
||||||
await Share.share(
|
await Share.share(
|
||||||
"Join us on FCS Logistics App. Here is the link:\n $appUrl\n" +
|
"Join us on FCS Logistics App. Here is the link:\n $appUrl\n" +
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class _InvitationEditorState extends State<InvitationEditor> {
|
|||||||
)),
|
)),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(Icons.open_in_new, color: primaryColor),
|
icon: Icon(Icons.open_in_new, color: primaryColor),
|
||||||
onPressed: () => call(context, widget.customer!.phoneNumber)),
|
onPressed: () => call(context, widget.customer?.phoneNumber ?? "")),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ class _InvitationEditorState extends State<InvitationEditor> {
|
|||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
widget.customer!.name,
|
widget.customer?.name ?? "",
|
||||||
style: TextStyle(fontSize: 20, color: primaryColor),
|
style: TextStyle(fontSize: 20, color: primaryColor),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -87,7 +87,7 @@ class _InvitationEditorState extends State<InvitationEditor> {
|
|||||||
CustomerModel customerModel =
|
CustomerModel customerModel =
|
||||||
Provider.of<CustomerModel>(context, listen: false);
|
Provider.of<CustomerModel>(context, listen: false);
|
||||||
try {
|
try {
|
||||||
await customerModel.deleteInvite(widget.customer!.phoneNumber);
|
await customerModel.deleteInvite(widget.customer?.phoneNumber ?? "");
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showMsgDialog(context, "Error", e.toString());
|
showMsgDialog(context, "Error", e.toString());
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ class CustomerModel extends BaseModel {
|
|||||||
|
|
||||||
List<User> customers = [];
|
List<User> customers = [];
|
||||||
List<User> invitations = [];
|
List<User> invitations = [];
|
||||||
late StreamSubscription<QuerySnapshot?> customerListener;
|
late StreamSubscription<QuerySnapshot>? customerListener;
|
||||||
late StreamSubscription<QuerySnapshot?> invitationListener;
|
late StreamSubscription<QuerySnapshot>? invitationListener;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void privilegeChanged() {
|
void privilegeChanged() {
|
||||||
@@ -24,8 +24,8 @@ class CustomerModel extends BaseModel {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
logout() async {
|
logout() async {
|
||||||
if (customerListener != null) customerListener.cancel();
|
if (customerListener != null) customerListener!.cancel();
|
||||||
if (invitationListener != null) invitationListener.cancel();
|
if (invitationListener != null) invitationListener!.cancel();
|
||||||
customers = [];
|
customers = [];
|
||||||
invitations = [];
|
invitations = [];
|
||||||
}
|
}
|
||||||
@@ -43,21 +43,22 @@ class CustomerModel extends BaseModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadCustomer() async {
|
Future<void> _loadCustomer() async {
|
||||||
if (user == null || !user.hasCustomers()) return;
|
if (user == null && !user!.hasCustomers()) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (customerListener != null) customerListener.cancel();
|
if (customerListener != null) customerListener!.cancel();
|
||||||
|
|
||||||
customerListener = Firestore.instance
|
customerListener = FirebaseFirestore.instance
|
||||||
.collection("/$user_collection")
|
.collection("/$user_collection")
|
||||||
.where("is_sys_admin", isEqualTo: false)
|
.where("is_sys_admin", isEqualTo: false)
|
||||||
.orderBy("message_time", descending: true)
|
.orderBy("message_time", descending: true)
|
||||||
.snapshots()
|
.snapshots()
|
||||||
.listen((QuerySnapshot snapshot) {
|
.listen((QuerySnapshot snapshot) {
|
||||||
customers.clear();
|
customers.clear();
|
||||||
customers = snapshot.documents.map((documentSnapshot) {
|
customers = snapshot.docs.map((documentSnapshot) {
|
||||||
var user =
|
var user = User.fromMap(
|
||||||
User.fromMap(documentSnapshot.data, documentSnapshot.documentID);
|
documentSnapshot.data() as Map<String, dynamic>,
|
||||||
|
documentSnapshot.id);
|
||||||
return user;
|
return user;
|
||||||
}).toList();
|
}).toList();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@@ -68,19 +69,20 @@ class CustomerModel extends BaseModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadInvitations() async {
|
Future<void> _loadInvitations() async {
|
||||||
if (user == null || !user.hasCustomers()) return;
|
if (user == null && !user!.hasCustomers()) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (invitationListener != null) invitationListener.cancel();
|
if (invitationListener != null) invitationListener!.cancel();
|
||||||
|
|
||||||
invitationListener = Firestore.instance
|
invitationListener = FirebaseFirestore.instance
|
||||||
.collection("/$invitations_collection")
|
.collection("/$invitations_collection")
|
||||||
.snapshots()
|
.snapshots()
|
||||||
.listen((QuerySnapshot snapshot) {
|
.listen((QuerySnapshot snapshot) {
|
||||||
invitations.clear();
|
invitations.clear();
|
||||||
invitations = snapshot.documents.map((documentSnapshot) {
|
invitations = snapshot.docs.map((documentSnapshot) {
|
||||||
var user =
|
var user = User.fromMap(
|
||||||
User.fromMap(documentSnapshot.data, documentSnapshot.documentID);
|
documentSnapshot.data() as Map<String, dynamic>,
|
||||||
|
documentSnapshot.id);
|
||||||
return user;
|
return user;
|
||||||
}).toList();
|
}).toList();
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@@ -92,21 +94,20 @@ class CustomerModel extends BaseModel {
|
|||||||
|
|
||||||
Future<User> getUser(String? id) async {
|
Future<User> getUser(String? id) async {
|
||||||
String path = "/$user_collection";
|
String path = "/$user_collection";
|
||||||
var snap = await Firestore.instance.collection(path).document(id).get();
|
var snap = await FirebaseFirestore.instance.collection(path).doc(id).get();
|
||||||
return User.fromMap(snap.data, snap.documentID);
|
return User.fromMap(snap.data() as Map<String, dynamic>, snap.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<User>> getInvoiceUsers(String fcsShipmentID) async {
|
Future<List<User>> getInvoiceUsers(String fcsShipmentID) async {
|
||||||
List<User> users = [];
|
List<User> users = [];
|
||||||
try {
|
try {
|
||||||
var snaps = await Firestore.instance
|
var snaps = await FirebaseFirestore.instance
|
||||||
.collection(
|
.collection(
|
||||||
"/$fcs_shipment_collection/$fcsShipmentID/$user_collection")
|
"/$fcs_shipment_collection/$fcsShipmentID/$user_collection")
|
||||||
.where("pending_invoice_carton_count", isGreaterThan: 0)
|
.where("pending_invoice_carton_count", isGreaterThan: 0)
|
||||||
.getDocuments(source: Source.server);
|
.get(GetOptions(source: Source.server));
|
||||||
users = snaps.documents.map((documentSnapshot) {
|
users = snaps.docs.map((documentSnapshot) {
|
||||||
var user =
|
var user = User.fromMap(documentSnapshot.data(), documentSnapshot.id);
|
||||||
User.fromMap(documentSnapshot.data, documentSnapshot.documentID);
|
|
||||||
return user;
|
return user;
|
||||||
}).toList();
|
}).toList();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -116,6 +117,6 @@ class CustomerModel extends BaseModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> enableUser(User user, bool enabled) {
|
Future<void> enableUser(User user, bool enabled) {
|
||||||
return Services.instance.userService.enableUser(user.id, enabled);
|
return Services.instance.userService.enableUser(user.id ?? "", enabled);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
new AndroidInitializationSettings('@mipmap/ic_launcher');
|
new AndroidInitializationSettings('@mipmap/ic_launcher');
|
||||||
var initializationSettingsIOS = new IOSInitializationSettings();
|
var initializationSettingsIOS = new IOSInitializationSettings();
|
||||||
var initializationSettings = new InitializationSettings(
|
var initializationSettings = new InitializationSettings(
|
||||||
initializationSettingsAndroid, initializationSettingsIOS);
|
android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
|
||||||
_flutterLocalNotificationsPlugin.initialize(initializationSettings);
|
_flutterLocalNotificationsPlugin.initialize(initializationSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,13 +179,15 @@ class _HomePageState extends State<HomePage> {
|
|||||||
'your channel id', 'your channel name', 'your channel description',
|
'your channel id', 'your channel name', 'your channel description',
|
||||||
playSound: true,
|
playSound: true,
|
||||||
enableVibration: true,
|
enableVibration: true,
|
||||||
importance: Importance.Max,
|
importance: Importance.max,
|
||||||
priority: Priority.High);
|
priority: Priority.high);
|
||||||
|
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
var platformChannelSpecificsIos =
|
var platformChannelSpecificsIos =
|
||||||
new IOSNotificationDetails(presentSound: true);
|
new IOSNotificationDetails(presentSound: true);
|
||||||
var platformChannelSpecifics = new NotificationDetails(
|
var platformChannelSpecifics = new NotificationDetails(
|
||||||
platformChannelSpecificsAndroid, platformChannelSpecificsIos);
|
android: platformChannelSpecificsAndroid,
|
||||||
|
iOS: platformChannelSpecificsIos);
|
||||||
|
|
||||||
new Future.delayed(Duration.zero, () {
|
new Future.delayed(Duration.zero, () {
|
||||||
_flutterLocalNotificationsPlugin.show(
|
_flutterLocalNotificationsPlugin.show(
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class _CargoEditorState extends State<CargoEditor> {
|
|||||||
super.initState();
|
super.initState();
|
||||||
if (widget.cargo != null) {
|
if (widget.cargo != null) {
|
||||||
_cargo = widget.cargo!;
|
_cargo = widget.cargo!;
|
||||||
_descController.text = _cargo.name;
|
_descController.text = _cargo.name ?? "";
|
||||||
_rateController.text = _cargo.rate.toStringAsFixed(2);
|
_rateController.text = _cargo.rate.toStringAsFixed(2);
|
||||||
} else {
|
} else {
|
||||||
_isNew = true;
|
_isNew = true;
|
||||||
@@ -138,7 +138,7 @@ class _CargoEditorState extends State<CargoEditor> {
|
|||||||
try {
|
try {
|
||||||
var shipmentRateModel =
|
var shipmentRateModel =
|
||||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||||
await shipmentRateModel.deleteCargoType(this._cargo.id);
|
await shipmentRateModel.deleteCargoType(this._cargo.id!);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showMsgDialog(context, "Error", e.toString());
|
showMsgDialog(context, "Error", e.toString());
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ class _CargoTypeListState extends State<CargoTypeList> {
|
|||||||
)));
|
)));
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
child: _row(cargo.name,
|
child: _row(cargo.name ?? "",
|
||||||
"\$ " + cargo.rate.toStringAsFixed(2), 'per pound'),
|
"\$ " + cargo.rate.toStringAsFixed(2), 'per pound'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class _CustomEditorState extends State<CustomEditor> {
|
|||||||
super.initState();
|
super.initState();
|
||||||
if (widget.custom != null) {
|
if (widget.custom != null) {
|
||||||
_custom = widget.custom!;
|
_custom = widget.custom!;
|
||||||
_productController.text = _custom.name;
|
_productController.text = _custom.name??"";
|
||||||
_feeController.text = _custom.customDutyFee.toStringAsFixed(2);
|
_feeController.text = _custom.customDutyFee.toStringAsFixed(2);
|
||||||
_shipmentRateController.text =
|
_shipmentRateController.text =
|
||||||
_custom.rate == null ? "" : _custom.rate.toStringAsFixed(2);
|
_custom.rate == null ? "" : _custom.rate.toStringAsFixed(2);
|
||||||
@@ -154,7 +154,7 @@ class _CustomEditorState extends State<CustomEditor> {
|
|||||||
try {
|
try {
|
||||||
var shipmentRateModel =
|
var shipmentRateModel =
|
||||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||||
await shipmentRateModel.deleteCustomDuty(this._custom.id);
|
await shipmentRateModel.deleteCustomDuty(this._custom.id!);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showMsgDialog(context, "Error", e.toString());
|
showMsgDialog(context, "Error", e.toString());
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class _CustomListState extends State<CustomList> {
|
|||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
child: _row(
|
child: _row(
|
||||||
custom.name,
|
custom.name??"",
|
||||||
"Custom Fee \$ " + custom.customDutyFee.toStringAsFixed(2),
|
"Custom Fee \$ " + custom.customDutyFee.toStringAsFixed(2),
|
||||||
custom.rate == null
|
custom.rate == null
|
||||||
? ""
|
? ""
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import 'package:fcs/domain/entities/custom_duty.dart';
|
import 'package:fcs/domain/entities/custom_duty.dart';
|
||||||
import 'package:fcs/domain/vo/delivery_address.dart';
|
|
||||||
import 'package:fcs/helpers/theme.dart';
|
import 'package:fcs/helpers/theme.dart';
|
||||||
import 'package:fcs/pages/widgets/local_text.dart';
|
import 'package:fcs/pages/widgets/local_text.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart';
|
||||||
|
|
||||||
typedef SelectionCallback(CustomDuty custom);
|
typedef SelectionCallback(CustomDuty custom);
|
||||||
|
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ class _DiscountByWeightEditorState extends State<DiscountByWeightEditor> {
|
|||||||
var shipmentRateModel =
|
var shipmentRateModel =
|
||||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||||
await shipmentRateModel
|
await shipmentRateModel
|
||||||
.deleteDiscountByWeight(this._discountByWeight.id);
|
.deleteDiscountByWeight(this._discountByWeight.id!);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showMsgDialog(context, "Error", e.toString());
|
showMsgDialog(context, "Error", e.toString());
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:fcs/data/services/services.dart';
|
import 'package:fcs/data/services/services.dart';
|
||||||
import 'package:fcs/domain/entities/cargo_type.dart';
|
import 'package:fcs/domain/entities/cargo_type.dart';
|
||||||
import 'package:fcs/domain/entities/custom_duty.dart';
|
|
||||||
import 'package:fcs/domain/entities/discount_by_weight.dart';
|
import 'package:fcs/domain/entities/discount_by_weight.dart';
|
||||||
import 'package:fcs/domain/entities/rate.dart';
|
import 'package:fcs/domain/entities/rate.dart';
|
||||||
import 'package:fcs/pages/main/model/base_model.dart';
|
import 'package:fcs/pages/main/model/base_model.dart';
|
||||||
@@ -11,12 +10,12 @@ import 'package:logging/logging.dart';
|
|||||||
class ShipmentRateModel extends BaseModel {
|
class ShipmentRateModel extends BaseModel {
|
||||||
final log = Logger('ShipmentRateModel');
|
final log = Logger('ShipmentRateModel');
|
||||||
|
|
||||||
StreamSubscription<Rate> listener;
|
StreamSubscription<Rate>? listener;
|
||||||
Rate rate;
|
late Rate rate;
|
||||||
|
|
||||||
void initUser(user) {
|
void initUser(user) {
|
||||||
super.initUser(user);
|
super.initUser(user);
|
||||||
if (listener != null) listener.cancel();
|
if (listener != null) listener!.cancel();
|
||||||
listener = Services.instance.rateService.getRateStream().listen((rate) {
|
listener = Services.instance.rateService.getRateStream().listen((rate) {
|
||||||
this.rate = rate;
|
this.rate = rate;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@@ -25,7 +24,7 @@ class ShipmentRateModel extends BaseModel {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
logout() async {
|
logout() async {
|
||||||
if (listener != null) await listener.cancel();
|
if (listener != null) await listener!.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rate
|
// Rate
|
||||||
@@ -51,12 +50,12 @@ class ShipmentRateModel extends BaseModel {
|
|||||||
//CustomDuty
|
//CustomDuty
|
||||||
|
|
||||||
Future<void> addCustomDuty(CargoType customDuty) {
|
Future<void> addCustomDuty(CargoType customDuty) {
|
||||||
customDuty.isCutomDuty=true;
|
customDuty.isCutomDuty = true;
|
||||||
return Services.instance.rateService.createCargoType(customDuty);
|
return Services.instance.rateService.createCargoType(customDuty);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateCustomDuty(CargoType customDuty) {
|
Future<void> updateCustomDuty(CargoType customDuty) {
|
||||||
customDuty.isCutomDuty=true;
|
customDuty.isCutomDuty = true;
|
||||||
return Services.instance.rateService.updateCargoType(customDuty);
|
return Services.instance.rateService.updateCargoType(customDuty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:fcs/domain/entities/cargo_type.dart';
|
import 'package:fcs/domain/entities/cargo_type.dart';
|
||||||
import 'package:fcs/domain/entities/custom_duty.dart';
|
|
||||||
import 'package:fcs/domain/entities/discount_by_weight.dart';
|
import 'package:fcs/domain/entities/discount_by_weight.dart';
|
||||||
import 'package:fcs/domain/entities/rate.dart';
|
import 'package:fcs/domain/entities/rate.dart';
|
||||||
import 'package:fcs/helpers/theme.dart';
|
import 'package:fcs/helpers/theme.dart';
|
||||||
@@ -185,8 +184,8 @@ class _ShipmentRatesState extends State<ShipmentRates> {
|
|||||||
List<Widget> getCargoWidget(List<CargoType> cargos) {
|
List<Widget> getCargoWidget(List<CargoType> cargos) {
|
||||||
return cargos.map((cargo) {
|
return cargos.map((cargo) {
|
||||||
return Container(
|
return Container(
|
||||||
child: _row(
|
child: _row(cargo.name ?? "", "\$ " + cargo.rate.toStringAsFixed(2),
|
||||||
cargo.name, "\$ " + cargo.rate.toStringAsFixed(2), 'per pound'),
|
'per pound'),
|
||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
@@ -194,7 +193,8 @@ class _ShipmentRatesState extends State<ShipmentRates> {
|
|||||||
List<Widget> getCustonWidget(List<CargoType> customs) {
|
List<Widget> getCustonWidget(List<CargoType> customs) {
|
||||||
return customs.map((c) {
|
return customs.map((c) {
|
||||||
return Container(
|
return Container(
|
||||||
child: _row(c.name, "\$ " + c.customDutyFee.toStringAsFixed(2), ''),
|
child:
|
||||||
|
_row(c.name ?? "", "\$ " + c.customDutyFee.toStringAsFixed(2), ''),
|
||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import 'package:fcs/pages/widgets/local_text.dart';
|
|||||||
import 'package:fcs/pages/widgets/progress.dart';
|
import 'package:fcs/pages/widgets/progress.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class ShipmentRatesCal extends StatefulWidget {
|
class ShipmentRatesCal extends StatefulWidget {
|
||||||
|
|||||||
@@ -35,12 +35,11 @@ class _ShipmentRatesEditState extends State<ShipmentRatesEdit> {
|
|||||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||||
rate = shipmentRateModel.rate;
|
rate = shipmentRateModel.rate;
|
||||||
|
|
||||||
_minWeight.text = rate.freeDeliveryWeight?.toStringAsFixed(2) ?? "";
|
_minWeight.text = rate.freeDeliveryWeight.toStringAsFixed(2);
|
||||||
_deliveryFee.text = rate.deliveryFee?.toStringAsFixed(2) ?? "";
|
_deliveryFee.text = rate.deliveryFee.toStringAsFixed(2);
|
||||||
_volumetricRatio.text = rate.volumetricRatio?.toStringAsFixed(2) ?? "";
|
_volumetricRatio.text = rate.volumetricRatio.toStringAsFixed(2);
|
||||||
_diffDiscountWeight.text =
|
_diffDiscountWeight.text = rate.diffDiscountWeight.toStringAsFixed(2);
|
||||||
rate.diffDiscountWeight?.toStringAsFixed(2) ?? "";
|
_diffWeightRate.text = rate.diffWeightRate.toStringAsFixed(2);
|
||||||
_diffWeightRate.text = rate.diffWeightRate?.toStringAsFixed(2) ?? "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -3,21 +3,20 @@ import 'package:fcs/domain/entities/user.dart';
|
|||||||
import 'package:fcs/pages/main/model/main_model.dart';
|
import 'package:fcs/pages/main/model/main_model.dart';
|
||||||
import 'package:fcs/pages/signin/invitation_request_page.dart';
|
import 'package:fcs/pages/signin/invitation_request_page.dart';
|
||||||
import 'package:fcs/pages/signin/signup_page.dart';
|
import 'package:fcs/pages/signin/signup_page.dart';
|
||||||
import 'package:fcs/pages/widgets/bottom_up_page_route.dart';
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
navigateAfterAuthVerified(BuildContext context) async {
|
navigateAfterAuthVerified(BuildContext context) async {
|
||||||
User user = Provider.of<MainModel>(context, listen: false).user;
|
User? user = Provider.of<MainModel>(context, listen: false).user;
|
||||||
Setting setting = Provider.of<MainModel>(context, listen: false).setting;
|
Setting? setting = Provider.of<MainModel>(context, listen: false).setting;
|
||||||
|
|
||||||
if (setting == null) return;
|
if (setting == null) return;
|
||||||
|
|
||||||
if (user != null && (user.joined || user.requested)) {
|
if (user != null && (user.joined || user.requested)) {
|
||||||
Navigator.pushNamedAndRemoveUntil(context, "/home", (r) => false);
|
Navigator.pushNamedAndRemoveUntil(context, "/home", (r) => false);
|
||||||
} else {
|
} else {
|
||||||
if (setting.inviteRequired) {
|
if (setting.inviteRequired ?? false) {
|
||||||
bool invited =
|
bool invited =
|
||||||
await Provider.of<MainModel>(context, listen: false).hasInvite();
|
await Provider.of<MainModel>(context, listen: false).hasInvite();
|
||||||
if (!invited) {
|
if (!invited) {
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ class _SigninPageState extends State<SigninPage> {
|
|||||||
await navigateAfterAuthVerified(context);
|
await navigateAfterAuthVerified(context);
|
||||||
}
|
}
|
||||||
if (auth.authStatus == AuthStatus.ERROR) {
|
if (auth.authStatus == AuthStatus.ERROR) {
|
||||||
showMsgDialog(context, "Error", auth.authErrorMsg);
|
showMsgDialog(context, "Error", auth.authErrorMsg ?? "");
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showMsgDialog(context, "Error", e.toString());
|
showMsgDialog(context, "Error", e.toString());
|
||||||
|
|||||||
@@ -3,23 +3,12 @@ import 'package:fcs/helpers/theme.dart';
|
|||||||
import 'package:fcs/pages/user_search/user_serach.dart';
|
import 'package:fcs/pages/user_search/user_serach.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
class UserListRow extends StatefulWidget {
|
class UserListRow extends StatelessWidget {
|
||||||
final OnUserRowSelect onUserRowSelect;
|
final OnUserRowSelect? onUserRowSelect;
|
||||||
final User user;
|
final User user;
|
||||||
const UserListRow({this.user, this.onUserRowSelect});
|
const UserListRow({required this.user, this.onUserRowSelect});
|
||||||
|
|
||||||
@override
|
|
||||||
_UserListRowState createState() => _UserListRowState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _UserListRowState extends State<UserListRow> {
|
|
||||||
final double dotSize = 15.0;
|
final double dotSize = 15.0;
|
||||||
User user;
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
this.user = widget.user;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -30,8 +19,7 @@ class _UserListRowState extends State<UserListRow> {
|
|||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (widget.onUserRowSelect != null)
|
if (onUserRowSelect != null) onUserRowSelect!(user);
|
||||||
widget.onUserRowSelect(widget.user);
|
|
||||||
},
|
},
|
||||||
child: Row(
|
child: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
@@ -53,17 +41,17 @@ class _UserListRowState extends State<UserListRow> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
new Text(
|
new Text(
|
||||||
user.name == null ? '' : user.name,
|
user.name ?? "",
|
||||||
style: new TextStyle(
|
style: new TextStyle(
|
||||||
fontSize: 15.0, color: Colors.black),
|
fontSize: 15.0, color: Colors.black),
|
||||||
),
|
),
|
||||||
new Text(
|
new Text(
|
||||||
user.fcsID == null ? "" : user.fcsID,
|
user.fcsID ?? "",
|
||||||
style: new TextStyle(
|
style: new TextStyle(
|
||||||
fontSize: 13.0, color: Colors.grey),
|
fontSize: 13.0, color: Colors.grey),
|
||||||
),
|
),
|
||||||
new Text(
|
new Text(
|
||||||
user.phoneNumber == null ? "" : user.phoneNumber,
|
user.phoneNumber ?? "",
|
||||||
style: new TextStyle(
|
style: new TextStyle(
|
||||||
fontSize: 13.0, color: Colors.grey),
|
fontSize: 13.0, color: Colors.grey),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import 'package:provider/provider.dart';
|
|||||||
typedef OnUserSelect(User suer);
|
typedef OnUserSelect(User suer);
|
||||||
typedef OnUserRowSelect(User suer);
|
typedef OnUserRowSelect(User suer);
|
||||||
|
|
||||||
Future<User> searchUser(BuildContext context,
|
Future<User?> searchUser(BuildContext context,
|
||||||
{OnUserSelect onUserSelect, bool popPage = false}) async =>
|
{required OnUserSelect onUserSelect, bool popPage = false}) async =>
|
||||||
await showSearch<User>(
|
await showSearch<User>(
|
||||||
context: context,
|
context: context,
|
||||||
delegate:
|
delegate:
|
||||||
@@ -20,7 +20,7 @@ class UserSearchDelegate extends SearchDelegate<User> {
|
|||||||
final OnUserSelect onUserSelect;
|
final OnUserSelect onUserSelect;
|
||||||
final bool popPage;
|
final bool popPage;
|
||||||
|
|
||||||
UserSearchDelegate({this.onUserSelect, this.popPage});
|
UserSearchDelegate({required this.onUserSelect, required this.popPage});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get searchFieldLabel => 'Search by FCS ID or Name';
|
String get searchFieldLabel => 'Search by FCS ID or Name';
|
||||||
@@ -31,10 +31,10 @@ class UserSearchDelegate extends SearchDelegate<User> {
|
|||||||
return theme.copyWith(
|
return theme.copyWith(
|
||||||
inputDecorationTheme: InputDecorationTheme(
|
inputDecorationTheme: InputDecorationTheme(
|
||||||
hintStyle: TextStyle(
|
hintStyle: TextStyle(
|
||||||
color: theme.primaryTextTheme.caption.color, fontSize: 14)),
|
color: theme.primaryTextTheme.caption?.color, fontSize: 14)),
|
||||||
textTheme: theme.textTheme.copyWith(
|
textTheme: theme.textTheme.copyWith(
|
||||||
title: theme.textTheme.title.copyWith(
|
title: theme.textTheme.title?.copyWith(
|
||||||
color: theme.primaryTextTheme.title.color, fontSize: 16)),
|
color: theme.primaryTextTheme.title?.color, fontSize: 16)),
|
||||||
primaryColor: primaryColor,
|
primaryColor: primaryColor,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@ class UserSearchDelegate extends SearchDelegate<User> {
|
|||||||
Widget buildLeading(BuildContext context) {
|
Widget buildLeading(BuildContext context) {
|
||||||
return IconButton(
|
return IconButton(
|
||||||
icon: Icon(Icons.arrow_back),
|
icon: Icon(Icons.arrow_back),
|
||||||
onPressed: () => close(context, null),
|
onPressed: () => close(context, new User()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ class UserSearchDelegate extends SearchDelegate<User> {
|
|||||||
future: packageModel.searchUser(query),
|
future: packageModel.searchUser(query),
|
||||||
builder: (context, AsyncSnapshot<List<User>> snapshot) {
|
builder: (context, AsyncSnapshot<List<User>> snapshot) {
|
||||||
if (snapshot.hasData) {
|
if (snapshot.hasData) {
|
||||||
if (snapshot.data.length == 0) {
|
if (snapshot.data == null || snapshot.data!.length == 0) {
|
||||||
return Container(
|
return Container(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
@@ -77,7 +77,7 @@ class UserSearchDelegate extends SearchDelegate<User> {
|
|||||||
return Container(
|
return Container(
|
||||||
padding: EdgeInsets.only(top: 15),
|
padding: EdgeInsets.only(top: 15),
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: snapshot.data
|
children: snapshot.data!
|
||||||
.map((u) => UserListRow(
|
.map((u) => UserListRow(
|
||||||
user: u,
|
user: u,
|
||||||
onUserRowSelect: (u) => _onUserRowSelect(context, u),
|
onUserRowSelect: (u) => _onUserRowSelect(context, u),
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
class FlavorBanner extends StatelessWidget {
|
class FlavorBanner extends StatelessWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
FlavorBanner({@required this.child});
|
FlavorBanner({required this.child});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import 'package:barcode_scan/barcode_scan.dart';
|
import 'package:barcode_scan2/platform_wrapper.dart';
|
||||||
|
|
||||||
Future<String> scanBarcode() async {
|
Future<String?> scanBarcode() async {
|
||||||
try {
|
try {
|
||||||
String barcode = await BarcodeScanner.scan();
|
var scanResult = await BarcodeScanner.scan();
|
||||||
if (barcode == null) return null;
|
String barcode = scanResult.rawContent;
|
||||||
|
|
||||||
String gs = String.fromCharCode(29);
|
String gs = String.fromCharCode(29);
|
||||||
if (barcode.contains(gs)) {
|
if (barcode.contains(gs)) {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class BottomWidgets extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var pkgInfo = Provider.of<MainModel>(context).packageInfo;
|
var pkgInfo = Provider.of<MainModel>(context).packageInfo;
|
||||||
final versionBox = Text(
|
final versionBox = Text(
|
||||||
"v${pkgInfo.version}+${pkgInfo.buildNumber}",
|
"v${pkgInfo?.version}+${pkgInfo?.buildNumber}",
|
||||||
style: TextStyle(color: Colors.white30),
|
style: TextStyle(color: Colors.white30),
|
||||||
);
|
);
|
||||||
return Column(
|
return Column(
|
||||||
|
|||||||
@@ -8,17 +8,26 @@ class DisplayImageSource {
|
|||||||
File? file;
|
File? file;
|
||||||
DisplayImageSource({this.url, this.file});
|
DisplayImageSource({this.url, this.file});
|
||||||
|
|
||||||
ImageProvider? get imageProvider =>
|
ImageProvider get imageProvider {
|
||||||
file == null ? CachedNetworkImageProvider(url!) : FileImage(file!);
|
if (file == null) {
|
||||||
|
return CachedNetworkImageProvider(url!);
|
||||||
|
} else {
|
||||||
|
return FileImage(file!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(other) {
|
bool operator ==(other) {
|
||||||
if (identical(this, other)) {
|
if (identical(this, other) && other is DisplayImageSource) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return (other.file == this.file &&
|
|
||||||
|
return (other is DisplayImageSource &&
|
||||||
|
other.file == this.file &&
|
||||||
(other.file != null || this.file != null)) ||
|
(other.file != null || this.file != null)) ||
|
||||||
(other.url == this.url && (other.url != null || this.url != null));
|
(other is DisplayImageSource &&
|
||||||
|
other.url == this.url &&
|
||||||
|
(other.url != null || this.url != null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import 'local_text.dart';
|
|||||||
|
|
||||||
typedef OnFile = void Function(File);
|
typedef OnFile = void Function(File);
|
||||||
|
|
||||||
modelBottomSheet(BuildContext context, {final OnFile onFile}) {
|
modelBottomSheet(BuildContext context, {final OnFile? onFile}) {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
elevation: 10,
|
elevation: 10,
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
@@ -84,7 +84,7 @@ class _ImageFileState extends State<ImageFile> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pickImage(ImageSource source) async {
|
pickImage(ImageSource source) async {
|
||||||
var tempImage = await ImagePicker.pickImage(source: source);
|
var tempImage = await ImagePicker().pickImage(source: source);
|
||||||
return tempImage;
|
return tempImage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:fcs/helpers/theme.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
@@ -7,19 +8,19 @@ import 'package:image_picker/image_picker.dart';
|
|||||||
|
|
||||||
import 'show_img.dart';
|
import 'show_img.dart';
|
||||||
|
|
||||||
typedef OnFile = void Function(File);
|
typedef OnFile = void Function(File?);
|
||||||
|
|
||||||
class LocalImagePicker extends StatefulWidget {
|
class LocalImagePicker extends StatefulWidget {
|
||||||
final Color color;
|
final Color? color;
|
||||||
final String title;
|
final String title;
|
||||||
final OnFile onFile;
|
final OnFile? onFile;
|
||||||
final bool enabled;
|
final bool enabled;
|
||||||
final String initialImgUrl;
|
final String? initialImgUrl;
|
||||||
final ImageSource imageSource;
|
final ImageSource imageSource;
|
||||||
|
|
||||||
const LocalImagePicker(
|
const LocalImagePicker(
|
||||||
{Key key,
|
{Key? key,
|
||||||
this.title,
|
required this.title,
|
||||||
this.onFile,
|
this.onFile,
|
||||||
this.enabled = true,
|
this.enabled = true,
|
||||||
this.initialImgUrl,
|
this.initialImgUrl,
|
||||||
@@ -31,8 +32,8 @@ class LocalImagePicker extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _LocalImagePickerState extends State<LocalImagePicker> {
|
class _LocalImagePickerState extends State<LocalImagePicker> {
|
||||||
String url;
|
String? url;
|
||||||
File file;
|
File? file;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@@ -56,16 +57,16 @@ class _LocalImagePickerState extends State<LocalImagePicker> {
|
|||||||
await _dialog(
|
await _dialog(
|
||||||
context, () => camera = true, () => gallery = true);
|
context, () => camera = true, () => gallery = true);
|
||||||
if (camera || gallery) {
|
if (camera || gallery) {
|
||||||
var selectedFile = await ImagePicker.pickImage(
|
var selectedFile = await ImagePicker().pickImage(
|
||||||
source: camera ? ImageSource.camera : ImageSource.gallery,
|
source: camera ? ImageSource.camera : ImageSource.gallery,
|
||||||
imageQuality: 80,
|
imageQuality: 80,
|
||||||
maxWidth: 1000);
|
maxWidth: 1000);
|
||||||
if (selectedFile != null) {
|
if (selectedFile != null) {
|
||||||
setState(() {
|
setState(() {
|
||||||
this.file = selectedFile;
|
this.file = File(selectedFile.path);
|
||||||
});
|
});
|
||||||
if (widget.onFile != null) {
|
if (widget.onFile != null) {
|
||||||
widget.onFile(selectedFile);
|
widget.onFile!(File(selectedFile.path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +94,7 @@ class _LocalImagePickerState extends State<LocalImagePicker> {
|
|||||||
this.file = null;
|
this.file = null;
|
||||||
this.url = null;
|
this.url = null;
|
||||||
if (widget.onFile != null) {
|
if (widget.onFile != null) {
|
||||||
widget.onFile(null);
|
widget.onFile!(null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -144,7 +144,8 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
|
|||||||
borderSide: BorderSide(color: primaryColor, width: 1.0),
|
borderSide: BorderSide(color: primaryColor, width: 1.0),
|
||||||
),
|
),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(color: Colors.grey.shade400, width: 1.0),
|
borderSide:
|
||||||
|
BorderSide(color: Colors.grey.shade400, width: 1.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -196,7 +197,8 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
|
|||||||
borderSide: BorderSide(color: primaryColor, width: 1.0),
|
borderSide: BorderSide(color: primaryColor, width: 1.0),
|
||||||
),
|
),
|
||||||
enabledBorder: OutlineInputBorder(
|
enabledBorder: OutlineInputBorder(
|
||||||
borderSide: BorderSide(color: Colors.grey.shade400, width: 1.0),
|
borderSide:
|
||||||
|
BorderSide(color: Colors.grey.shade400, width: 1.0),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -273,7 +275,7 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
|
|||||||
min: 0,
|
min: 0,
|
||||||
max: MAX_FEET,
|
max: MAX_FEET,
|
||||||
divisions: 100,
|
divisions: 100,
|
||||||
label: (_valueFeet ?? 0).round().toString(),
|
label: _valueFeet.round().toString(),
|
||||||
onChanged: (double v) {
|
onChanged: (double v) {
|
||||||
_updateFeet(v);
|
_updateFeet(v);
|
||||||
},
|
},
|
||||||
@@ -301,7 +303,7 @@ class _LengthPickerDialogState extends State<LengthPickerDialog> {
|
|||||||
min: 0,
|
min: 0,
|
||||||
max: widget.displayFeet! ? 11 : MAX_INC,
|
max: widget.displayFeet! ? 11 : MAX_INC,
|
||||||
divisions: 100,
|
divisions: 100,
|
||||||
label: (_valueInc ?? 0).round().toString(),
|
label: _valueInc.round().toString(),
|
||||||
onChanged: (double v) {
|
onChanged: (double v) {
|
||||||
_updateInc(v);
|
_updateInc(v);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import 'display_image_source.dart';
|
|||||||
|
|
||||||
class MultiImgController {
|
class MultiImgController {
|
||||||
List<String> imageUrls = [];
|
List<String> imageUrls = [];
|
||||||
List<File> imageFiles = [];
|
List<File?> imageFiles = [];
|
||||||
List<DisplayImageSource> addedFiles = [];
|
List<DisplayImageSource> addedFiles = [];
|
||||||
List<DisplayImageSource> removedFiles = [];
|
List<DisplayImageSource> removedFiles = [];
|
||||||
|
|
||||||
List<DisplayImageSource> fileContainers = [];
|
List<DisplayImageSource> fileContainers = [];
|
||||||
CallBack callback;
|
CallBack? callback;
|
||||||
MultiImgController() {
|
MultiImgController() {
|
||||||
fileContainers = [];
|
fileContainers = [];
|
||||||
}
|
}
|
||||||
@@ -26,7 +26,7 @@ class MultiImgController {
|
|||||||
fileContainers.add(DisplayImageSource(url: e));
|
fileContainers.add(DisplayImageSource(url: e));
|
||||||
});
|
});
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
callback();
|
callback!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ class MultiImgController {
|
|||||||
fileContainers.add(DisplayImageSource(file: e));
|
fileContainers.add(DisplayImageSource(file: e));
|
||||||
});
|
});
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
callback();
|
callback!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ class MultiImgController {
|
|||||||
// if (fileContainers.contains(fileContainer)) return;
|
// if (fileContainers.contains(fileContainer)) return;
|
||||||
addedFiles.add(fileContainer);
|
addedFiles.add(fileContainer);
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
callback();
|
callback!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ class MultiImgController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
callback();
|
callback!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ dependencies:
|
|||||||
flutter_icons_null_safety: ^1.1.0
|
flutter_icons_null_safety: ^1.1.0
|
||||||
country_icons: ^2.0.2
|
country_icons: ^2.0.2
|
||||||
timeline_list: ^0.0.5
|
timeline_list: ^0.0.5
|
||||||
# barcode_scan: ^2.0.2
|
barcode_scan2: ^4.1.3
|
||||||
barcode_scan2: ^4.1.4
|
barcode_scan2: ^4.1.4
|
||||||
flutter_pdfview: ^1.2.1
|
flutter_pdfview: ^1.2.1
|
||||||
flutter_local_notifications: ^8.2.0
|
flutter_local_notifications: ^8.2.0
|
||||||
|
|||||||
Reference in New Issue
Block a user