Files
enterprise-addons/account_3way_match/tests/test_release_to_pay_invoice.py
T

110 lines
6.1 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import Command, fields
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
from odoo.tests import tagged, Form
@tagged('post_install', '-at_install')
class TestReleaseToPayInvoice(AccountTestInvoicingCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.user.group_ids |= cls.quick_ref('purchase.group_purchase_user')
cls.partner = cls.env['res.partner'].create({'name': 'Zizizapartner'})
cls.product = cls.env['product.product'].create({
'name': 'VR Computer',
'standard_price': 2500.0,
'list_price': 2899.0,
'type': 'service',
'default_code': 'VR-01',
'weight': 1.0,
'purchase_method': 'receive',
})
cls.other_currency = cls.setup_other_currency('HRK', rounding=0.001)
def check_release_to_pay_scenario(self, ordered_qty, scenario, invoicing_policy='receive', order_price=500.0):
""" Generic test function to check that each use scenario behaves properly.
"""
self.product.purchase_method = invoicing_policy
purchase_order = self.env['purchase.order'].create({
'partner_id': self.partner.id,
'order_line': [
(0, 0, {
'name': self.product.name,
'product_id': self.product.id,
'product_qty': ordered_qty,
'product_uom_id': self.product.uom_id.id,
'price_unit': order_price,
'date_planned': fields.Datetime.now(),
})]
})
purchase_order.button_confirm()
invoices_list = []
purchase_line = purchase_order.order_line[-1]
AccountMove = self.env['account.move'].with_context(default_move_type='in_invoice')
for (action, params) in scenario:
if action == 'invoice':
# <field name="purchase_id" invisible="1"/>
move_form = Form(AccountMove.with_context(default_purchase_id=purchase_order.id))
with move_form.invoice_line_ids.edit(0) as line_form:
if 'price' in params:
line_form.price_unit = params['price']
if 'qty' in params:
line_form.quantity = params['qty']
new_invoice = move_form.save()
new_invoice.write({'invoice_line_ids': [
Command.create({'display_type': 'line_section', 'name': 'Section'}),
Command.create({'display_type': 'line_note', 'name': 'Note'}),
]})
invoices_list.append(new_invoice)
self.assertEqual(new_invoice.release_to_pay, params['rslt'], "Wrong invoice release to pay status for scenario " + str(scenario))
elif action == 'receive':
purchase_line.write({'qty_received': params['qty']}) # as the product is a service, its recieved quantity is set manually
if 'rslt' in params:
for (invoice_index, status) in params['rslt']:
self.assertEqual(invoices_list[invoice_index].release_to_pay, status, "Wrong invoice release to pay status for scenario " + str(scenario))
def test_3_way_match(self):
self.check_release_to_pay_scenario(10, [('receive',{'qty': 5}), ('invoice', {'qty': 5, 'rslt': 'yes'})], invoicing_policy='purchase')
self.check_release_to_pay_scenario(10, [('receive',{'qty': 5}), ('invoice', {'qty': 10, 'rslt': 'yes'})], invoicing_policy='purchase')
self.check_release_to_pay_scenario(10, [('invoice', {'qty': 10, 'rslt': 'yes'})], invoicing_policy='purchase')
self.check_release_to_pay_scenario(10, [('invoice', {'qty': 5, 'rslt': 'yes'}), ('receive',{'qty': 5}), ('invoice', {'qty': 6, 'rslt': 'exception'})], invoicing_policy='purchase')
self.check_release_to_pay_scenario(10, [('invoice', {'qty': 10, 'rslt': 'yes'}), ('invoice', {'qty': 10, 'rslt': 'no'})], invoicing_policy='purchase')
self.check_release_to_pay_scenario(10, [('receive',{'qty': 5}), ('invoice', {'qty': 5, 'rslt': 'yes'})])
self.check_release_to_pay_scenario(10, [('receive',{'qty': 5}), ('invoice', {'qty': 10, 'rslt': 'exception'})])
self.check_release_to_pay_scenario(10, [('invoice', {'qty': 5, 'rslt': 'no'})])
self.check_release_to_pay_scenario(10, [('invoice', {'qty': 5, 'rslt': 'no'}), ('receive', {'qty': 5, 'rslt': [(-1, 'yes')]})])
self.check_release_to_pay_scenario(10, [('invoice', {'qty': 5, 'rslt': 'no'}), ('receive', {'qty': 3, 'rslt': [(-1, 'exception')]})])
self.check_release_to_pay_scenario(10, [('invoice', {'qty': 5, 'rslt': 'no'}), ('receive', {'qty': 10, 'rslt': [(-1, 'yes')]})])
# Special use case : a price change between order and invoice should always put the bill in exception
self.check_release_to_pay_scenario(10, [('receive',{'qty': 5}), ('invoice', {'qty': 5, 'rslt': 'exception', 'price':42})])
self.check_release_to_pay_scenario(10, [('receive',{'qty': 5}), ('invoice', {'qty': 5, 'rslt': 'exception', 'price':42})], invoicing_policy='purchase')
def test_amount_currency_edit(self):
"""
Ensure that editing the `amount_currency` of a journal item on an invoice is possible.
In 17.0 changes to Binary fields and web_save were made (related to context key 'bin_size').
They led to tracebacks in the flow tested here.
"""
move_form = Form(self.env['account.move'].with_context(default_move_type='out_invoice'))
move_form.invoice_date = fields.Date.from_string('2023-01-01')
move_form.partner_id = self.partner_a
move_form.currency_id = self.other_currency
with move_form.invoice_line_ids.new() as line_form:
line_form.quantity = 1
line_form.price_unit = 10
move_form.save()
with move_form.line_ids.edit(0) as line_form:
line_form.amount_currency = -30
move_form.save()
self.assertEqual(move_form.line_ids.edit(0).amount_currency, -30)