================== Carrier load Sale ================== Imports:: >>> import datetime >>> from trytond.tests.tools import activate_modules >>> from dateutil.relativedelta import relativedelta >>> from decimal import Decimal >>> from trytond.modules.company.tests.tools import create_company, \ ... get_company >>> from trytond.modules.account.tests.tools import create_fiscalyear, \ ... create_chart, get_accounts, create_tax >>> from trytond.modules.account_invoice.tests.tools import \ ... set_fiscalyear_invoice_sequences, create_payment_term >>> from trytond.modules.stock_unit_load.tests.tools import create_unit_load >>> from trytond.exceptions import UserWarning >>> from proteus import Model, Wizard, Report >>> today = datetime.date.today() Install agro Module:: >>> config = activate_modules('carrier_load_ul') Create company:: >>> _ = create_company() >>> company = get_company() Create fiscal year:: >>> fiscalyear = set_fiscalyear_invoice_sequences( ... create_fiscalyear(company)) >>> fiscalyear.click('create_period') Create chart of accounts:: >>> _ = create_chart(company) >>> accounts = get_accounts(company) >>> revenue = accounts['revenue'] >>> expense = accounts['expense'] Create tax:: >>> tax = create_tax(Decimal('.10')) >>> tax.save() Create account categories:: >>> ProductCategory = Model.get('product.category') >>> account_category = ProductCategory(name="Account Category") >>> account_category.accounting = True >>> account_category.account_expense = expense >>> account_category.account_revenue = revenue >>> account_category.save() >>> account_category_tax, = account_category.duplicate() >>> account_category_tax.customer_taxes.append(tax) >>> account_category_tax.save() Create parties:: >>> Party = Model.get('party.party') >>> customer = Party(name='Customer') >>> customer.save() Create payment term:: >>> payment_term = create_payment_term() >>> payment_term.save() Create carrier:: >>> Carrier = Model.get('carrier') >>> Uom = Model.get('product.uom') >>> Template = Model.get('product.template') >>> carrier = Carrier() >>> unit, = Uom.find([('name', '=', 'Unit')], limit=1) >>> transport_template = Template( ... name='Transport', ... type='service', ... list_price=Decimal(500), ... cost_price=Decimal(0), ... default_uom=unit) >>> transport_template.save() >>> party_carrier = Party(name='Carrier 1') >>> party_carrier.save() >>> carrier.party = party_carrier >>> carrier.carrier_product = transport_template.products[0] >>> carrier.save() >>> carrier_product = carrier.carrier_product.template >>> carrier_product.purchasable = True >>> carrier_product.purchase_uom = carrier_product.default_uom >>> carrier_product.account_category = account_category_tax >>> carrier_product.save() Get warehouse and dock:: >>> Location = Model.get('stock.location') >>> wh, = Location.find([('type', '=', 'warehouse')]) >>> dock = wh.docks.new() >>> dock.name = 'Dock 1' >>> dock.code = 'D1' >>> wh.save() Add other products to unit load:: >>> ProductUom = Model.get('product.uom') >>> unit, = ProductUom.find([('name', '=', 'Unit')]) >>> ProductTemplate = Model.get('product.template') >>> Product = Model.get('product.product') >>> ProductCategory = Model.get('product.category') >>> category = ProductCategory(name='Category') >>> category.save() >>> product = Product() >>> template = ProductTemplate() >>> template.name = 'Plastic Case 30x30' >>> template.categories.append(category) >>> template.default_uom = unit >>> template.type = 'goods' >>> template.salable = True >>> template.list_price = Decimal('10') >>> template.account_category = account_category_tax >>> template.save() >>> product, = template.products >>> product.cost_price = Decimal('5') >>> product.save() Create unit load:: >>> Unitload = Model.get('stock.unit_load') >>> uls = [] >>> main_product = None >>> for x in range(0, 7): ... ul = create_unit_load(config=config, do_state=False, product=main_product, ... default_values={'start_date': datetime.datetime.now() + relativedelta(days=-1)}) ... move = ul.moves.new() ... move.planned_date = today ... move.product = product ... move.quantity = Decimal(2) ... move.from_location = ul.moves[0].from_location ... move.to_location = ul.moves[0].to_location ... move.currency = move.company.currency ... move.unit_price = product.cost_price ... ul.save() ... uls.append(ul) ... if main_product is None: ... main_product = ul.product >>> template = main_product.template >>> template.salable = True >>> template.account_category = account_category_tax >>> template.save() Create sale:: >>> Sale = Model.get('sale.sale') >>> SaleLine = Model.get('sale.line') >>> sale = Sale() >>> sale.party = customer >>> sale.payment_term = payment_term >>> sale.invoice_method = 'order' >>> sale_line = SaleLine() >>> sale.lines.append(sale_line) >>> sale_line.product = main_product >>> sale_line.quantity = 70.0 >>> sale_line.ul_quantity = 2.0 >>> sale_line.cases_quantity = 10 >>> sale_line = SaleLine() >>> sale.lines.append(sale_line) >>> sale_line.type = 'comment' >>> sale_line.description = 'Comment' >>> sale_line = SaleLine() >>> sale.lines.append(sale_line) >>> sale_line.product = main_product >>> sale_line.quantity = 140.0 >>> sale_line.ul_quantity = 4.0 >>> sale_line.cases_quantity = 20 >>> sale.click('quote') >>> import logging >>> sale.click('confirm') >>> sale.click('process') Traceback (most recent call last): ... trytond.exceptions.UserWarning: The Sale "1" has no loads. - >>> sale.click('draft') >>> sale.click('quote') Start loading:: >>> start_load = Wizard('carrier.load.create_wizard', [sale]) Traceback (most recent call last): ... trytond.exceptions.UserError: Sale "1" must be Confirmed or Processing to be loaded. - >>> sale.click('confirm') >>> start_load = Wizard('carrier.load.create_wizard', [sale]) >>> len(start_load.form.lines) 2 >>> start_load.form.dock = sale.warehouse.docks[0] >>> start_load.form.carrier = carrier >>> start_load.form.vehicle_number = 'MX3449' >>> start_load.form.trailer_number = 'AC3460' >>> start_load.form.driver = 'Driver' >>> start_load.form.driver_identifier = 'ID Driver' >>> start_load.form.lines[0].available_ul_quantity 2.0 >>> start_load.form.lines[1].available_ul_quantity 4.0 >>> start_load.form.lines[1].ul_quantity = Decimal(1) >>> start_load.execute('pre_load_') Check load order:: >>> Load = Model.get('carrier.load') >>> Loadorder = Model.get('carrier.load.order') >>> sale.reload() >>> len(sale.load_lines) 2 >>> len(sale.loads) 1 >>> sale.ul_quantity_to_load 3.0 >>> load_order = Loadorder(sale.loads[0].id) >>> load = load_order.load >>> len(load_order.lines) 2 >>> load_order.state 'draft' >>> load_order.sale.id == sale.id True >>> load_order.click('wait') >>> sum(l.ul_quantity for l in load_order.lines) 3.0 >>> loading = Wizard('carrier.load.create_wizard', [sale]) >>> loading.form.load_order = load_order >>> loading.form.lines[0].ul_quantity 3.0 >>> loading.form.lines[0].ul_quantity = Decimal(1) >>> loading.execute('pre_load_') >>> load_order.reload() >>> len(load_order.lines) 2 >>> sum(l.ul_quantity for l in load_order.lines) 4.0 >>> load_order.load.driver 'Driver' >>> load_order.load.driver_identifier 'ID Driver' >>> load_order.origins == ', '.join(l.origin.rec_name for l in load_order.lines) True >>> load.origins == ', '.join(o.origins for o in load.orders) True Check sale:: >>> sale.reload() >>> sale.shipment_method 'manual' >>> sale.invoice_method 'shipment' >>> len(sale.loads) 1 >>> len(sale.load_lines) 2 >>> len(sale.lines[0].load_lines) 1 >>> sale.lines[0].ul_quantity_to_load 0.0 >>> sale.lines[-1].ul_quantity_to_load 2.0 Check UL quantity control:: >>> loading = Wizard('carrier.load.create_wizard', [sale]) >>> loading.form.load_order = load_order >>> loading.form.lines[0].ul_quantity = Decimal(3) >>> loading.execute('pre_load_') Traceback (most recent call last): ... trytond.exceptions.UserError: Cannot exceed quantity of "140u Product @ 1". - Start loading ULs restrictions:: >>> for ul in uls: ... ul.click('assign') ... ul.click('do') >>> start_load = Wizard('carrier.load_uls', [load_order]) >>> start_load.form.ul_code = uls[0].code >>> start_load.execute('load_') >>> start_load.form.ul_code = uls[1].code >>> start_load.execute('load_') >>> start_load.form.ul_code = uls[2].code >>> start_load.execute('load_') >>> start_load.form.loaded_uls 3 >>> start_load.execute('exit') >>> load_order.reload() >>> len(load_order.unit_loads) 3 Load an invalid UL:: >>> ProductUom = Model.get('product.uom') >>> ProductTemplate = Model.get('product.template') >>> Product = Model.get('product.product') >>> UnitLoad = Model.get('stock.unit_load') >>> unit, = ProductUom.find([('name', '=', 'Unit')]) >>> product = Product() >>> template = ProductTemplate() >>> template.name = 'Another product' >>> template.default_uom = unit >>> template.type = 'goods' >>> template.list_price = Decimal('20') >>> template.save() >>> product2, = template.products >>> wrong_ul = UnitLoad(start_date=datetime.datetime.now() + relativedelta(days=-1)) >>> wrong_ul.end_date = wrong_ul.start_date + relativedelta(minutes=5) >>> wrong_ul.production_type = 'location' >>> wrong_ul.warehouse = wh >>> wrong_ul.production_location = uls[0].production_location >>> wrong_ul.product = product2 >>> wrong_ul.cases_quantity = 5 >>> wrong_ul.quantity = Decimal('35.0') >>> wrong_ul.save() >>> wrong_ul.click('do') >>> start_load = Wizard('carrier.load_uls', [load_order]) >>> start_load.form.ul_code = wrong_ul.code >>> start_load.execute('load_') >>> start_load.execute('force') >>> wrong_ul.reload() >>> not wrong_ul.load_line False >>> wrong_ul.click('unload') Finish loading:: >>> sale.click('process') Traceback (most recent call last): ... trytond.exceptions.UserError: Cannot Process Sale "1" with ULs and undone loads. - >>> start_load = Wizard('carrier.load_uls', [load_order]) >>> Model.get('res.user.warning')(user=config.user, ... name='pending_uls_1', always=True).save() >>> start_load.execute('pre_do') >>> load_order.reload() >>> len(load_order.unit_loads) 3 >>> load_order.state 'done' >>> sale.reload() >>> len(sale.shipments) 1 >>> len(sale.invoices) 0 >>> len(sale.shipments[0].outgoing_moves) 6 >>> len(sale.shipments[0].inventory_moves) 6 >>> shipment, = sale.shipments >>> shipment.click('done') >>> sale.reload() >>> len(sale.invoices) 1 >>> invoice, = sale.invoices >>> len(invoice.lines) 2 >>> sum(l.quantity for l in invoice.lines) 105.0 >>> sorted(l.quantity for l in invoice.lines) [35.0, 70.0] Load the other UL of sale:: >>> start_load = Wizard('carrier.load.create_wizard', [sale]) >>> start_load.form.dock = sale.warehouse.docks[0] >>> start_load.form.carrier = carrier >>> start_load.form.vehicle_number = 'MX3449' >>> start_load.form.lines[0].available_ul_quantity 2.0 >>> start_load.execute('pre_load_') >>> sale.reload() >>> len(sale.loads) 2 >>> load_order2, = [o for o in sale.loads if o != load_order] >>> load_order2.sale == sale True >>> start_load = Wizard('carrier.load_uls', [load_order2]) >>> start_load.form.ul_code = uls[3].code >>> start_load.execute('load_') >>> start_load.form.ul_code = uls[4].code >>> start_load.execute('load_') >>> start_load.execute('pre_do') >>> sale.reload() >>> len(sale.shipments) 2 >>> len(sale.invoices) 1 >>> shipment2 = load_order2.shipment >>> len(shipment2.inventory_moves) 4 >>> shipment2.click('done') >>> sale.reload() >>> len(sale.invoices) 2 >>> len(sale.invoices[1].lines) 1 >>> sale.invoices[1].lines[0].quantity 70.0 Check report:: >>> load_sheet = Report('carrier.load.sheet') >>> ext, _, _, name = load_sheet.execute([load], {}) >>> ext 'odt' >>> name 'Load sheet-1'