diff --git a/stock.py b/stock.py index 4d60ff7b79..3dc7b1d442 100644 --- a/stock.py +++ b/stock.py @@ -182,3 +182,17 @@ class Move: else: raise AssertionError('missing account_stock_supplier') return move_lines + + # Remove shipment cost if account_stock_anglo_saxon is installed + @classmethod + def _get_anglo_saxon_move(cls, moves, quantity, type_): + pool = Pool() + Currency = pool.get('currency.currency') + for move, qty, cost_price in super(Move, cls)._get_anglo_saxon_move( + moves, quantity, type_): + if (type_.startswith('in_') + and move.unit_shipment_cost): + shipment_cost = Currency.compute(move.currency, + move.unit_shipment_cost, move.company.currency) + cost_price -= shipment_cost + yield move, qty, cost_price diff --git a/tests/scenario_purchase_shipment_cost_with_account_stock_anglo_saxon.rst b/tests/scenario_purchase_shipment_cost_with_account_stock_anglo_saxon.rst new file mode 100644 index 0000000000..ac2f8c52b6 --- /dev/null +++ b/tests/scenario_purchase_shipment_cost_with_account_stock_anglo_saxon.rst @@ -0,0 +1,288 @@ +============================================================== +Purchase Shipment Cost with Account Stock Anglo-Saxon Scenario +============================================================== + +============= +General Setup +============= + +Imports:: + + >>> import datetime + >>> from dateutil.relativedelta import relativedelta + >>> from decimal import Decimal + >>> from proteus import config, Model, Wizard + >>> today = datetime.date.today() + +Create database:: + + >>> current_config = config.set_trytond() + >>> current_config.pool.test = True + +Install purchase_shipment_cost, account_stock_continental and purchase:: + + >>> Module = Model.get('ir.module.module') + >>> modules = Module.find([ + ... ('name', 'in', ('purchase_shipment_cost', + ... 'account_stock_anglo_saxon', 'purchase')), + ... ]) + >>> Module.install([x.id for x in modules], current_config.context) + >>> Wizard('ir.module.module.install_upgrade').execute('upgrade') + +Create company:: + + >>> Currency = Model.get('currency.currency') + >>> CurrencyRate = Model.get('currency.currency.rate') + >>> Company = Model.get('company.company') + >>> Party = Model.get('party.party') + >>> company_config = Wizard('company.company.config') + >>> company_config.execute('company') + >>> company = company_config.form + >>> party = Party(name='Dunder Mifflin') + >>> party.save() + >>> company.party = party + >>> currencies = Currency.find([('code', '=', 'USD')]) + >>> if not currencies: + ... currency = Currency(name='US Dollar', symbol='$', code='USD', + ... rounding=Decimal('0.01'), mon_grouping='[3, 3, 0]', + ... mon_decimal_point='.') + ... currency.save() + ... CurrencyRate(date=today + relativedelta(month=1, day=1), + ... rate=Decimal('1.0'), currency=currency).save() + ... else: + ... currency, = currencies + >>> company.currency = currency + >>> company_config.execute('add') + >>> company, = Company.find() + +Reload the context:: + + >>> User = Model.get('res.user') + >>> current_config._context = User.get_preferences(True, + ... current_config.context) + +Create an accountant user:: + + >>> Group = Model.get('res.group') + >>> accountant = User() + >>> accountant.name = 'Accountant' + >>> accountant.login = 'accountant' + >>> accountant.password = 'accountant' + >>> account_group, = Group.find([('name', '=', 'Account')]) + >>> accountant.groups.append(account_group) + >>> accountant.save() + +Create fiscal year:: + + >>> FiscalYear = Model.get('account.fiscalyear') + >>> Sequence = Model.get('ir.sequence') + >>> SequenceStrict = Model.get('ir.sequence.strict') + >>> fiscalyear = FiscalYear(name='%s' % today.year) + >>> fiscalyear.start_date = today + relativedelta(month=1, day=1) + >>> fiscalyear.end_date = today + relativedelta(month=12, day=31) + >>> fiscalyear.company = company + >>> post_move_sequence = Sequence(name='%s' % today.year, + ... code='account.move', + ... company=company) + >>> post_move_sequence.save() + >>> fiscalyear.post_move_sequence = post_move_sequence + >>> invoice_sequence = SequenceStrict(name='%s' % today.year, + ... code='account.invoice', + ... company=company) + >>> invoice_sequence.save() + >>> fiscalyear.out_invoice_sequence = invoice_sequence + >>> fiscalyear.in_invoice_sequence = invoice_sequence + >>> fiscalyear.out_credit_note_sequence = invoice_sequence + >>> fiscalyear.in_credit_note_sequence = invoice_sequence + >>> fiscalyear.save() + >>> FiscalYear.create_period([fiscalyear.id], current_config.context) + +Create chart of accounts:: + + >>> AccountTemplate = Model.get('account.account.template') + >>> Account = Model.get('account.account') + >>> AccountJournal = Model.get('account.journal') + >>> account_template, = AccountTemplate.find([('parent', '=', False)]) + >>> create_chart = Wizard('account.create_chart') + >>> create_chart.execute('account') + >>> create_chart.form.account_template = account_template + >>> create_chart.form.company = company + >>> create_chart.execute('create_account') + >>> receivable, = Account.find([ + ... ('kind', '=', 'receivable'), + ... ('company', '=', company.id), + ... ]) + >>> payable, = Account.find([ + ... ('kind', '=', 'payable'), + ... ('company', '=', company.id), + ... ]) + >>> revenue, = Account.find([ + ... ('kind', '=', 'revenue'), + ... ('company', '=', company.id), + ... ]) + >>> expense, = Account.find([ + ... ('kind', '=', 'expense'), + ... ('company', '=', company.id), + ... ]) + >>> (stock, stock_customer, stock_lost_found, stock_production, + ... stock_supplier) = Account.find([ + ... ('kind', '=', 'stock'), + ... ('company', '=', company.id), + ... ('name', 'like', 'Stock%'), + ... ], order=[('name', 'ASC')]) + >>> cogs, = Account.find([ + ... ('kind', '=', 'other'), + ... ('company', '=', company.id), + ... ('name', '=', 'COGS'), + ... ]) + >>> create_chart.form.account_receivable = receivable + >>> create_chart.form.account_payable = payable + >>> create_chart.execute('create_properties') + >>> stock_journal, = AccountJournal.find([('code', '=', 'STO')]) + +Create parties:: + + >>> Party = Model.get('party.party') + >>> supplier = Party(name='Supplier') + >>> supplier.save() + +Create product:: + + >>> ProductUom = Model.get('product.uom') + >>> unit, = ProductUom.find([('name', '=', 'Unit')]) + >>> ProductTemplate = Model.get('product.template') + >>> Product = Model.get('product.product') + >>> product = Product() + >>> template = ProductTemplate() + >>> template.name = 'product' + >>> template.default_uom = unit + >>> template.type = 'goods' + >>> template.purchasable = True + >>> template.list_price = Decimal('10') + >>> template.cost_price = Decimal('5') + >>> template.cost_price_method = 'average' + >>> template.account_expense = expense + >>> template.account_revenue = revenue + >>> template.account_stock = stock + >>> template.account_cogs = cogs + >>> template.account_stock_supplier = stock_supplier + >>> template.account_stock_customer = stock_customer + >>> template.account_stock_production = stock_production + >>> template.account_stock_lost_found = stock_lost_found + >>> template.account_journal_stock_supplier = stock_journal + >>> template.account_journal_stock_customer = stock_journal + >>> template.account_journal_stock_lost_found = stock_journal + >>> template.save() + >>> product.template = template + >>> product.save() + >>> carrier_product = Product() + >>> carrier_template = ProductTemplate() + >>> carrier_template.name = 'Carrier Product' + >>> carrier_template.default_uom = unit + >>> carrier_template.type = 'service' + >>> carrier_template.list_price = Decimal('5') + >>> carrier_template.cost_price = Decimal('3') + >>> carrier_template.account_expense = expense + >>> carrier_template.account_revenue = revenue + >>> carrier_template.save() + >>> carrier_product.template = carrier_template + >>> carrier_product.save() + +Create carrier:: + + >>> Carrier = Model.get('carrier') + >>> carrier = Carrier() + >>> party = Party(name='Carrier') + >>> party.save() + >>> carrier.party = party + >>> carrier.carrier_product = carrier_product + >>> carrier.save() + +Create payment term:: + + >>> PaymentTerm = Model.get('account.invoice.payment_term') + >>> PaymentTermLine = Model.get('account.invoice.payment_term.line') + >>> payment_term = PaymentTerm(name='Direct') + >>> payment_term_line = PaymentTermLine(type='remainder', days=0) + >>> payment_term.lines.append(payment_term_line) + >>> payment_term.save() + +Purchase 5 products:: + + >>> Purchase = Model.get('purchase.purchase') + >>> PurchaseLine = Model.get('purchase.line') + >>> purchase = Purchase() + >>> purchase.party = supplier + >>> purchase.payment_term = payment_term + >>> purchase.invoice_method = 'shipment' + >>> purchase_line = PurchaseLine() + >>> purchase.lines.append(purchase_line) + >>> purchase_line.product = product + >>> purchase_line.quantity = 5.0 + >>> purchase.save() + >>> Purchase.quote([purchase.id], current_config.context) + >>> Purchase.confirm([purchase.id], current_config.context) + >>> purchase.state + u'confirmed' + +Receive 4 products:: + + >>> ShipmentIn = Model.get('stock.shipment.in') + >>> Move = Model.get('stock.move') + >>> shipment = ShipmentIn(supplier=supplier) + >>> move = Move(purchase.moves[0].id) + >>> move.quantity = 4.0 + >>> shipment.incoming_moves.append(move) + >>> shipment.carrier = carrier + >>> shipment.cost == Decimal('3') + True + >>> shipment.cost_currency == currency + True + >>> shipment.save() + >>> ShipmentIn.receive([shipment.id], current_config.context) + >>> shipment.reload() + >>> shipment.state + u'received' + >>> move, = shipment.incoming_moves + >>> move.unit_price == Decimal('5.75') + True + >>> ShipmentIn.done([shipment.id], current_config.context) + >>> shipment.reload() + >>> shipment.state + u'done' + >>> stock_supplier.reload() + >>> stock.reload() + >>> (stock_supplier.debit, stock_supplier.credit) == \ + ... (Decimal('0.00'), Decimal('20.00')) + True + >>> stock.reload() + >>> (stock.debit, stock.credit) == \ + ... (Decimal('23.00'), Decimal('0.00')) + True + >>> expense.reload() + >>> (expense.debit, expense.credit) == \ + ... (Decimal('0.00'), Decimal('3.00')) + True + +Open supplier invoice:: + + >>> Invoice = Model.get('account.invoice') + >>> purchase.reload() + >>> invoice, = purchase.invoices + >>> invoice.invoice_date = today + >>> invoice.save() + >>> Invoice.post([invoice.id], current_config.context) + >>> invoice.state + u'posted' + >>> payable.reload() + >>> (payable.debit, payable.credit) == \ + ... (Decimal('0.00'), Decimal('20.00')) + True + >>> expense.reload() + >>> (expense.debit, expense.credit) == \ + ... (Decimal('20.00'), Decimal('23.00')) + True + >>> stock_supplier.reload() + >>> (stock_supplier.debit, stock_supplier.credit) == \ + ... (Decimal('20.00'), Decimal('20.00')) + True diff --git a/tests/test_purchase_shipment_cost.py b/tests/test_purchase_shipment_cost.py index 7509d67e49..3a51af86ec 100644 --- a/tests/test_purchase_shipment_cost.py +++ b/tests/test_purchase_shipment_cost.py @@ -60,6 +60,10 @@ def suite(): 'scenario_purchase_shipment_cost_with_account_stock.rst', setUp=doctest_dropdb, tearDown=doctest_dropdb, encoding='utf-8', optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) + suite.addTests(doctest.DocFileSuite( + 'scenario_purchase_shipment_cost_with_account_stock_anglo_saxon.rst', + setUp=doctest_dropdb, tearDown=doctest_dropdb, encoding='utf-8', + optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) return suite if __name__ == '__main__': diff --git a/tryton.cfg b/tryton.cfg index fa716b756e..ff340c26b3 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -9,6 +9,7 @@ depends: extras_depend: account_product account_stock_continental + account_stock_anglo_saxon xml: stock.xml carrier.xml