This commit is contained in:
Sai Naw Wun
2020-10-07 02:33:06 +06:30
parent 01a2798a74
commit 65dda16fe6
475 changed files with 1543 additions and 90780 deletions

View File

@@ -1,519 +0,0 @@
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/fcs/common/helpers/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 '../../fcs/common/pages/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;
});
}
}
}

View File

@@ -1,40 +1,23 @@
import 'package:fcs/helpers/theme.dart';
import 'package:fcs/localization/app_translations.dart';
import 'package:fcs/pages/box/model/box_model.dart';
import 'package:fcs/pages/widgets/progress.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:fcs/model/delivery_model.dart';
import 'package:fcs/model/language_model.dart';
import 'package:fcs/model/main_model.dart';
import 'package:fcs/pages/delivery/delivery_item.dart';
import 'package:fcs/fcs/common/pages/util.dart';
import 'package:fcs/fcs/common/helpers/theme.dart';
import 'package:fcs/vo/popup_menu.dart';
import 'package:fcs/widget/localization/app_translations.dart';
import 'package:fcs/widget/popupmenu.dart';
import 'package:fcs/widget/progress.dart';
class DeliveryList extends StatefulWidget {
import 'delivery_list_row.dart';
class DeliverList extends StatefulWidget {
@override
_DeliveryListState createState() => _DeliveryListState();
_DeliverListState createState() => _DeliverListState();
}
class _DeliveryListState extends State<DeliveryList> {
var dateFormatter = new DateFormat('dd MMM yyyy');
final double dotSize = 10.0;
DateTime _selectedDate = DateTime.now();
String status;
int _selectedIndex = 0;
int _dateIndex = 0;
class _DeliverListState extends State<DeliverList> {
bool _isLoading = false;
@override
void initState() {
super.initState();
var doModel = Provider.of<DeliveryModel>(context, listen: false);
_selectedIndex = doModel.popupMenu.index;
_dateIndex = doModel.dateIndex;
_selectedDate = doModel.selectedDate;
}
@override
@@ -42,233 +25,104 @@ class _DeliveryListState extends State<DeliveryList> {
super.dispose();
}
Future<Null> _selectDate(BuildContext context) async {
var deliveryModel = Provider.of<DeliveryModel>(context);
final DateTime picked = await showDatePicker(
context: context,
initialDate: _selectedDate,
firstDate: DateTime(2015, 8),
lastDate: DateTime(2101),
builder: (BuildContext context, Widget child) {
return Theme(
data: ThemeData.light().copyWith(
primaryColor: primaryColor, //Head background
accentColor: secondaryColor, //selection color
dialogBackgroundColor: Colors.white, //Background color
),
child: child,
);
},
);
if (picked != null) {
var pickedDate = new DateTime(picked.year, picked.month, picked.day);
var currentDate = new DateTime(
DateTime.now().year, DateTime.now().month, DateTime.now().day);
this._dateIndex = pickedDate == currentDate ? 0 : 1;
setState(() {
_selectedDate = picked;
deliveryModel.filterData(
status, _selectedDate, _selectedIndex, _dateIndex);
});
}
}
@override
Widget build(BuildContext context) {
var deliveryModel = Provider.of<DeliveryModel>(context);
MainModel mainModel = Provider.of<MainModel>(context);
bool isBuyer = mainModel.user.isBuyer();
var languageModle = Provider.of<LanguageModel>(context);
return Scaffold(
appBar: AppBar(
backgroundColor: primaryColor,
title: Text(
AppTranslations.of(context).text("delivery.title"),
style: languageModle.isEng
? TextStyle()
: TextStyle(fontFamily: 'MyanmarUnicode'),
),
actions: <Widget>[
InkWell(
child: Container(
padding: EdgeInsets.only(top: 15),
child: Stack(
children: <Widget>[
Image.asset(
"assets/date_filter.png",
return LocalProgress(
inAsyncCall: _isLoading,
child: DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
centerTitle: true,
leading: new IconButton(
icon: new Icon(Icons.close),
onPressed: () => Navigator.of(context).pop(),
),
backgroundColor: primaryColor,
title: Text(AppTranslations.of(context).text("delivery")),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.search,
color: Colors.white,
width: 25,
),
_dateIndex == 0
? Container()
: Positioned(
bottom: 15,
right: 10,
child: Container(
width: 10,
height: 10,
decoration: new BoxDecoration(
shape: BoxShape.circle,
color: secondaryColor,
),
),
)
iconSize: 30,
// onPressed: () => showPlacesSearch(context),
),
],
bottom: TabBar(
unselectedLabelColor: Colors.grey,
tabs: [
Tab(
text: "Upcoming",
),
Tab(text: "Delivered"),
],
),
),
onTap: () => _selectDate(context),
),
PopupMenuButton<PopupMenu>(
elevation: 3.2,
onSelected: (selected) {
setState(() {
_selectedIndex = selected.index;
});
if (selected.status == 'All') {
status = null;
} else {
status = selected.status;
}
deliveryModel.filterData(
status, _selectedDate, _selectedIndex, _dateIndex);
},
icon: Container(
width: 30,
height: 30,
decoration: new BoxDecoration(
shape: BoxShape.circle,
color: Colors.white,
),
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Icon(
Icons.filter_list,
color: primaryColor,
),
_selectedIndex != 0
? Positioned(
bottom: 0,
right: 0,
child: Container(
width: 10,
height: 10,
decoration: new BoxDecoration(
shape: BoxShape.circle,
color: secondaryColor,
),
),
)
: Container()
],
)),
itemBuilder: (BuildContext context) {
return deliveryStatusMenu.map((PopupMenu choice) {
return PopupMenuItem<PopupMenu>(
value: choice,
child: Row(
children: <Widget>[
Text(choice.status),
SizedBox(
width: 10,
),
_selectedIndex != null && _selectedIndex == choice.index
? Icon(
Icons.check,
color: Colors.grey,
)
: Container(),
],
),
);
}).toList();
}),
],
),
body: LocalProgress(
inAsyncCall: _isLoading,
child: new ListView.builder(
scrollDirection: Axis.vertical,
padding: EdgeInsets.only(left: 15, right: 15, top: 15),
shrinkWrap: true,
itemCount: deliveryModel.dos.length,
itemBuilder: (BuildContext context, int index) {
return Card(
elevation: 10,
color: Colors.white,
child: Row(
children: <Widget>[
Expanded(
child: InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DeliveryItem(
doSubmission: deliveryModel.dos[index])),
);
},
child: new Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: new Row(
children: <Widget>[
new Padding(
padding: new EdgeInsets.symmetric(
horizontal: 32.0 - dotSize / 2),
child: Image.asset(
"assets/truck.png",
width: 50,
height: 50,
color: primaryColor,
),
),
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
new Text(
deliveryModel.dos[index].doNumber,
style: new TextStyle(
fontSize: 12.0, color: Colors.black),
),
new Text(
deliveryModel.dos[index].deliveryDate ==
null
? ""
: dateFormatter.format(deliveryModel
.dos[index].deliveryDate),
style: new TextStyle(
fontSize: 14.0, color: Colors.grey),
),
!isBuyer
? new Text(
deliveryModel.dos[index].userName,
style: new TextStyle(
fontSize: 12.0,
color: Colors.grey),
)
: Container()
],
),
),
Container(
padding: EdgeInsets.only(right: 15),
child:
getStatus(deliveryModel.dos[index].status),
),
],
),
),
),
),
],
),
);
}),
// floatingActionButton: FloatingActionButton.extended(
// onPressed: () {
// _newPickup();
// },
// icon: Icon(Icons.add),
// label: Text(AppTranslations.of(context).text("boxes.new")),
// backgroundColor: primaryColor,
// ),
body: TabBarView(
children: [
_upComing(),
_completed(),
],
)),
),
);
}
Widget _upComing() {
var boxModel = Provider.of<BoxModel>(context);
return Column(
children: <Widget>[
Expanded(
child: new ListView.separated(
separatorBuilder: (context, index) => Divider(
color: Colors.black,
),
scrollDirection: Axis.vertical,
padding: EdgeInsets.only(top: 15),
shrinkWrap: true,
itemCount: boxModel.upcoming.length,
itemBuilder: (BuildContext context, int index) {
return DeliveryListRow(
box: boxModel.upcoming[index],
isReadOnly: false,
);
}),
),
],
);
}
Widget _completed() {
var boxModel = Provider.of<BoxModel>(context);
return Column(
children: <Widget>[
Expanded(
child: new ListView.separated(
separatorBuilder: (context, index) => Divider(
color: Colors.black,
),
scrollDirection: Axis.vertical,
padding: EdgeInsets.only(top: 15),
shrinkWrap: true,
itemCount: boxModel.completed.length,
itemBuilder: (BuildContext context, int index) {
return DeliveryListRow(
box: boxModel.completed[index],
isReadOnly: false,
);
}),
),
],
);
}
}

