import 'package:fcs/domain/entities/box.dart'; import 'package:fcs/domain/entities/cargo_type.dart'; import 'package:fcs/domain/entities/custom_duty.dart'; import 'package:fcs/domain/entities/discount.dart'; import 'package:fcs/domain/entities/invoice.dart'; import 'package:fcs/domain/entities/payment_method.dart'; import 'package:fcs/domain/entities/user.dart'; import 'package:fcs/helpers/theme.dart'; import 'package:fcs/localization/app_translations.dart'; import 'package:fcs/pages/discount/discount_list.dart'; import 'package:fcs/pages/discount/model/discount_model.dart'; import 'package:fcs/pages/invoice/invoice_editor.dart'; import 'package:fcs/pages/main/model/language_model.dart'; import 'package:fcs/pages/main/model/main_model.dart'; import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/payment_methods/model/payment_method_model.dart'; import 'package:fcs/pages/rates/custom_list.dart'; import 'package:fcs/pages/rates/model/shipment_rate_model.dart'; import 'package:fcs/pages/user_search/user_serach.dart'; import 'package:fcs/pages/widgets/bottom_up_page_route.dart'; import 'package:fcs/pages/widgets/discount_dropdown.dart'; import 'package:fcs/pages/widgets/display_text.dart'; import 'package:fcs/pages/widgets/fcs_id_icon.dart'; import 'package:fcs/pages/widgets/input_text.dart'; import 'package:fcs/pages/widgets/local_dropdown.dart'; import 'package:fcs/pages/widgets/local_text.dart'; import 'package:fcs/pages/widgets/local_title.dart'; import 'package:fcs/pages/widgets/multi_img_controller.dart'; import 'package:fcs/pages/widgets/multi_img_file.dart'; import 'package:fcs/pages/widgets/my_data_table.dart'; import 'package:fcs/pages/widgets/progress.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_icons/flutter_icons.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; class InvoiceInfoPage extends StatefulWidget { final Invoice invoice; final User customer; InvoiceInfoPage({this.invoice, this.customer}); @override _InvoiceInfoPageState createState() => _InvoiceInfoPageState(); } class _InvoiceInfoPageState extends State { User user; var dateFormatter = new DateFormat('dd MMM yyyy'); TextEditingController _invoiceNumberController = new TextEditingController(); TextEditingController _dateController = new TextEditingController(); TextEditingController _nameController = new TextEditingController(); TextEditingController _phoneController = new TextEditingController(); TextEditingController _discountController = new TextEditingController(); TextEditingController _amountController = new TextEditingController(); TextEditingController _statusController = new TextEditingController(); TextEditingController _customFeeController = new TextEditingController(); MultiImgController multiImgController = MultiImgController(); TextEditingController _descriptionController = new TextEditingController(); TextEditingController _balanceController = new TextEditingController(); Invoice _invoice; bool _isLoading = false; List _boxes = []; bool isSwitched = false; int deliveryfee = 0; double customFee = 0; double total = 0; Discount _discount; bool isNew = false; Discount selectedDiscount; int selectedDiscountAmt; PaymentMethod paymentMethod; double volumetricRatio = 0; List selectedBoxes = []; List customs = []; List _cargoTypes = [ CargoType(id: "1", name: 'General Cargo', weight: 33, rate: 6), CargoType(id: "2", name: 'Medicine', weight: 33, rate: 7), CargoType(id: "3", name: 'Dangerous Cargo', weight: 33, rate: 8) ]; List _receipts = [ "assets/buying_online_with_first_last_name.png", ]; @override void initState() { super.initState(); volumetricRatio = Provider.of(context, listen: false) .rate .volumetricRatio; if (widget.invoice != null) { _invoice = widget.invoice; _invoiceNumberController.text = _invoice.invoiceNumber; _dateController.text = dateFormatter.format(_invoice.invoiceDate); _nameController.text = _invoice.customerName; _phoneController.text = _invoice.customerPhoneNumber; // _amountController.text = _invoice.getAmount.toString(); _amountController.text = _invoice.amount.toString(); _statusController.text = _invoice.status.toString(); _customFeeController.text = '0'; // multiImgController.setImageUrls = _receipts; _descriptionController.text = 'For Electronics goods'; _balanceController.text = (_invoice.amount - _invoice.receipts[0].amount).toString(); // _boxes = _invoice.packages; } else { _dateController.text = dateFormatter.format(DateTime.now()); _amountController.text = '0'; _customFeeController.text = '0'; _descriptionController.text = ''; _balanceController.text = '0'; setState(() { isNew = true; }); } _boxes = [ Box( shipmentNumber: "A202", receiverNumber: "3", receiverName: "Ko Myo Min", boxNumber: "1", rate: 7, packageType: "General", weight: 75, status: "Packed", receiverAddress: '1 Bo Yar Nyunt St.\nDagon Tsp, Yangon', cargoDesc: "Clothes", arrivedDate: DateTime(2020, 6, 1), width: 10, height: 10, length: 10, // packages: packages, // statusHistory: statusHistory, cargoTypes: [ CargoType(name: 'General Cargo', weight: 25), CargoType(name: 'Medicine', weight: 20), CargoType(name: 'Dangerous Cargo', weight: 30) ]), Box( shipmentNumber: "A202", receiverNumber: "3", receiverName: "Ko Myo Min", boxNumber: "2", rate: 7, packageType: "General", weight: 75, status: "Packed", cargoDesc: "Clothes", arrivedDate: DateTime(2020, 6, 1), width: 10, height: 10, length: 10, // statusHistory: statusHistory, // packages: packages, receiverAddress: '1 Bo Yar Nyunt St.\nDagon Tsp, Yangon', cargoTypes: [ CargoType(name: 'General Cargo', weight: 25), CargoType(name: 'Medicine', weight: 20), CargoType(name: 'Dangerous Cargo', weight: 30) ]) ]; } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { final nameBox = DisplayText( iconData: Feather.user, labelTextKey: 'invoice.customer_name', text: user != null ? user.name : 'Ko Nyi'); final fcsIDBox = DisplayText( text: user != null ? user.fcsID : "FCS-KRUTUG", labelTextKey: "box.fcs.id", icon: FcsIDIcon(), ); final statusBox = DisplayText( text: _statusController.text, iconData: Icons.av_timer, labelTextKey: 'invoice.status'); return LocalProgress( inAsyncCall: _isLoading, child: Scaffold( appBar: AppBar( centerTitle: true, leading: new IconButton( icon: new Icon(CupertinoIcons.back, color: primaryColor), onPressed: () => Navigator.of(context).pop(), ), backgroundColor: Colors.white, shadowColor: Colors.transparent, title: LocalText(context, 'invoice.form.title', color: primaryColor, fontSize: 20), actions: [ new IconButton( icon: Icon( Icons.delete, color: primaryColor, ), onPressed: () {}), new IconButton( icon: Icon( Icons.edit, color: primaryColor, ), onPressed: () { Navigator.of(context).push(CupertinoPageRoute( builder: (context) => InvoiceEditor(invoice: _invoice))); }) ], ), body: Padding( padding: const EdgeInsets.all(8.0), child: ListView( children: [ LocalTitle(textKey: "invoice.customer_info"), DisplayText( labelTextKey: 'invoice.date', iconData: Icons.date_range, text: _dateController.text), widget.invoice == null ? Container() : DisplayText( labelTextKey: 'invoice.number', iconData: FontAwesomeIcons.fileInvoice, text: _invoiceNumberController.text), fcsIDBox, nameBox, statusBox, LocalTitle(textKey: "invoice.box_info"), Center(child: Column(children: getCartonRows(context))), SizedBox(height: 20), LocalTitle(textKey: "invoice.custom_fee"), Column(children: getCustomFeeRows(context)), SizedBox(height: 20), LocalTitle(textKey: "invoice.cargo_type"), Column(children: getCargoTableByBox(context)), SizedBox(height: 20), Container( padding: EdgeInsets.only(top: 5, left: 18), child: Row( children: [ Expanded( child: LocalText(context, 'invoice.payment_method', fontSize: 16, color: Colors.grey, fontWeight: FontWeight.bold), ), Text( '${paymentMethod != null ? paymentMethod.accountName : "KBZ Bank"}', style: TextStyle(fontSize: 16)), ], ), ), SizedBox(height: 30), !isNew ? LocalTitle(textKey: "invoice.payment_attachment") : Container(), ], ), ), ), ); } getCartonRows(BuildContext context) { List dataRow = []; dataRow = _boxes.map((box) { return Container( height: 50, decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), padding: const EdgeInsets.only(left: 5.0, right: 5.0, top: 5.0, bottom: 5.0), child: Row( children: [ Expanded( flex: 1, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(box.packageNumber), Text(box.shipmentNumber), ], )), Expanded( flex: 2, child: Text( box.length == null ? "" : box.length.toString() + ' x ' + box.length.toString() + ' x ' + box.height.toString(), textAlign: TextAlign.center)), Expanded( flex: 2, child: Center( child: Text( box.getShipmentWeight(volumetricRatio).toString()))), ], ), ); }).toList(); dataRow.insert( 0, Container( decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), padding: const EdgeInsets.only( left: 5.0, right: 5.0, top: 5.0, bottom: 15.0), child: Row( children: [ Expanded( flex: 1, child: Center( child: LocalText( context, "invoice.box.number", color: Colors.grey, ), )), Expanded( flex: 2, child: Center( child: Text('L x W x H', style: TextStyle(color: Colors.grey)))), Expanded( flex: 2, child: Center( child: LocalText( context, "invoice.shipment_weight", color: Colors.grey, ), )), ], ), )); return dataRow; } getCustomFeeRows(BuildContext context) { customFee = 0; List dataRow = []; dataRow = customs.map((custom) { customFee += custom.fee; return Container( decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), padding: const EdgeInsets.only(left: 5.0, right: 5.0, top: 5.0, bottom: 5.0), child: Row( children: [ Expanded(flex: 2, child: Text('${custom.productType}')), Expanded( flex: 1, child: Text('\$ ${custom.fee}', textAlign: TextAlign.center)), Expanded(child: SizedBox(height: 40)) ], ), ); }).toList(); dataRow.insert( 0, Container( decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), padding: const EdgeInsets.only( left: 5.0, right: 5.0, top: 15.0, bottom: 15.0), child: Row( children: [ Expanded( flex: 2, child: Text('Product', style: TextStyle(color: Colors.grey))), Expanded( flex: 1, child: Text('Fee', textAlign: TextAlign.center, style: TextStyle(color: Colors.grey))), Expanded(flex: 1, child: Container()) ], ), )); dataRow.insert( dataRow.length, Container( padding: const EdgeInsets.only( left: 5.0, right: 5.0, top: 15.0, bottom: 15.0), child: Row( children: [ Expanded( flex: 2, child: Center( child: LocalText( context, 'invoice.total_custom_fee', color: Colors.black, fontWeight: FontWeight.bold, ), ), ), Expanded( flex: 1, child: Center( child: Text('\$ $customFee', textAlign: TextAlign.center, style: TextStyle(fontWeight: FontWeight.bold)))), Expanded( child: Container(), ) ], ), )); return dataRow; } getCargoTableByBox(BuildContext context) { total = 0; List dataRow = _cargoTypes.map((cargo) { var amount = cargo.weight * cargo.rate; total += amount; return Container( decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), padding: const EdgeInsets.only( left: 5.0, right: 5.0, top: 15.0, bottom: 15.0), child: Row( children: [ Expanded(flex: 2, child: Text('${cargo.rate}')), Expanded( flex: 2, child: Text('${cargo.weight} x ${cargo.rate}', textAlign: TextAlign.center)), Expanded( child: Text('\$ $amount', textAlign: TextAlign.end, style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, ))) ], ), ); }).toList(); dataRow.insert( 0, Container( padding: const EdgeInsets.only( left: 5.0, right: 5.0, top: 15.0, bottom: 15.0), decoration: BoxDecoration( border: Border(bottom: BorderSide(color: Colors.grey))), child: Row( children: [ Expanded( flex: 2, child: Text(getLocalString(context, 'invoice.box.cargo_type'), style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: Colors.grey))), Expanded( flex: 2, child: Text( getLocalString(context, 'cargo.weight') + ' x ' + getLocalString(context, 'cargo.rate'), textAlign: TextAlign.center, style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: Colors.grey))), Expanded( child: Text(getLocalString(context, 'invoice.amount'), textAlign: TextAlign.end, style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: Colors.grey))) ], ), )); dataRow.insert( dataRow.length, Container( padding: const EdgeInsets.only( left: 5.0, right: 5.0, top: 10.0, bottom: 10.0), child: Row( children: [ Expanded( flex: 2, child: Center( child: LocalText( context, 'invoice.total', color: Colors.black, ), ), ), Expanded( child: Text( '\$ $total', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), textAlign: TextAlign.end, )) ], ), )); dataRow.insert( dataRow.length, Container( padding: const EdgeInsets.only(left: 5.0, right: 5.0), child: Row( children: [ Expanded( flex: 2, child: Center( child: LocalText( context, 'invoice.discount_value', color: Colors.black, ), ), ), Expanded( child: Text( '\$ ${_discount != null ? _discount.amount.toInt() : 0}', textAlign: TextAlign.end, style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, ))) ], ), )); dataRow.insert( dataRow.length, Container( padding: const EdgeInsets.only( left: 5.0, right: 5.0, top: 10.0, bottom: 0.0), child: Row( children: [ Expanded( flex: 2, child: Center( child: LocalText( context, 'invoice.custom_fee', color: Colors.black, ), )), Expanded( child: Text('\$ $customFee', textAlign: TextAlign.end, style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, )), ), ], ), )); dataRow.insert( dataRow.length, Container( padding: const EdgeInsets.only( left: 5.0, right: 5.0, top: 20.0, bottom: 5.0), child: Row( children: [ Expanded( flex: 2, child: Center( child: LocalText( context, 'invoice.handling_fee', color: Colors.black, ), )), Expanded( child: Text('\$ 10.0', textAlign: TextAlign.end, style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, )), ), ], ), )); dataRow.insert( dataRow.length, Container( padding: const EdgeInsets.only( left: 5.0, right: 5.0, top: 10.0, bottom: 10.0), child: Row( children: [ Expanded( flex: 2, child: Center( child: LocalText( context, 'invoice.delivery_fee', color: Colors.black, ), ), ), Expanded( child: Text('\$ $deliveryfee', textAlign: TextAlign.end, style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, ))) ], ), )); dataRow.insert( dataRow.length, Container( child: Row( children: [ Expanded(child: Text('')), Expanded( flex: 2, child: Divider( thickness: 3, )), ], ))); dataRow.insert( dataRow.length, Container( padding: const EdgeInsets.only( left: 5.0, right: 5.0, top: 10.0, bottom: 10.0), child: Row( children: [ Expanded( flex: 2, child: Center( child: LocalText( context, 'invoice.net_amount', color: Colors.black, fontSize: 15, fontWeight: FontWeight.bold, ), ), ), Expanded( child: Text('\$ ${getTotalBalance(total)}', textAlign: TextAlign.end, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: primaryColor))) ], ), )); dataRow.insert( dataRow.length, Container( padding: const EdgeInsets.only( left: 5.0, right: 5.0, top: 10.0, bottom: 10.0), child: Row( children: [ Expanded( flex: 2, child: Center( child: LocalText( context, 'invoice.balance', color: Colors.black, fontSize: 15, fontWeight: FontWeight.bold, ), ), ), Expanded( child: Text('\$ ${getTotalBalance(total)}', textAlign: TextAlign.end, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: primaryColor))) ], ), )); return dataRow; } getTotalBalance(total) { double balance = 0; double custom = customFee != 0 ? customFee.toDouble() : 0; double deliveryFee = deliveryfee != 0 ? deliveryfee.toDouble() : 0; double discount = _discount != null ? _discount.amount.toDouble() : 0; balance = (total + custom + deliveryFee) - discount; return balance; } List getBoxRow(BuildContext context) { return _boxes.map((p) { p.cargoTypes.map((cargo) { _cargoTypes.asMap().map((index, _cargo) { if (_cargo.id == cargo.id) { setState(() { _cargoTypes[index].weight += cargo.weight; }); } }); }); return MyDataRow( onSelectChanged: (bool selected) {}, cells: [ MyDataCell(Checkbox( value: true, onChanged: (value) { selectedBoxes.add(p); }, )), MyDataCell(new Text( p.boxNumber == null ? "" : '${p.shipmentNumber}-${p.receiverNumber} #${p.boxNumber}', style: textStyle, )), MyDataCell(new Text( p.length == null ? "" : p.length.toString() + ' x ' + p.length.toString() + ' x ' + p.height.toString(), style: textStyle, )), ], ); }).toList(); } List getCargoDataRow(BuildContext context) { return _cargoTypes.asMap().entries.map((c) { var cargo = c.value; var amt = cargo.weight * cargo.rate; return MyDataRow( onSelectChanged: (bool selected) {}, cells: [ MyDataCell(new Text( cargo.name, style: textStyle, )), MyDataCell(new Text( cargo.weight.toString() + ' x ' + cargo.rate.toString(), style: textStyle, )), MyDataCell(new Text( "\$$amt", style: textStyle, )), ], ); }).toList() // .insert(_cargoTypes.length,MyDataRow(cells: [ // MyDataCell(new Text('')), // MyDataCell(new Text('Total')), // MyDataCell(new Text( // "\$5000", // style: textStyle, // )), // ]) // ) ; } }