summaryrefslogtreecommitdiff
path: root/addons/purchase_stock/tests/test_anglo_saxon_valuation_reconciliation.py
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/purchase_stock/tests/test_anglo_saxon_valuation_reconciliation.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/purchase_stock/tests/test_anglo_saxon_valuation_reconciliation.py')
-rw-r--r--addons/purchase_stock/tests/test_anglo_saxon_valuation_reconciliation.py212
1 files changed, 212 insertions, 0 deletions
diff --git a/addons/purchase_stock/tests/test_anglo_saxon_valuation_reconciliation.py b/addons/purchase_stock/tests/test_anglo_saxon_valuation_reconciliation.py
new file mode 100644
index 00000000..b54aedd2
--- /dev/null
+++ b/addons/purchase_stock/tests/test_anglo_saxon_valuation_reconciliation.py
@@ -0,0 +1,212 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+from odoo.addons.stock_account.tests.test_anglo_saxon_valuation_reconciliation_common import ValuationReconciliationTestCommon
+from odoo.tests.common import Form, tagged
+
+
+@tagged('post_install', '-at_install')
+class TestValuationReconciliation(ValuationReconciliationTestCommon):
+
+ @classmethod
+ def setUpClass(cls, chart_template_ref=None):
+ super().setUpClass(chart_template_ref=chart_template_ref)
+
+ cls.stock_account_product_categ.property_account_creditor_price_difference_categ = cls.company_data['default_account_stock_price_diff']
+
+ @classmethod
+ def setup_company_data(cls, company_name, chart_template=None, **kwargs):
+ company_data = super().setup_company_data(company_name, chart_template=chart_template, **kwargs)
+
+ # Create stock config.
+ company_data.update({
+ 'default_account_stock_price_diff': cls.env['account.account'].create({
+ 'name': 'default_account_stock_price_diff',
+ 'code': 'STOCKDIFF',
+ 'reconcile': True,
+ 'user_type_id': cls.env.ref('account.data_account_type_current_assets').id,
+ 'company_id': company_data['company'].id,
+ }),
+ })
+ return company_data
+
+ def _create_purchase(self, product, date, quantity=1.0, set_tax=False, price_unit=66.0):
+ rslt = self.env['purchase.order'].create({
+ 'partner_id': self.partner_a.id,
+ 'currency_id': self.currency_data['currency'].id,
+ 'order_line': [
+ (0, 0, {
+ 'name': product.name,
+ 'product_id': product.id,
+ 'product_qty': quantity,
+ 'product_uom': product.uom_po_id.id,
+ 'price_unit': price_unit,
+ 'date_planned': date,
+ 'taxes_id': [(6, 0, product.supplier_taxes_id.ids)] if set_tax else False,
+ })],
+ 'date_order': date,
+ })
+ rslt.button_confirm()
+ return rslt
+
+ def _create_invoice_for_po(self, purchase_order, date):
+ move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice', default_date=date))
+ move_form.invoice_date = date
+ move_form.partner_id = self.partner_a
+ move_form.currency_id = self.currency_data['currency']
+ move_form.purchase_id = purchase_order
+ return move_form.save()
+
+ def test_shipment_invoice(self):
+ """ Tests the case into which we receive the goods first, and then make the invoice.
+ """
+ test_product = self.test_product_delivery
+ date_po_and_delivery = '2018-01-01'
+
+ purchase_order = self._create_purchase(test_product, date_po_and_delivery)
+ self._process_pickings(purchase_order.picking_ids, date=date_po_and_delivery)
+
+ invoice = self._create_invoice_for_po(purchase_order, '2018-02-02')
+ invoice.action_post()
+ picking = self.env['stock.picking'].search([('purchase_id','=',purchase_order.id)])
+ self.check_reconciliation(invoice, picking)
+ # cancel the invoice
+ invoice.button_cancel()
+
+ def test_invoice_shipment(self):
+ """ Tests the case into which we make the invoice first, and then receive the goods.
+ """
+ # Create a PO and an invoice for it
+ test_product = self.test_product_order
+ purchase_order = self._create_purchase(test_product, '2017-12-01')
+
+ invoice = self._create_invoice_for_po(purchase_order, '2017-12-23')
+ move_form = Form(invoice)
+ with move_form.invoice_line_ids.edit(0) as line_form:
+ line_form.quantity = 1
+ invoice = move_form.save()
+
+ # Validate the invoice and refund the goods
+ invoice.action_post()
+ self._process_pickings(purchase_order.picking_ids, date='2017-12-24')
+ picking = self.env['stock.picking'].search([('purchase_id', '=', purchase_order.id)])
+ self.check_reconciliation(invoice, picking)
+
+ # Return the goods and refund the invoice
+ stock_return_picking_form = Form(self.env['stock.return.picking']
+ .with_context(active_ids=picking.ids, active_id=picking.ids[0],
+ active_model='stock.picking'))
+ stock_return_picking = stock_return_picking_form.save()
+ stock_return_picking.product_return_moves.quantity = 1.0
+ stock_return_picking_action = stock_return_picking.create_returns()
+ return_pick = self.env['stock.picking'].browse(stock_return_picking_action['res_id'])
+ return_pick.action_assign()
+ return_pick.move_lines.quantity_done = 1
+ return_pick._action_done()
+ self._change_pickings_date(return_pick, '2018-01-13')
+
+ # Refund the invoice
+ refund_invoice_wiz = self.env['account.move.reversal'].with_context(active_model="account.move", active_ids=[invoice.id]).create({
+ 'reason': 'test_invoice_shipment_refund',
+ 'refund_method': 'cancel',
+ 'date': '2018-03-15',
+ })
+ refund_invoice = self.env['account.move'].browse(refund_invoice_wiz.reverse_moves()['res_id'])
+
+ # Check the result
+ self.assertEqual(invoice.payment_state, 'reversed', "Invoice should be in 'reversed' state")
+ self.assertEqual(refund_invoice.payment_state, 'paid', "Refund should be in 'paid' state")
+ self.check_reconciliation(refund_invoice, return_pick)
+
+ def test_multiple_shipments_invoices(self):
+ """ Tests the case into which we receive part of the goods first, then 2 invoices at different rates, and finally the remaining quantities
+ """
+ test_product = self.test_product_delivery
+ date_po_and_delivery0 = '2017-01-01'
+ purchase_order = self._create_purchase(test_product, date_po_and_delivery0, quantity=5.0)
+ self._process_pickings(purchase_order.picking_ids, quantity=2.0, date=date_po_and_delivery0)
+ picking = self.env['stock.picking'].search([('purchase_id', '=', purchase_order.id)], order="id asc", limit=1)
+
+ invoice = self._create_invoice_for_po(purchase_order, '2017-01-15')
+ move_form = Form(invoice)
+ with move_form.invoice_line_ids.edit(0) as line_form:
+ line_form.quantity = 3.0
+ invoice = move_form.save()
+ invoice.action_post()
+ self.check_reconciliation(invoice, picking, full_reconcile=False)
+
+ invoice2 = self._create_invoice_for_po(purchase_order, '2017-02-15')
+ move_form = Form(invoice2)
+ with move_form.invoice_line_ids.edit(0) as line_form:
+ line_form.quantity = 2.0
+ invoice2 = move_form.save()
+ invoice2.action_post()
+ self.check_reconciliation(invoice2, picking, full_reconcile=False)
+
+ # We don't need to make the date of processing explicit since the very last rate
+ # will be taken
+ self._process_pickings(purchase_order.picking_ids.filtered(lambda x: x.state != 'done'), quantity=3.0)
+ picking = self.env['stock.picking'].search([('purchase_id', '=', purchase_order.id)], order='id desc', limit=1)
+ self.check_reconciliation(invoice2, picking)
+
+ def test_rounding_discount(self):
+ self.env.ref("product.decimal_discount").digits = 5
+ tax_exclude_id = self.env["account.tax"].create(
+ {
+ "name": "Exclude tax",
+ "amount": "0.00",
+ "type_tax_use": "purchase",
+ }
+ )
+
+ test_product = self.test_product_delivery
+ test_product.supplier_taxes_id = [(6, 0, tax_exclude_id.ids)]
+ date_po_and_delivery = '2018-01-01'
+
+ purchase_order = self._create_purchase(test_product, date_po_and_delivery, quantity=10000, set_tax=True)
+ self._process_pickings(purchase_order.picking_ids, date=date_po_and_delivery)
+
+ invoice = self._create_invoice_for_po(purchase_order, '2018-01-01')
+
+ # Set a discount
+ move_form = Form(invoice)
+ with move_form.invoice_line_ids.edit(0) as line_form:
+ line_form.discount = 0.92431
+ move_form.save()
+
+ invoice.action_post()
+
+ # Check the price difference amount.
+ price_diff_line = invoice.line_ids.filtered(lambda l: l.account_id == self.stock_account_product_categ.property_account_creditor_price_difference_categ)
+ self.assertTrue(len(price_diff_line) == 1, "A price difference line should be created")
+ self.assertAlmostEqual(price_diff_line.price_total, -6100.446)
+
+ picking = self.env['stock.picking'].search([('purchase_id','=',purchase_order.id)])
+ self.check_reconciliation(invoice, picking)
+
+ def test_rounding_price_unit(self):
+ self.env.ref("product.decimal_price").digits = 6
+
+ test_product = self.test_product_delivery
+ date_po_and_delivery = '2018-01-01'
+
+ purchase_order = self._create_purchase(test_product, date_po_and_delivery, quantity=1000000, price_unit=0.0005)
+ self._process_pickings(purchase_order.picking_ids, date=date_po_and_delivery)
+
+ invoice = self._create_invoice_for_po(purchase_order, '2018-01-01')
+
+ # Set a discount
+ move_form = Form(invoice)
+ with move_form.invoice_line_ids.edit(0) as line_form:
+ line_form.price_unit = 0.0006
+ move_form.save()
+
+ invoice.action_post()
+
+ # Check the price difference amount. It's expected that price_unit * qty != price_total.
+ price_diff_line = invoice.line_ids.filtered(lambda l: l.account_id == self.stock_account_product_categ.property_account_creditor_price_difference_categ)
+ self.assertTrue(len(price_diff_line) == 1, "A price difference line should be created")
+ self.assertAlmostEqual(price_diff_line.price_unit, 0.0001)
+ self.assertAlmostEqual(price_diff_line.price_total, 100.0)
+
+ picking = self.env['stock.picking'].search([('purchase_id','=',purchase_order.id)])
+ self.check_reconciliation(invoice, picking)