summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorwan <wan@odoo.com>2021-04-02 10:33:24 +0000
committerwan <wan@odoo.com>2021-04-12 18:19:00 +0000
commitfcaa54939e9a4f0dd5e47cd0ccffe7aa24bd451c (patch)
tree04953cd19b1bcb09648fc88624c3da7e403fc706 /addons
parent14abcfa92cd37db82338f9a933221142026a78bd (diff)
[FIX] account: never set default for invoice_date
For customer invoices: * do not set default date because if you prepare an invoice (and it gets a default date), then validate it the next day, the date will be wrong * set the date when posting if it wasn't set, because why not? For vendor bills: * do not set default date because you rarely encode a bill at the bill date. Forcing the user to enter it reduces risks of user error (duplicated vendor bill) * do not set it when posting, same reason. opw-2492862 Related #68368 Closes #68367 closes odoo/odoo#68689 Related: odoo/enterprise#17502 Signed-off-by: Laurent Smet <smetl@users.noreply.github.com>
Diffstat (limited to 'addons')
-rw-r--r--addons/account/i18n/account.pot6
-rw-r--r--addons/account/models/account_move.py20
-rw-r--r--addons/product_margin/tests/test_product_margin.py1
-rw-r--r--addons/purchase/tests/test_purchase_order_report.py1
-rw-r--r--addons/purchase_stock/tests/test_purchase_order.py2
-rw-r--r--addons/purchase_stock/tests/test_stockvaluation.py7
-rw-r--r--addons/sale/tests/test_reinvoice.py7
-rw-r--r--addons/sale/tests/test_sale_order.py1
-rw-r--r--addons/sale_timesheet/tests/test_reinvoice.py17
-rw-r--r--addons/stock_dropshipping/tests/test_stockvaluation.py1
-rw-r--r--addons/stock_landed_costs/tests/test_stock_landed_costs_purchase.py1
-rw-r--r--addons/stock_landed_costs/tests/test_stockvaluationlayer.py7
12 files changed, 57 insertions, 14 deletions
diff --git a/addons/account/i18n/account.pot b/addons/account/i18n/account.pot
index 521986c0a3f..084130b171c 100644
--- a/addons/account/i18n/account.pot
+++ b/addons/account/i18n/account.pot
@@ -11475,6 +11475,12 @@ msgid ""
msgstr ""
#. module: account
+#: code:addons/account/models/account_move.py:0
+#, python-format
+msgid "The Bill/Refund date is required to validate this document."
+msgstr ""
+
+#. module: account
#: model:ir.model.fields,help:account.field_account_bank_statement__country_code
#: model:ir.model.fields,help:account.field_account_bank_statement_line__country_code
#: model:ir.model.fields,help:account.field_account_journal__country_code
diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py
index f44cfcc7140..a6a9c7d4358 100644
--- a/addons/account/models/account_move.py
+++ b/addons/account/models/account_move.py
@@ -104,8 +104,10 @@ class AccountMove(models.Model):
return journal
+ # TODO remove in master
@api.model
def _get_default_invoice_date(self):
+ warnings.warn("Method '_get_default_invoice_date()' is deprecated and has been removed.", DeprecationWarning)
return fields.Date.context_today(self) if self._context.get('default_move_type', 'entry') in self.get_purchase_types(include_receipts=True) else False
@api.model
@@ -264,8 +266,7 @@ class AccountMove(models.Model):
string='Salesperson',
default=lambda self: self.env.user)
invoice_date = fields.Date(string='Invoice/Bill Date', readonly=True, index=True, copy=False,
- states={'draft': [('readonly', False)]},
- default=_get_default_invoice_date)
+ states={'draft': [('readonly', False)]})
invoice_date_due = fields.Date(string='Due Date', readonly=True, index=True, copy=False,
states={'draft': [('readonly', False)]})
invoice_origin = fields.Char(string='Origin', readonly=True, tracking=True,
@@ -1652,7 +1653,11 @@ class AccountMove(models.Model):
duplicated_moves = self.browse([r[0] for r in self._cr.fetchall()])
if duplicated_moves:
raise ValidationError(_('Duplicated vendor reference detected. You probably encoded twice the same vendor bill/credit note:\n%s') % "\n".join(
- duplicated_moves.mapped(lambda m: "%(partner)s - %(ref)s - %(date)s" % {'ref': m.ref, 'partner': m.partner_id.display_name, 'date': format_date(self.env, m.date)})
+ duplicated_moves.mapped(lambda m: "%(partner)s - %(ref)s - %(date)s" % {
+ 'ref': m.ref,
+ 'partner': m.partner_id.display_name,
+ 'date': format_date(self.env, m.invoice_date),
+ })
))
def _check_balanced(self):
@@ -2449,9 +2454,12 @@ class AccountMove(models.Model):
# lines are recomputed accordingly.
# /!\ 'check_move_validity' must be there since the dynamic lines will be recomputed outside the 'onchange'
# environment.
- if not move.invoice_date and move.is_invoice(include_receipts=True):
- move.invoice_date = fields.Date.context_today(self)
- move.with_context(check_move_validity=False)._onchange_invoice_date()
+ if not move.invoice_date:
+ if move.is_sale_document(include_receipts=True):
+ move.invoice_date = fields.Date.context_today(self)
+ move.with_context(check_move_validity=False)._onchange_invoice_date()
+ elif move.is_purchase_document(include_receipts=True):
+ raise UserError(_("The Bill/Refund date is required to validate this document."))
# When the accounting date is prior to the tax lock date, move it automatically to the next available date.
# /!\ 'check_move_validity' must be there since the dynamic lines will be recomputed outside the 'onchange'
diff --git a/addons/product_margin/tests/test_product_margin.py b/addons/product_margin/tests/test_product_margin.py
index 17f6f376988..161b09d3f50 100644
--- a/addons/product_margin/tests/test_product_margin.py
+++ b/addons/product_margin/tests/test_product_margin.py
@@ -40,6 +40,7 @@ class TestProductMargin(AccountTestInvoicingCommon):
'invoice_line_ids': [(0, 0, {'product_id': ipad.id, 'quantity': 10.0, 'price_unit': 550.0})],
},
])
+ invoices.invoice_date = invoices[0].date
invoices.action_post()
result = ipad._compute_product_margin_fields_values()
diff --git a/addons/purchase/tests/test_purchase_order_report.py b/addons/purchase/tests/test_purchase_order_report.py
index e3df301e813..8b38611373a 100644
--- a/addons/purchase/tests/test_purchase_order_report.py
+++ b/addons/purchase/tests/test_purchase_order_report.py
@@ -39,6 +39,7 @@ class TestPurchaseOrderReport(AccountTestInvoicingCommon):
po.button_confirm()
f = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ f.invoice_date = f.date
f.partner_id = po.partner_id
f.purchase_id = po
invoice = f.save()
diff --git a/addons/purchase_stock/tests/test_purchase_order.py b/addons/purchase_stock/tests/test_purchase_order.py
index ddb5dd80ceb..7d98d24792e 100644
--- a/addons/purchase_stock/tests/test_purchase_order.py
+++ b/addons/purchase_stock/tests/test_purchase_order.py
@@ -106,6 +106,7 @@ class TestPurchaseOrder(ValuationReconciliationTestCommon):
#After Receiving all products create vendor bill.
move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ move_form.invoice_date = move_form.date
move_form.partner_id = self.partner_a
move_form.purchase_id = self.po
self.invoice = move_form.save()
@@ -136,6 +137,7 @@ class TestPurchaseOrder(ValuationReconciliationTestCommon):
self.assertEqual(self.po.order_line[0].qty_received, 3.0, 'Purchase: delivered quantity should be 3.0 instead of "%s" after picking return' % self.po.order_line[0].qty_received)
#Create vendor bill for refund qty
move_form = Form(self.env['account.move'].with_context(default_move_type='in_refund'))
+ move_form.invoice_date = move_form.date
move_form.partner_id = self.partner_a
move_form.purchase_id = self.po
self.invoice = move_form.save()
diff --git a/addons/purchase_stock/tests/test_stockvaluation.py b/addons/purchase_stock/tests/test_stockvaluation.py
index e2972a456a4..06cfabd666a 100644
--- a/addons/purchase_stock/tests/test_stockvaluation.py
+++ b/addons/purchase_stock/tests/test_stockvaluation.py
@@ -379,6 +379,7 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon):
receipt_po1.button_validate()
move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ move_form.invoice_date = move_form.date
move_form.partner_id = self.partner_id
move_form.purchase_id = po1
invoice_po1 = move_form.save()
@@ -404,6 +405,7 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon):
receipt_po2.button_validate()
move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ move_form.invoice_date = move_form.date
move_form.partner_id = self.partner_id
move_form.purchase_id = po2
invoice_po2 = move_form.save()
@@ -428,6 +430,7 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon):
# create a credit note for po2
move_form = Form(self.env['account.move'].with_context(default_move_type='in_refund'))
+ move_form.invoice_date = move_form.date
move_form.partner_id = self.partner_id
move_form.purchase_id = po2
with move_form.invoice_line_ids.edit(0) as line_form:
@@ -462,6 +465,7 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon):
# Create an invoice with a different price
move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ move_form.invoice_date = move_form.date
move_form.partner_id = order.partner_id
move_form.purchase_id = order
with move_form.invoice_line_ids.edit(0) as line_form:
@@ -1211,6 +1215,7 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon):
# Create an invoice with a different price and a discount
invoice_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ invoice_form.invoice_date = invoice_form.date
invoice_form.purchase_id = order
with invoice_form.invoice_line_ids.edit(0) as line_form:
line_form.price_unit = 100.0
@@ -1257,6 +1262,7 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon):
# Create an invoice with a different price and a discount
invoice_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ invoice_form.invoice_date = invoice_form.date
invoice_form.purchase_id = order
with invoice_form.invoice_line_ids.edit(0) as line_form:
line_form.tax_ids.clear()
@@ -1303,6 +1309,7 @@ class TestStockValuationWithCOA(AccountTestInvoicingCommon):
# Create an invoice with a different price and a discount
invoice_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ invoice_form.invoice_date = invoice_form.date
invoice_form.purchase_id = order
with invoice_form.invoice_line_ids.edit(0) as line_form:
line_form.price_unit = 100.0
diff --git a/addons/sale/tests/test_reinvoice.py b/addons/sale/tests/test_reinvoice.py
index 6ba53f7e24b..56e887fa9ce 100644
--- a/addons/sale/tests/test_reinvoice.py
+++ b/addons/sale/tests/test_reinvoice.py
@@ -26,7 +26,12 @@ class TestReInvoice(TestSaleCommon):
'pricelist_id': cls.company_data['default_pricelist'].id,
})
- cls.AccountMove = cls.env['account.move'].with_context(default_move_type='in_invoice', mail_notrack=True, mail_create_nolog=True)
+ cls.AccountMove = cls.env['account.move'].with_context(
+ default_move_type='in_invoice',
+ default_invoice_date=cls.sale_order.date_order,
+ mail_notrack=True,
+ mail_create_nolog=True,
+ )
def test_at_cost(self):
""" Test vendor bill at cost for product based on ordered and delivered quantities. """
diff --git a/addons/sale/tests/test_sale_order.py b/addons/sale/tests/test_sale_order.py
index bfdfa219b0c..3a9ace87e02 100644
--- a/addons/sale/tests/test_sale_order.py
+++ b/addons/sale/tests/test_sale_order.py
@@ -240,6 +240,7 @@ class TestSaleOrder(TestSaleCommon):
inv = self.env['account.move'].with_context(default_move_type='in_invoice').create({
'partner_id': self.partner_a.id,
+ 'invoice_date': so.date_order,
'invoice_line_ids': [
(0, 0, {
'name': serv_cost.name,
diff --git a/addons/sale_timesheet/tests/test_reinvoice.py b/addons/sale_timesheet/tests/test_reinvoice.py
index 0ea1087d926..0b85f45093e 100644
--- a/addons/sale_timesheet/tests/test_reinvoice.py
+++ b/addons/sale_timesheet/tests/test_reinvoice.py
@@ -40,7 +40,12 @@ class TestReInvoice(TestCommonSaleTimesheet):
'pricelist_id': cls.company_data['default_pricelist'].id,
})
- cls.Invoice = cls.env['account.move'].with_context(mail_notrack=True, mail_create_nolog=True)
+ cls.Invoice = cls.env['account.move'].with_context(
+ default_move_type='in_invoice',
+ default_invoice_date=cls.sale_order.date_order,
+ mail_notrack=True,
+ mail_create_nolog=True,
+ )
def test_at_cost(self):
""" Test vendor bill at cost for product based on ordered and delivered quantities. """
@@ -82,7 +87,7 @@ class TestReInvoice(TestCommonSaleTimesheet):
'company_id': self.company_data['company'].id,
})
- move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ move_form = Form(self.Invoice)
move_form.partner_id = self.partner_a
with move_form.line_ids.new() as line_form:
line_form.product_id = self.company_data['product_order_cost']
@@ -117,7 +122,7 @@ class TestReInvoice(TestCommonSaleTimesheet):
self.assertEqual(sale_order_line4.qty_delivered_method, 'analytic', "Delivered quantity of 'expense' SO line should be computed by analytic amount")
# create second invoice lines and validate it
- move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ move_form = Form(self.Invoice)
move_form.partner_id = self.partner_a
with move_form.line_ids.new() as line_form:
line_form.product_id = self.company_data['product_order_cost']
@@ -181,7 +186,7 @@ class TestReInvoice(TestCommonSaleTimesheet):
})
# create invoice lines and validate it
- move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ move_form = Form(self.Invoice)
move_form.partner_id = self.partner_a
with move_form.line_ids.new() as line_form:
line_form.product_id = self.company_data['product_delivery_sales_price']
@@ -216,7 +221,7 @@ class TestReInvoice(TestCommonSaleTimesheet):
self.assertEqual(sale_order_line4.qty_delivered_method, 'analytic', "Delivered quantity of 'expense' SO line 4 should be computed by analytic amount")
# create second invoice lines and validate it
- move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ move_form = Form(self.Invoice)
move_form.partner_id = self.partner_a
with move_form.line_ids.new() as line_form:
line_form.product_id = self.company_data['product_delivery_sales_price']
@@ -256,7 +261,7 @@ class TestReInvoice(TestCommonSaleTimesheet):
self.sale_order.action_confirm()
# create invoice lines and validate it
- move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ move_form = Form(self.Invoice)
move_form.partner_id = self.partner_a
with move_form.line_ids.new() as line_form:
line_form.product_id = self.company_data['product_order_no']
diff --git a/addons/stock_dropshipping/tests/test_stockvaluation.py b/addons/stock_dropshipping/tests/test_stockvaluation.py
index f4709c03829..b1ac78d2003 100644
--- a/addons/stock_dropshipping/tests/test_stockvaluation.py
+++ b/addons/stock_dropshipping/tests/test_stockvaluation.py
@@ -69,6 +69,7 @@ class TestStockValuation(ValuationReconciliationTestCommon):
move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
move_form.partner_id = vendor1
move_form.purchase_id = self.purchase_order1
+ move_form.invoice_date = move_form.date
for i in range(len(self.purchase_order1.order_line)):
with move_form.invoice_line_ids.edit(i) as line_form:
line_form.tax_ids.clear()
diff --git a/addons/stock_landed_costs/tests/test_stock_landed_costs_purchase.py b/addons/stock_landed_costs/tests/test_stock_landed_costs_purchase.py
index 2c879fae12b..f18ec214707 100644
--- a/addons/stock_landed_costs/tests/test_stock_landed_costs_purchase.py
+++ b/addons/stock_landed_costs/tests/test_stock_landed_costs_purchase.py
@@ -355,6 +355,7 @@ class TestLandedCostsWithPurchaseAndInv(TestStockValuationLCCommon):
# Create an invoice with the same price
move_form = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ move_form.invoice_date = move_form.date
move_form.partner_id = order.partner_id
move_form.purchase_id = order
move = move_form.save()
diff --git a/addons/stock_landed_costs/tests/test_stockvaluationlayer.py b/addons/stock_landed_costs/tests/test_stockvaluationlayer.py
index c2cb5354282..30ea438f49d 100644
--- a/addons/stock_landed_costs/tests/test_stockvaluationlayer.py
+++ b/addons/stock_landed_costs/tests/test_stockvaluationlayer.py
@@ -65,7 +65,7 @@ class TestStockValuationLCCommon(TestStockLandedCostsCommon):
lc.compute_landed_cost()
lc.button_validate()
return lc
-
+
def _make_in_move(self, product, quantity, unit_cost=None, create_picking=False):
""" Helper to create and validate a receipt move.
"""
@@ -341,6 +341,7 @@ class TestStockValuationLCFIFOVB(TestStockValuationLCCommon):
# Create a vendor bill for the RFQ
action = rfq.action_create_invoice()
vb = self.env['account.move'].browse(action['res_id'])
+ vb.invoice_date = vb.date
vb.action_post()
input_aml = self._get_stock_input_move_lines()[-1]
@@ -353,6 +354,7 @@ class TestStockValuationLCFIFOVB(TestStockValuationLCCommon):
# Create a vendor bill for a landed cost product, post it and validate a landed cost
# linked to this vendor bill. LC; 1@50
lcvb = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
+ lcvb.invoice_date = lcvb.date
lcvb.partner_id = self.vendor2
with lcvb.invoice_line_ids.new() as inv_line:
inv_line.product_id = self.productlc1
@@ -429,6 +431,7 @@ class TestStockValuationLCFIFOVB(TestStockValuationLCCommon):
# Create a vendor bill for the RFQ and add to it the landed cost
vb = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
vb.partner_id = self.vendor1
+ vb.invoice_date = vb.date
with vb.invoice_line_ids.new() as inv_line:
inv_line.product_id = self.productlc1
inv_line.price_unit = 50
@@ -481,6 +484,7 @@ class TestStockValuationLCFIFOVB(TestStockValuationLCCommon):
# Create a vebdor bill for the RFQ
action = rfq.action_create_invoice()
vb = self.env['account.move'].browse(action['res_id'])
+ vb.invoice_date = vb.date
vb.action_post()
expense_aml = self._get_expense_move_lines()[-1]
@@ -495,6 +499,7 @@ class TestStockValuationLCFIFOVB(TestStockValuationLCCommon):
# linked to this vendor bill. LC; 1@50
lcvb = Form(self.env['account.move'].with_context(default_move_type='in_invoice'))
lcvb.partner_id = self.vendor2
+ lcvb.invoice_date = lcvb.date
with lcvb.invoice_line_ids.new() as inv_line:
inv_line.product_id = self.productlc1
inv_line.price_unit = 50