Files
fcs/lib/pages/delivery/delivery_item.dart
2020-05-29 07:45:27 +06:30

522 lines
16 KiB
Dart

import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:quiver/async.dart';
import 'package:fcs/model/do_model.dart';
import 'package:fcs/model/language_model.dart';
import 'package:fcs/model/main_model.dart';
import 'package:fcs/model/po_model.dart';
import 'package:fcs/model/product_model.dart';
import 'package:fcs/pages/do/photo_page.dart';
import 'package:fcs/theme/theme.dart';
import 'package:fcs/vo/do.dart';
import 'package:fcs/widget/img_file.dart';
import 'package:fcs/widget/local_text.dart';
import 'package:fcs/widget/localization/app_translations.dart';
import 'package:fcs/widget/my_data_table.dart';
import 'package:fcs/widget/number_cell.dart';
import 'package:fcs/widget/progress.dart';
import '../util.dart';
class DeliveryItem extends StatefulWidget {
final DOSubmission doSubmission;
const DeliveryItem({this.doSubmission});
@override
_DeliveryItemState createState() => _DeliveryItemState();
}
class _DeliveryItemState extends State<DeliveryItem> {
var dateFormatter = new DateFormat('dd MMM yyyy');
final numberFormatter = new NumberFormat("#,###");
bool _isLoading = false;
TextEditingController _date = new TextEditingController();
TextEditingController _number = new TextEditingController();
TextEditingController _licence = new TextEditingController();
TextEditingController _driver = new TextEditingController();
TextEditingController _carNo = new TextEditingController();
TextEditingController _type = new TextEditingController();
TextEditingController _name = new TextEditingController();
TextEditingController _bizName = new TextEditingController();
TextEditingController _storage = new TextEditingController();
TextEditingController _comment = new TextEditingController();
DOSubmission doObj = DOSubmission();
int _count;
DateTime _result;
File storageChargeFile;
File receiptImageFile;
@override
void initState() {
super.initState();
var mainModel = Provider.of<MainModel>(context, listen: false);
var doModel = Provider.of<DOModel>(context, listen: false);
doObj = widget.doSubmission;
_date.text = doObj.deliveryDate != null
? dateFormatter.format(doObj.deliveryDate)
: "";
_number.text = doObj.doNumber.toString();
_licence.text = doObj.driverLicenseNumber;
_driver.text = doObj.driverName;
_carNo.text = doObj.carNo;
_type.text = doObj.type;
_name.text = doObj.userName;
_bizName.text = doObj.bizName;
_storage.text = doObj.storageCharge == null
? ""
: numberFormatter.format(doObj.storageCharge);
_comment.text = doObj.comment;
if (doObj.deliveryStatus == 'initiated') {
_count = doModel.timber;
Duration diff = DateTime.now().difference(doObj.deliveryInitiatedTime);
if (diff.inMinutes < mainModel.setting.deliveryStartWaitMin) {
var time = mainModel.setting.deliveryStartWaitMin - diff.inMinutes;
new CountdownTimer(
new Duration(minutes: time), new Duration(seconds: 1))
.listen((data) {
if (mounted) {
setState(() {
_count = data.remaining.inSeconds;
doModel.addTimber(_count);
});
}
});
}
} else {
_count = 0;
}
_load();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
MainModel mainModel = Provider.of<MainModel>(context);
bool isBuyer = mainModel.user.isBuyer();
String formattedTime;
if (doObj.deliveryStatus == 'initiated') {
_result = DateTime(
doObj.deliveryInitiatedTime.year,
doObj.deliveryInitiatedTime.month,
doObj.deliveryInitiatedTime.day,
doObj.deliveryInitiatedTime.hour,
doObj.deliveryInitiatedTime.minute,
_count);
formattedTime = DateFormat.ms().format(_result);
}
final dateBox = Container(
padding: EdgeInsets.only(left: 20, top: 15),
child: Row(
children: <Widget>[
LocalText(context, "do.date"),
Container(
padding: EdgeInsets.only(left: 10),
child: Text(
_date.text,
style: textStyle,
),
)
],
),
);
final numberBox = Container(
padding: EdgeInsets.only(left: 20, top: 5),
child: Row(
children: <Widget>[
LocalText(context, "do.do_num"),
Container(
padding: EdgeInsets.only(left: 10),
child: Text(
_number.text,
style: textStyle,
),
)
],
),
);
final driverBox = Container(
padding: EdgeInsets.only(left: 20, top: 5),
child: Row(
children: <Widget>[
LocalText(context, "do.driver"),
Container(
padding: EdgeInsets.only(left: 10),
child: Text(
_driver.text,
style: textStyle,
),
)
],
),
);
final carNoBox = Container(
padding: EdgeInsets.only(left: 20, top: 5),
child: Row(
children: <Widget>[
LocalText(context, "do.car"),
Container(
padding: EdgeInsets.only(left: 10),
child: Text(
_carNo.text,
style: textStyle,
),
)
],
),
);
final licenceBox = Container(
padding: EdgeInsets.only(left: 20, top: 5),
child: Row(
children: <Widget>[
LocalText(context, "do.licence"),
ImageFile(
enabled: false,
title: "Image",
initialImgUrl: doObj.driverLicenceUrl,
onFile: (file) {}),
],
),
);
final statusBox = Container(
padding: EdgeInsets.only(left: 20, top: 5),
child: Row(
children: <Widget>[
LocalText(context, "do.status"),
Container(
padding: EdgeInsets.only(left: 10),
child: Text(
doObj.status,
style: doObj.isPending
? textHighlightBlueStyle
: doObj.isApproved
? textHighlightGreenStyle
: textHighlightRedStyle,
),
),
],
),
);
final deliveryStatusBox = Container(
padding: EdgeInsets.only(left: 20, top: 5),
child: Row(
children: <Widget>[
LocalText(context, "do.delivery.status"),
Container(
padding: EdgeInsets.only(left: 10, right: 15),
child: Text(
doObj.getDeliveryStatus,
style: textStyle,
),
),
doObj.deliveryStatus == 'initiated'
? Text(
"(can start in $formattedTime)",
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
)
: Container()
],
),
);
final typeBox = Container(
padding: EdgeInsets.only(left: 20, top: 5),
child: Row(
children: <Widget>[
LocalText(context, "do.type"),
Container(
padding: EdgeInsets.only(left: 20),
child: Text(
_type.text,
style: textStyle,
),
)
],
),
);
final userNameBox = Container(
padding: EdgeInsets.only(top: 5, left: 20),
child: Row(
children: <Widget>[
LocalText(context, "do.name"),
Container(
padding: EdgeInsets.only(left: 20),
child: Text(
_name.text,
style: textStyle,
),
)
],
),
);
final bizNameBox = Container(
padding: EdgeInsets.only(left: 20, top: 5),
child: Row(
children: <Widget>[
LocalText(context, "do.biz"),
Container(
padding: EdgeInsets.only(left: 20),
child: Text(
_bizName.text,
style: textStyle,
),
)
],
),
);
final receiptImagebox = Container(
padding: EdgeInsets.only(left: 20, top: 0),
child: Row(children: <Widget>[
LocalText(context, "do.receipt"),
Container(
padding: EdgeInsets.only(left: 10),
child: ImageFile(
enabled: true,
initialImgUrl: doObj.doReceiptUrl,
title: "Receipt File",
onFile: (file) {
this.receiptImageFile = file;
},
),
),
]));
final storageBox = Container(
padding: EdgeInsets.only(left: 20),
child: Row(
children: <Widget>[
LocalText(context, "do.storage_charge"),
Container(
padding: EdgeInsets.only(left: 10),
child: Text(
_storage.text,
style: textStyle,
),
)
],
),
);
final storagePaymentBox = Container(
padding: EdgeInsets.only(left: 20),
child: Row(children: <Widget>[
LocalText(context, "do.storage_receipt"),
ImageFile(
enabled: false,
title: "Receipt File",
initialImgUrl: this.doObj.storageReceiptUrl,
onFile: (file) {
this.storageChargeFile = file;
}),
]));
final commentBox = Container(
padding: EdgeInsets.only(top: 5, left: 20),
child: Row(
children: <Widget>[
LocalText(context, "do.comment"),
Container(
padding: EdgeInsets.only(left: 10),
child: Text(
_comment.text,
style: textStyle,
),
)
],
),
);
return LocalProgress(
inAsyncCall: _isLoading,
child: Scaffold(
appBar: AppBar(
backgroundColor: primaryColor,
title: Text(AppTranslations.of(context).text("delivery"),
style: Provider.of<LanguageModel>(context).isEng
? TextStyle(fontSize: 18)
: TextStyle(fontSize: 18, fontFamily: 'MyanmarUnicode')),
actions: <Widget>[
isBuyer
? Container()
: PopupMenuButton(
onSelected: _select,
itemBuilder: (context) => List<PopupMenuEntry>.from([
PopupMenuItem(
enabled: this.doObj.isApproved,
value: 5,
child: Text("End Delivery"),
),
]),
),
],
),
body: Container(
padding: EdgeInsets.only(left: 10, right: 10, top: 10, bottom: 10),
child: Card(
elevation: 23,
child: ListView(
children: <Widget>[
Column(
children: <Widget>[
dateBox,
Divider(),
numberBox,
Divider(),
userNameBox,
Divider(),
bizNameBox,
Divider(),
typeBox,
Divider(),
statusBox,
Divider(),
doObj.comment == null || doObj.comment == ''
? Container()
: commentBox,
doObj.comment == null || doObj.comment == ''
? Container()
: Divider(),
driverBox,
Divider(),
carNoBox,
Divider(),
licenceBox,
Divider(),
receiptImagebox,
Divider(),
doObj.hasStorageCharge() ? storageBox : Container(),
doObj.hasStorageCharge() ? Divider() : Container(),
doObj.hasStorageCharge()
? storagePaymentBox
: Container(),
doObj.isApproved || doObj.isClosed
? deliveryStatusBox
: Container(),
doObj.isApproved || doObj.isClosed
? Divider()
: Container(),
Container(
padding: EdgeInsets.only(top: 10),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: MyDataTable(
headingRowHeight: 40,
columnSpacing: 40,
columns: [
MyDataColumn(
label: LocalText(context, "do.product"),
),
MyDataColumn(
label: LocalText(context, "do.storage"),
),
MyDataColumn(
label: LocalText(context, "do.quantity"),numeric: true
),
],
rows: getProductRow(doObj.doLines),
),
),
),
SizedBox(
height: 15,
)
],
),
],
),
),
)),
);
}
List<MyDataRow> getProductRow(List<DOLine> doLines) {
ProductModel productModel = Provider.of<ProductModel>(context);
if (doLines.isNotEmpty) {
doLines.forEach((d) {
productModel.products.forEach((p) {
if (p.id == d.productID) {
d.displayOrder = p.displayOrder;
} else {
return;
}
});
});
doLines.sort((p1, p2) => p1.displayOrder.compareTo(p2.displayOrder));
}
return doLines.map((d) {
return MyDataRow(
cells: [
MyDataCell(
new Text(
d.productName,
style: textStyle,
),
),
MyDataCell(
new Text(d.storageName, style: textStyle),
),
MyDataCell(
NumberCell(d.qty)
),
],
);
}).toList();
}
_select(s) {
if (s == 5) {
if (receiptImageFile == null) {
showMsgDialog(context, "Error", "Please insert delivery receipt file");
return;
}
showConfirmDialog(context, "delivery.confirm", () {
_endDelivery(receiptImageFile);
});
}
}
Future<void> _load() async {
POSubmissionModel poModel =
Provider.of<POSubmissionModel>(context, listen: false);
var _doSub = await poModel.loadDOLines(doObj);
setState(() {
doObj.doLines = _doSub.doLines;
});
}
_endDelivery(dynamic receiptFile) async {
Uint8List bytesPhoto = receiptFile.readAsBytesSync() as Uint8List;
setState(() {
_isLoading = true;
});
try {
DOModel doModel = Provider.of<DOModel>(context);
await doModel.endDelivery(doObj, bytesPhoto);
Navigator.pop(context);
} catch (e) {
showMsgDialog(context, "Error", e.toString());
} finally {
setState(() {
_isLoading = false;
});
}
}
}