View File

@@ -0,0 +1,114 @@
import 'package:fcs/domain/entities/box.dart';
import 'package:fcs/pages/box/box_editor.dart';
import 'package:fcs/pages/main/util.dart';
import 'package:fcs/pages/widgets/bottom_up_page_route.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class DeliveryListRow extends StatefulWidget {
final bool isReadOnly;
final Box box;
const DeliveryListRow({this.box, this.isReadOnly});
@override
_DeliveryListRowState createState() => _DeliveryListRowState();
}
class _DeliveryListRowState extends State<DeliveryListRow> {
final double dotSize = 15.0;
Box _box = new Box();
final DateFormat dateFormat = new DateFormat("dd MMM yyyy");
@override
void initState() {
super.initState();
_box = widget.box;
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.only(left: 15, right: 15),
child: InkWell(
onTap: () {
if (widget.isReadOnly) {
// Navigator.push(
// context,
// BottomUpPageRoute(PackageInfo(package: _box)),
// );
} else {
Navigator.push(
context,
BottomUpPageRoute(BoxEditor(box: _box)),
);
}
},
child: Row(
children: <Widget>[
Expanded(
child: new Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: new Row(
children: <Widget>[
new Expanded(
child: new Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(left: 8.0),
child: new Text(
_box.packageNumber == null
? ''
: _box.packageNumber,
style: new TextStyle(
fontSize: 15.0, color: Colors.black),
),
),
Padding(
padding: const EdgeInsets.only(left: 10.0, top: 10),
child: new Text(
dateFormat.format(_box.arrivedDate),
style: new TextStyle(
fontSize: 15.0, color: Colors.grey),
),
)
],
),
),
],
),
),
),
Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(0),
child: getStatus(_box.status),
),
Padding(
padding: const EdgeInsets.only(left: 8.0, top: 5, bottom: 5),
child: Row(
children: <Widget>[
new Text(
_box.weight == null
? ''
: _box.weight.toString() + 'lb - ',
style:
new TextStyle(fontSize: 15.0, color: Colors.grey),
),
new Text(
_box.price == null ? "" : "\$ " + _box.price.toString(),
style:
new TextStyle(fontSize: 15.0, color: Colors.grey),
),
],
),
),
],
)
],
),
),
);
}
}