2
0

[16.0][MIG] account_spread_cost_revenue

This commit is contained in:
Andrea Stirpe 2023-10-10 11:12:05 +02:00
parent e2ab9e5fdb
commit 0698663e48
22 changed files with 371 additions and 340 deletions

View File

@ -2,10 +2,13 @@
Cost-Revenue Spread Cost-Revenue Spread
=================== ===================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !! !! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !! !! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:560d87ede92fd18ca4a929595b6a9fd9f558f6b577e8c9bad1f8e7236ad4175d
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status :target: https://odoo-community.org/page/development-status
@ -14,14 +17,14 @@ Cost-Revenue Spread
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3 :alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github
:target: https://github.com/OCA/account-financial-tools/tree/14.0/account_spread_cost_revenue :target: https://github.com/OCA/account-financial-tools/tree/16.0/account_spread_cost_revenue
:alt: OCA/account-financial-tools :alt: OCA/account-financial-tools
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/account-financial-tools-14-0/account-financial-tools-14-0-account_spread_cost_revenue :target: https://translation.odoo-community.org/projects/account-financial-tools-16-0/account-financial-tools-16-0-account_spread_cost_revenue
:alt: Translate me on Weblate :alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/92/14.0 :target: https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&target_branch=16.0
:alt: Try me on Runbot :alt: Try me on Runboat
|badge1| |badge2| |badge3| |badge4| |badge5| |badge1| |badge2| |badge3| |badge4| |badge5|
@ -67,7 +70,7 @@ Usage
Define Spread Costs/Revenues Board Define Spread Costs/Revenues Board
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Under Invoicing -> Adviser -> Accounting Entries -> Spread Costs/Revenues, create a new spread board. Under Invoicing -> Accounting -> Journals -> Spread Costs/Revenues, create a new spread board.
Complete the definition of the spreading criteria, by setting the the fields: Complete the definition of the spreading criteria, by setting the the fields:
@ -79,17 +82,17 @@ Complete the definition of the spreading criteria, by setting the the fields:
* *Start date* * *Start date*
* *Journal* * *Journal*
.. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/spread.png .. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/spread.png
:alt: Create a new spread board :alt: Create a new spread board
Click on the button on the top-left to calculate the spread lines. Click on the "Recalculate unposted lines" button on the top-left to calculate the spread lines.
.. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/create_spread.png .. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/create_spread.png
:alt: The spreading board is defined :alt: The spreading board is defined
A cron job will automatically create the accounting moves for all the lines having date previous that the current day (today). A cron job will automatically create the accounting moves for all the lines having date previous that the current day (today).
.. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/update_spread.png .. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/update_spread.png
:alt: The spreading board is updated by the cron job :alt: The spreading board is updated by the cron job
By default, the status of the created accounting moves is posted. By default, the status of the created accounting moves is posted.
@ -104,7 +107,7 @@ Link Invoice to Spread Costs/Revenues Board
Create an invoice or vendor bill in draft. On its lines, the spreading right-arrow icon are displayed in dark-grey color. Create an invoice or vendor bill in draft. On its lines, the spreading right-arrow icon are displayed in dark-grey color.
.. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/invoice_line_1.png .. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/invoice_line_1.png
:alt: On the invoice line the spreading icon is displayed :alt: On the invoice line the spreading icon is displayed
Click on the spreading right-arrow icon. A wizard prompts to enter a *Spread Action Type*: Click on the spreading right-arrow icon. A wizard prompts to enter a *Spread Action Type*:
@ -119,11 +122,11 @@ the selected Spread Board will be automatically displayed.
Go back to the draft invoice/bill. The spreading functionality is now enabled on the invoice line: Go back to the draft invoice/bill. The spreading functionality is now enabled on the invoice line:
the spreading right-arrow icon is now displayed in green color. the spreading right-arrow icon is now displayed in green color.
.. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/invoice_line_2.png .. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/invoice_line_2.png
:alt: On the invoice line the spreading icon is displayed in green color :alt: On the invoice line the spreading icon is displayed in green color
Validate the invoice/bill. Click on the spreading (green) right-arrow icon to open the spread board, then click Validate the invoice/bill. Click on the spreading (green) right-arrow icon to open the spread board, then click
on the smart button *Reconciled entries*: the moves of the spread lines are reconciled with the move of the invoice line. on the smart button *Posted entries* to see the moves of the spread lines together with the move of the invoice line.
In case the Subtotal Price of the invoice line is different than the *Estimated Amount* of the spread board, the spread In case the Subtotal Price of the invoice line is different than the *Estimated Amount* of the spread board, the spread
lines (not yet posted) will be recalculated when validating the invoice/bill. lines (not yet posted) will be recalculated when validating the invoice/bill.
@ -181,8 +184,8 @@ Bug Tracker
Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-financial-tools/issues>`_. Bugs are tracked on `GitHub Issues <https://github.com/OCA/account-financial-tools/issues>`_.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_spread_cost_revenue%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. `feedback <https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_spread_cost_revenue%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues. Do not contact contributors directly about support or help with technical issues.
@ -199,6 +202,7 @@ Contributors
* Andrea Stirpe <a.stirpe@onestein.nl> * Andrea Stirpe <a.stirpe@onestein.nl>
* Kitti U. <kittiu@ecosoft.co.th> * Kitti U. <kittiu@ecosoft.co.th>
* Saran Lim. <saranl@ecosoft.co.th>
Other credits Other credits
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
@ -220,14 +224,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and mission is to support the collaborative development of Odoo features and
promote its widespread use. promote its widespread use.
.. |maintainer-astirpe| image:: https://github.com/astirpe.png?size=40px This module is part of the `OCA/account-financial-tools <https://github.com/OCA/account-financial-tools/tree/16.0/account_spread_cost_revenue>`_ project on GitHub.
:target: https://github.com/astirpe
:alt: astirpe
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
|maintainer-astirpe|
This module is part of the `OCA/account-financial-tools <https://github.com/OCA/account-financial-tools/tree/14.0/account_spread_cost_revenue>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@ -4,20 +4,13 @@
{ {
"name": "Cost-Revenue Spread", "name": "Cost-Revenue Spread",
"summary": "Spread costs and revenues over a custom period", "summary": "Spread costs and revenues over a custom period",
"version": "15.0.1.0.0", "version": "16.0.1.0.0",
"development_status": "Beta", "development_status": "Beta",
"author": "Onestein,Odoo Community Association (OCA)", "author": "Onestein,Odoo Community Association (OCA)",
"maintainers": ["astirpe"],
"license": "AGPL-3", "license": "AGPL-3",
"website": "https://github.com/OCA/account-financial-tools", "website": "https://github.com/OCA/account-financial-tools",
"category": "Accounting & Finance", "category": "Accounting & Finance",
"depends": ["account"], "depends": ["account"],
"assets": {
"web.assets_backend": [
"/account_spread_cost_revenue/static/src/scss/account_spread.scss",
"/account_spread_cost_revenue/static/src/js/account_spread.js",
],
},
"data": [ "data": [
"security/ir.model.access.csv", "security/ir.model.access.csv",
"security/account_spread_security.xml", "security/account_spread_security.xml",

View File

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

View File

@ -129,8 +129,8 @@ class AccountMoveLine(models.Model):
if aline.account_id and iline.account_id != aline.account_id: if aline.account_id and iline.account_id != aline.account_id:
return False return False
if ( if (
aline.analytic_account_id aline.analytic_distribution
and iline.account_analytic_id != aline.analytic_account_id and iline.analytic_distribution != aline.analytic_distribution
): ):
return False return False
return True return True

View File

@ -3,7 +3,6 @@
import calendar import calendar
import time import time
from datetime import timedelta
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
@ -15,7 +14,8 @@ from odoo.tools import float_is_zero
class AccountSpread(models.Model): class AccountSpread(models.Model):
_name = "account.spread" _name = "account.spread"
_description = "Account Spread" _description = "Account Spread"
_inherit = ["mail.thread"] _inherit = ["mail.thread", "analytic.mixin"]
_check_company_auto = True
name = fields.Char(required=True) name = fields.Char(required=True)
template_id = fields.Many2one("account.spread.template", string="Spread Template") template_id = fields.Many2one("account.spread.template", string="Spread Template")
@ -96,8 +96,15 @@ class AccountSpread(models.Model):
"account.journal", "account.journal",
compute="_compute_journal_id", compute="_compute_journal_id",
readonly=False, readonly=False,
precompute=True,
store=True, store=True,
required=True, required=True,
check_company=True,
domain="[('id', 'in', suitable_journal_ids)]",
)
suitable_journal_ids = fields.Many2many(
"account.journal",
compute="_compute_suitable_journal_ids",
) )
invoice_line_ids = fields.One2many( invoice_line_ids = fields.One2many(
"account.move.line", "spread_id", copy=False, string="Invoice Lines" "account.move.line", "spread_id", copy=False, string="Invoice Lines"
@ -123,10 +130,6 @@ class AccountSpread(models.Model):
required=True, required=True,
default=lambda self: self.env.company.currency_id.id, default=lambda self: self.env.company.currency_id.id,
) )
account_analytic_id = fields.Many2one(
"account.analytic.account", string="Analytic Account"
)
analytic_tag_ids = fields.Many2many("account.analytic.tag", string="Analytic Tags")
move_line_auto_post = fields.Boolean("Auto-post lines", default=True) move_line_auto_post = fields.Boolean("Auto-post lines", default=True)
display_create_all_moves = fields.Boolean( display_create_all_moves = fields.Boolean(
compute="_compute_display_create_all_moves", compute="_compute_display_create_all_moves",
@ -155,6 +158,12 @@ class AccountSpread(models.Model):
res["journal_id"] = default_journal.id res["journal_id"] = default_journal.id
return res return res
@api.depends("company_id")
def _compute_suitable_journal_ids(self):
for spread in self:
domain = [("company_id", "=", spread.company_id.id)]
spread.suitable_journal_ids = self.env["account.journal"].search(domain)
@api.depends("invoice_type") @api.depends("invoice_type")
def _compute_spread_type(self): def _compute_spread_type(self):
for spread in self: for spread in self:
@ -248,6 +257,8 @@ class AccountSpread(models.Model):
self.period_type = self.template_id.period_type self.period_type = self.template_id.period_type
if self.template_id.start_date: if self.template_id.start_date:
self.spread_date = self.template_id.start_date self.spread_date = self.template_id.start_date
if self.template_id.analytic_distribution:
self.analytic_distribution = self.template_id.analytic_distribution
self.days_calc = self.template_id.days_calc self.days_calc = self.template_id.days_calc
@api.depends("invoice_type", "company_id") @api.depends("invoice_type", "company_id")
@ -444,7 +455,7 @@ class AccountSpread(models.Model):
spread_end_date = spread_start_date + relativedelta(years=number_of_periods) spread_end_date = spread_start_date + relativedelta(years=number_of_periods)
# calculate by days and not first day of month should compute residual day only # calculate by days and not first day of month should compute residual day only
if self.days_calc and spread_end_date.day != 1: if self.days_calc and spread_end_date.day != 1:
spread_end_date = spread_end_date - timedelta(days=1) spread_end_date = spread_end_date - relativedelta(days=1)
else: else:
spread_end_date = self._get_last_day_of_month(spread_end_date) spread_end_date = self._get_last_day_of_month(spread_end_date)
return spread_end_date return spread_end_date
@ -564,6 +575,8 @@ class AccountSpread(models.Model):
if mls_to_reconcile: if mls_to_reconcile:
do_reconcile = mls_to_reconcile + self.invoice_line_id do_reconcile = mls_to_reconcile + self.invoice_line_id
do_reconcile.remove_move_reconcile() do_reconcile.remove_move_reconcile()
for line in do_reconcile:
line.reconciled = False
# ensure to reconcile only posted items # ensure to reconcile only posted items
do_reconcile = do_reconcile.filtered(lambda l: l.move_id.state == "posted") do_reconcile = do_reconcile.filtered(lambda l: l.move_id.state == "posted")
do_reconcile._check_spread_reconcile_validity() do_reconcile._check_spread_reconcile_validity()
@ -588,12 +601,13 @@ class AccountSpread(models.Model):
spread.is_debit_account_deprecated = spread.debit_account_id.deprecated spread.is_debit_account_deprecated = spread.debit_account_id.deprecated
spread.is_credit_account_deprecated = spread.credit_account_id.deprecated spread.is_credit_account_deprecated = spread.credit_account_id.deprecated
def open_reconcile_view(self): def open_posted_view(self):
action_name = "account_spread_cost_revenue.action_account_moves_all_spread" action_name = "account_spread_cost_revenue.action_account_moves_all_spread"
[action] = self.env.ref(action_name).read() action = self.env["ir.actions.act_window"]._for_xml_id(action_name)
action["domain"] = [("id", "in", [])] action["domain"] = [("id", "in", [])]
spread_mls = self.line_ids.mapped("move_id.line_ids") spread_mls = self.line_ids.mapped("move_id.line_ids")
spread_mls = spread_mls.filtered(lambda m: m.reconciled) if self.env.context.get("show_reconciled_only"):
spread_mls = spread_mls.filtered(lambda m: m.reconciled)
if spread_mls: if spread_mls:
domain = [("id", "in", spread_mls.ids + [self.invoice_line_id.id])] domain = [("id", "in", spread_mls.ids + [self.invoice_line_id.id])]
action["domain"] = domain action["domain"] = domain

View File

@ -64,16 +64,10 @@ class AccountInvoiceSpreadLine(models.Model):
spread_date = self.env.context.get("spread_date") or self.date spread_date = self.env.context.get("spread_date") or self.date
spread = self.spread_id spread = self.spread_id
analytic = spread.account_analytic_id analytic_distribution = spread.analytic_distribution
analytic_tags = []
if self.env["account.analytic.tag"].check_access_rights(
"read", raise_exception=False
):
analytic_tags = [(6, 0, spread.analytic_tag_ids.ids)]
company_currency = spread.company_id.currency_id company_currency = spread.company_id.currency_id
current_currency = spread.currency_id current_currency = spread.currency_id
not_same_curr = company_currency != current_currency
amount = current_currency._convert( amount = current_currency._convert(
self.amount, company_currency, spread.company_id, spread_date self.amount, company_currency, spread.company_id, spread_date
) )
@ -92,10 +86,9 @@ class AccountInvoiceSpreadLine(models.Model):
"debit": amount if amount > 0.0 else 0.0, "debit": amount if amount > 0.0 else 0.0,
"credit": -amount if amount < 0.0 else 0.0, "credit": -amount if amount < 0.0 else 0.0,
"partner_id": self.spread_id.invoice_id.partner_id.id, "partner_id": self.spread_id.invoice_id.partner_id.id,
"analytic_account_id": analytic.id, "journal_id": self.spread_id.journal_id.id,
"analytic_tag_ids": analytic_tags, "analytic_distribution": analytic_distribution,
"currency_id": not_same_curr and current_currency.id or False, "date": self.date,
"amount_currency": not_same_curr and -1.0 * self.amount or 0.0,
}, },
), ),
( (
@ -109,10 +102,9 @@ class AccountInvoiceSpreadLine(models.Model):
"credit": amount if amount > 0.0 else 0.0, "credit": amount if amount > 0.0 else 0.0,
"debit": -amount if amount < 0.0 else 0.0, "debit": -amount if amount < 0.0 else 0.0,
"partner_id": self.spread_id.invoice_id.partner_id.id, "partner_id": self.spread_id.invoice_id.partner_id.id,
"analytic_account_id": analytic.id, "journal_id": self.spread_id.journal_id.id,
"analytic_tag_ids": analytic_tags, "analytic_distribution": analytic_distribution,
"currency_id": not_same_curr and current_currency.id or False, "date": self.date,
"amount_currency": not_same_curr and self.amount or 0.0,
}, },
), ),
] ]

View File

@ -7,6 +7,7 @@ from odoo.exceptions import UserError
class AccountSpreadTemplate(models.Model): class AccountSpreadTemplate(models.Model):
_name = "account.spread.template" _name = "account.spread.template"
_inherit = "analytic.mixin"
_description = "Account Spread Template" _description = "Account Spread Template"
name = fields.Char(required=True) name = fields.Char(required=True)
@ -147,34 +148,10 @@ class AccountSpreadTemplate(models.Model):
spread_vals["invoice_type"] = invoice_type spread_vals["invoice_type"] = invoice_type
return spread_vals return spread_vals
@api.constrains("auto_spread_ids", "auto_spread")
def _check_auto_spread_ids_unique(self):
query = """
select product_id, account_id, analytic_account_id
from (
select product_id, account_id, analytic_account_id, count(*)
from account_spread_template_auto a
join account_spread_template b on a.template_id = b.id
where b.auto_spread = true and b.id in %s
group by product_id, account_id, analytic_account_id
) x where x.count > 1 """
self._cr.execute(query, [self._ids])
results = []
for res in self._cr.fetchall():
product = self.env["product.product"].browse(res[0])
account = self.env["account.account"].browse(res[1])
analytic = self.env["account.analytic.account"].browse(res[2])
results.append(
"{} / {} / {}".format(product.name, account.name, analytic.name)
)
if results:
raise UserError(
_("Followings are duplicated combinations,\n\n%s") % "\n".join(results)
)
class AccountSpreadTemplateAuto(models.Model): class AccountSpreadTemplateAuto(models.Model):
_name = "account.spread.template.auto" _name = "account.spread.template.auto"
_inherit = "analytic.mixin"
_description = "Auto create spread, based on product/account/analytic" _description = "Auto create spread, based on product/account/analytic"
template_id = fields.Many2one( template_id = fields.Many2one(
@ -200,7 +177,3 @@ class AccountSpreadTemplateAuto(models.Model):
comodel_name="account.account", comodel_name="account.account",
string="Account", string="Account",
) )
analytic_account_id = fields.Many2one(
comodel_name="account.analytic.account",
string="Analytic",
)

View File

@ -1,7 +1,7 @@
Define Spread Costs/Revenues Board Define Spread Costs/Revenues Board
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Under Invoicing -> Accounting -> Miscellaneous -> Spread Costs/Revenues, create a new spread board. Under Invoicing -> Accounting -> Journals -> Spread Costs/Revenues, create a new spread board.
Complete the definition of the spreading criteria, by setting the the fields: Complete the definition of the spreading criteria, by setting the the fields:
@ -13,17 +13,17 @@ Complete the definition of the spreading criteria, by setting the the fields:
* *Start date* * *Start date*
* *Journal* * *Journal*
.. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/spread.png .. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/spread.png
:alt: Create a new spread board :alt: Create a new spread board
Click on the "Recalculate unposted lines" button on the top-left to calculate the spread lines. Click on the "Recalculate unposted lines" button on the top-left to calculate the spread lines.
.. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/create_spread.png .. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/create_spread.png
:alt: The spreading board is defined :alt: The spreading board is defined
A cron job will automatically create the accounting moves for all the lines having date previous that the current day (today). A cron job will automatically create the accounting moves for all the lines having date previous that the current day (today).
.. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/update_spread.png .. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/update_spread.png
:alt: The spreading board is updated by the cron job :alt: The spreading board is updated by the cron job
By default, the status of the created accounting moves is posted. By default, the status of the created accounting moves is posted.
@ -38,7 +38,7 @@ Link Invoice to Spread Costs/Revenues Board
Create an invoice or vendor bill in draft. On its lines, the spreading right-arrow icon are displayed in dark-grey color. Create an invoice or vendor bill in draft. On its lines, the spreading right-arrow icon are displayed in dark-grey color.
.. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/invoice_line_1.png .. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/invoice_line_1.png
:alt: On the invoice line the spreading icon is displayed :alt: On the invoice line the spreading icon is displayed
Click on the spreading right-arrow icon. A wizard prompts to enter a *Spread Action Type*: Click on the spreading right-arrow icon. A wizard prompts to enter a *Spread Action Type*:
@ -53,11 +53,11 @@ the selected Spread Board will be automatically displayed.
Go back to the draft invoice/bill. The spreading functionality is now enabled on the invoice line: Go back to the draft invoice/bill. The spreading functionality is now enabled on the invoice line:
the spreading right-arrow icon is now displayed in green color. the spreading right-arrow icon is now displayed in green color.
.. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/invoice_line_2.png .. figure:: https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/invoice_line_2.png
:alt: On the invoice line the spreading icon is displayed in green color :alt: On the invoice line the spreading icon is displayed in green color
Validate the invoice/bill. Click on the spreading (green) right-arrow icon to open the spread board, then click Validate the invoice/bill. Click on the spreading (green) right-arrow icon to open the spread board, then click
on the smart button *Reconciled entries*: the moves of the spread lines are reconciled with the move of the invoice line. on the smart button *Posted entries* to see the moves of the spread lines together with the move of the invoice line.
In case the Subtotal Price of the invoice line is different than the *Estimated Amount* of the spread board, the spread In case the Subtotal Price of the invoice line is different than the *Estimated Amount* of the spread board, the spread
lines (not yet posted) will be recalculated when validating the invoice/bill. lines (not yet posted) will be recalculated when validating the invoice/bill.

View File

@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.15.1: http://docutils.sourceforge.net/" /> <meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>Cost-Revenue Spread</title> <title>Cost-Revenue Spread</title>
<style type="text/css"> <style type="text/css">
/* /*
:Author: David Goodger (goodger@python.org) :Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $ :Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Copyright: This stylesheet has been placed in the public domain. :Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils. Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet. customize this style sheet.
*/ */
@ -366,39 +366,41 @@ ul.auto-toc {
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! <!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !! !! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !! !! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:560d87ede92fd18ca4a929595b6a9fd9f558f6b577e8c9bad1f8e7236ad4175d
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/14.0/account_spread_cost_revenue"><img alt="OCA/account-financial-tools" src="https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/account-financial-tools-14-0/account-financial-tools-14-0-account_spread_cost_revenue"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/92/14.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p> <p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/account-financial-tools/tree/16.0/account_spread_cost_revenue"><img alt="OCA/account-financial-tools" src="https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/account-financial-tools-16-0/account-financial-tools-16-0-account_spread_cost_revenue"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/account-financial-tools&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Allows to spread costs or revenues over a customizable periods, to even out cost or invoice spikes.</p> <p>Allows to spread costs or revenues over a customizable periods, to even out cost or invoice spikes.</p>
<p><strong>Table of contents</strong></p> <p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents"> <div class="contents local topic" id="contents">
<ul class="simple"> <ul class="simple">
<li><a class="reference internal" href="#configuration" id="id7">Configuration</a></li> <li><a class="reference internal" href="#configuration" id="toc-entry-1">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="id8">Usage</a><ul> <li><a class="reference internal" href="#usage" id="toc-entry-2">Usage</a><ul>
<li><a class="reference internal" href="#define-spread-costs-revenues-board" id="id9">Define Spread Costs/Revenues Board</a></li> <li><a class="reference internal" href="#define-spread-costs-revenues-board" id="toc-entry-3">Define Spread Costs/Revenues Board</a></li>
<li><a class="reference internal" href="#link-invoice-to-spread-costs-revenues-board" id="id10">Link Invoice to Spread Costs/Revenues Board</a></li> <li><a class="reference internal" href="#link-invoice-to-spread-costs-revenues-board" id="toc-entry-4">Link Invoice to Spread Costs/Revenues Board</a></li>
<li><a class="reference internal" href="#define-spread-costs-revenues-template" id="id11">Define Spread Costs/Revenues Template</a></li> <li><a class="reference internal" href="#define-spread-costs-revenues-template" id="toc-entry-5">Define Spread Costs/Revenues Template</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#changelog" id="id12">Changelog</a><ul> <li><a class="reference internal" href="#changelog" id="toc-entry-6">Changelog</a><ul>
<li><a class="reference internal" href="#id1" id="id13">13.0.1.0.0</a></li> <li><a class="reference internal" href="#section-1" id="toc-entry-7">13.0.1.0.0</a></li>
<li><a class="reference internal" href="#id2" id="id14">12.0.2.0.0</a></li> <li><a class="reference internal" href="#section-2" id="toc-entry-8">12.0.2.0.0</a></li>
<li><a class="reference internal" href="#id3" id="id15">12.0.1.1.0</a></li> <li><a class="reference internal" href="#section-3" id="toc-entry-9">12.0.1.1.0</a></li>
<li><a class="reference internal" href="#id4" id="id16">12.0.1.0.0</a></li> <li><a class="reference internal" href="#section-4" id="toc-entry-10">12.0.1.0.0</a></li>
<li><a class="reference internal" href="#id5" id="id17">11.0.1.0.0</a></li> <li><a class="reference internal" href="#section-5" id="toc-entry-11">11.0.1.0.0</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#bug-tracker" id="id18">Bug Tracker</a></li> <li><a class="reference internal" href="#bug-tracker" id="toc-entry-12">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id19">Credits</a><ul> <li><a class="reference internal" href="#credits" id="toc-entry-13">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id20">Authors</a></li> <li><a class="reference internal" href="#authors" id="toc-entry-14">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id21">Contributors</a></li> <li><a class="reference internal" href="#contributors" id="toc-entry-15">Contributors</a></li>
<li><a class="reference internal" href="#other-credits" id="id22">Other credits</a></li> <li><a class="reference internal" href="#other-credits" id="toc-entry-16">Other credits</a></li>
<li><a class="reference internal" href="#maintainers" id="id23">Maintainers</a></li> <li><a class="reference internal" href="#maintainers" id="toc-entry-17">Maintainers</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</div> </div>
<div class="section" id="configuration"> <div class="section" id="configuration">
<h1><a class="toc-backref" href="#id7">Configuration</a></h1> <h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
<p>To be able to access the full spreading features, the user must belong to <em>Show Full Accounting Features</em> group.</p> <p>To be able to access the full spreading features, the user must belong to <em>Show Full Accounting Features</em> group.</p>
<p>On the form view of the company, in the <em>Account Spread</em> tab, you can configure <p>On the form view of the company, in the <em>Account Spread</em> tab, you can configure
the journals in which the spread journal items will be generated by default:</p> the journals in which the spread journal items will be generated by default:</p>
@ -422,10 +424,10 @@ enable/disable the automatic posting by the flag <em>Auto-post lines</em> presen
cron job to automatically archive the spreads when all lines are posted.</p> cron job to automatically archive the spreads when all lines are posted.</p>
</div> </div>
<div class="section" id="usage"> <div class="section" id="usage">
<h1><a class="toc-backref" href="#id8">Usage</a></h1> <h1><a class="toc-backref" href="#toc-entry-2">Usage</a></h1>
<div class="section" id="define-spread-costs-revenues-board"> <div class="section" id="define-spread-costs-revenues-board">
<h2><a class="toc-backref" href="#id9">Define Spread Costs/Revenues Board</a></h2> <h2><a class="toc-backref" href="#toc-entry-3">Define Spread Costs/Revenues Board</a></h2>
<p>Under Invoicing -&gt; Adviser -&gt; Accounting Entries -&gt; Spread Costs/Revenues, create a new spread board.</p> <p>Under Invoicing -&gt; Accounting -&gt; Journals -&gt; Spread Costs/Revenues, create a new spread board.</p>
<p>Complete the definition of the spreading criteria, by setting the the fields:</p> <p>Complete the definition of the spreading criteria, by setting the the fields:</p>
<ul class="simple"> <ul class="simple">
<li><em>Debit Account</em></li> <li><em>Debit Account</em></li>
@ -437,15 +439,15 @@ cron job to automatically archive the spreads when all lines are posted.</p>
<li><em>Journal</em></li> <li><em>Journal</em></li>
</ul> </ul>
<div class="figure"> <div class="figure">
<img alt="Create a new spread board" src="https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/spread.png" /> <img alt="Create a new spread board" src="https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/spread.png" />
</div> </div>
<p>Click on the button on the top-left to calculate the spread lines.</p> <p>Click on the “Recalculate unposted lines” button on the top-left to calculate the spread lines.</p>
<div class="figure"> <div class="figure">
<img alt="The spreading board is defined" src="https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/create_spread.png" /> <img alt="The spreading board is defined" src="https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/create_spread.png" />
</div> </div>
<p>A cron job will automatically create the accounting moves for all the lines having date previous that the current day (today).</p> <p>A cron job will automatically create the accounting moves for all the lines having date previous that the current day (today).</p>
<div class="figure"> <div class="figure">
<img alt="The spreading board is updated by the cron job" src="https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/update_spread.png" /> <img alt="The spreading board is updated by the cron job" src="https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/update_spread.png" />
</div> </div>
<p>By default, the status of the created accounting moves is posted. <p>By default, the status of the created accounting moves is posted.
To disable the automatic posting of the accounting moves, set the flag <em>Auto-post lines</em> to False. To disable the automatic posting of the accounting moves, set the flag <em>Auto-post lines</em> to False.
@ -454,10 +456,10 @@ This flag is only available when the <em>Auto-post spread lines</em> option, pre
this will also reset all the journal entries previously created.</p> this will also reset all the journal entries previously created.</p>
</div> </div>
<div class="section" id="link-invoice-to-spread-costs-revenues-board"> <div class="section" id="link-invoice-to-spread-costs-revenues-board">
<h2><a class="toc-backref" href="#id10">Link Invoice to Spread Costs/Revenues Board</a></h2> <h2><a class="toc-backref" href="#toc-entry-4">Link Invoice to Spread Costs/Revenues Board</a></h2>
<p>Create an invoice or vendor bill in draft. On its lines, the spreading right-arrow icon are displayed in dark-grey color.</p> <p>Create an invoice or vendor bill in draft. On its lines, the spreading right-arrow icon are displayed in dark-grey color.</p>
<div class="figure"> <div class="figure">
<img alt="On the invoice line the spreading icon is displayed" src="https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/invoice_line_1.png" /> <img alt="On the invoice line the spreading icon is displayed" src="https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/invoice_line_1.png" />
</div> </div>
<p>Click on the spreading right-arrow icon. A wizard prompts to enter a <em>Spread Action Type</em>:</p> <p>Click on the spreading right-arrow icon. A wizard prompts to enter a <em>Spread Action Type</em>:</p>
<ul class="simple"> <ul class="simple">
@ -470,15 +472,15 @@ the selected Spread Board will be automatically displayed.</p>
<p>Go back to the draft invoice/bill. The spreading functionality is now enabled on the invoice line: <p>Go back to the draft invoice/bill. The spreading functionality is now enabled on the invoice line:
the spreading right-arrow icon is now displayed in green color.</p> the spreading right-arrow icon is now displayed in green color.</p>
<div class="figure"> <div class="figure">
<img alt="On the invoice line the spreading icon is displayed in green color" src="https://raw.githubusercontent.com/OCA/account-financial-tools/12.0/account_spread_cost_revenue/static/description/invoice_line_2.png" /> <img alt="On the invoice line the spreading icon is displayed in green color" src="https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/account_spread_cost_revenue/static/description/invoice_line_2.png" />
</div> </div>
<p>Validate the invoice/bill. Click on the spreading (green) right-arrow icon to open the spread board, then click <p>Validate the invoice/bill. Click on the spreading (green) right-arrow icon to open the spread board, then click
on the smart button <em>Reconciled entries</em>: the moves of the spread lines are reconciled with the move of the invoice line.</p> on the smart button <em>Posted entries</em> to see the moves of the spread lines together with the move of the invoice line.</p>
<p>In case the Subtotal Price of the invoice line is different than the <em>Estimated Amount</em> of the spread board, the spread <p>In case the Subtotal Price of the invoice line is different than the <em>Estimated Amount</em> of the spread board, the spread
lines (not yet posted) will be recalculated when validating the invoice/bill.</p> lines (not yet posted) will be recalculated when validating the invoice/bill.</p>
</div> </div>
<div class="section" id="define-spread-costs-revenues-template"> <div class="section" id="define-spread-costs-revenues-template">
<h2><a class="toc-backref" href="#id11">Define Spread Costs/Revenues Template</a></h2> <h2><a class="toc-backref" href="#toc-entry-5">Define Spread Costs/Revenues Template</a></h2>
<p>Under Invoicing -&gt; Configuration -&gt; Accounting -&gt; Spread Templates, create a new spread template.</p> <p>Under Invoicing -&gt; Configuration -&gt; Accounting -&gt; Spread Templates, create a new spread template.</p>
<ul class="simple"> <ul class="simple">
<li><em>Spread Type</em></li> <li><em>Spread Type</em></li>
@ -493,34 +495,34 @@ This way the above fields will be copied to the Spread Board.</p>
</div> </div>
</div> </div>
<div class="section" id="changelog"> <div class="section" id="changelog">
<h1><a class="toc-backref" href="#id12">Changelog</a></h1> <h1><a class="toc-backref" href="#toc-entry-6">Changelog</a></h1>
<div class="section" id="id1"> <div class="section" id="section-1">
<h2><a class="toc-backref" href="#id13">13.0.1.0.0</a></h2> <h2><a class="toc-backref" href="#toc-entry-7">13.0.1.0.0</a></h2>
<ul class="simple"> <ul class="simple">
<li>[MIG] Port account_spread_cost_revenue to V13.</li> <li>[MIG] Port account_spread_cost_revenue to V13.</li>
</ul> </ul>
</div> </div>
<div class="section" id="id2"> <div class="section" id="section-2">
<h2><a class="toc-backref" href="#id14">12.0.2.0.0</a></h2> <h2><a class="toc-backref" href="#toc-entry-8">12.0.2.0.0</a></h2>
<ul class="simple"> <ul class="simple">
<li>[ENH] In spread template, add option to auto create spread on invoice validation</li> <li>[ENH] In spread template, add option to auto create spread on invoice validation</li>
</ul> </ul>
</div> </div>
<div class="section" id="id3"> <div class="section" id="section-3">
<h2><a class="toc-backref" href="#id15">12.0.1.1.0</a></h2> <h2><a class="toc-backref" href="#toc-entry-9">12.0.1.1.0</a></h2>
<ul class="simple"> <ul class="simple">
<li>[ENH] Add optional Expense/Revenue Account in Chart Template, which can be used <li>[ENH] Add optional Expense/Revenue Account in Chart Template, which can be used
in place of account from invoice line to set Expense/Revenue account in the spread</li> in place of account from invoice line to set Expense/Revenue account in the spread</li>
</ul> </ul>
</div> </div>
<div class="section" id="id4"> <div class="section" id="section-4">
<h2><a class="toc-backref" href="#id16">12.0.1.0.0</a></h2> <h2><a class="toc-backref" href="#toc-entry-10">12.0.1.0.0</a></h2>
<ul class="simple"> <ul class="simple">
<li>[MIG] Port account_spread_cost_revenue to V12.</li> <li>[MIG] Port account_spread_cost_revenue to V12.</li>
</ul> </ul>
</div> </div>
<div class="section" id="id5"> <div class="section" id="section-5">
<h2><a class="toc-backref" href="#id17">11.0.1.0.0</a></h2> <h2><a class="toc-backref" href="#toc-entry-11">11.0.1.0.0</a></h2>
<ul class="simple"> <ul class="simple">
<li>[ADD] Module account_spread_cost_revenue. <li>[ADD] Module account_spread_cost_revenue.
(<a class="reference external" href="https://github.com/OCA/account-financial-tools/pull/715">#715</a>)</li> (<a class="reference external" href="https://github.com/OCA/account-financial-tools/pull/715">#715</a>)</li>
@ -528,44 +530,43 @@ in place of account from invoice line to set Expense/Revenue account in the spre
</div> </div>
</div> </div>
<div class="section" id="bug-tracker"> <div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id18">Bug Tracker</a></h1> <h1><a class="toc-backref" href="#toc-entry-12">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues">GitHub Issues</a>. <p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_spread_cost_revenue%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p> <a class="reference external" href="https://github.com/OCA/account-financial-tools/issues/new?body=module:%20account_spread_cost_revenue%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p> <p>Do not contact contributors directly about support or help with technical issues.</p>
</div> </div>
<div class="section" id="credits"> <div class="section" id="credits">
<h1><a class="toc-backref" href="#id19">Credits</a></h1> <h1><a class="toc-backref" href="#toc-entry-13">Credits</a></h1>
<div class="section" id="authors"> <div class="section" id="authors">
<h2><a class="toc-backref" href="#id20">Authors</a></h2> <h2><a class="toc-backref" href="#toc-entry-14">Authors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Onestein</li> <li>Onestein</li>
</ul> </ul>
</div> </div>
<div class="section" id="contributors"> <div class="section" id="contributors">
<h2><a class="toc-backref" href="#id21">Contributors</a></h2> <h2><a class="toc-backref" href="#toc-entry-15">Contributors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Andrea Stirpe &lt;<a class="reference external" href="mailto:a.stirpe&#64;onestein.nl">a.stirpe&#64;onestein.nl</a>&gt;</li> <li>Andrea Stirpe &lt;<a class="reference external" href="mailto:a.stirpe&#64;onestein.nl">a.stirpe&#64;onestein.nl</a>&gt;</li>
<li>Kitti U. &lt;<a class="reference external" href="mailto:kittiu&#64;ecosoft.co.th">kittiu&#64;ecosoft.co.th</a>&gt;</li> <li>Kitti U. &lt;<a class="reference external" href="mailto:kittiu&#64;ecosoft.co.th">kittiu&#64;ecosoft.co.th</a>&gt;</li>
<li>Saran Lim. &lt;<a class="reference external" href="mailto:saranl&#64;ecosoft.co.th">saranl&#64;ecosoft.co.th</a>&gt;</li>
</ul> </ul>
</div> </div>
<div class="section" id="other-credits"> <div class="section" id="other-credits">
<h2><a class="toc-backref" href="#id22">Other credits</a></h2> <h2><a class="toc-backref" href="#toc-entry-16">Other credits</a></h2>
<p>Part of the code in this module (in particular the computation of the spread lines) <p>Part of the code in this module (in particular the computation of the spread lines)
is highly inspired by the Assets Management module from the standard is highly inspired by the Assets Management module from the standard
Odoo 11.0 Community developed by Odoo SA.</p> Odoo 11.0 Community developed by Odoo SA.</p>
</div> </div>
<div class="section" id="maintainers"> <div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id23">Maintainers</a></h2> <h2><a class="toc-backref" href="#toc-entry-17">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p> <p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a> <a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose <p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and mission is to support the collaborative development of Odoo features and
promote its widespread use.</p> promote its widespread use.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p> <p>This module is part of the <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/16.0/account_spread_cost_revenue">OCA/account-financial-tools</a> project on GitHub.</p>
<p><a class="reference external" href="https://github.com/astirpe"><img alt="astirpe" src="https://github.com/astirpe.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/account-financial-tools/tree/14.0/account_spread_cost_revenue">OCA/account-financial-tools</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p> <p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div> </div>
</div> </div>

View File

@ -1,61 +0,0 @@
odoo.define("account_spread_cost_revenue.widget", function (require) {
"use strict";
var AbstractField = require("web.AbstractField");
var core = require("web.core");
var registry = require("web.field_registry");
var _t = core._t;
var AccountSpreadWidget = AbstractField.extend({
events: _.extend({}, AbstractField.prototype.events, {
click: "_onClick",
}),
noLabel: true,
/**
* @override
*/
isSet: function () {
return this.value !== "unavailable";
},
/**
* @override
* @private
*/
_render: function () {
var className = "";
var style = "btn fa fa-arrow-circle-right o_spread_line ";
var title = "";
if (this.recordData.spread_check === "linked") {
className = "o_is_linked";
title = _t("Linked to spread");
} else {
title = _t("Not linked to spread");
}
var $button = $("<button/>", {
type: "button",
title: title,
}).addClass(style + className);
this.$el.html($button);
},
/**
* @private
* @param {MouseEvent} event
*/
_onClick: function (event) {
event.stopPropagation();
this.trigger_up("button_clicked", {
attrs: {
name: "spread_details",
type: "object",
},
record: this.record,
});
},
});
registry.add("spread_line_widget", AccountSpreadWidget);
});

View File

@ -1,5 +0,0 @@
.o_web_client .o_spread_line {
&.o_is_linked {
color: theme-color("success");
}
}

View File

@ -58,7 +58,6 @@ class TestAccountInvoiceAutoSpread(TestAccountInvoiceSpread):
], ],
} }
) )
template2._check_auto_spread_ids_unique()
self.assertFalse(self.vendor_bill_line.spread_id) self.assertFalse(self.vendor_bill_line.spread_id)
with self.assertRaises(UserError): # too many auto_spread_ids matched with self.assertRaises(UserError): # too many auto_spread_ids matched

View File

@ -33,14 +33,14 @@ class TestAccountInvoiceSpread(common.TransactionCase):
{ {
"code": "X2120", "code": "X2120",
"name": "Expenses - (test)", "name": "Expenses - (test)",
"user_type_id": self.env.ref("account.data_account_type_expenses").id, "account_type": "expense",
} }
) )
a_sale = self.env["account.account"].create( a_sale = self.env["account.account"].create(
{ {
"code": "X2020", "code": "X2020",
"name": "Product Sales - (test)", "name": "Product Sales - (test)",
"user_type_id": self.env.ref("account.data_account_type_revenue").id, "account_type": "expense_direct_cost",
} }
) )
@ -67,9 +67,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
{ {
"name": "Test account payable", "name": "Test account payable",
"code": "321spread", "code": "321spread",
"user_type_id": self.env.ref( "account_type": "income_other",
"account.data_account_type_other_income"
).id,
"reconcile": True, "reconcile": True,
} }
) )
@ -78,9 +76,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
{ {
"name": "Test account receivable", "name": "Test account receivable",
"code": "322spread", "code": "322spread",
"user_type_id": self.env.ref( "account_type": "income_other",
"account.data_account_type_other_income"
).id,
"reconcile": True, "reconcile": True,
} }
) )
@ -89,9 +85,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
{ {
"name": "test spread account_payable", "name": "test spread account_payable",
"code": "765spread", "code": "765spread",
"user_type_id": self.env.ref( "account_type": "income_other",
"account.data_account_type_other_income"
).id,
"reconcile": True, "reconcile": True,
} }
) )
@ -100,9 +94,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
{ {
"name": "test spread account_receivable", "name": "test spread account_receivable",
"code": "766spread", "code": "766spread",
"user_type_id": self.env.ref( "account_type": "income_other",
"account.data_account_type_other_income"
).id,
"reconcile": True, "reconcile": True,
} }
) )
@ -120,9 +112,17 @@ class TestAccountInvoiceSpread(common.TransactionCase):
self.vendor_bill_line.account_id.reconcile = True self.vendor_bill_line.account_id.reconcile = True
self.invoice_line.account_id.reconcile = True self.invoice_line.account_id.reconcile = True
analytic_tags = [(6, 0, self.env.ref("analytic.tag_contract").ids)] analytic_plan = self.env["account.analytic.plan"].create(
{"name": "Plan Test", "company_id": False}
)
self.analytic_account = self.env["account.analytic.account"].create( self.analytic_account = self.env["account.analytic.account"].create(
{"name": "test account"} {"name": "test account", "plan_id": analytic_plan.id}
)
self.distribution = self.env["account.analytic.distribution.model"].create(
{
"partner_id": self.vendor_bill.partner_id.id,
"analytic_distribution": {self.analytic_account.id: 100},
}
) )
self.spread = ( self.spread = (
self.env["account.spread"] self.env["account.spread"]
@ -139,8 +139,11 @@ class TestAccountInvoiceSpread(common.TransactionCase):
"estimated_amount": 1000.0, "estimated_amount": 1000.0,
"journal_id": self.vendor_bill.journal_id.id, "journal_id": self.vendor_bill.journal_id.id,
"invoice_type": "in_invoice", "invoice_type": "in_invoice",
"account_analytic_id": self.analytic_account.id, "analytic_distribution": self.distribution._get_distribution(
"analytic_tag_ids": analytic_tags, {
"partner_id": self.vendor_bill.partner_id.id,
}
),
} }
] ]
) )
@ -248,7 +251,6 @@ class TestAccountInvoiceSpread(common.TransactionCase):
{ {
"groups_id": [ "groups_id": [
(4, self.env.ref("analytic.group_analytic_accounting").id), (4, self.env.ref("analytic.group_analytic_accounting").id),
(4, self.env.ref("analytic.group_analytic_tags").id),
], ],
} }
) )
@ -279,9 +281,9 @@ class TestAccountInvoiceSpread(common.TransactionCase):
line.create_move() line.create_move()
self.assertTrue(line.move_id) self.assertTrue(line.move_id)
for ml in line.move_id.line_ids: for ml in line.move_id.line_ids:
analytic_tag = self.env.ref("analytic.tag_contract") self.assertEqual(
self.assertEqual(ml.analytic_account_id, self.analytic_account) ml.analytic_distribution, self.spread.analytic_distribution
self.assertEqual(ml.analytic_tag_ids, analytic_tag) )
self.spread.invoice_id.button_cancel() self.spread.invoice_id.button_cancel()
@ -558,10 +560,10 @@ class TestAccountInvoiceSpread(common.TransactionCase):
if spread_ml.credit: if spread_ml.credit:
self.assertFalse(spread_ml.full_reconcile_id) self.assertFalse(spread_ml.full_reconcile_id)
action_reconcile_view = self.spread2.open_reconcile_view() action_posted_view = self.spread2.open_posted_view()
self.assertTrue(isinstance(action_reconcile_view, dict)) self.assertTrue(isinstance(action_posted_view, dict))
self.assertFalse(action_reconcile_view.get("domain")[0][2]) self.assertFalse(action_posted_view.get("domain")[0][2])
self.assertTrue(action_reconcile_view.get("context")) self.assertTrue(action_posted_view.get("context"))
def test_11_link_vendor_bill_line_with_spread_sheet(self): def test_11_link_vendor_bill_line_with_spread_sheet(self):
invoice_form = Form(self.vendor_bill) invoice_form = Form(self.vendor_bill)
@ -625,10 +627,10 @@ class TestAccountInvoiceSpread(common.TransactionCase):
self.assertEqual(spread_ml.account_id, expense_account) self.assertEqual(spread_ml.account_id, expense_account)
self.assertFalse(spread_ml.full_reconcile_id) self.assertFalse(spread_ml.full_reconcile_id)
action_reconcile_view = self.spread.open_reconcile_view() action_posted_view = self.spread.open_posted_view()
self.assertTrue(isinstance(action_reconcile_view, dict)) self.assertTrue(isinstance(action_posted_view, dict))
self.assertTrue(action_reconcile_view.get("domain")[0][2]) self.assertTrue(action_posted_view.get("domain")[0][2])
self.assertTrue(action_reconcile_view.get("context")) self.assertTrue(action_posted_view.get("context"))
action_spread_details = self.vendor_bill_line.spread_details() action_spread_details = self.vendor_bill_line.spread_details()
self.assertTrue(isinstance(action_spread_details, dict)) self.assertTrue(isinstance(action_spread_details, dict))
@ -679,11 +681,11 @@ class TestAccountInvoiceSpread(common.TransactionCase):
for invoice_ml in invoice_mls: for invoice_ml in invoice_mls:
self.assertEqual(invoice_ml.account_id, balance_sheet) self.assertEqual(invoice_ml.account_id, balance_sheet)
action_reconcile_view = self.spread2.open_reconcile_view() action_posted_view = self.spread2.open_posted_view()
self.assertTrue(isinstance(action_reconcile_view, dict)) self.assertTrue(isinstance(action_posted_view, dict))
self.assertFalse(action_reconcile_view.get("domain")[0][2]) self.assertTrue(action_posted_view.get("domain")[0][2])
self.assertFalse(action_reconcile_view.get("res_id")) self.assertFalse(action_posted_view.get("res_id"))
self.assertTrue(action_reconcile_view.get("context")) self.assertTrue(action_posted_view.get("context"))
action_spread_details = self.invoice_line.spread_details() action_spread_details = self.invoice_line.spread_details()
self.assertTrue(isinstance(action_spread_details, dict)) self.assertTrue(isinstance(action_spread_details, dict))

View File

@ -3,7 +3,7 @@
import datetime import datetime
from psycopg2 import IntegrityError from psycopg2.errors import NotNullViolation
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
from odoo.tests import Form, common from odoo.tests import Form, common
@ -22,16 +22,11 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
{"name": "Vendor Bills - Test", "code": "TEST2", "type": "purchase"} {"name": "Vendor Bills - Test", "code": "TEST2", "type": "purchase"}
) )
type_receivable = self.env.ref("account.data_account_type_receivable")
type_expenses = self.env.ref("account.data_account_type_expenses")
type_payable = self.env.ref("account.data_account_type_payable")
type_revenue = self.env.ref("account.data_account_type_revenue")
self.credit_account = self.env["account.account"].create( self.credit_account = self.env["account.account"].create(
{ {
"name": "test_account_receivable", "name": "test_account_receivable",
"code": "123", "code": "123",
"user_type_id": type_receivable.id, "account_type": "asset_receivable",
"reconcile": True, "reconcile": True,
} }
) )
@ -40,7 +35,7 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
{ {
"name": "test account_expenses", "name": "test account_expenses",
"code": "765", "code": "765",
"user_type_id": type_expenses.id, "account_type": "expense",
"reconcile": True, "reconcile": True,
} }
) )
@ -49,7 +44,7 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
{ {
"name": "test_account_payable", "name": "test_account_payable",
"code": "321", "code": "321",
"user_type_id": type_payable.id, "account_type": "liability_payable",
"reconcile": True, "reconcile": True,
} }
) )
@ -58,7 +53,7 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
{ {
"name": "test_account_revenue", "name": "test_account_revenue",
"code": "864", "code": "864",
"user_type_id": type_revenue.id, "account_type": "asset_receivable",
"reconcile": True, "reconcile": True,
} }
) )
@ -85,8 +80,7 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
self.assertFalse(spread.invoice_line_ids) self.assertFalse(spread.invoice_line_ids)
self.assertFalse(spread.invoice_line_id) self.assertFalse(spread.invoice_line_id)
self.assertFalse(spread.invoice_id) self.assertFalse(spread.invoice_id)
self.assertFalse(spread.account_analytic_id) self.assertFalse(spread.analytic_distribution)
self.assertFalse(spread.analytic_tag_ids)
self.assertTrue(spread.move_line_auto_post) self.assertTrue(spread.move_line_auto_post)
self.assertEqual(spread.name, "test") self.assertEqual(spread.name, "test")
self.assertEqual(spread.invoice_type, "out_invoice") self.assertEqual(spread.invoice_type, "out_invoice")
@ -116,14 +110,29 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
@mute_logger("odoo.sql_db") @mute_logger("odoo.sql_db")
def test_03_no_defaults(self): def test_03_no_defaults(self):
with self.assertRaises(IntegrityError): with self.assertRaises(NotNullViolation):
self.env["account.spread"].create({"name": "test"}) self.env["account.spread"].create({"name": "test"})
with self.assertRaises(NotNullViolation):
self.env["account.spread"].create(
{"name": "test", "invoice_type": "out_invoice"}
)
@mute_logger("odoo.sql_db") @mute_logger("odoo.sql_db")
def test_04_no_defaults(self): def test_04_no_defaults(self):
with self.assertRaises(IntegrityError): with self.assertRaises(NotNullViolation):
self.env["account.spread"].create( self.env["account.spread"].create(
{"name": "test", "invoice_type": "out_invoice"} {
"name": "test",
"debit_account_id": self.debit_account.id,
"credit_account_id": self.credit_account.id,
}
)
with self.assertRaises(NotNullViolation):
self.env["account.spread"].create(
{
"name": "test",
"credit_account_id": self.credit_account.id,
}
) )
def test_05_config_settings(self): def test_05_config_settings(self):
@ -137,6 +146,8 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
self.assertTrue(self.env.company.default_spread_revenue_journal_id) self.assertTrue(self.env.company.default_spread_revenue_journal_id)
self.assertTrue(self.env.company.default_spread_expense_journal_id) self.assertTrue(self.env.company.default_spread_expense_journal_id)
self.env.user.groups_id += self.env.ref("base.group_multi_company")
spread_form = Form(self.env["account.spread"]) spread_form = Form(self.env["account.spread"])
spread_form.name = "test" spread_form.name = "test"
spread_form.invoice_type = "in_invoice" spread_form.invoice_type = "in_invoice"
@ -149,8 +160,7 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
self.assertFalse(spread.invoice_line_ids) self.assertFalse(spread.invoice_line_ids)
self.assertFalse(spread.invoice_line_id) self.assertFalse(spread.invoice_line_id)
self.assertFalse(spread.invoice_id) self.assertFalse(spread.invoice_id)
self.assertFalse(spread.account_analytic_id) self.assertFalse(spread.analytic_distribution)
self.assertFalse(spread.analytic_tag_ids)
self.assertTrue(spread.move_line_auto_post) self.assertTrue(spread.move_line_auto_post)
defaults = self.env["account.spread"].default_get(["company_id", "currency_id"]) defaults = self.env["account.spread"].default_get(["company_id", "currency_id"])

View File

@ -4,14 +4,12 @@
import datetime import datetime
from odoo.exceptions import UserError from odoo.exceptions import UserError
from odoo.tests import common from odoo.tests import Form, common
class TestComputeSpreadBoard(common.TransactionCase): class TestComputeSpreadBoard(common.TransactionCase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
type_receivable = self.env.ref("account.data_account_type_receivable")
type_expenses = self.env.ref("account.data_account_type_expenses")
journal = self.env["account.journal"].create( journal = self.env["account.journal"].create(
{"name": "Test", "type": "general", "code": "test"} {"name": "Test", "type": "general", "code": "test"}
@ -21,7 +19,7 @@ class TestComputeSpreadBoard(common.TransactionCase):
{ {
"name": "test_account_receivable", "name": "test_account_receivable",
"code": "123", "code": "123",
"user_type_id": type_receivable.id, "account_type": "asset_receivable",
"reconcile": True, "reconcile": True,
} }
) )
@ -30,7 +28,7 @@ class TestComputeSpreadBoard(common.TransactionCase):
{ {
"name": "test account_expenses", "name": "test account_expenses",
"code": "765", "code": "765",
"user_type_id": type_expenses.id, "account_type": "expense",
"reconcile": True, "reconcile": True,
} }
) )
@ -39,7 +37,7 @@ class TestComputeSpreadBoard(common.TransactionCase):
{ {
"name": "test spread account_expenses", "name": "test spread account_expenses",
"code": "321", "code": "321",
"user_type_id": type_expenses.id, "account_type": "expense",
"reconcile": True, "reconcile": True,
} }
) )
@ -72,6 +70,34 @@ class TestComputeSpreadBoard(common.TransactionCase):
} }
) )
self.spread3 = self.env["account.spread"].create(
{
"name": "test by cal days",
"debit_account_id": self.spread_account.id,
"credit_account_id": self.expense_account.id,
"period_number": 12,
"period_type": "month",
"spread_date": "2017-02-01",
"estimated_amount": 12000.0,
"journal_id": journal.id,
"invoice_type": "out_invoice",
"days_calc": True,
}
)
self.template = self.env["account.spread.template"].create(
{
"name": "test",
"spread_type": "purchase",
"period_number": 5,
"period_type": "month",
"start_date": "2017-01-01",
"spread_account_id": self.spread_account.id,
"spread_journal_id": journal.id,
"days_calc": True,
}
)
def test_01_supplier_invoice(self): def test_01_supplier_invoice(self):
self.spread.compute_spread_board() self.spread.compute_spread_board()
spread_lines = self.spread.line_ids spread_lines = self.spread.line_ids
@ -617,3 +643,83 @@ class TestComputeSpreadBoard(common.TransactionCase):
self.assertAlmostEqual(self.spread.unspread_amount, 682.81) self.assertAlmostEqual(self.spread.unspread_amount, 682.81)
self.assertAlmostEqual(self.spread.unposted_amount, 682.81) self.assertAlmostEqual(self.spread.unposted_amount, 682.81)
def test_19_supplier_invoice_calc_day(self):
self.assertTrue(self.spread3.days_calc)
self.spread3.compute_spread_board()
spread_lines = self.spread3.line_ids
self.assertEqual(len(spread_lines), 12)
# Calculate by day has formula:
# (amount spread cost / all spread cost day) * day of <period_type>
self.assertAlmostEqual(920.55, spread_lines[0].amount)
self.assertAlmostEqual(1019.18, spread_lines[1].amount)
self.assertAlmostEqual(986.30, spread_lines[2].amount)
self.assertAlmostEqual(1019.18, spread_lines[3].amount)
self.assertAlmostEqual(986.30, spread_lines[4].amount)
self.assertAlmostEqual(1019.18, spread_lines[5].amount)
self.assertAlmostEqual(1019.18, spread_lines[6].amount)
self.assertAlmostEqual(986.30, spread_lines[7].amount)
self.assertAlmostEqual(1019.18, spread_lines[8].amount)
self.assertAlmostEqual(986.30, spread_lines[9].amount)
self.assertAlmostEqual(1019.18, spread_lines[10].amount)
self.assertAlmostEqual(1019.17, spread_lines[11].amount) # total left
self.assertEqual(datetime.date(2017, 2, 28), spread_lines[0].date)
self.assertEqual(datetime.date(2017, 3, 31), spread_lines[1].date)
self.assertEqual(datetime.date(2017, 4, 30), spread_lines[2].date)
self.assertEqual(datetime.date(2017, 5, 31), spread_lines[3].date)
self.assertEqual(datetime.date(2017, 6, 30), spread_lines[4].date)
self.assertEqual(datetime.date(2017, 7, 31), spread_lines[5].date)
self.assertEqual(datetime.date(2017, 8, 31), spread_lines[6].date)
self.assertEqual(datetime.date(2017, 9, 30), spread_lines[7].date)
self.assertEqual(datetime.date(2017, 10, 31), spread_lines[8].date)
self.assertEqual(datetime.date(2017, 11, 30), spread_lines[9].date)
self.assertEqual(datetime.date(2017, 12, 31), spread_lines[10].date)
self.assertEqual(datetime.date(2018, 1, 31), spread_lines[11].date)
# Period Type is 'Quarter'
self.spread3.period_type = "quarter"
self.spread3.compute_spread_board()
spread_lines = self.spread3.line_ids
self.assertEqual(len(spread_lines), 12)
self.assertAlmostEqual(325.27, spread_lines[0].amount)
self.assertAlmostEqual(1068.73, spread_lines[1].amount)
self.assertAlmostEqual(1068.73, spread_lines[2].amount)
self.assertAlmostEqual(1057.12, spread_lines[3].amount)
self.assertAlmostEqual(1045.50, spread_lines[4].amount)
self.assertAlmostEqual(1068.73, spread_lines[5].amount)
self.assertAlmostEqual(1068.73, spread_lines[6].amount)
self.assertAlmostEqual(1057.12, spread_lines[7].amount)
self.assertAlmostEqual(1045.50, spread_lines[8].amount)
self.assertAlmostEqual(1068.73, spread_lines[9].amount)
self.assertAlmostEqual(1068.73, spread_lines[10].amount)
self.assertAlmostEqual(1057.11, spread_lines[11].amount) # total left
# Period Type is 'Year' and spread date is not first month
self.spread3.period_type = "year"
self.spread3.spread_date = "2017-02-02"
self.spread3.compute_spread_board()
spread_lines = self.spread3.line_ids
self.assertEqual(len(spread_lines), 13)
self.assertAlmostEqual(73.92, spread_lines[0].amount)
self.assertAlmostEqual(999.32, spread_lines[1].amount)
self.assertAlmostEqual(999.32, spread_lines[2].amount)
self.assertAlmostEqual(1002.05, spread_lines[3].amount)
self.assertAlmostEqual(999.32, spread_lines[4].amount)
self.assertAlmostEqual(999.32, spread_lines[5].amount)
self.assertAlmostEqual(999.32, spread_lines[6].amount)
self.assertAlmostEqual(1002.05, spread_lines[7].amount)
self.assertAlmostEqual(999.32, spread_lines[8].amount)
self.assertAlmostEqual(999.32, spread_lines[9].amount)
self.assertAlmostEqual(999.32, spread_lines[10].amount)
self.assertAlmostEqual(1002.05, spread_lines[11].amount)
self.assertAlmostEqual(925.37, spread_lines[12].amount)
def test_20_supplier_invoice_template(self):
"""Test onchange template"""
self.assertEqual(self.spread3.invoice_type, "out_invoice")
with Form(self.spread3) as sp:
sp.template_id = self.template
sp.credit_account_id = self.expense_account
sp.save()
self.assertEqual(self.spread3.invoice_type, "in_invoice")

View File

@ -10,9 +10,46 @@
> >
<field <field
name="spread_check" name="spread_check"
widget="spread_line_widget" invisible="1"
groups="account.group_account_user,account.group_account_manager" groups="account.group_account_user,account.group_account_manager"
/> />
<button
name="spread_details"
type="object"
class="btn btn-link"
icon="fa-arrow-circle-right"
title="Not linked to any spread board"
attrs="{'invisible': [('spread_check', '!=', 'unlinked')]}"
groups="account.group_account_user,account.group_account_manager"
/>
<button
name="spread_details"
type="object"
class="btn btn-success"
icon="fa-arrow-circle-right"
title="Linked to spread board"
attrs="{'invisible': [('spread_check', '!=', 'linked')]}"
groups="account.group_account_user,account.group_account_manager"
/>
</xpath>
<xpath
expr="//field[@name='line_ids']/tree//button[@name='action_automatic_entry']"
position="after"
>
<field
name="spread_check"
invisible="1"
groups="account.group_account_user,account.group_account_manager"
/>
<button
name="spread_details"
type="object"
class="btn btn-success"
icon="fa-arrow-circle-right"
title="Linked to spread board"
groups="account.group_account_user,account.group_account_manager"
attrs="{'invisible': [('spread_check', '!=', 'linked')], 'column_invisible': ['|', ('parent.move_type', '=', 'entry'), ('parent.state', '!=', 'posted')]}"
/>
</xpath> </xpath>
</field> </field>
</record> </record>
@ -25,7 +62,7 @@
<field <field
name="domain" name="domain"
>[('display_type', 'not in', ('line_section', 'line_note'))]</field> >[('display_type', 'not in', ('line_section', 'line_note'))]</field>
<field name="view_id" ref="account.view_move_line_tree_grouped" /> <field name="view_id" ref="account.view_move_line_tree" />
<field name="view_mode">tree,pivot,graph,form,kanban</field> <field name="view_mode">tree,pivot,graph,form,kanban</field>
</record> </record>
</odoo> </odoo>

View File

@ -37,11 +37,11 @@
<sheet> <sheet>
<div name="button_box" class="oe_button_box"> <div name="button_box" class="oe_button_box">
<button <button
name="open_reconcile_view" name="open_posted_view"
class="oe_stat_button" class="oe_stat_button"
icon="fa-bars" icon="fa-bars"
type="object" type="object"
string="Reconciled entries" string="Posted entries"
> >
</button> </button>
</div> </div>
@ -91,7 +91,7 @@
/> />
<div <div
attrs="{'invisible': [('use_invoice_line_account', '=', True)]}" attrs="{'invisible': [('use_invoice_line_account', '=', True)]}"
colspan="2" colspan="3"
> >
<span <span
class="help-block" class="help-block"
@ -112,7 +112,7 @@
</div> </div>
<div <div
attrs="{'invisible': [('use_invoice_line_account', '!=', True)]}" attrs="{'invisible': [('use_invoice_line_account', '!=', True)]}"
colspan="2" colspan="3"
> >
<span <span
class="help-block" class="help-block"
@ -134,7 +134,7 @@
<field <field
name="debit_account_id" name="debit_account_id"
required="1" required="1"
domain="[('company_id', '=', company_id), ('deprecated', '=', False), ('internal_type','!=','liquidity'), ('internal_group', '!=', 'off_balance')]" domain="[('deprecated', '=', False), ('account_type', 'not in', ('asset_cash','liability_credit_card')), ('internal_group', '!=', 'off_balance')]"
attrs="{'readonly':[('invoice_line_id','!=',False)]}" attrs="{'readonly':[('invoice_line_id','!=',False)]}"
/> />
<span <span
@ -161,7 +161,7 @@
/> />
<div <div
attrs="{'invisible': [('use_invoice_line_account', '=', True)]}" attrs="{'invisible': [('use_invoice_line_account', '=', True)]}"
colspan="2" colspan="3"
> >
<span <span
class="help-block" class="help-block"
@ -182,7 +182,7 @@
</div> </div>
<div <div
attrs="{'invisible': [('use_invoice_line_account', '!=', True)]}" attrs="{'invisible': [('use_invoice_line_account', '!=', True)]}"
colspan="2" colspan="3"
> >
<span <span
class="help-block" class="help-block"
@ -204,7 +204,7 @@
<field <field
name="credit_account_id" name="credit_account_id"
required="1" required="1"
domain="[('company_id', '=', company_id), ('deprecated', '=', False), ('internal_type','!=','liquidity'), ('internal_group', '!=', 'off_balance')]" domain="[('deprecated', '=', False), ('account_type', 'not in', ('asset_cash','liability_credit_card')), ('internal_group', '!=', 'off_balance')]"
attrs="{'readonly':[('invoice_line_id','!=',False)]}" attrs="{'readonly':[('invoice_line_id','!=',False)]}"
/> />
<span <span
@ -244,12 +244,9 @@
<field name="period_number" /> <field name="period_number" />
<field name="period_type" /> <field name="period_type" />
<field name="spread_date" /> <field name="spread_date" />
<field
name="journal_id"
domain="[('company_id', '=', company_id)]"
widget="selection"
/>
<field name="days_calc" /> <field name="days_calc" />
<field name="suitable_journal_ids" invisible="1" />
<field name="journal_id" widget="selection" />
</group> </group>
</group> </group>
<notebook name="notebook"> <notebook name="notebook">
@ -303,6 +300,7 @@
string="Create All Moves" string="Create All Moves"
type="object" type="object"
icon="fa-play" icon="fa-play"
colspan="2"
attrs="{'invisible':[('display_create_all_moves','!=',True)]}" attrs="{'invisible':[('display_create_all_moves','!=',True)]}"
/> />
<field <field
@ -335,15 +333,9 @@
</group> </group>
<group> <group>
<field <field
name="account_analytic_id" name="analytic_distribution"
domain="[('company_id', '=', company_id)]"
groups="analytic.group_analytic_accounting" groups="analytic.group_analytic_accounting"
options="{'no_create': True}" widget="analytic_distribution"
/>
<field
name="analytic_tag_ids"
groups="analytic.group_analytic_accounting"
widget="many2many_tags"
/> />
</group> </group>
</group> </group>
@ -357,22 +349,6 @@
</form> </form>
</field> </field>
</record> </record>
<record id="view_account_spread_account_manager" model="ir.ui.view">
<field name="model">account.spread</field>
<field name="inherit_id" ref="view_account_spread" />
<field name="groups_id" eval="[(4, ref('account.group_account_manager'))]" />
<field name="arch" type="xml">
<tree position="attributes">
<attribute name="editable">1</attribute>
</tree>
<field name="amount" position="attributes">
<attribute name="readonly" />
</field>
<field name="line_ids" position="attributes">
<attribute name="readonly" />
</field>
</field>
</record>
<record id="view_account_spread_tree" model="ir.ui.view"> <record id="view_account_spread_tree" model="ir.ui.view">
<field name="model">account.spread</field> <field name="model">account.spread</field>
<field name="arch" type="xml"> <field name="arch" type="xml">

View File

@ -32,20 +32,21 @@
<field name="use_invoice_line_account" /> <field name="use_invoice_line_account" />
<field <field
name="spread_account_id" name="spread_account_id"
domain="[('company_id', '=', company_id), ('deprecated', '=', False), ('internal_type','!=','liquidity'), ('internal_group', '!=', 'off_balance')]" domain="[('deprecated', '=', False), ('account_type', 'not in', ('asset_cash','liability_credit_card')), ('internal_group', '!=', 'off_balance')]"
options="{'no_create': True}" options="{'no_create': True}"
attrs="{'required': [('use_invoice_line_account', '!=', True)], 'invisible': [('use_invoice_line_account', '=', True)]}" attrs="{'required': [('use_invoice_line_account', '!=', True)], 'invisible': [('use_invoice_line_account', '=', True)]}"
/> />
<field <field
name="exp_rev_account_id" 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)]" domain="[('deprecated', '=', False)]"
options="{'no_create': True}" options="{'no_create': True}"
/> />
<field name="spread_journal_id" widget="selection" />
<field <field
name="spread_journal_id" name="analytic_distribution"
domain="[('company_id', '=', company_id)]" groups="analytic.group_analytic_accounting"
widget="selection" widget="analytic_distribution"
/> />
</group> </group>
</group> </group>
@ -65,10 +66,6 @@
<field name="name" /> <field name="name" />
<field name="product_id" /> <field name="product_id" />
<field name="account_id" /> <field name="account_id" />
<field
name="analytic_account_id"
groups="analytic.group_analytic_accounting"
/>
</tree> </tree>
</field> </field>
</sheet> </sheet>

View File

@ -163,8 +163,7 @@ class AccountSpreadInvoiceLineLinkWizard(models.TransientModel):
self.exp_rev_account_id or self.invoice_line_id.account_id self.exp_rev_account_id or self.invoice_line_id.account_id
) )
analytic_account = self.invoice_line_id.analytic_account_id analytic_distribution = self.invoice_line_id.analytic_distribution
analytic_tags = self.invoice_line_id.analytic_tag_ids
date_invoice = self.invoice_id.invoice_date or fields.Date.today() date_invoice = self.invoice_id.invoice_date or fields.Date.today()
return { return {
@ -183,8 +182,7 @@ class AccountSpreadInvoiceLineLinkWizard(models.TransientModel):
"default_debit_account_id": debit_account.id, "default_debit_account_id": debit_account.id,
"default_credit_account_id": credit_account.id, "default_credit_account_id": credit_account.id,
"default_journal_id": self.spread_journal_id.id, "default_journal_id": self.spread_journal_id.id,
"default_account_analytic_id": analytic_account.id, "default_analytic_distribution": analytic_distribution,
"default_analytic_tag_ids": analytic_tags.ids,
"default_spread_date": date_invoice, "default_spread_date": date_invoice,
}, },
} }
@ -214,16 +212,13 @@ class AccountSpreadInvoiceLineLinkWizard(models.TransientModel):
else: else:
spread_vals["debit_account_id"] = account.id spread_vals["debit_account_id"] = account.id
analytic_account = self.invoice_line_id.analytic_account_id analytic_distribution = self.invoice_line_id.analytic_distribution
spread_vals["account_analytic_id"] = analytic_account.id spread_vals["analytic_distribution"] = analytic_distribution
spread_vals["currency_id"] = self.invoice_id.currency_id.id spread_vals["currency_id"] = self.invoice_id.currency_id.id
spread = self.env["account.spread"].create(spread_vals) spread = self.env["account.spread"].create(spread_vals)
analytic_tags = self.invoice_line_id.analytic_tag_ids
spread.analytic_tag_ids = analytic_tags
self.invoice_line_id.spread_id = spread self.invoice_line_id.spread_id = spread
return { return {
"name": _("Spread Details"), "name": _("Spread Details"),

View File

@ -37,19 +37,18 @@
<field <field
name="spread_account_id" name="spread_account_id"
attrs="{'invisible': [('spread_action_type', '!=', 'new')],'required': [('spread_action_type', '=', 'new')]}" attrs="{'invisible': [('spread_action_type', '!=', 'new')],'required': [('spread_action_type', '=', 'new')]}"
domain="[('company_id', '=', company_id), ('deprecated', '=', False), ('internal_type','!=','liquidity'), ('internal_group', '!=', 'off_balance')]" domain="[('deprecated', '=', False), ('account_type', 'not in', ('asset_cash','liability_credit_card')), ('internal_group', '!=', 'off_balance')]"
options="{'no_create': True}" options="{'no_create': True}"
/> />
<field <field
name="exp_rev_account_id" name="exp_rev_account_id"
attrs="{'invisible': ['|', ('use_invoice_line_account', '=', False), ('spread_action_type', '!=', 'new')], 'required': [('use_invoice_line_account', '=', True)]}" attrs="{'invisible': ['|', ('use_invoice_line_account', '=', False), ('spread_action_type', '!=', 'new')], 'required': [('use_invoice_line_account', '=', True)]}"
domain="[('company_id', '=', company_id), ('deprecated', '=', False)]" domain="[('deprecated', '=', False)]"
options="{'no_create': True}" options="{'no_create': True}"
/> />
<field <field
name="spread_journal_id" name="spread_journal_id"
attrs="{'invisible': [('spread_action_type', '!=', 'new')],'required': [('spread_action_type', '=', 'new')]}" attrs="{'invisible': [('spread_action_type', '!=', 'new')],'required': [('spread_action_type', '=', 'new')]}"
domain="[('company_id', '=', company_id)]"
options="{'no_create': True}" options="{'no_create': True}"
/> />
</group> </group>

View File

@ -0,0 +1 @@
../../../../account_spread_cost_revenue

View File

@ -0,0 +1,6 @@
import setuptools
setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)