2
0

[14.0][MIG] account_spread_cost_revenue

This commit is contained in:
Kitti U 2021-10-01 16:50:58 +07:00 committed by Andrea Stirpe
parent 01a2998bf2
commit 163eb46e4f
14 changed files with 93 additions and 109 deletions

View File

@ -4,7 +4,7 @@
{
"name": "Cost-Revenue Spread",
"summary": "Spread costs and revenues over a custom period",
"version": "13.0.1.0.0",
"version": "14.0.1.0.0",
"development_status": "Beta",
"author": "Onestein,Odoo Community Association (OCA)",
"maintainers": ["astirpe"],

View File

@ -1,26 +0,0 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import SUPERUSER_ID, api
def migrate(cr, version):
env = api.Environment(cr, SUPERUSER_ID, {})
rule_name = "account_spread_cost_revenue.account_spread_multi_company_rule"
rule = env.ref(rule_name, raise_if_not_found=False)
if rule:
domain = "['|',('company_id','=',False),('company_id','in',company_ids)]"
rule.write({"domain_force": domain})
rule_name = "account_spread_cost_revenue.account_spread_template_multi_company_rule"
rule = env.ref(rule_name, raise_if_not_found=False)
if rule:
domain = "['|',('company_id','=',False),('company_id','in',company_ids)]"
rule.write({"domain_force": domain})
rule_name = (
"account_spread_cost_revenue.account_spread_template_auto_multi_company_rule"
)
rule = env.ref(rule_name, raise_if_not_found=False)
if rule:
domain = "['|',('company_id','=',False),('company_id','in',company_ids)]"
rule.write({"domain_force": domain})

View File

@ -1,7 +0,0 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo.tools import sql
def migrate(cr, version):
sql.rename_column(cr, "res_partner", "auto_archive", "auto_archive_spread")

View File

@ -13,6 +13,11 @@ class AccountMove(models.Model):
res = super().action_post()
spreads = self.mapped("invoice_line_ids.spread_id")
spreads.compute_spread_board()
# On posting of spread moves. Find their related spreads to creconcile
move_spreads = self.env["account.spread"].search(
[("line_ids.move_id", "in", self.ids)]
)
spreads += move_spreads
spreads.reconcile_spread_moves()
return res

View File

@ -68,7 +68,7 @@ class AccountMoveLine(models.Model):
for line in self:
if not line.spread_id:
pass
elif line.move_id.type in ("out_invoice", "in_refund"):
elif line.move_id.move_type in ("out_invoice", "in_refund"):
if line.account_id != line.spread_id.debit_account_id:
raise ValidationError(
_(
@ -76,7 +76,7 @@ class AccountMoveLine(models.Model):
"to the Balance Sheet (debit account) of the spread"
)
)
elif line.move_id.type in ("in_invoice", "out_refund"):
elif line.move_id.move_type in ("in_invoice", "out_refund"):
if line.account_id != line.spread_id.credit_account_id:
raise ValidationError(
_(
@ -110,10 +110,10 @@ class AccountMoveLine(models.Model):
raise ValidationError(msg)
def create_auto_spread(self):
""" Create auto spread table for each invoice line, when needed """
"""Create auto spread table for each invoice line, when needed"""
def _filter_line(aline, iline):
""" Find matching template auto line with invoice line """
"""Find matching template auto line with invoice line"""
if aline.product_id and iline.product_id != aline.product_id:
return False
if aline.account_id and iline.account_id != aline.account_id:
@ -130,7 +130,7 @@ class AccountMoveLine(models.Model):
continue
spread_type = (
"sale"
if line.move_id.type in ["out_invoice", "out_refund"]
if line.move_id.move_type in ["out_invoice", "out_refund"]
else "purchase"
)
spread_auto = self.env["account.spread.template.auto"].search(

View File

@ -273,7 +273,7 @@ class AccountSpread(models.Model):
@api.constrains("invoice_id", "invoice_type")
def _check_invoice_type(self):
if self.filtered(
lambda s: s.invoice_id and s.invoice_type != s.invoice_id.type
lambda s: s.invoice_id and s.invoice_type != s.invoice_id.move_type
):
raise ValidationError(
_("The Invoice Type does not correspond to the Invoice")
@ -498,6 +498,8 @@ class AccountSpread(models.Model):
if mls_to_reconcile:
do_reconcile = mls_to_reconcile + self.invoice_line_id
do_reconcile.remove_move_reconcile()
# ensure to reconcile only posted items
do_reconcile = do_reconcile.filtered(lambda l: l.move_id.state == "posted")
do_reconcile._check_spread_reconcile_validity()
do_reconcile.reconcile()
@ -507,11 +509,12 @@ class AccountSpread(models.Model):
def _post_spread_moves(self, moves):
self.ensure_one()
moves = moves.filtered(lambda l: l.state != "posted")
if not moves:
return
ctx = dict(self.env.context, skip_unique_sequence_number=True)
if self.company_id.force_move_auto_post or self.move_line_auto_post:
moves.with_context(ctx).post()
moves.with_context(ctx).action_post()
@api.depends("debit_account_id.deprecated", "credit_account_id.deprecated")
def _compute_deprecated_accounts(self):

View File

@ -35,8 +35,6 @@ class AccountInvoiceSpreadLine(models.Model):
for move in created_moves
)
spread.message_post(body=post_msg)
if spread.invoice_id.state == "posted":
spread._reconcile_spread_moves(created_moves)
spread._post_spread_moves(created_moves)
def create_move(self):
@ -120,9 +118,10 @@ class AccountInvoiceSpreadLine(models.Model):
]
return {
"name": self.name or "/",
"name": False,
"ref": self.name,
"date": spread_date,
"invoice_date": spread_date,
"journal_id": spread.journal_id.id,
"line_ids": line_ids,
"company_id": spread.company_id.id,
@ -168,7 +167,9 @@ class AccountInvoiceSpreadLine(models.Model):
.mapped("move_id")
.filtered(lambda m: m.state != "posted")
)
unposted_moves.filtered(lambda m: m.company_id.force_move_auto_post).post()
unposted_moves.filtered(
lambda m: m.company_id.force_move_auto_post
).action_post()
spreads_to_archive = (
self.env["account.spread"]

View File

@ -1,9 +1,10 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_spread_cost_revenue_full,Full access on account.spread,model_account_spread,account.group_account_manager,1,1,1,1
access_account_spread_cost_revenue_read,Read access on account.spread,model_account_spread,account.group_account_user,1,0,0,0
access_account_spread_cost_revenue_read,Read access on account.spread,model_account_spread,account.group_account_invoice,1,0,0,0
access_account_spread_cost_revenue_line_full,Full access on account.spread.line,model_account_spread_line,account.group_account_manager,1,1,1,1
access_account_spread_cost_revenue_line_read,Read access on account.spread.line,model_account_spread_line,account.group_account_user,1,0,0,0
access_account_spread_cost_revenue_line_read,Read access on account.spread.line,model_account_spread_line,account.group_account_invoice,1,0,0,0
access_account_spread_cost_revenue_template_full,Full access on account.spread.template,model_account_spread_template,account.group_account_manager,1,1,1,1
access_account_spread_cost_revenue_template_read,Read access on account.spread.template,model_account_spread_template,account.group_account_user,1,0,0,0
access_account_spread_cost_revenue_template_read,Read access on account.spread.template,model_account_spread_template,account.group_account_invoice,1,0,0,0
access_account_spread_cost_revenue_template_auto_full,Full access on account.spread.template.auto,model_account_spread_template_auto,account.group_account_manager,1,1,1,1
access_account_spread_cost_revenue_template_auto_read,Read access on account.spread.template.auto,model_account_spread_template_auto,account.group_account_user,1,0,0,0
access_account_spread_cost_revenue_template_auto_read,Read access on account.spread.template.auto,model_account_spread_template_auto,account.group_account_invoice,1,0,0,0
access_account_spread_invoice_line_link_wizard,access_account_spread_invoice_line_link_wizard,model_account_spread_invoice_line_link_wizard,base.group_user,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_account_spread_cost_revenue_full Full access on account.spread model_account_spread account.group_account_manager 1 1 1 1
3 access_account_spread_cost_revenue_read Read access on account.spread model_account_spread account.group_account_user account.group_account_invoice 1 0 0 0
4 access_account_spread_cost_revenue_line_full Full access on account.spread.line model_account_spread_line account.group_account_manager 1 1 1 1
5 access_account_spread_cost_revenue_line_read Read access on account.spread.line model_account_spread_line account.group_account_user account.group_account_invoice 1 0 0 0
6 access_account_spread_cost_revenue_template_full Full access on account.spread.template model_account_spread_template account.group_account_manager 1 1 1 1
7 access_account_spread_cost_revenue_template_read Read access on account.spread.template model_account_spread_template account.group_account_user account.group_account_invoice 1 0 0 0
8 access_account_spread_cost_revenue_template_auto_full Full access on account.spread.template.auto model_account_spread_template_auto account.group_account_manager 1 1 1 1
9 access_account_spread_cost_revenue_template_auto_read Read access on account.spread.template.auto model_account_spread_template_auto account.group_account_user account.group_account_invoice 1 0 0 0
10 access_account_spread_invoice_line_link_wizard access_account_spread_invoice_line_link_wizard model_account_spread_invoice_line_link_wizard base.group_user 1 1 1 1

View File

@ -3,9 +3,7 @@
from odoo.exceptions import UserError
from odoo.addons.account_spread_cost_revenue.tests.test_account_invoice_spread import (
TestAccountInvoiceSpread,
)
from .test_account_invoice_spread import TestAccountInvoiceSpread
class TestAccountInvoiceAutoSpread(TestAccountInvoiceSpread):
@ -18,9 +16,7 @@ class TestAccountInvoiceAutoSpread(TestAccountInvoiceSpread):
"period_number": 5,
"period_type": "month",
"spread_account_id": self.account_payable.id,
"spread_journal_id": self.ref(
"account_spread_cost_revenue.expenses_journal"
),
"spread_journal_id": self.expenses_journal.id,
"auto_spread": False, # Auto Spread = False
"auto_spread_ids": [
(0, 0, {"account_id": self.vendor_bill_line.account_id.id})
@ -41,9 +37,7 @@ class TestAccountInvoiceAutoSpread(TestAccountInvoiceSpread):
"period_number": 5,
"period_type": "month",
"spread_account_id": self.account_payable.id,
"spread_journal_id": self.ref(
"account_spread_cost_revenue.expenses_journal"
),
"spread_journal_id": self.expenses_journal.id,
"auto_spread": True, # Auto Spread
"auto_spread_ids": [
(0, 0, {"account_id": self.vendor_bill_line.account_id.id})
@ -57,9 +51,7 @@ class TestAccountInvoiceAutoSpread(TestAccountInvoiceSpread):
"period_number": 5,
"period_type": "month",
"spread_account_id": self.account_payable.id,
"spread_journal_id": self.ref(
"account_spread_cost_revenue.expenses_journal"
),
"spread_journal_id": self.expenses_journal.id,
"auto_spread": True, # Auto Spread
"auto_spread_ids": [
(0, 0, {"account_id": self.vendor_bill_line.account_id.id})
@ -92,9 +84,7 @@ class TestAccountInvoiceAutoSpread(TestAccountInvoiceSpread):
"period_number": 5,
"period_type": "month",
"spread_account_id": self.account_receivable.id,
"spread_journal_id": self.ref(
"account_spread_cost_revenue.sales_journal"
),
"spread_journal_id": self.sales_journal.id,
"auto_spread": True, # Auto Spread
"auto_spread_ids": [
(0, 0, {"account_id": self.invoice_line.account_id.id})

View File

@ -5,29 +5,15 @@ import datetime
from odoo import fields
from odoo.exceptions import UserError, ValidationError
from odoo.modules.module import get_resource_path
from odoo.tests import Form, common
from odoo.tools import convert_file
class TestAccountInvoiceSpread(common.TransactionCase):
def _load(self, module, *args):
convert_file(
self.cr,
"account_spread_cost_revenue",
get_resource_path(module, *args),
{},
"init",
False,
"test",
self.registry._assertion_report,
)
def create_account_invoice(self, invoice_type, quantity=1.0, price_unit=1000.0):
""" Create an invoice as in a view by triggering its onchange methods"""
"""Create an invoice as in a view by triggering its onchange methods"""
invoice_form = Form(
self.env["account.move"].with_context(default_type=invoice_type)
self.env["account.move"].with_context(default_move_type=invoice_type)
)
invoice_form.partner_id = self.env["res.partner"].create(
{"name": "Partner Name"}
@ -41,7 +27,41 @@ class TestAccountInvoiceSpread(common.TransactionCase):
def setUp(self):
super().setUp()
self._load("account", "test", "account_minimal_test.xml")
# Define minimal accounting data to run
a_expense = self.env["account.account"].create(
{
"code": "X2120",
"name": "Expenses - (test)",
"user_type_id": self.env.ref("account.data_account_type_expenses").id,
}
)
a_sale = self.env["account.account"].create(
{
"code": "X2020",
"name": "Product Sales - (test)",
"user_type_id": self.env.ref("account.data_account_type_revenue").id,
}
)
self.expenses_journal = self.env["account.journal"].create(
{
"name": "Vendor Bills - Test",
"code": "TEXJ",
"type": "purchase",
"default_account_id": a_expense.id,
"refund_sequence": True,
}
)
self.sales_journal = self.env["account.journal"].create(
{
"name": "Customer Invoices - Test",
"code": "TINV",
"type": "sale",
"default_account_id": a_sale.id,
"refund_sequence": True,
}
)
self.account_payable = self.env["account.account"].create(
{
@ -88,8 +108,11 @@ class TestAccountInvoiceSpread(common.TransactionCase):
)
# Invoices
self.vendor_bill = self.create_account_invoice("in_invoice")
self.vendor_bill.invoice_date = fields.Date.today()
self.sale_invoice = self.create_account_invoice("out_invoice")
self.sale_invoice.invoice_date = fields.Date.today()
self.vendor_bill_line = self.vendor_bill.invoice_line_ids[0]
self.invoice_line = self.sale_invoice.invoice_line_ids[0]
@ -174,12 +197,10 @@ class TestAccountInvoiceSpread(common.TransactionCase):
def test_02_wizard_defaults(self):
Wizard = self.env["account.spread.invoice.line.link.wizard"]
exp_journal = self.ref("account_spread_cost_revenue.expenses_journal")
sales_journal = self.ref("account_spread_cost_revenue.sales_journal")
self.env.company.default_spread_revenue_account_id = self.account_receivable
self.env.company.default_spread_expense_account_id = self.account_payable
self.env.company.default_spread_revenue_journal_id = sales_journal
self.env.company.default_spread_expense_journal_id = exp_journal
self.env.company.default_spread_revenue_journal_id = self.sales_journal
self.env.company.default_spread_expense_journal_id = self.expenses_journal
self.assertTrue(self.env.company.default_spread_revenue_account_id)
self.assertTrue(self.env.company.default_spread_expense_account_id)
@ -201,7 +222,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
self.assertTrue(wizard1.spread_account_id)
self.assertTrue(wizard1.spread_journal_id)
self.assertEqual(wizard1.spread_account_id, self.account_payable)
self.assertEqual(wizard1.spread_journal_id.id, exp_journal)
self.assertEqual(wizard1.spread_journal_id.id, self.expenses_journal.id)
self.assertTrue(wizard1.spread_invoice_type_domain_ids)
wizard2 = Wizard.with_context(
@ -218,7 +239,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
self.assertTrue(wizard2.spread_account_id)
self.assertTrue(wizard2.spread_journal_id)
self.assertEqual(wizard2.spread_account_id, self.account_receivable)
self.assertEqual(wizard2.spread_journal_id.id, sales_journal)
self.assertEqual(wizard2.spread_journal_id.id, self.sales_journal.id)
self.assertTrue(wizard2.spread_invoice_type_domain_ids)
def test_03_link_invoice_line_with_spread_sheet(self):
@ -241,9 +262,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
self.assertEqual(wizard1.spread_action_type, "link")
wizard1.spread_account_id = self.account_receivable
wizard1.spread_journal_id = self.ref(
"account_spread_cost_revenue.expenses_journal"
)
wizard1.spread_journal_id = self.expenses_journal
wizard1.spread_id = self.spread
res_action = wizard1.confirm()
self.assertTrue(isinstance(res_action, dict))
@ -277,7 +296,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
Wizard = self.env["account.spread.invoice.line.link.wizard"]
spread_journal_id = self.ref("account_spread_cost_revenue.expenses_journal")
spread_journal_id = self.expenses_journal
wizard1 = Wizard.with_context(
default_invoice_line_id=self.vendor_bill_line.id,
@ -348,7 +367,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
spread_account = self.account_payable
self.assertTrue(spread_account)
spread_journal_id = self.ref("account_spread_cost_revenue.expenses_journal")
spread_journal_id = self.expenses_journal.id
template = self.env["account.spread.template"].create(
{
@ -537,7 +556,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
if spread_ml.debit:
self.assertFalse(spread_ml.full_reconcile_id)
if spread_ml.credit:
self.assertTrue(spread_ml.full_reconcile_id)
self.assertFalse(spread_ml.full_reconcile_id)
action_reconcile_view = self.spread2.open_reconcile_view()
self.assertTrue(isinstance(action_reconcile_view, dict))
@ -648,8 +667,8 @@ class TestAccountInvoiceSpread(common.TransactionCase):
for spread_ml in spread_mls:
if spread_ml.debit:
self.assertEqual(spread_ml.account_id, balance_sheet)
self.assertTrue(spread_ml.reconciled)
self.assertTrue(spread_ml.full_reconcile_id)
self.assertFalse(spread_ml.reconciled)
self.assertFalse(spread_ml.full_reconcile_id)
if spread_ml.credit:
self.assertEqual(spread_ml.account_id, payable_account)
self.assertFalse(spread_ml.reconciled)
@ -662,7 +681,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
action_reconcile_view = self.spread2.open_reconcile_view()
self.assertTrue(isinstance(action_reconcile_view, dict))
self.assertTrue(action_reconcile_view.get("domain")[0][2])
self.assertFalse(action_reconcile_view.get("domain")[0][2])
self.assertFalse(action_reconcile_view.get("res_id"))
self.assertTrue(action_reconcile_view.get("context"))

View File

@ -311,9 +311,7 @@ class TestComputeSpreadBoard(common.TransactionCase):
attrs = spread_line.open_move()
self.assertTrue(isinstance(attrs, dict))
# post and then unlink all created moves
for line in self.spread.line_ids:
line.move_id.post()
# unlink all created moves
self.spread.line_ids.unlink_move()
for spread_line in self.spread.line_ids:
self.assertFalse(spread_line.move_id)
@ -375,9 +373,9 @@ class TestComputeSpreadBoard(common.TransactionCase):
self.spread.compute_spread_board()
spread_lines = self.spread.line_ids
self.assertEqual(len(spread_lines), 3)
self.assertAlmostEquals(115.32, spread_lines[0].amount)
self.assertAlmostEquals(115.32, spread_lines[1].amount)
self.assertAlmostEquals(115.32, spread_lines[2].amount)
self.assertAlmostEqual(115.32, spread_lines[0].amount)
self.assertAlmostEqual(115.32, spread_lines[1].amount)
self.assertAlmostEqual(115.32, spread_lines[2].amount)
self.assertEqual(datetime.date(2017, 1, 31), spread_lines[0].date)
self.assertEqual(datetime.date(2017, 2, 28), spread_lines[1].date)
self.assertEqual(datetime.date(2017, 3, 31), spread_lines[2].date)
@ -572,10 +570,10 @@ class TestComputeSpreadBoard(common.TransactionCase):
for line in spread_lines:
self.assertFalse(line.move_id)
spread_lines[0]._create_moves().post()
spread_lines[1]._create_moves().post()
spread_lines[2]._create_moves().post()
spread_lines[3]._create_moves().post()
spread_lines[0]._create_moves().action_post()
spread_lines[1]._create_moves().action_post()
spread_lines[2]._create_moves().action_post()
spread_lines[3]._create_moves().action_post()
self.assertEqual(spread_lines[0].move_id.state, "posted")
self.assertEqual(spread_lines[1].move_id.state, "posted")

View File

@ -269,7 +269,7 @@
string="Create Move"
type="object"
groups="account.group_account_manager"
attrs="{'invisible':['|',('move_id','!=',False)]}"
attrs="{'invisible':[('move_id','!=',False)]}"
/>
<button
name="open_move"

View File

@ -37,7 +37,7 @@
/>
<field
name="exp_rev_account_id"
attrs="{'invisible': ['|', ('use_invoice_line_account', '=', False)], 'required': [('use_invoice_line_account', '=', True)]}"
attrs="{'invisible': [('use_invoice_line_account', '=', False)], 'required': [('use_invoice_line_account', '=', True)]}"
domain="[('company_id', '=', company_id), ('deprecated', '=', False)]"
options="{'no_create': True}"
/>

View File

@ -88,7 +88,7 @@ class AccountSpreadInvoiceLineLinkWizard(models.TransientModel):
def _compute_invoice_type(self):
for wizard in self:
invoice = wizard.invoice_line_id.move_id
wizard.invoice_type = invoice.type
wizard.invoice_type = invoice.move_type
if invoice.is_sale_document(include_receipts=True):
wizard.spread_type = "sale"
else: