436 lines
14 KiB
ReStructuredText
436 lines
14 KiB
ReStructuredText
==================
|
|
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()
|
|
|
|
Carrier Configuration::
|
|
|
|
>>> Configuration = Model.get('carrier.configuration')
|
|
>>> configuration = Configuration(1)
|
|
>>> configuration.quantity_check
|
|
['uls']
|
|
>>> configuration.quantity_check = ['uls', 'cases']
|
|
>>> configuration.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')
|
|
>>> 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')
|
|
Traceback (most recent call last):
|
|
...
|
|
trytond.modules.carrier_load_ul.exceptions.AddUnitLoadError: Cannot force loading UL "8" in Order "1". -
|
|
|
|
|
|
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])
|
|
>>> start_load.execute('pre_do')
|
|
Traceback (most recent call last):
|
|
...
|
|
trytond.exceptions.UserWarning: You have loaded less ULs (3) than expected (4). -
|
|
>>> Model.get('res.user.warning')(user=config.user,
|
|
... name='pending_uls_%s' % load_order.origins, always=True).save()
|
|
>>> start_load.execute('pre_do')
|
|
Traceback (most recent call last):
|
|
...
|
|
trytond.exceptions.UserWarning: You have loaded less Cases (15.0) than expected (20.0). -
|
|
>>> Model.get('res.user.warning')(user=config.user,
|
|
... name='pending_cases_%s' % load_order.origins, 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' |