first commit
This commit is contained in:
2
modules/account_stock_eu/tests/__init__.py
Normal file
2
modules/account_stock_eu/tests/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,387 @@
|
||||
=================================
|
||||
Account Stock EU Arrival Scenario
|
||||
=================================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> import io
|
||||
>>> import zipfile
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model, Wizard
|
||||
>>> from trytond.modules.account.tests.tools import create_fiscalyear
|
||||
>>> from trytond.modules.company.tests.tools import create_company, get_company
|
||||
>>> from trytond.modules.currency.tests.tools import get_currency
|
||||
>>> from trytond.tests.tools import activate_modules, assertEqual
|
||||
|
||||
>>> intrastat_extended = globals().get('intrastat_extended', False)
|
||||
>>> today = dt.date.today()
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules([
|
||||
... 'account_stock_eu', 'incoterm',
|
||||
... 'stock_shipment_cost', 'purchase_shipment_cost'])
|
||||
|
||||
>>> Carrier = Model.get('carrier')
|
||||
>>> Country = Model.get('country.country')
|
||||
>>> Incoterm = Model.get('incoterm.incoterm')
|
||||
>>> IntrastatDeclaration = Model.get('account.stock.eu.intrastat.declaration')
|
||||
>>> IntrastatDeclarationLine = Model.get(
|
||||
... 'account.stock.eu.intrastat.declaration.line')
|
||||
>>> IntrastatTransport = Model.get('account.stock.eu.intrastat.transport')
|
||||
>>> Organization = Model.get('country.organization')
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> ProductTemplate = Model.get('product.template')
|
||||
>>> ProductUom = Model.get('product.uom')
|
||||
>>> ShipmentIn = Model.get('stock.shipment.in')
|
||||
>>> ShipmentOutReturn = Model.get('stock.shipment.out.return')
|
||||
>>> StockLocation = Model.get('stock.location')
|
||||
>>> TariffCode = Model.get('customs.tariff.code')
|
||||
|
||||
Create countries::
|
||||
|
||||
>>> europe, = Organization.find([('code', '=', 'EU')])
|
||||
>>> belgium = Country(name="Belgium", code='BE')
|
||||
>>> subdivision = belgium.subdivisions.new(
|
||||
... name="Flemish Region", intrastat_code='1', type='region')
|
||||
>>> subdivision = belgium.subdivisions.new(
|
||||
... name="Walloon Region", intrastat_code='2', type='region')
|
||||
>>> belgium.save()
|
||||
>>> flemish, walloon = belgium.subdivisions
|
||||
>>> subdivision = belgium.subdivisions.new(
|
||||
... name="Liège", type='province', parent=walloon)
|
||||
>>> belgium.save()
|
||||
>>> liege, = [s for s in belgium.subdivisions if s.parent == walloon]
|
||||
>>> france = Country(name="France", code='FR')
|
||||
>>> france.save()
|
||||
>>> united_state = Country(name="United State", code='US')
|
||||
>>> united_state.save()
|
||||
|
||||
>>> member = europe.members.new(country=belgium)
|
||||
>>> member = europe.members.new(country=france)
|
||||
>>> europe.save()
|
||||
|
||||
Create currency::
|
||||
|
||||
>>> eur = get_currency('EUR')
|
||||
>>> usd = get_currency('USD')
|
||||
|
||||
Create company in Belgium::
|
||||
|
||||
>>> _ = create_company(currency=eur)
|
||||
>>> company = get_company()
|
||||
>>> company.incoterms.extend(Incoterm.find())
|
||||
>>> company.save()
|
||||
>>> company_address, = company.party.addresses
|
||||
>>> company_address.country = belgium
|
||||
>>> company_address.subdivision = liege
|
||||
>>> company_address.save()
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = create_fiscalyear(company)
|
||||
>>> fiscalyear.intrastat_extended = intrastat_extended
|
||||
>>> fiscalyear.save()
|
||||
|
||||
Create suppliers::
|
||||
|
||||
>>> supplier_be = Party(name="Supplier BE")
|
||||
>>> address, = supplier_be.addresses
|
||||
>>> address.country = belgium
|
||||
>>> identifier = supplier_be.identifiers.new(type='eu_vat')
|
||||
>>> identifier.code = "BE0428759497"
|
||||
>>> supplier_be.save()
|
||||
|
||||
>>> supplier_fr = Party(name="Supplier FR")
|
||||
>>> address, = supplier_fr.addresses
|
||||
>>> address.country = france
|
||||
>>> identifier = supplier_fr.identifiers.new(type='eu_vat')
|
||||
>>> identifier.code = "FR40303265045"
|
||||
>>> supplier_fr.save()
|
||||
|
||||
>>> customer_fr = Party(name="Customer FR")
|
||||
>>> address, = customer_fr.addresses
|
||||
>>> address.country = france
|
||||
>>> customer_fr.save()
|
||||
|
||||
>>> supplier_us = Party(name="Supplier US")
|
||||
>>> address, = supplier_us.addresses
|
||||
>>> address.country = united_state
|
||||
>>> supplier_us.save()
|
||||
|
||||
Create product::
|
||||
|
||||
>>> unit, = ProductUom.find([('name', '=', "Unit")])
|
||||
>>> kg, = ProductUom.find([('name', '=', "Kilogram")])
|
||||
|
||||
>>> tariff_code = TariffCode(code="9403 10 51")
|
||||
>>> tariff_code.description = "Desks"
|
||||
>>> tariff_code.intrastat_uom = unit
|
||||
>>> tariff_code.save()
|
||||
|
||||
>>> template = ProductTemplate(name="Desk")
|
||||
>>> template.default_uom = unit
|
||||
>>> template.type = 'goods'
|
||||
>>> template.cost_price = Decimal('100.0000')
|
||||
>>> _ = template.tariff_codes.new(tariff_code=tariff_code)
|
||||
>>> template.weight = 3
|
||||
>>> template.weight_uom = kg
|
||||
>>> template.save()
|
||||
>>> product, = template.products
|
||||
|
||||
Create carriers::
|
||||
|
||||
>>> carrier_template = ProductTemplate(name="Carrier Product")
|
||||
>>> carrier_template.default_uom = unit
|
||||
>>> carrier_template.type = 'service'
|
||||
>>> carrier_template.list_price = Decimal('5')
|
||||
>>> carrier_template.save()
|
||||
>>> carrier_product, = carrier_template.products
|
||||
|
||||
>>> road_transport, = IntrastatTransport.find([('name', '=', "Road transport")])
|
||||
>>> carrier = Carrier()
|
||||
>>> party = Party(name="Carrier")
|
||||
>>> party.save()
|
||||
>>> carrier.party = party
|
||||
>>> carrier.carrier_product = carrier_product
|
||||
>>> carrier.shipment_cost_allocation_method = 'cost'
|
||||
>>> carrier.intrastat_transport = road_transport
|
||||
>>> carrier.save()
|
||||
|
||||
Get stock locations::
|
||||
|
||||
>>> warehouse_loc, = StockLocation.find([('code', '=', 'WH')])
|
||||
>>> warehouse_loc.address = company_address
|
||||
>>> warehouse_loc.save()
|
||||
|
||||
Receive products from Belgium::
|
||||
|
||||
>>> shipment = ShipmentIn()
|
||||
>>> shipment.supplier = supplier_be
|
||||
>>> move = shipment.incoming_moves.new()
|
||||
>>> move.from_location = shipment.supplier_location
|
||||
>>> move.to_location = shipment.warehouse_input
|
||||
>>> move.product = product
|
||||
>>> move.quantity = 10
|
||||
>>> move.unit_price = Decimal('100.0000')
|
||||
>>> move.currency = eur
|
||||
>>> shipment.click('receive')
|
||||
>>> shipment.click('do')
|
||||
>>> shipment.state
|
||||
'done'
|
||||
|
||||
>>> move, = shipment.incoming_moves
|
||||
>>> move.intrastat_type
|
||||
|
||||
>>> move, = shipment.inventory_moves
|
||||
>>> move.intrastat_type
|
||||
|
||||
Receive products from France::
|
||||
|
||||
>>> shipment = ShipmentIn()
|
||||
>>> shipment.supplier = supplier_fr
|
||||
>>> shipment.incoterm, = Incoterm.find([
|
||||
... ('code', '=', 'EXW'), ('version', '=', '2020')])
|
||||
>>> shipment.incoterm_location = supplier_fr.addresses[0]
|
||||
>>> shipment.carrier = carrier
|
||||
>>> move = shipment.incoming_moves.new()
|
||||
>>> move.from_location = shipment.supplier_location
|
||||
>>> move.to_location = shipment.warehouse_input
|
||||
>>> move.product = product
|
||||
>>> move.quantity = 20
|
||||
>>> move.unit_price = Decimal('90.0000')
|
||||
>>> move.currency = eur
|
||||
>>> shipment.click('receive')
|
||||
>>> shipment.click('do')
|
||||
>>> shipment.state
|
||||
'done'
|
||||
|
||||
>>> move, = shipment.incoming_moves
|
||||
>>> move.intrastat_type
|
||||
'arrival'
|
||||
>>> move.intrastat_warehouse_country.code
|
||||
'BE'
|
||||
>>> move.intrastat_country.code
|
||||
'FR'
|
||||
>>> move.intrastat_subdivision.intrastat_code
|
||||
'2'
|
||||
>>> move.intrastat_tariff_code.code
|
||||
'9403 10 51'
|
||||
>>> move.intrastat_value
|
||||
Decimal('1800.00')
|
||||
>>> move.intrastat_transaction.code
|
||||
'11'
|
||||
>>> move.intrastat_additional_unit
|
||||
20.0
|
||||
>>> move.intrastat_country_of_origin
|
||||
>>> move.intrastat_vat
|
||||
>>> assertEqual(move.intrastat_declaration.month, today.replace(day=1))
|
||||
|
||||
>>> move, = shipment.inventory_moves
|
||||
>>> move.intrastat_type
|
||||
|
||||
Receive products from US::
|
||||
|
||||
>>> shipment = ShipmentIn()
|
||||
>>> shipment.supplier = supplier_us
|
||||
>>> shipment.carrier = carrier
|
||||
>>> move = shipment.incoming_moves.new()
|
||||
>>> move.from_location = shipment.supplier_location
|
||||
>>> move.to_location = shipment.warehouse_input
|
||||
>>> move.product = product
|
||||
>>> move.quantity = 30
|
||||
>>> move.unit_price = Decimal('120.0000')
|
||||
>>> move.currency = usd
|
||||
>>> shipment.click('receive')
|
||||
>>> shipment.click('do')
|
||||
>>> shipment.state
|
||||
'done'
|
||||
|
||||
>>> move, = shipment.incoming_moves
|
||||
>>> move.intrastat_type
|
||||
|
||||
>>> move, = shipment.inventory_moves
|
||||
>>> move.intrastat_type
|
||||
|
||||
Receive returned products from France::
|
||||
|
||||
>>> shipment = ShipmentOutReturn()
|
||||
>>> shipment.customer = customer_fr
|
||||
>>> shipment.carrier = carrier
|
||||
>>> shipment.incoterm, = Incoterm.find([
|
||||
... ('code', '=', 'FCA'), ('version', '=', '2020')])
|
||||
>>> shipment.incoterm_location = warehouse_loc.address
|
||||
>>> move = shipment.incoming_moves.new()
|
||||
>>> move.from_location = shipment.customer_location
|
||||
>>> move.to_location = shipment.warehouse_input
|
||||
>>> move.product = product
|
||||
>>> move.quantity = 5
|
||||
>>> move.unit_price = Decimal('150.0000')
|
||||
>>> move.currency = eur
|
||||
>>> shipment.click('receive')
|
||||
>>> shipment.click('do')
|
||||
>>> shipment.state
|
||||
'done'
|
||||
|
||||
>>> move, = shipment.incoming_moves
|
||||
>>> move.intrastat_type
|
||||
'arrival'
|
||||
>>> move.intrastat_warehouse_country.code
|
||||
'BE'
|
||||
>>> move.intrastat_country.code
|
||||
'FR'
|
||||
>>> move.intrastat_subdivision.intrastat_code
|
||||
'2'
|
||||
>>> move.intrastat_tariff_code.code
|
||||
'9403 10 51'
|
||||
>>> move.intrastat_value
|
||||
Decimal('750.00')
|
||||
>>> move.intrastat_transaction.code
|
||||
'21'
|
||||
>>> move.intrastat_additional_unit
|
||||
5.0
|
||||
>>> move.intrastat_country_of_origin
|
||||
>>> move.intrastat_vat
|
||||
>>> assertEqual(move.intrastat_declaration.month, today.replace(day=1))
|
||||
|
||||
>>> move, = shipment.inventory_moves
|
||||
>>> move.intrastat_type
|
||||
|
||||
Check declaration::
|
||||
|
||||
>>> declaration, = IntrastatDeclaration.find([])
|
||||
>>> declaration.country.code
|
||||
'BE'
|
||||
>>> assertEqual(declaration.month, today.replace(day=1))
|
||||
>>> declaration.state
|
||||
'opened'
|
||||
>>> assertEqual(bool(declaration.extended), intrastat_extended)
|
||||
|
||||
>>> with config.set_context(declaration=declaration.id):
|
||||
... declaration_line, _ = IntrastatDeclarationLine.find([])
|
||||
>>> declaration_line.type
|
||||
'arrival'
|
||||
>>> declaration_line.country.code
|
||||
'FR'
|
||||
>>> declaration_line.subdivision.intrastat_code
|
||||
'2'
|
||||
>>> declaration_line.tariff_code.code
|
||||
'9403 10 51'
|
||||
>>> declaration_line.weight
|
||||
60.0
|
||||
>>> declaration_line.value
|
||||
Decimal('1800.00')
|
||||
>>> declaration_line.transaction.code
|
||||
'11'
|
||||
>>> declaration_line.additional_unit
|
||||
20.0
|
||||
>>> declaration_line.country_of_origin
|
||||
>>> assertEqual(declaration_line.transport, road_transport)
|
||||
>>> declaration_line.incoterm.code
|
||||
'EXW'
|
||||
>>> declaration_line.vat
|
||||
|
||||
Export declaration::
|
||||
|
||||
>>> _ = declaration.click('export')
|
||||
>>> export = Wizard('account.stock.eu.intrastat.declaration.export', [declaration])
|
||||
>>> assertEqual(
|
||||
... export.form.file,
|
||||
... b'19;FR;11;2;9403 10 51;60.0;20.0;1800.00;3;EXW;;\r\n'
|
||||
... b'19;FR;21;2;9403 10 51;15.0;5.0;750.00;3;FCA;;\r\n'
|
||||
... if intrastat_extended else
|
||||
... b'19;FR;11;2;9403 10 51;60.0;20.0;1800.00;;\r\n'
|
||||
... b'19;FR;21;2;9403 10 51;15.0;5.0;750.00;;\r\n')
|
||||
>>> export.form.filename.endswith('.csv')
|
||||
True
|
||||
>>> declaration.state
|
||||
'closed'
|
||||
|
||||
Export declaration as Spain::
|
||||
|
||||
>>> belgium.code = 'ES'
|
||||
>>> belgium.save()
|
||||
|
||||
>>> _ = declaration.click('export')
|
||||
>>> export = Wizard('account.stock.eu.intrastat.declaration.export', [declaration])
|
||||
>>> export.form.filename.endswith('.zip')
|
||||
True
|
||||
>>> zip = zipfile.ZipFile(io.BytesIO(export.form.file))
|
||||
>>> zip.namelist()
|
||||
['arrival-0.csv']
|
||||
>>> assertEqual(
|
||||
... zip.open('arrival-0.csv').read(),
|
||||
... b'FR;2;EXW;11;3;;9403 10 51;;;60.0;20.0;1800.00;1800.00;\r\n'
|
||||
... b'FR;2;FCA;21;3;;9403 10 51;;;15.0;5.0;750.00;750.00;\r\n'
|
||||
... if intrastat_extended else
|
||||
... b'FR;2;;11;;;9403 10 51;;;60.0;20.0;1800.00;1800.00;\r\n'
|
||||
... b'FR;2;;21;;;9403 10 51;;;15.0;5.0;750.00;750.00;\r\n')
|
||||
|
||||
Export declaration as fallback::
|
||||
|
||||
>>> belgium.code = 'XX'
|
||||
>>> belgium.save()
|
||||
|
||||
>>> _ = declaration.click('export')
|
||||
>>> export = Wizard('account.stock.eu.intrastat.declaration.export', [declaration])
|
||||
>>> assertEqual(
|
||||
... export.form.file,
|
||||
... b'arrival,FR,2,9403 10 51,60.0,1800.00,11,20.0,,,3,EXW\r\n'
|
||||
... b'arrival,FR,2,9403 10 51,15.0,750.00,21,5.0,,,3,FCA\r\n'
|
||||
... if intrastat_extended else
|
||||
... b'arrival,FR,2,9403 10 51,60.0,1800.00,11,20.0,,\r\n'
|
||||
... b'arrival,FR,2,9403 10 51,15.0,750.00,21,5.0,,\r\n')
|
||||
>>> export.form.filename.endswith('.csv')
|
||||
True
|
||||
|
||||
Cancelling the shipment reopens the declaration::
|
||||
|
||||
>>> shipment.click('cancel')
|
||||
>>> shipment.state
|
||||
'cancelled'
|
||||
|
||||
>>> declaration.reload()
|
||||
>>> declaration.state
|
||||
'opened'
|
||||
@@ -0,0 +1,398 @@
|
||||
==================================
|
||||
Account Stock EU Dispatch Scenario
|
||||
==================================
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime as dt
|
||||
>>> import io
|
||||
>>> import zipfile
|
||||
>>> from decimal import Decimal
|
||||
|
||||
>>> from proteus import Model, Wizard
|
||||
>>> from trytond.modules.account.tests.tools import create_fiscalyear
|
||||
>>> from trytond.modules.company.tests.tools import create_company, get_company
|
||||
>>> from trytond.modules.currency.tests.tools import get_currency
|
||||
>>> from trytond.tests.tools import activate_modules, assertEqual
|
||||
|
||||
>>> intrastat_extended = globals().get('intrastat_extended', False)
|
||||
>>> today = dt.date.today()
|
||||
|
||||
Activate modules::
|
||||
|
||||
>>> config = activate_modules([
|
||||
... 'account_stock_eu', 'incoterm',
|
||||
... 'stock_shipment_cost', 'stock_package_shipping'])
|
||||
|
||||
>>> Carrier = Model.get('carrier')
|
||||
>>> Country = Model.get('country.country')
|
||||
>>> Incoterm = Model.get('incoterm.incoterm')
|
||||
>>> IntrastatDeclaration = Model.get('account.stock.eu.intrastat.declaration')
|
||||
>>> IntrastatDeclarationLine = Model.get(
|
||||
... 'account.stock.eu.intrastat.declaration.line')
|
||||
>>> IntrastatTransport = Model.get('account.stock.eu.intrastat.transport')
|
||||
>>> Organization = Model.get('country.organization')
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> ProductTemplate = Model.get('product.template')
|
||||
>>> ProductUom = Model.get('product.uom')
|
||||
>>> ShipmentOut = Model.get('stock.shipment.out')
|
||||
>>> ShipmentInReturn = Model.get('stock.shipment.in.return')
|
||||
>>> StockLocation = Model.get('stock.location')
|
||||
>>> TariffCode = Model.get('customs.tariff.code')
|
||||
|
||||
Create countries::
|
||||
|
||||
>>> europe, = Organization.find([('code', '=', 'EU')])
|
||||
>>> belgium = Country(name="Belgium", code='BE')
|
||||
>>> subdivision = belgium.subdivisions.new(
|
||||
... name="Flemish Region", intrastat_code='1', type='region')
|
||||
>>> subdivision = belgium.subdivisions.new(
|
||||
... name="Walloon Region", intrastat_code='2', type='region')
|
||||
>>> belgium.save()
|
||||
>>> flemish, walloon = belgium.subdivisions
|
||||
>>> subdivision = belgium.subdivisions.new(
|
||||
... name="Liège", type='province', parent=walloon)
|
||||
>>> belgium.save()
|
||||
>>> liege, = [s for s in belgium.subdivisions if s.parent == walloon]
|
||||
>>> france = Country(name="France", code='FR')
|
||||
>>> france.save()
|
||||
>>> united_state = Country(name="United State", code='US')
|
||||
>>> united_state.save()
|
||||
>>> china = Country(name="China", code='CN')
|
||||
>>> china.save()
|
||||
|
||||
>>> member = europe.members.new(country=belgium)
|
||||
>>> member = europe.members.new(country=france)
|
||||
>>> europe.save()
|
||||
|
||||
Create currency::
|
||||
|
||||
>>> eur = get_currency('EUR')
|
||||
>>> usd = get_currency('USD')
|
||||
|
||||
Create company in Belgium::
|
||||
|
||||
>>> _ = create_company(currency=eur)
|
||||
>>> company = get_company()
|
||||
>>> company.incoterms.extend(Incoterm.find())
|
||||
>>> company.save()
|
||||
>>> company_address, = company.party.addresses
|
||||
>>> company_address.country = belgium
|
||||
>>> company_address.subdivision = liege
|
||||
>>> company_address.save()
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> fiscalyear = create_fiscalyear(company)
|
||||
>>> fiscalyear.intrastat_extended = intrastat_extended
|
||||
>>> fiscalyear.save()
|
||||
|
||||
Create suppliers::
|
||||
|
||||
>>> customer_be = Party(name="Customer BE")
|
||||
>>> address, = customer_be.addresses
|
||||
>>> address.country = belgium
|
||||
>>> customer_be.save()
|
||||
|
||||
>>> supplier_fr = Party(name="Supplier FR")
|
||||
>>> address, = supplier_fr.addresses
|
||||
>>> address.country = france
|
||||
>>> identifier = supplier_fr.identifiers.new(type='eu_vat')
|
||||
>>> identifier.code = "FR40303265045"
|
||||
>>> supplier_fr.save()
|
||||
|
||||
>>> customer_fr = Party(name="Customer FR")
|
||||
>>> address, = customer_fr.addresses
|
||||
>>> address.country = france
|
||||
>>> customer_fr.save()
|
||||
|
||||
>>> customer_us = Party(name="Customer US")
|
||||
>>> address, = customer_us.addresses
|
||||
>>> address.country = united_state
|
||||
>>> customer_us.save()
|
||||
|
||||
Create product::
|
||||
|
||||
>>> unit, = ProductUom.find([('name', '=', "Unit")])
|
||||
>>> kg, = ProductUom.find([('name', '=', "Kilogram")])
|
||||
|
||||
>>> tariff_code = TariffCode(code="9403 10 51")
|
||||
>>> tariff_code.description = "Desks"
|
||||
>>> tariff_code.intrastat_uom = unit
|
||||
>>> tariff_code.save()
|
||||
|
||||
>>> template = ProductTemplate(name="Desk")
|
||||
>>> template.default_uom = unit
|
||||
>>> template.type = 'goods'
|
||||
>>> template.cost_price = Decimal('100.0000')
|
||||
>>> _ = template.tariff_codes.new(tariff_code=tariff_code)
|
||||
>>> template.weight = 3
|
||||
>>> template.weight_uom = kg
|
||||
>>> template.country_of_origin = china
|
||||
>>> template.save()
|
||||
>>> product, = template.products
|
||||
|
||||
Create carriers::
|
||||
|
||||
>>> carrier_template = ProductTemplate(name="Carrier Product")
|
||||
>>> carrier_template.default_uom = unit
|
||||
>>> carrier_template.type = 'service'
|
||||
>>> carrier_template.list_price = Decimal('5')
|
||||
>>> carrier_template.save()
|
||||
>>> carrier_product, = carrier_template.products
|
||||
|
||||
>>> road_transport, = IntrastatTransport.find([('name', '=', "Road transport")])
|
||||
>>> carrier = Carrier()
|
||||
>>> party = Party(name="Carrier")
|
||||
>>> party.save()
|
||||
>>> carrier.party = party
|
||||
>>> carrier.carrier_product = carrier_product
|
||||
>>> carrier.shipment_cost_allocation_method = 'cost'
|
||||
>>> carrier.intrastat_transport = road_transport
|
||||
>>> carrier.save()
|
||||
|
||||
Get stock locations::
|
||||
|
||||
>>> warehouse_loc, = StockLocation.find([('code', '=', 'WH')])
|
||||
>>> warehouse_loc.address = company_address
|
||||
>>> warehouse_loc.save()
|
||||
|
||||
Send products to Belgium::
|
||||
|
||||
>>> shipment = ShipmentOut()
|
||||
>>> shipment.customer = customer_be
|
||||
>>> shipment.carrier = carrier
|
||||
>>> move = shipment.outgoing_moves.new()
|
||||
>>> move.from_location = shipment.warehouse_output
|
||||
>>> move.to_location = shipment.customer_location
|
||||
>>> move.product = product
|
||||
>>> move.quantity = 10
|
||||
>>> move.unit_price = Decimal('100.0000')
|
||||
>>> move.currency = eur
|
||||
>>> shipment.click('wait')
|
||||
>>> shipment.click('pick')
|
||||
>>> shipment.click('pack')
|
||||
>>> shipment.click('do')
|
||||
>>> shipment.state
|
||||
'done'
|
||||
|
||||
>>> move, = shipment.inventory_moves
|
||||
>>> move.intrastat_type
|
||||
|
||||
>>> move, = shipment.outgoing_moves
|
||||
>>> move.intrastat_type
|
||||
|
||||
Send products to particular to France::
|
||||
|
||||
>>> shipment = ShipmentOut()
|
||||
>>> shipment.customer = customer_fr
|
||||
>>> shipment.carrier = carrier
|
||||
>>> shipment.incoterm, = Incoterm.find([
|
||||
... ('code', '=', 'FCA'), ('version', '=', '2020')])
|
||||
>>> shipment.incoterm_location = shipment.delivery_address
|
||||
>>> move = shipment.outgoing_moves.new()
|
||||
>>> move.from_location = shipment.warehouse_output
|
||||
>>> move.to_location = shipment.customer_location
|
||||
>>> move.product = product
|
||||
>>> move.quantity = 20
|
||||
>>> move.unit_price = Decimal('90.0000')
|
||||
>>> move.currency = eur
|
||||
>>> shipment.click('wait')
|
||||
>>> shipment.click('pick')
|
||||
>>> shipment.click('pack')
|
||||
>>> shipment.click('do')
|
||||
>>> shipment.state
|
||||
'done'
|
||||
|
||||
>>> move, = shipment.inventory_moves
|
||||
>>> move.intrastat_type
|
||||
|
||||
>>> move, = shipment.outgoing_moves
|
||||
>>> move.intrastat_type
|
||||
'dispatch'
|
||||
>>> move.intrastat_warehouse_country.code
|
||||
'BE'
|
||||
>>> move.intrastat_country.code
|
||||
'FR'
|
||||
>>> move.intrastat_subdivision.intrastat_code
|
||||
'2'
|
||||
>>> move.intrastat_tariff_code.code
|
||||
'9403 10 51'
|
||||
>>> move.intrastat_value
|
||||
Decimal('1800.00')
|
||||
>>> move.intrastat_transaction.code
|
||||
'12'
|
||||
>>> move.intrastat_additional_unit
|
||||
20.0
|
||||
>>> move.intrastat_country_of_origin.code
|
||||
'CN'
|
||||
>>> move.intrastat_vat
|
||||
>>> assertEqual(move.intrastat_declaration.month, today.replace(day=1))
|
||||
|
||||
|
||||
Send products to US::
|
||||
|
||||
>>> shipment = ShipmentOut()
|
||||
>>> shipment.customer = customer_us
|
||||
>>> shipment.carrier = carrier
|
||||
>>> move = shipment.outgoing_moves.new()
|
||||
>>> move.from_location = shipment.warehouse_output
|
||||
>>> move.to_location = shipment.customer_location
|
||||
>>> move.product = product
|
||||
>>> move.quantity = 30
|
||||
>>> move.unit_price = Decimal('120.0000')
|
||||
>>> move.currency = usd
|
||||
>>> shipment.click('wait')
|
||||
>>> shipment.click('pick')
|
||||
>>> shipment.click('pack')
|
||||
>>> shipment.click('do')
|
||||
>>> shipment.state
|
||||
'done'
|
||||
|
||||
>>> move, = shipment.inventory_moves
|
||||
>>> move.intrastat_type
|
||||
|
||||
>>> move, = shipment.outgoing_moves
|
||||
>>> move.intrastat_type
|
||||
|
||||
Send returned products to France::
|
||||
|
||||
>>> shipment = ShipmentInReturn()
|
||||
>>> shipment.supplier = supplier_fr
|
||||
>>> shipment.from_location = warehouse_loc.storage_location
|
||||
>>> shipment.carrier = carrier
|
||||
>>> shipment.incoterm, = Incoterm.find([
|
||||
... ('code', '=', 'EXW'), ('version', '=', '2020')])
|
||||
>>> move = shipment.moves.new()
|
||||
>>> move.from_location = shipment.from_location
|
||||
>>> move.to_location = shipment.to_location
|
||||
>>> move.product = product
|
||||
>>> move.quantity = 5
|
||||
>>> move.unit_price = Decimal('150.0000')
|
||||
>>> move.currency = eur
|
||||
>>> shipment.click('wait')
|
||||
>>> shipment.click('assign_force')
|
||||
>>> shipment.click('do')
|
||||
>>> shipment.state
|
||||
'done'
|
||||
|
||||
>>> move, = shipment.moves
|
||||
>>> move.intrastat_type
|
||||
'dispatch'
|
||||
>>> move.intrastat_warehouse_country.code
|
||||
'BE'
|
||||
>>> move.intrastat_country.code
|
||||
'FR'
|
||||
>>> move.intrastat_subdivision.intrastat_code
|
||||
'2'
|
||||
>>> move.intrastat_tariff_code.code
|
||||
'9403 10 51'
|
||||
>>> move.intrastat_value
|
||||
Decimal('750.00')
|
||||
>>> move.intrastat_transaction.code
|
||||
'21'
|
||||
>>> move.intrastat_additional_unit
|
||||
5.0
|
||||
>>> move.intrastat_country_of_origin.code
|
||||
'CN'
|
||||
>>> move.intrastat_vat.code
|
||||
'FR40303265045'
|
||||
>>> assertEqual(move.intrastat_declaration.month, today.replace(day=1))
|
||||
|
||||
Check declaration::
|
||||
|
||||
>>> declaration, = IntrastatDeclaration.find([])
|
||||
>>> declaration.country.code
|
||||
'BE'
|
||||
>>> assertEqual(declaration.month, today.replace(day=1))
|
||||
>>> declaration.state
|
||||
'opened'
|
||||
|
||||
>>> with config.set_context(declaration=declaration.id):
|
||||
... _, declaration_line = IntrastatDeclarationLine.find([])
|
||||
>>> declaration_line.type
|
||||
'dispatch'
|
||||
>>> declaration_line.country.code
|
||||
'FR'
|
||||
>>> declaration_line.subdivision.intrastat_code
|
||||
'2'
|
||||
>>> declaration_line.tariff_code.code
|
||||
'9403 10 51'
|
||||
>>> declaration_line.weight
|
||||
15.0
|
||||
>>> declaration_line.value
|
||||
Decimal('750.00')
|
||||
>>> declaration_line.transaction.code
|
||||
'21'
|
||||
>>> declaration_line.additional_unit
|
||||
5.0
|
||||
>>> declaration_line.country_of_origin.code
|
||||
'CN'
|
||||
>>> declaration_line.vat.code
|
||||
'FR40303265045'
|
||||
>>> assertEqual(declaration_line.transport, road_transport)
|
||||
>>> declaration_line.incoterm.code
|
||||
'EXW'
|
||||
|
||||
Export declaration::
|
||||
|
||||
>>> _ = declaration.click('export')
|
||||
>>> export = Wizard('account.stock.eu.intrastat.declaration.export', [declaration])
|
||||
>>> export.form.filename.endswith('.csv')
|
||||
True
|
||||
>>> assertEqual(
|
||||
... export.form.file,
|
||||
... b'29;FR;12;2;9403 10 51;60.0;20.0;1800.00;3;FCA;CN;\r\n'
|
||||
... b'29;FR;21;2;9403 10 51;15.0;5.0;750.00;3;EXW;CN;FR40303265045\r\n'
|
||||
... if intrastat_extended else
|
||||
... b'29;FR;12;2;9403 10 51;60.0;20.0;1800.00;CN;\r\n'
|
||||
... b'29;FR;21;2;9403 10 51;15.0;5.0;750.00;CN;FR40303265045\r\n')
|
||||
>>> declaration.state
|
||||
'closed'
|
||||
|
||||
Export declaration as Spain::
|
||||
|
||||
>>> belgium.code = 'ES'
|
||||
>>> belgium.save()
|
||||
|
||||
>>> _ = declaration.click('export')
|
||||
>>> export = Wizard('account.stock.eu.intrastat.declaration.export', [declaration])
|
||||
>>> export.form.filename.endswith('.zip')
|
||||
True
|
||||
>>> zip = zipfile.ZipFile(io.BytesIO(export.form.file))
|
||||
>>> zip.namelist()
|
||||
['dispatch-0.csv']
|
||||
>>> assertEqual(
|
||||
... zip.open('dispatch-0.csv').read(),
|
||||
... b'FR;2;FCA;12;3;;9403 10 51;CN;;60.0;20.0;1800.00;1800.00;\r\n'
|
||||
... b'FR;2;EXW;21;3;;9403 10 51;CN;;15.0;5.0;750.00;750.00;FR40303265045\r\n'
|
||||
... if intrastat_extended else
|
||||
... b'FR;2;;12;;;9403 10 51;CN;;60.0;20.0;1800.00;1800.00;\r\n'
|
||||
... b'FR;2;;21;;;9403 10 51;CN;;15.0;5.0;750.00;750.00;FR40303265045\r\n')
|
||||
|
||||
Export declaration as fallback::
|
||||
|
||||
>>> belgium.code = 'XX'
|
||||
>>> belgium.save()
|
||||
|
||||
>>> _ = declaration.click('export')
|
||||
>>> export = Wizard('account.stock.eu.intrastat.declaration.export', [declaration])
|
||||
>>> export.form.filename.endswith('.csv')
|
||||
True
|
||||
>>> assertEqual(
|
||||
... export.form.file,
|
||||
... b'dispatch,FR,2,9403 10 51,60.0,1800.00,12,20.0,CN,,3,FCA\r\n'
|
||||
... b'dispatch,FR,2,9403 10 51,15.0,750.00,21,5.0,CN,FR40303265045,3,EXW\r\n'
|
||||
... if intrastat_extended else
|
||||
... b'dispatch,FR,2,9403 10 51,60.0,1800.00,12,20.0,CN,\r\n'
|
||||
... b'dispatch,FR,2,9403 10 51,15.0,750.00,21,5.0,CN,FR40303265045\r\n')
|
||||
|
||||
Cancelling the shipment reopens the declaration::
|
||||
|
||||
>>> shipment.click('cancel')
|
||||
>>> shipment.state
|
||||
'cancelled'
|
||||
|
||||
>>> declaration.reload()
|
||||
>>> declaration.state
|
||||
'opened'
|
||||
126
modules/account_stock_eu/tests/test_module.py
Normal file
126
modules/account_stock_eu/tests/test_module.py
Normal file
@@ -0,0 +1,126 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
from trytond.modules.account.exceptions import FiscalYearNotFoundError
|
||||
from trytond.pool import Pool
|
||||
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
|
||||
|
||||
|
||||
class AccountStockEuTestCase(ModuleTestCase):
|
||||
"Test Account Stock Eu module"
|
||||
module = 'account_stock_eu'
|
||||
extras = ['carrier', 'incoterm', 'production', 'stock_consignment']
|
||||
|
||||
@with_transaction()
|
||||
def test_sale_incoterm_required(self):
|
||||
"Test incoterm required on sale"
|
||||
pool = Pool()
|
||||
Sale = pool.get('sale.sale')
|
||||
FiscalYear = pool.get('account.fiscalyear')
|
||||
Country = pool.get('country.country')
|
||||
|
||||
from_country = Mock(spec=Country)
|
||||
to_country = Mock(spec=Country)
|
||||
sale = Mock(spec=Sale)
|
||||
sale.warehouse.address.country = from_country
|
||||
sale.shipment_address.country = to_country
|
||||
type(sale)._incoterm_required = Sale._incoterm_required
|
||||
fiscalyear = Mock(spec=FiscalYear)
|
||||
|
||||
with patch.object(FiscalYear, 'find') as fiscalyear_find:
|
||||
fiscalyear_find.return_value = fiscalyear
|
||||
for extended, from_europe, to_europe, result in [
|
||||
(False, False, False, True),
|
||||
(False, False, True, True),
|
||||
(False, True, False, True),
|
||||
(False, True, True, False),
|
||||
(True, False, False, True),
|
||||
(True, False, True, True),
|
||||
(True, True, False, True),
|
||||
(True, True, True, True),
|
||||
(None, False, False, True),
|
||||
(None, False, True, True),
|
||||
(None, True, False, True),
|
||||
(None, True, True, False),
|
||||
]:
|
||||
if extended is not None:
|
||||
fiscalyear_find.side_effect = None
|
||||
fiscalyear.intrastat_extended = extended
|
||||
else:
|
||||
fiscalyear_find.side_effect = FiscalYearNotFoundError('')
|
||||
from_country.is_member.return_value = from_europe
|
||||
to_country.is_member.return_value = to_europe
|
||||
with self.subTest(
|
||||
extended=extended,
|
||||
from_europe=from_europe,
|
||||
to_europe=to_europe):
|
||||
self.assertEqual(sale._incoterm_required, result)
|
||||
|
||||
@with_transaction()
|
||||
def test_sale_incoterm_required_same_country(self):
|
||||
"Test incoterm required on sale with same country"
|
||||
pool = Pool()
|
||||
Sale = pool.get('sale.sale')
|
||||
FiscalYear = pool.get('account.fiscalyear')
|
||||
Country = pool.get('country.country')
|
||||
|
||||
country = Mock(spec=Country)
|
||||
sale = Mock(spec=Sale)
|
||||
sale.warehouse.address.country = country
|
||||
sale.shipment_address.country = country
|
||||
type(sale)._incoterm_required = Sale._incoterm_required
|
||||
fiscalyear = Mock(spec=FiscalYear)
|
||||
|
||||
with patch.object(FiscalYear, 'find') as fiscalyear_find:
|
||||
fiscalyear_find.return_value = fiscalyear
|
||||
for extended, europe, result in [
|
||||
(False, False, False),
|
||||
(False, True, False),
|
||||
(True, False, False),
|
||||
(True, True, False),
|
||||
(None, False, False),
|
||||
(None, True, False),
|
||||
]:
|
||||
if extended is not None:
|
||||
fiscalyear_find.side_effect = None
|
||||
fiscalyear.intrastat_extended = extended
|
||||
else:
|
||||
fiscalyear_find.side_effect = FiscalYearNotFoundError('')
|
||||
country.is_member.return_value = europe
|
||||
with self.subTest(
|
||||
extended=extended,
|
||||
europe=europe):
|
||||
self.assertEqual(sale._incoterm_required, result)
|
||||
|
||||
@with_transaction()
|
||||
def test_sale_incoterm_required_no_country(self):
|
||||
"Test incoterm required on sale without country"
|
||||
pool = Pool()
|
||||
Sale = pool.get('sale.sale')
|
||||
FiscalYear = pool.get('account.fiscalyear')
|
||||
|
||||
sale = Mock(spec=Sale)
|
||||
sale.warehouse.address.country = None
|
||||
sale.shipment_address.country = None
|
||||
type(sale)._incoterm_required = Sale._incoterm_required
|
||||
fiscalyear = Mock(spec=FiscalYear)
|
||||
|
||||
with patch.object(FiscalYear, 'find') as fiscalyear_find:
|
||||
fiscalyear_find.return_value = fiscalyear
|
||||
|
||||
for extended, result in [
|
||||
(False, False),
|
||||
(True, False),
|
||||
(None, False),
|
||||
]:
|
||||
if extended is not None:
|
||||
fiscalyear_find.side_effect = None
|
||||
fiscalyear.intrastat_extended = extended
|
||||
else:
|
||||
fiscalyear_find.side_effect = FiscalYearNotFoundError('')
|
||||
with self.subTest(extended=extended):
|
||||
self.assertEqual(sale._incoterm_required, result)
|
||||
|
||||
|
||||
del ModuleTestCase
|
||||
8
modules/account_stock_eu/tests/test_scenario.py
Normal file
8
modules/account_stock_eu/tests/test_scenario.py
Normal file
@@ -0,0 +1,8 @@
|
||||
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
# this repository contains the full copyright notices and license terms.
|
||||
|
||||
from trytond.tests.test_tryton import load_doc_tests
|
||||
|
||||
|
||||
def load_tests(*args, **kwargs):
|
||||
return load_doc_tests(__name__, __file__, *args, **kwargs)
|
||||
Reference in New Issue
Block a user