import 'package:fcs/domain/entities/box.dart'; import 'package:fcs/domain/entities/cargo.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/model/discount_model.dart'; import 'package:fcs/pages/main/model/language_model.dart'; import 'package:fcs/pages/main/model/main_model.dart'; import 'package:fcs/pages/main/util.dart'; import 'package:fcs/pages/payment_methods/model/payment_method_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/input_text.dart'; import 'package:fcs/pages/widgets/local_dropdown.dart'; import 'package:fcs/pages/widgets/local_text.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'; import 'box_addition.dart'; class InvoiceEditor extends StatefulWidget { final Invoice invoice; InvoiceEditor({this.invoice}); @override _InvoiceEditorState createState() => _InvoiceEditorState(); } class _InvoiceEditorState 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 _handlingFeeController = 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; int customFee = 10; double total = 0; Discount _discount; bool isNew = false; Discount selectedDiscount; int selectedDiscountAmt; PaymentMethod paymentMethod; List selectedBoxes = []; List _cargoTypes = [ Cargo(type: 'General Cargo', weight: 33, price: 6), Cargo(type: 'Medicine', weight: 33, price: 7), Cargo(type: 'Dangerous Cargo', weight: 33, price: 8) ]; List _receipts = [ "assets/buying_online_with_first_last_name.png", ]; @override void initState() { super.initState(); 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(); _handlingFeeController.text = '0'; _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'; _handlingFeeController.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: [ Cargo(type: 'General Cargo', weight: 25), Cargo(type: 'Medicine', weight: 20), Cargo(type: '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: [ Cargo(type: 'General Cargo', weight: 25), Cargo(type: 'Medicine', weight: 20), Cargo(type: 'Dangerous Cargo', weight: 30) ]) ]; } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { var mainModel = Provider.of(context); var discountModel = Provider.of(context); var paymentMethodModel = Provider.of(context); final discountBox = Container( child: DiscountDropdown( callback: (v) { setState(() { selectedDiscount = v; }); }, iconData: Entypo.price_ribbon, selectedValue: selectedDiscount, values: discountModel.discounts, )); 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), ), body: Card( child: Column( children: [ Expanded( child: Padding( padding: const EdgeInsets.all(10.0), child: ListView(children: [ 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), widget.invoice == null ? Row( children: [ Expanded( child: DisplayText( text: user != null ? user.name : "", labelTextKey: "invoice.customer_name", iconData: Feather.user, )), IconButton( icon: Icon(Icons.search, color: primaryColor), onPressed: () => searchUser(context, callbackUserSelect: (u) { setState(() { this.user = u; }); })), ], ) : DisplayText( text: _nameController.text, iconData: Feather.user, labelTextKey: 'invoice.customer_name'), InputText( controller: _handlingFeeController, iconData: FontAwesomeIcons.moneyBill, labelTextKey: 'invoice.handling_fee'), SizedBox(height: 15), discountBox, widget.invoice == null ? Container() : DisplayText( text: _statusController.text, iconData: Icons.av_timer, labelTextKey: 'invoice.status'), SizedBox(height: 30), Container( child: Row( children: [ Icon(MaterialCommunityIcons.package, color: primaryColor), SizedBox(width: 10), LocalText( context, "invoice.box_info", color: Colors.grey, fontSize: 20, fontWeight: FontWeight.w700, ), ], ), ), Container( padding: const EdgeInsets.only(top: 15), child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: MyDataTable( headingRowHeight: 40, columnSpacing: 20, columns: [ MyDataColumn( label: Text(''), ), MyDataColumn( label: LocalText( context, "invoice.box.number", color: Colors.grey, ), ), MyDataColumn( label: Text( getLocalString(context, "invoice.box.length") + ' x ' + getLocalString(context, "invoice.box.width") + ' x ' + getLocalString(context, "invoice.box.height"), ), ), ], rows: getBoxRow(context), ), ), ), SizedBox(height: 40), Container( child: Row( children: [ Icon(MaterialCommunityIcons.briefcase_check, color: primaryColor), SizedBox(width: 10), LocalText( context, "invoice.cargo_type", color: Colors.grey, fontSize: 20, fontWeight: FontWeight.w700, ), ], ), ), Container( padding: const EdgeInsets.only(top: 10), child: 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), ), Container( width: 150.0, child: DropdownButtonFormField( icon: Icon(Icons.edit), value: paymentMethod, items: paymentMethodModel.paymentMethods .map((e) => DropdownMenuItem( child: Text(e.name), value: e.name)) .toList(), onChanged: (selected) => {}, ), ), ], ), ), SizedBox(height: 30), !isNew ? Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( child: Row( children: [ Icon(Icons.receipt, color: primaryColor), SizedBox(width: 10), LocalText( context, "invoice.payment_attachment", color: Colors.grey, fontSize: 20, fontWeight: FontWeight.w700, ), ], ), ), Spacer(), Icon(Icons.add, color: primaryColor), ], ) : Container() ]), )), widget.invoice == null ? fcsButton( context, getLocalString(context, 'invoice.btn_create')) : mainModel.isCustomer() ? Container() : Container( child: Column( children: [ fcsButton(context, getLocalString(context, 'invoice.btn_save')) ], )), isNew ? Container() : fcsButton(context, getLocalString(context, 'invoice.btn_payment_receipt')) ], ), ), ), ); } getCargoTableByBox(BuildContext context) { var discountModel = Provider.of(context); total = 0; List dataRow = _cargoTypes.map((cargo) { var amount = cargo.weight * cargo.price; 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.type}')), Expanded( flex: 2, child: Text('${cargo.weight} x ${cargo.price}', 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, top: 10), 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: 20.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: 10.0, bottom: 10.0), child: Row( children: [ Expanded( flex: 1, child: Container( alignment: Alignment.centerRight, child: LocalText( context, 'invoice.delivery_fee', color: Colors.black, ), )), Switch( value: isSwitched, onChanged: (value) { setState(() { isSwitched = value; if (value) { deliveryfee = 5; } else { deliveryfee = 0; } print(isSwitched); }); }, activeTrackColor: primaryColor.withOpacity(0.8), activeColor: primaryColor, ), 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; balance = (total + custom + deliveryFee) - 100.0; return balance; } List getBoxRow(BuildContext context) { return _boxes.map((p) { p.cargoTypes.map((cargo) { _cargoTypes.asMap().map((index, _cargo) { if (_cargo.type == cargo.type) { 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.price; return MyDataRow( onSelectChanged: (bool selected) {}, cells: [ MyDataCell(new Text( cargo.type, style: textStyle, )), MyDataCell(new Text( cargo.weight.toString() + ' x ' + cargo.price.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, // )), // ]) // ) ; } }