pre-commit
This commit is contained in:
parent
d36c50c766
commit
702444752b
@ -11,9 +11,7 @@
|
||||
"license": "AGPL-3",
|
||||
"website": "https://github.com/OCA/account-financial-tools/",
|
||||
"category": "Accounting & Finance",
|
||||
"depends": [
|
||||
"account",
|
||||
],
|
||||
"depends": ["account",],
|
||||
"data": [
|
||||
"security/ir.model.access.csv",
|
||||
"security/account_spread_security.xml",
|
||||
|
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo noupdate="1">
|
||||
|
||||
<record id="ir_cron_spread_create_entries" forcecreate="True" model="ir.cron">
|
||||
<field name="name">Cost/revenue Spread: Create Entries</field>
|
||||
<field name="active" eval="True" />
|
||||
@ -13,5 +12,4 @@
|
||||
<field name="state">code</field>
|
||||
<field name="code">model._create_entries()</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
@ -5,7 +5,7 @@ from odoo import api, models
|
||||
|
||||
|
||||
class AccountInvoice(models.Model):
|
||||
_inherit = 'account.invoice'
|
||||
_inherit = "account.invoice"
|
||||
|
||||
def action_invoice_open(self):
|
||||
for invoice in self:
|
||||
@ -16,7 +16,7 @@ class AccountInvoice(models.Model):
|
||||
def action_move_create(self):
|
||||
"""Invoked when validating the invoices."""
|
||||
res = super().action_move_create()
|
||||
spreads = self.mapped('invoice_line_ids.spread_id')
|
||||
spreads = self.mapped("invoice_line_ids.spread_id")
|
||||
spreads.compute_spread_board()
|
||||
spreads.reconcile_spread_moves()
|
||||
return res
|
||||
@ -26,14 +26,14 @@ class AccountInvoice(models.Model):
|
||||
"""Copying expense/revenue account from spread to move lines."""
|
||||
res = super().invoice_line_move_line_get()
|
||||
for line in res:
|
||||
invl_id = line.get('invl_id')
|
||||
invl = self.env['account.invoice.line'].browse(invl_id)
|
||||
invl_id = line.get("invl_id")
|
||||
invl = self.env["account.invoice.line"].browse(invl_id)
|
||||
if invl.spread_id:
|
||||
if invl.invoice_id.type in ('out_invoice', 'in_refund'):
|
||||
if invl.invoice_id.type in ("out_invoice", "in_refund"):
|
||||
account = invl.spread_id.debit_account_id
|
||||
else:
|
||||
account = invl.spread_id.credit_account_id
|
||||
line['account_id'] = account.id
|
||||
line["account_id"] = account.id
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
@ -41,8 +41,8 @@ class AccountInvoice(models.Model):
|
||||
"""Cancel the spread lines and their related moves when
|
||||
the invoice is canceled."""
|
||||
res = super().action_cancel()
|
||||
spread_lines = self.mapped('invoice_line_ids.spread_id.line_ids')
|
||||
moves = spread_lines.mapped('move_id')
|
||||
spread_lines = self.mapped("invoice_line_ids.spread_id.line_ids")
|
||||
moves = spread_lines.mapped("move_id")
|
||||
moves.button_cancel()
|
||||
moves.unlink()
|
||||
spread_lines.unlink()
|
||||
@ -53,7 +53,7 @@ class AccountInvoice(models.Model):
|
||||
result = super()._refund_cleanup_lines(lines)
|
||||
for i, line in enumerate(lines):
|
||||
for name in line._fields.keys():
|
||||
if name == 'spread_id':
|
||||
if name == "spread_id":
|
||||
result[i][2][name] = False
|
||||
break
|
||||
return result
|
||||
|
@ -6,27 +6,27 @@ from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountInvoiceLine(models.Model):
|
||||
_inherit = 'account.invoice.line'
|
||||
_inherit = "account.invoice.line"
|
||||
|
||||
spread_id = fields.Many2one(
|
||||
'account.spread',
|
||||
string='Spread Board',
|
||||
copy=False)
|
||||
spread_check = fields.Selection([
|
||||
('linked', 'Linked'),
|
||||
('unlinked', 'Unlinked'),
|
||||
('unavailable', 'Unavailable')
|
||||
], compute='_compute_spread_check')
|
||||
spread_id = fields.Many2one("account.spread", string="Spread Board", copy=False)
|
||||
spread_check = fields.Selection(
|
||||
[
|
||||
("linked", "Linked"),
|
||||
("unlinked", "Unlinked"),
|
||||
("unavailable", "Unavailable"),
|
||||
],
|
||||
compute="_compute_spread_check",
|
||||
)
|
||||
|
||||
@api.depends('spread_id', 'invoice_id.state')
|
||||
@api.depends("spread_id", "invoice_id.state")
|
||||
def _compute_spread_check(self):
|
||||
for line in self:
|
||||
if line.spread_id:
|
||||
line.spread_check = 'linked'
|
||||
elif line.invoice_id.state == 'draft':
|
||||
line.spread_check = 'unlinked'
|
||||
line.spread_check = "linked"
|
||||
elif line.invoice_id.state == "draft":
|
||||
line.spread_check = "unlinked"
|
||||
else:
|
||||
line.spread_check = 'unavailable'
|
||||
line.spread_check = "unavailable"
|
||||
|
||||
@api.multi
|
||||
def spread_details(self):
|
||||
@ -38,14 +38,14 @@ class AccountInvoiceLine(models.Model):
|
||||
|
||||
if self.spread_id:
|
||||
return {
|
||||
'name': _('Spread Details'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'account.spread',
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'current',
|
||||
'readonly': False,
|
||||
'res_id': self.spread_id.id,
|
||||
"name": _("Spread Details"),
|
||||
"view_type": "form",
|
||||
"view_mode": "form",
|
||||
"res_model": "account.spread",
|
||||
"type": "ir.actions.act_window",
|
||||
"target": "current",
|
||||
"readonly": False,
|
||||
"res_id": self.spread_id.id,
|
||||
}
|
||||
|
||||
# In case no spread board is linked to the invoice line
|
||||
@ -58,13 +58,13 @@ class AccountInvoiceLine(models.Model):
|
||||
allow_spread_planning=company.allow_spread_planning,
|
||||
)
|
||||
return {
|
||||
'name': _('Link Invoice Line with Spread Board'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'account.spread.invoice.line.link.wizard',
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'new',
|
||||
'context': ctx,
|
||||
"name": _("Link Invoice Line with Spread Board"),
|
||||
"view_type": "form",
|
||||
"view_mode": "form",
|
||||
"res_model": "account.spread.invoice.line.link.wizard",
|
||||
"type": "ir.actions.act_window",
|
||||
"target": "new",
|
||||
"context": ctx,
|
||||
}
|
||||
|
||||
def create_auto_spread(self):
|
||||
@ -76,33 +76,46 @@ class AccountInvoiceLine(models.Model):
|
||||
return False
|
||||
if aline.account_id and iline.account_id != aline.account_id:
|
||||
return False
|
||||
if aline.analytic_account_id and \
|
||||
iline.account_analytic_id != aline.analytic_account_id:
|
||||
if (
|
||||
aline.analytic_account_id
|
||||
and iline.account_analytic_id != aline.analytic_account_id
|
||||
):
|
||||
return False
|
||||
return True
|
||||
|
||||
for line in self:
|
||||
if line.spread_check == 'linked':
|
||||
if line.spread_check == "linked":
|
||||
continue
|
||||
spread_type = (
|
||||
'sale' if line.invoice_type in ['out_invoice', 'out_refund']
|
||||
else 'purchase')
|
||||
spread_auto = self.env['account.spread.template.auto'].search(
|
||||
[('template_id.auto_spread', '=', True),
|
||||
('template_id.spread_type', '=', spread_type)])
|
||||
"sale"
|
||||
if line.invoice_type in ["out_invoice", "out_refund"]
|
||||
else "purchase"
|
||||
)
|
||||
spread_auto = self.env["account.spread.template.auto"].search(
|
||||
[
|
||||
("template_id.auto_spread", "=", True),
|
||||
("template_id.spread_type", "=", spread_type),
|
||||
]
|
||||
)
|
||||
matched = spread_auto.filtered(lambda a, i=line: _filter_line(a, i))
|
||||
template = matched.mapped('template_id')
|
||||
template = matched.mapped("template_id")
|
||||
if not template:
|
||||
continue
|
||||
elif len(template) > 1:
|
||||
raise UserError(
|
||||
_('Too many auto spread templates (%s) matched with the '
|
||||
'invoice line, %s') % (len(template), line.display_name))
|
||||
_(
|
||||
"Too many auto spread templates (%s) matched with the "
|
||||
"invoice line, %s"
|
||||
)
|
||||
% (len(template), line.display_name)
|
||||
)
|
||||
# Found auto spread template for this invoice line, create it
|
||||
wizard = self.env['account.spread.invoice.line.link.wizard'].new({
|
||||
'invoice_line_id': line.id,
|
||||
'company_id': line.company_id.id,
|
||||
'spread_action_type': 'template',
|
||||
'template_id': template.id,
|
||||
})
|
||||
wizard = self.env["account.spread.invoice.line.link.wizard"].new(
|
||||
{
|
||||
"invoice_line_id": line.id,
|
||||
"company_id": line.company_id.id,
|
||||
"spread_action_type": "template",
|
||||
"template_id": template.id,
|
||||
}
|
||||
)
|
||||
wizard.confirm()
|
||||
|
@ -7,154 +7,145 @@ import time
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.tools import float_is_zero
|
||||
|
||||
from odoo.addons import decimal_precision as dp
|
||||
|
||||
|
||||
class AccountSpread(models.Model):
|
||||
_name = 'account.spread'
|
||||
_description = 'Account Spread'
|
||||
_inherit = ['mail.thread']
|
||||
_name = "account.spread"
|
||||
_description = "Account Spread"
|
||||
_inherit = ["mail.thread"]
|
||||
|
||||
name = fields.Char(required=True)
|
||||
template_id = fields.Many2one(
|
||||
'account.spread.template',
|
||||
string='Spread Template')
|
||||
invoice_type = fields.Selection([
|
||||
('out_invoice', 'Customer Invoice'),
|
||||
('in_invoice', 'Vendor Bill'),
|
||||
('out_refund', 'Customer Credit Note'),
|
||||
('in_refund', 'Vendor Credit Note')],
|
||||
required=True)
|
||||
spread_type = fields.Selection([
|
||||
('sale', 'Customer'),
|
||||
('purchase', 'Supplier')],
|
||||
compute='_compute_spread_type',
|
||||
required=True)
|
||||
template_id = fields.Many2one("account.spread.template", string="Spread Template")
|
||||
invoice_type = fields.Selection(
|
||||
[
|
||||
("out_invoice", "Customer Invoice"),
|
||||
("in_invoice", "Vendor Bill"),
|
||||
("out_refund", "Customer Credit Note"),
|
||||
("in_refund", "Vendor Credit Note"),
|
||||
],
|
||||
required=True,
|
||||
)
|
||||
spread_type = fields.Selection(
|
||||
[("sale", "Customer"), ("purchase", "Supplier")],
|
||||
compute="_compute_spread_type",
|
||||
required=True,
|
||||
)
|
||||
period_number = fields.Integer(
|
||||
string='Number of Repetitions',
|
||||
string="Number of Repetitions",
|
||||
default=12,
|
||||
help="Define the number of spread lines",
|
||||
required=True)
|
||||
period_type = fields.Selection([
|
||||
('month', 'Month'),
|
||||
('quarter', 'Quarter'),
|
||||
('year', 'Year')],
|
||||
default='month',
|
||||
help="Period length for the entries",
|
||||
required=True)
|
||||
use_invoice_line_account = fields.Boolean(
|
||||
string="Use invoice line's account",
|
||||
required=True,
|
||||
)
|
||||
period_type = fields.Selection(
|
||||
[("month", "Month"), ("quarter", "Quarter"), ("year", "Year")],
|
||||
default="month",
|
||||
help="Period length for the entries",
|
||||
required=True,
|
||||
)
|
||||
use_invoice_line_account = fields.Boolean(string="Use invoice line's account",)
|
||||
credit_account_id = fields.Many2one(
|
||||
'account.account',
|
||||
string='Credit Account',
|
||||
required=True)
|
||||
"account.account", string="Credit Account", required=True
|
||||
)
|
||||
debit_account_id = fields.Many2one(
|
||||
'account.account',
|
||||
string='Debit Account',
|
||||
required=True)
|
||||
"account.account", string="Debit Account", required=True
|
||||
)
|
||||
is_credit_account_deprecated = fields.Boolean(
|
||||
compute='_compute_deprecated_accounts')
|
||||
is_debit_account_deprecated = fields.Boolean(
|
||||
compute='_compute_deprecated_accounts')
|
||||
compute="_compute_deprecated_accounts"
|
||||
)
|
||||
is_debit_account_deprecated = fields.Boolean(compute="_compute_deprecated_accounts")
|
||||
unspread_amount = fields.Float(
|
||||
digits=dp.get_precision('Account'),
|
||||
compute='_compute_amounts')
|
||||
digits=dp.get_precision("Account"), compute="_compute_amounts"
|
||||
)
|
||||
unposted_amount = fields.Float(
|
||||
digits=dp.get_precision('Account'),
|
||||
compute='_compute_amounts')
|
||||
digits=dp.get_precision("Account"), compute="_compute_amounts"
|
||||
)
|
||||
posted_amount = fields.Float(
|
||||
digits=dp.get_precision('Account'),
|
||||
compute='_compute_amounts')
|
||||
digits=dp.get_precision("Account"), compute="_compute_amounts"
|
||||
)
|
||||
total_amount = fields.Float(
|
||||
digits=dp.get_precision('Account'),
|
||||
compute='_compute_amounts')
|
||||
all_posted = fields.Boolean(
|
||||
compute='_compute_amounts',
|
||||
store=True)
|
||||
digits=dp.get_precision("Account"), compute="_compute_amounts"
|
||||
)
|
||||
all_posted = fields.Boolean(compute="_compute_amounts", store=True)
|
||||
line_ids = fields.One2many(
|
||||
'account.spread.line',
|
||||
'spread_id',
|
||||
string='Spread Lines')
|
||||
"account.spread.line", "spread_id", string="Spread Lines"
|
||||
)
|
||||
spread_date = fields.Date(
|
||||
string='Start Date',
|
||||
default=time.strftime('%Y-01-01'),
|
||||
required=True)
|
||||
journal_id = fields.Many2one(
|
||||
'account.journal',
|
||||
string='Journal',
|
||||
required=True)
|
||||
string="Start Date", default=time.strftime("%Y-01-01"), required=True
|
||||
)
|
||||
journal_id = fields.Many2one("account.journal", string="Journal", required=True)
|
||||
invoice_line_ids = fields.One2many(
|
||||
'account.invoice.line',
|
||||
'spread_id',
|
||||
copy=False,
|
||||
string='Invoice Lines')
|
||||
"account.invoice.line", "spread_id", copy=False, string="Invoice Lines"
|
||||
)
|
||||
invoice_line_id = fields.Many2one(
|
||||
'account.invoice.line',
|
||||
string='Invoice line',
|
||||
compute='_compute_invoice_line',
|
||||
inverse='_inverse_invoice_line',
|
||||
store=True)
|
||||
"account.invoice.line",
|
||||
string="Invoice line",
|
||||
compute="_compute_invoice_line",
|
||||
inverse="_inverse_invoice_line",
|
||||
store=True,
|
||||
)
|
||||
invoice_id = fields.Many2one(
|
||||
related='invoice_line_id.invoice_id',
|
||||
related="invoice_line_id.invoice_id",
|
||||
readonly=True,
|
||||
store=True,
|
||||
string='Invoice')
|
||||
estimated_amount = fields.Float(digits=dp.get_precision('Account'))
|
||||
string="Invoice",
|
||||
)
|
||||
estimated_amount = fields.Float(digits=dp.get_precision("Account"))
|
||||
company_id = fields.Many2one(
|
||||
'res.company',
|
||||
"res.company",
|
||||
default=lambda self: self.env.user.company_id,
|
||||
string='Company',
|
||||
required=True)
|
||||
currency_id = fields.Many2one(
|
||||
'res.currency',
|
||||
string='Currency',
|
||||
string="Company",
|
||||
required=True,
|
||||
default=lambda self: self.env.user.company_id.currency_id.id)
|
||||
)
|
||||
currency_id = fields.Many2one(
|
||||
"res.currency",
|
||||
string="Currency",
|
||||
required=True,
|
||||
default=lambda self: self.env.user.company_id.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)
|
||||
"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)
|
||||
display_create_all_moves = fields.Boolean(
|
||||
compute='_compute_display_create_all_moves',
|
||||
string='Display Button All Moves')
|
||||
compute="_compute_display_create_all_moves", string="Display Button All Moves"
|
||||
)
|
||||
display_recompute_buttons = fields.Boolean(
|
||||
compute='_compute_display_recompute_buttons',
|
||||
string='Display Buttons Recompute')
|
||||
compute="_compute_display_recompute_buttons", string="Display Buttons Recompute"
|
||||
)
|
||||
display_move_line_auto_post = fields.Boolean(
|
||||
compute='_compute_display_move_line_auto_post',
|
||||
string='Display Button Auto-post lines')
|
||||
compute="_compute_display_move_line_auto_post",
|
||||
string="Display Button Auto-post lines",
|
||||
)
|
||||
active = fields.Boolean(default=True)
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
res = super().default_get(fields)
|
||||
if 'company_id' not in fields:
|
||||
if "company_id" not in fields:
|
||||
company_id = self.env.user.company_id.id
|
||||
else:
|
||||
company_id = res['company_id']
|
||||
default_journal = self.env['account.journal'].search([
|
||||
('type', '=', 'general'),
|
||||
('company_id', '=', company_id)
|
||||
], limit=1)
|
||||
if 'journal_id' not in res and default_journal:
|
||||
res['journal_id'] = default_journal.id
|
||||
company_id = res["company_id"]
|
||||
default_journal = self.env["account.journal"].search(
|
||||
[("type", "=", "general"), ("company_id", "=", company_id)], limit=1
|
||||
)
|
||||
if "journal_id" not in res and default_journal:
|
||||
res["journal_id"] = default_journal.id
|
||||
return res
|
||||
|
||||
@api.depends('invoice_type')
|
||||
@api.depends("invoice_type")
|
||||
def _compute_spread_type(self):
|
||||
for spread in self:
|
||||
if spread.invoice_type in ['out_invoice', 'out_refund']:
|
||||
spread.spread_type = 'sale'
|
||||
if spread.invoice_type in ["out_invoice", "out_refund"]:
|
||||
spread.spread_type = "sale"
|
||||
else:
|
||||
spread.spread_type = 'purchase'
|
||||
spread.spread_type = "purchase"
|
||||
|
||||
@api.depends('invoice_line_ids', 'invoice_line_ids.invoice_id')
|
||||
@api.depends("invoice_line_ids", "invoice_line_ids.invoice_id")
|
||||
def _compute_invoice_line(self):
|
||||
for spread in self:
|
||||
invoice_lines = spread.invoice_line_ids
|
||||
@ -165,9 +156,9 @@ class AccountSpread(models.Model):
|
||||
def _inverse_invoice_line(self):
|
||||
for spread in self:
|
||||
invoice_line = spread.invoice_line_id
|
||||
spread.write({
|
||||
'invoice_line_ids': [(6, 0, [invoice_line.id])],
|
||||
})
|
||||
spread.write(
|
||||
{"invoice_line_ids": [(6, 0, [invoice_line.id])],}
|
||||
)
|
||||
|
||||
@api.depends(
|
||||
"estimated_amount",
|
||||
@ -189,13 +180,13 @@ class AccountSpread(models.Model):
|
||||
spread.invoice_line_id.price_subtotal,
|
||||
spread.currency_id,
|
||||
spread.company_id,
|
||||
invoice._get_currency_rate_date() or fields.Date.today()
|
||||
invoice._get_currency_rate_date() or fields.Date.today(),
|
||||
)
|
||||
|
||||
for spread_line in spread.line_ids:
|
||||
if spread_line.move_id:
|
||||
moves_amount += spread_line.amount
|
||||
if spread_line.move_id.state == 'posted':
|
||||
if spread_line.move_id.state == "posted":
|
||||
posted_amount += spread_line.amount
|
||||
spread.unspread_amount = total_amount - moves_amount
|
||||
spread.unposted_amount = total_amount - posted_amount
|
||||
@ -216,7 +207,7 @@ class AccountSpread(models.Model):
|
||||
for spread in self:
|
||||
spread.display_recompute_buttons = True
|
||||
if not spread.company_id.allow_spread_planning:
|
||||
if spread.invoice_id.state == 'draft':
|
||||
if spread.invoice_id.state == "draft":
|
||||
spread.display_recompute_buttons = False
|
||||
|
||||
@api.multi
|
||||
@ -230,17 +221,17 @@ class AccountSpread(models.Model):
|
||||
def _get_spread_entry_name(self, seq):
|
||||
"""Use this method to customise the name of the accounting entry."""
|
||||
self.ensure_one()
|
||||
return (self.name or '') + '/' + str(seq)
|
||||
return (self.name or "") + "/" + str(seq)
|
||||
|
||||
@api.onchange('template_id')
|
||||
@api.onchange("template_id")
|
||||
def onchange_template(self):
|
||||
if self.template_id:
|
||||
if self.template_id.spread_type == 'sale':
|
||||
if self.invoice_type in ['in_invoice', 'in_refund']:
|
||||
self.invoice_type = 'out_invoice'
|
||||
if self.template_id.spread_type == "sale":
|
||||
if self.invoice_type in ["in_invoice", "in_refund"]:
|
||||
self.invoice_type = "out_invoice"
|
||||
else:
|
||||
if self.invoice_type in ['out_invoice', 'out_refund']:
|
||||
self.invoice_type = 'in_invoice'
|
||||
if self.invoice_type in ["out_invoice", "out_refund"]:
|
||||
self.invoice_type = "in_invoice"
|
||||
if self.template_id.period_number:
|
||||
self.period_number = self.template_id.period_number
|
||||
if self.template_id.period_type:
|
||||
@ -248,64 +239,72 @@ class AccountSpread(models.Model):
|
||||
if self.template_id.start_date:
|
||||
self.spread_date = self.template_id.start_date
|
||||
|
||||
@api.onchange('invoice_type', 'company_id')
|
||||
@api.onchange("invoice_type", "company_id")
|
||||
def onchange_invoice_type(self):
|
||||
company = self.company_id
|
||||
if not self.env.context.get('default_journal_id'):
|
||||
if not self.env.context.get("default_journal_id"):
|
||||
journal = company.default_spread_expense_journal_id
|
||||
if self.invoice_type in ('out_invoice', 'in_refund'):
|
||||
if self.invoice_type in ("out_invoice", "in_refund"):
|
||||
journal = company.default_spread_revenue_journal_id
|
||||
if journal:
|
||||
self.journal_id = journal
|
||||
|
||||
if not self.env.context.get('default_debit_account_id'):
|
||||
if self.invoice_type in ('out_invoice', 'in_refund'):
|
||||
if not self.env.context.get("default_debit_account_id"):
|
||||
if self.invoice_type in ("out_invoice", "in_refund"):
|
||||
debit_account_id = company.default_spread_revenue_account_id
|
||||
self.debit_account_id = debit_account_id
|
||||
|
||||
if not self.env.context.get('default_credit_account_id'):
|
||||
if self.invoice_type in ('in_invoice', 'out_refund'):
|
||||
if not self.env.context.get("default_credit_account_id"):
|
||||
if self.invoice_type in ("in_invoice", "out_refund"):
|
||||
credit_account_id = company.default_spread_expense_account_id
|
||||
self.credit_account_id = credit_account_id
|
||||
|
||||
@api.constrains('invoice_id', 'invoice_type')
|
||||
@api.constrains("invoice_id", "invoice_type")
|
||||
def _check_invoice_type(self):
|
||||
for spread in self:
|
||||
if not spread.invoice_id:
|
||||
pass
|
||||
elif spread.invoice_type != spread.invoice_id.type:
|
||||
raise ValidationError(_(
|
||||
'The Invoice Type does not correspond to the Invoice'))
|
||||
raise ValidationError(
|
||||
_("The Invoice Type does not correspond to the Invoice")
|
||||
)
|
||||
|
||||
@api.constrains('journal_id')
|
||||
@api.constrains("journal_id")
|
||||
def _check_journal(self):
|
||||
for spread in self:
|
||||
moves = spread.mapped('line_ids.move_id').filtered('journal_id')
|
||||
moves = spread.mapped("line_ids.move_id").filtered("journal_id")
|
||||
if any(move.journal_id != spread.journal_id for move in moves):
|
||||
raise ValidationError(_(
|
||||
'The Journal is not consistent with the account moves.'))
|
||||
raise ValidationError(
|
||||
_("The Journal is not consistent with the account moves.")
|
||||
)
|
||||
|
||||
@api.constrains('template_id', 'invoice_type')
|
||||
@api.constrains("template_id", "invoice_type")
|
||||
def _check_template_invoice_type(self):
|
||||
for spread in self:
|
||||
if spread.invoice_type in ['in_invoice', 'in_refund']:
|
||||
if spread.template_id.spread_type == 'sale':
|
||||
raise ValidationError(_(
|
||||
'The Spread Template (Sales) is not compatible '
|
||||
'with selected invoice type'))
|
||||
elif spread.invoice_type in ['out_invoice', 'out_refund']:
|
||||
if spread.template_id.spread_type == 'purchase':
|
||||
raise ValidationError(_(
|
||||
'The Spread Template (Purchases) is not compatible '
|
||||
'with selected invoice type'))
|
||||
if spread.invoice_type in ["in_invoice", "in_refund"]:
|
||||
if spread.template_id.spread_type == "sale":
|
||||
raise ValidationError(
|
||||
_(
|
||||
"The Spread Template (Sales) is not compatible "
|
||||
"with selected invoice type"
|
||||
)
|
||||
)
|
||||
elif spread.invoice_type in ["out_invoice", "out_refund"]:
|
||||
if spread.template_id.spread_type == "purchase":
|
||||
raise ValidationError(
|
||||
_(
|
||||
"The Spread Template (Purchases) is not compatible "
|
||||
"with selected invoice type"
|
||||
)
|
||||
)
|
||||
|
||||
@api.multi
|
||||
def _get_spread_period_duration(self):
|
||||
"""Converts the selected period_type to number of months."""
|
||||
self.ensure_one()
|
||||
if self.period_type == 'year':
|
||||
if self.period_type == "year":
|
||||
return 12
|
||||
elif self.period_type == 'quarter':
|
||||
elif self.period_type == "quarter":
|
||||
return 3
|
||||
return 1
|
||||
|
||||
@ -348,10 +347,11 @@ class AccountSpread(models.Model):
|
||||
self.ensure_one()
|
||||
|
||||
posted_line_ids = self.line_ids.filtered(
|
||||
lambda x: x.move_id.state == 'posted').sorted(
|
||||
key=lambda l: l.date)
|
||||
lambda x: x.move_id.state == "posted"
|
||||
).sorted(key=lambda l: l.date)
|
||||
unposted_line_ids = self.line_ids.filtered(
|
||||
lambda x: not x.move_id.state == 'posted')
|
||||
lambda x: not x.move_id.state == "posted"
|
||||
)
|
||||
|
||||
# Remove old unposted spread lines.
|
||||
commands = [(2, line_id.id, False) for line_id in unposted_line_ids]
|
||||
@ -375,19 +375,19 @@ class AccountSpread(models.Model):
|
||||
continue
|
||||
unposted_amount -= amount
|
||||
vals = {
|
||||
'amount': amount,
|
||||
'spread_id': self.id,
|
||||
'name': self._get_spread_entry_name(sequence),
|
||||
'date': self._get_last_day_of_month(spread_date),
|
||||
"amount": amount,
|
||||
"spread_id": self.id,
|
||||
"name": self._get_spread_entry_name(sequence),
|
||||
"date": self._get_last_day_of_month(spread_date),
|
||||
}
|
||||
commands.append((0, False, vals))
|
||||
|
||||
spread_date = self._next_line_date(month_day, spread_date)
|
||||
|
||||
self.write({'line_ids': commands})
|
||||
invoice_type_selection = dict(self.fields_get(
|
||||
allfields=['invoice_type']
|
||||
)['invoice_type']['selection'])[self.invoice_type]
|
||||
self.write({"line_ids": commands})
|
||||
invoice_type_selection = dict(
|
||||
self.fields_get(allfields=["invoice_type"])["invoice_type"]["selection"]
|
||||
)[self.invoice_type]
|
||||
msg_body = _("Spread table '%s' created.") % invoice_type_selection
|
||||
self.message_post(body=msg_body)
|
||||
|
||||
@ -430,60 +430,68 @@ class AccountSpread(models.Model):
|
||||
def action_recalculate_spread(self):
|
||||
"""Recalculate spread"""
|
||||
self.ensure_one()
|
||||
spread_lines = self.mapped('line_ids').filtered('move_id')
|
||||
spread_lines = self.mapped("line_ids").filtered("move_id")
|
||||
spread_lines.unlink_move()
|
||||
self.compute_spread_board()
|
||||
self.env['account.spread.line']._create_entries()
|
||||
self.env["account.spread.line"]._create_entries()
|
||||
|
||||
@api.multi
|
||||
def action_undo_spread(self):
|
||||
"""Undo spreading: Remove all created moves,
|
||||
restore original account on move line"""
|
||||
self.ensure_one()
|
||||
self.mapped('line_ids').filtered('move_id').unlink_move()
|
||||
self.mapped('line_ids').unlink()
|
||||
self.mapped("line_ids").filtered("move_id").unlink_move()
|
||||
self.mapped("line_ids").unlink()
|
||||
|
||||
@api.multi
|
||||
def action_unlink_invoice_line(self):
|
||||
"""Unlink the invoice line from the spread board"""
|
||||
self.ensure_one()
|
||||
if self.invoice_id.state != 'draft':
|
||||
if self.invoice_id.state != "draft":
|
||||
raise UserError(
|
||||
_("Cannot unlink invoice lines if the invoice is validated"))
|
||||
_("Cannot unlink invoice lines if the invoice is validated")
|
||||
)
|
||||
self._action_unlink_invoice_line()
|
||||
|
||||
@api.multi
|
||||
def _action_unlink_invoice_line(self):
|
||||
spread_mls = self.mapped('line_ids.move_id.line_ids')
|
||||
spread_mls = self.mapped("line_ids.move_id.line_ids")
|
||||
spread_mls.remove_move_reconcile()
|
||||
self._message_post_unlink_invoice_line()
|
||||
self.write({'invoice_line_ids': [(5, 0, 0)]})
|
||||
self.write({"invoice_line_ids": [(5, 0, 0)]})
|
||||
|
||||
def _message_post_unlink_invoice_line(self):
|
||||
for spread in self:
|
||||
invoice_id = spread.invoice_id.id
|
||||
inv_link = '<a href=# data-oe-model=account.invoice ' \
|
||||
'data-oe-id=%d>%s</a>' % (invoice_id, _("Invoice"))
|
||||
inv_link = (
|
||||
"<a href=# data-oe-model=account.invoice "
|
||||
"data-oe-id=%d>%s</a>" % (invoice_id, _("Invoice"))
|
||||
)
|
||||
msg_body = _("Unlinked invoice line '%s' (view %s).") % (
|
||||
spread.invoice_line_id.name, inv_link)
|
||||
spread.invoice_line_id.name,
|
||||
inv_link,
|
||||
)
|
||||
spread.message_post(body=msg_body)
|
||||
spread_link = '<a href=# data-oe-model=account.spread ' \
|
||||
'data-oe-id=%d>%s</a>' % (spread.id, _("Spread"))
|
||||
spread_link = (
|
||||
"<a href=# data-oe-model=account.spread "
|
||||
"data-oe-id=%d>%s</a>" % (spread.id, _("Spread"))
|
||||
)
|
||||
msg_body = _("Unlinked '%s' (invoice line %s).") % (
|
||||
spread_link, spread.invoice_line_id.name)
|
||||
spread_link,
|
||||
spread.invoice_line_id.name,
|
||||
)
|
||||
spread.invoice_id.message_post(body=msg_body)
|
||||
|
||||
@api.multi
|
||||
def unlink(self):
|
||||
if self.filtered(lambda s: s.invoice_line_id):
|
||||
raise UserError(
|
||||
_('Cannot delete spread(s) that are linked '
|
||||
'to an invoice line.'))
|
||||
if self.mapped('line_ids.move_id').filtered(
|
||||
lambda m: m.state == 'posted'):
|
||||
_("Cannot delete spread(s) that are linked " "to an invoice line.")
|
||||
)
|
||||
if self.mapped("line_ids.move_id").filtered(lambda m: m.state == "posted"):
|
||||
raise ValidationError(
|
||||
_('Cannot delete spread(s): there are '
|
||||
'posted Journal Entries.'))
|
||||
_("Cannot delete spread(s): there are " "posted Journal Entries.")
|
||||
)
|
||||
return super().unlink()
|
||||
|
||||
@api.multi
|
||||
@ -499,40 +507,40 @@ class AccountSpread(models.Model):
|
||||
if not self.invoice_id.number:
|
||||
return
|
||||
|
||||
spread_mls = self.line_ids.mapped('move_id.line_ids')
|
||||
spread_mls = self.line_ids.mapped("move_id.line_ids")
|
||||
if created_moves:
|
||||
spread_mls |= created_moves.mapped('line_ids')
|
||||
spread_mls |= created_moves.mapped("line_ids")
|
||||
|
||||
spread_sign = True if self.total_amount >= 0.0 else False
|
||||
in_invoice_or_out_refund = ('in_invoice', 'out_refund')
|
||||
in_invoice_or_out_refund = ("in_invoice", "out_refund")
|
||||
|
||||
if self.invoice_type in in_invoice_or_out_refund and spread_sign:
|
||||
spread_mls = spread_mls.filtered(lambda x: x.credit != 0.)
|
||||
spread_mls = spread_mls.filtered(lambda x: x.credit != 0.0)
|
||||
elif self.invoice_type in in_invoice_or_out_refund:
|
||||
spread_mls = spread_mls.filtered(lambda x: x.debit != 0.)
|
||||
spread_mls = spread_mls.filtered(lambda x: x.debit != 0.0)
|
||||
elif spread_sign:
|
||||
spread_mls = spread_mls.filtered(lambda x: x.debit != 0.)
|
||||
spread_mls = spread_mls.filtered(lambda x: x.debit != 0.0)
|
||||
else:
|
||||
spread_mls = spread_mls.filtered(lambda x: x.credit != 0.)
|
||||
spread_mls = spread_mls.filtered(lambda x: x.credit != 0.0)
|
||||
|
||||
invoice_mls = self.invoice_id.move_id.mapped('line_ids')
|
||||
invoice_mls = self.invoice_id.move_id.mapped("line_ids")
|
||||
if self.invoice_id.type in in_invoice_or_out_refund and spread_sign:
|
||||
invoice_mls = invoice_mls.filtered(lambda x: x.debit != 0.)
|
||||
invoice_mls = invoice_mls.filtered(lambda x: x.debit != 0.0)
|
||||
elif self.invoice_id.type in in_invoice_or_out_refund:
|
||||
invoice_mls = invoice_mls.filtered(lambda x: x.credit != 0.)
|
||||
invoice_mls = invoice_mls.filtered(lambda x: x.credit != 0.0)
|
||||
elif spread_sign:
|
||||
invoice_mls = invoice_mls.filtered(lambda x: x.credit != 0.)
|
||||
invoice_mls = invoice_mls.filtered(lambda x: x.credit != 0.0)
|
||||
else:
|
||||
invoice_mls = invoice_mls.filtered(lambda x: x.debit != 0.)
|
||||
invoice_mls = invoice_mls.filtered(lambda x: x.debit != 0.0)
|
||||
|
||||
to_be_reconciled = self.env['account.move.line']
|
||||
to_be_reconciled = self.env["account.move.line"]
|
||||
if len(invoice_mls) > 1:
|
||||
# Refine selection of move line.
|
||||
# The name is formatted the same way as it is done when creating
|
||||
# move lines in method "def invoice_line_move_line_get()" of
|
||||
# standard account module
|
||||
raw_name = self.invoice_line_id.name
|
||||
formatted_name = raw_name.split('\n')[0][:64]
|
||||
formatted_name = raw_name.split("\n")[0][:64]
|
||||
for move_line in invoice_mls:
|
||||
if move_line.name == formatted_name:
|
||||
to_be_reconciled |= move_line
|
||||
@ -546,11 +554,10 @@ class AccountSpread(models.Model):
|
||||
|
||||
@api.multi
|
||||
def create_all_moves(self):
|
||||
for line in self.mapped('line_ids').filtered(lambda l: not l.move_id):
|
||||
for line in self.mapped("line_ids").filtered(lambda l: not l.move_id):
|
||||
line.create_move()
|
||||
|
||||
@api.depends(
|
||||
'debit_account_id.deprecated', 'credit_account_id.deprecated')
|
||||
@api.depends("debit_account_id.deprecated", "credit_account_id.deprecated")
|
||||
def _compute_deprecated_accounts(self):
|
||||
for spread in self:
|
||||
debit_deprecated = bool(spread.debit_account_id.deprecated)
|
||||
@ -561,5 +568,5 @@ class AccountSpread(models.Model):
|
||||
@api.multi
|
||||
def open_reconcile_view(self):
|
||||
self.ensure_one()
|
||||
spread_mls = self.line_ids.mapped('move_id.line_ids')
|
||||
spread_mls = self.line_ids.mapped("move_id.line_ids")
|
||||
return spread_mls.open_reconcile_view()
|
||||
|
@ -2,22 +2,23 @@
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.addons import decimal_precision as dp
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
from odoo.addons import decimal_precision as dp
|
||||
|
||||
|
||||
class AccountInvoiceSpreadLine(models.Model):
|
||||
_name = 'account.spread.line'
|
||||
_description = 'Account Spread Lines'
|
||||
_order = 'date'
|
||||
_name = "account.spread.line"
|
||||
_description = "Account Spread Lines"
|
||||
_order = "date"
|
||||
|
||||
name = fields.Char('Description', readonly=True)
|
||||
amount = fields.Float(digits=dp.get_precision('Account'), required=True)
|
||||
name = fields.Char("Description", readonly=True)
|
||||
amount = fields.Float(digits=dp.get_precision("Account"), required=True)
|
||||
date = fields.Date(required=True)
|
||||
spread_id = fields.Many2one(
|
||||
'account.spread', string='Spread Board', ondelete='cascade')
|
||||
move_id = fields.Many2one(
|
||||
'account.move', string='Journal Entry', readonly=True)
|
||||
"account.spread", string="Spread Board", ondelete="cascade"
|
||||
)
|
||||
move_id = fields.Many2one("account.move", string="Journal Entry", readonly=True)
|
||||
|
||||
@api.multi
|
||||
def create_and_reconcile_moves(self):
|
||||
@ -25,19 +26,19 @@ class AccountInvoiceSpreadLine(models.Model):
|
||||
for spread_line in self:
|
||||
spread = spread_line.spread_id
|
||||
spread_line_list = grouped_lines.get(
|
||||
spread, self.env['account.spread.line'])
|
||||
grouped_lines.update({
|
||||
spread: spread_line_list + spread_line
|
||||
})
|
||||
spread, self.env["account.spread.line"]
|
||||
)
|
||||
grouped_lines.update({spread: spread_line_list + spread_line})
|
||||
for spread in grouped_lines:
|
||||
created_moves = grouped_lines[spread]._create_moves()
|
||||
|
||||
if created_moves:
|
||||
post_msg = _("Created move(s) ")
|
||||
post_msg += ", ".join(
|
||||
'<a href=# data-oe-model=account.move data-oe-id=%d'
|
||||
'>%s</a>' % (move.id, move.name)
|
||||
for move in created_moves)
|
||||
"<a href=# data-oe-model=account.move data-oe-id=%d"
|
||||
">%s</a>" % (move.id, move.name)
|
||||
for move in created_moves
|
||||
)
|
||||
spread.message_post(body=post_msg)
|
||||
|
||||
spread._reconcile_spread_moves(created_moves)
|
||||
@ -62,15 +63,19 @@ class AccountInvoiceSpreadLine(models.Model):
|
||||
@api.multi
|
||||
def _create_moves(self):
|
||||
if self.filtered(lambda l: l.move_id):
|
||||
raise UserError(_('This spread line is already linked to a '
|
||||
'journal entry! Please post or delete it.'))
|
||||
raise UserError(
|
||||
_(
|
||||
"This spread line is already linked to a "
|
||||
"journal entry! Please post or delete it."
|
||||
)
|
||||
)
|
||||
|
||||
created_moves = self.env['account.move']
|
||||
created_moves = self.env["account.move"]
|
||||
for line in self:
|
||||
move_vals = line._prepare_move()
|
||||
move = self.env['account.move'].create(move_vals)
|
||||
move = self.env["account.move"].create(move_vals)
|
||||
|
||||
line.write({'move_id': move.id})
|
||||
line.write({"move_id": move.id})
|
||||
created_moves += move
|
||||
return created_moves
|
||||
|
||||
@ -78,7 +83,7 @@ class AccountInvoiceSpreadLine(models.Model):
|
||||
def _prepare_move(self):
|
||||
self.ensure_one()
|
||||
|
||||
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
|
||||
analytic = spread.account_analytic_id
|
||||
analytic_tags = [(4, tag.id, None) for tag in spread.analytic_tag_ids]
|
||||
@ -87,37 +92,49 @@ class AccountInvoiceSpreadLine(models.Model):
|
||||
current_currency = spread.currency_id
|
||||
not_same_curr = company_currency != current_currency
|
||||
amount = current_currency._convert(
|
||||
self.amount, company_currency, spread.company_id, spread_date)
|
||||
self.amount, company_currency, spread.company_id, spread_date
|
||||
)
|
||||
|
||||
line_ids = [(0, 0, {
|
||||
'name': spread.name.split('\n')[0][:64],
|
||||
'account_id': spread.debit_account_id.id,
|
||||
'debit': 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,
|
||||
'analytic_account_id': analytic.id,
|
||||
'analytic_tag_ids': analytic_tags,
|
||||
'currency_id': not_same_curr and current_currency.id or False,
|
||||
'amount_currency': not_same_curr and - 1.0 * self.amount or 0.0,
|
||||
}), (0, 0, {
|
||||
'name': spread.name.split('\n')[0][:64],
|
||||
'account_id': spread.credit_account_id.id,
|
||||
'credit': 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,
|
||||
'analytic_account_id': analytic.id,
|
||||
'analytic_tag_ids': analytic_tags,
|
||||
'currency_id': not_same_curr and current_currency.id or False,
|
||||
'amount_currency': not_same_curr and self.amount or 0.0,
|
||||
})]
|
||||
line_ids = [
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"name": spread.name.split("\n")[0][:64],
|
||||
"account_id": spread.debit_account_id.id,
|
||||
"debit": 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,
|
||||
"analytic_account_id": analytic.id,
|
||||
"analytic_tag_ids": analytic_tags,
|
||||
"currency_id": not_same_curr and current_currency.id or False,
|
||||
"amount_currency": not_same_curr and -1.0 * self.amount or 0.0,
|
||||
},
|
||||
),
|
||||
(
|
||||
0,
|
||||
0,
|
||||
{
|
||||
"name": spread.name.split("\n")[0][:64],
|
||||
"account_id": spread.credit_account_id.id,
|
||||
"credit": 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,
|
||||
"analytic_account_id": analytic.id,
|
||||
"analytic_tag_ids": analytic_tags,
|
||||
"currency_id": not_same_curr and current_currency.id or False,
|
||||
"amount_currency": not_same_curr and self.amount or 0.0,
|
||||
},
|
||||
),
|
||||
]
|
||||
|
||||
return {
|
||||
'name': self.name or "/",
|
||||
'ref': self.name,
|
||||
'date': spread_date,
|
||||
'journal_id': spread.journal_id.id,
|
||||
'line_ids': line_ids,
|
||||
'company_id': spread.company_id.id,
|
||||
"name": self.name or "/",
|
||||
"ref": self.name,
|
||||
"date": spread_date,
|
||||
"journal_id": spread.journal_id.id,
|
||||
"line_ids": line_ids,
|
||||
"company_id": spread.company_id.id,
|
||||
}
|
||||
|
||||
@api.multi
|
||||
@ -127,13 +144,13 @@ class AccountInvoiceSpreadLine(models.Model):
|
||||
"""
|
||||
self.ensure_one()
|
||||
return {
|
||||
'name': _("Journal Entry"),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'account.move',
|
||||
'view_id': False,
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_id': self.move_id.id,
|
||||
"name": _("Journal Entry"),
|
||||
"view_type": "form",
|
||||
"view_mode": "form",
|
||||
"res_model": "account.move",
|
||||
"view_id": False,
|
||||
"type": "ir.actions.act_window",
|
||||
"res_id": self.move_id.id,
|
||||
}
|
||||
|
||||
@api.multi
|
||||
@ -143,7 +160,7 @@ class AccountInvoiceSpreadLine(models.Model):
|
||||
"""
|
||||
for line in self:
|
||||
move = line.move_id
|
||||
if move.state == 'posted':
|
||||
if move.state == "posted":
|
||||
move.button_cancel()
|
||||
move.line_ids.remove_move_reconcile()
|
||||
post_msg = _("Deleted move %s") % line.move_id.id
|
||||
@ -156,18 +173,21 @@ class AccountInvoiceSpreadLine(models.Model):
|
||||
"""Find spread line entries where date is in the past and
|
||||
create moves for them. Method also called by the cron job.
|
||||
"""
|
||||
lines = self.search([
|
||||
('date', '<=', fields.Date.today()),
|
||||
('move_id', '=', False)
|
||||
])
|
||||
lines = self.search(
|
||||
[("date", "<=", fields.Date.today()), ("move_id", "=", False)]
|
||||
)
|
||||
lines.create_and_reconcile_moves()
|
||||
|
||||
unposted_moves = self.search([('move_id', '!=', False)]).mapped(
|
||||
'move_id').filtered(lambda m: m.state != 'posted')
|
||||
unposted_moves.filtered(
|
||||
lambda m: m.company_id.force_move_auto_post).post()
|
||||
unposted_moves = (
|
||||
self.search([("move_id", "!=", False)])
|
||||
.mapped("move_id")
|
||||
.filtered(lambda m: m.state != "posted")
|
||||
)
|
||||
unposted_moves.filtered(lambda m: m.company_id.force_move_auto_post).post()
|
||||
|
||||
spreads_to_archive = self.env['account.spread'].search([
|
||||
('all_posted', '=', True)
|
||||
]).filtered(lambda s: s.company_id.auto_archive)
|
||||
spreads_to_archive.write({'active': False})
|
||||
spreads_to_archive = (
|
||||
self.env["account.spread"]
|
||||
.search([("all_posted", "=", True)])
|
||||
.filtered(lambda s: s.company_id.auto_archive)
|
||||
)
|
||||
spreads_to_archive.write({"active": False})
|
||||
|
@ -1,89 +1,89 @@
|
||||
# Copyright 2018-2019 Onestein (<https://www.onestein.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountSpreadTemplate(models.Model):
|
||||
_name = 'account.spread.template'
|
||||
_description = 'Account Spread Template'
|
||||
_name = "account.spread.template"
|
||||
_description = "Account Spread Template"
|
||||
|
||||
name = fields.Char(required=True)
|
||||
spread_type = fields.Selection([
|
||||
('sale', 'Customer'),
|
||||
('purchase', 'Supplier')],
|
||||
default='sale',
|
||||
required=True)
|
||||
spread_type = fields.Selection(
|
||||
[("sale", "Customer"), ("purchase", "Supplier")], default="sale", required=True
|
||||
)
|
||||
company_id = fields.Many2one(
|
||||
'res.company',
|
||||
"res.company",
|
||||
default=lambda self: self.env.user.company_id,
|
||||
string='Company',
|
||||
required=True)
|
||||
string="Company",
|
||||
required=True,
|
||||
)
|
||||
spread_journal_id = fields.Many2one(
|
||||
'account.journal',
|
||||
string='Journal',
|
||||
required=True)
|
||||
"account.journal", string="Journal", required=True
|
||||
)
|
||||
use_invoice_line_account = fields.Boolean(
|
||||
string="Invoice account as spread account",
|
||||
help="Use invoice line's account as Balance sheet / spread account.\n"
|
||||
"In this case, user need to select expense/revenue account too.")
|
||||
"In this case, user need to select expense/revenue account too.",
|
||||
)
|
||||
spread_account_id = fields.Many2one(
|
||||
'account.account',
|
||||
string='Spread Balance Sheet Account',
|
||||
required=False)
|
||||
"account.account", string="Spread Balance Sheet Account", required=False
|
||||
)
|
||||
exp_rev_account_id = fields.Many2one(
|
||||
'account.account',
|
||||
string='Expense/Revenue Account',
|
||||
help="Optional account to overwrite the existing expense/revenue "
|
||||
"account")
|
||||
"account.account",
|
||||
string="Expense/Revenue Account",
|
||||
help="Optional account to overwrite the existing expense/revenue " "account",
|
||||
)
|
||||
period_number = fields.Integer(
|
||||
string='Number of Repetitions',
|
||||
help="Define the number of spread lines")
|
||||
period_type = fields.Selection([
|
||||
('month', 'Month'),
|
||||
('quarter', 'Quarter'),
|
||||
('year', 'Year')],
|
||||
help="Period length for the entries")
|
||||
string="Number of Repetitions", help="Define the number of spread lines"
|
||||
)
|
||||
period_type = fields.Selection(
|
||||
[("month", "Month"), ("quarter", "Quarter"), ("year", "Year")],
|
||||
help="Period length for the entries",
|
||||
)
|
||||
start_date = fields.Date()
|
||||
auto_spread = fields.Boolean(
|
||||
string='Auto assign template on invoice validate',
|
||||
string="Auto assign template on invoice validate",
|
||||
help="If checked, provide option to auto create spread during "
|
||||
"invoice validation, based on product/account/analytic in invoice line."
|
||||
"invoice validation, based on product/account/analytic in invoice line.",
|
||||
)
|
||||
auto_spread_ids = fields.One2many(
|
||||
comodel_name='account.spread.template.auto',
|
||||
string='Auto Spread On',
|
||||
inverse_name='template_id',
|
||||
comodel_name="account.spread.template.auto",
|
||||
string="Auto Spread On",
|
||||
inverse_name="template_id",
|
||||
)
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
res = super().default_get(fields)
|
||||
if 'company_id' not in fields:
|
||||
if "company_id" not in fields:
|
||||
company_id = self.env.user.company_id.id
|
||||
else:
|
||||
company_id = res['company_id']
|
||||
default_journal = self.env['account.journal'].search([
|
||||
('type', '=', 'general'),
|
||||
('company_id', '=', company_id)],
|
||||
limit=1)
|
||||
if 'spread_journal_id' not in res and default_journal:
|
||||
res['spread_journal_id'] = default_journal.id
|
||||
company_id = res["company_id"]
|
||||
default_journal = self.env["account.journal"].search(
|
||||
[("type", "=", "general"), ("company_id", "=", company_id)], limit=1
|
||||
)
|
||||
if "spread_journal_id" not in res and default_journal:
|
||||
res["spread_journal_id"] = default_journal.id
|
||||
return res
|
||||
|
||||
@api.constrains('auto_spread', 'auto_spread_ids')
|
||||
@api.constrains("auto_spread", "auto_spread_ids")
|
||||
def _check_product_account(self):
|
||||
for rec in self.filtered('auto_spread'):
|
||||
for rec in self.filtered("auto_spread"):
|
||||
for line in rec.auto_spread_ids:
|
||||
if not line.product_id and not line.account_id:
|
||||
raise UserError(_('Please select product and/or account '
|
||||
'on auto spread options'))
|
||||
raise UserError(
|
||||
_(
|
||||
"Please select product and/or account "
|
||||
"on auto spread options"
|
||||
)
|
||||
)
|
||||
|
||||
@api.onchange('spread_type', 'company_id')
|
||||
@api.onchange("spread_type", "company_id")
|
||||
def onchange_spread_type(self):
|
||||
company = self.company_id
|
||||
if self.spread_type == 'sale':
|
||||
if self.spread_type == "sale":
|
||||
account = company.default_spread_revenue_account_id
|
||||
journal = company.default_spread_revenue_journal_id
|
||||
else:
|
||||
@ -94,7 +94,7 @@ class AccountSpreadTemplate(models.Model):
|
||||
if journal:
|
||||
self.spread_journal_id = journal
|
||||
|
||||
@api.onchange('use_invoice_line_account')
|
||||
@api.onchange("use_invoice_line_account")
|
||||
def _onchange_user_invoice_line_account(self):
|
||||
self.exp_rev_account_id = False
|
||||
|
||||
@ -102,32 +102,32 @@ class AccountSpreadTemplate(models.Model):
|
||||
self.ensure_one()
|
||||
company = self.company_id
|
||||
spread_vals = {
|
||||
'name': self.name,
|
||||
'template_id': self.id,
|
||||
'journal_id': self.spread_journal_id.id,
|
||||
'use_invoice_line_account': self.use_invoice_line_account,
|
||||
'company_id': company.id,
|
||||
"name": self.name,
|
||||
"template_id": self.id,
|
||||
"journal_id": self.spread_journal_id.id,
|
||||
"use_invoice_line_account": self.use_invoice_line_account,
|
||||
"company_id": company.id,
|
||||
}
|
||||
|
||||
account_id = spread_account_id or self.spread_account_id.id
|
||||
if self.spread_type == 'sale':
|
||||
invoice_type = 'out_invoice'
|
||||
spread_vals['debit_account_id'] = account_id
|
||||
if self.spread_type == "sale":
|
||||
invoice_type = "out_invoice"
|
||||
spread_vals["debit_account_id"] = account_id
|
||||
else:
|
||||
invoice_type = 'in_invoice'
|
||||
spread_vals['credit_account_id'] = account_id
|
||||
invoice_type = "in_invoice"
|
||||
spread_vals["credit_account_id"] = account_id
|
||||
|
||||
if self.period_number:
|
||||
spread_vals['period_number'] = self.period_number
|
||||
spread_vals["period_number"] = self.period_number
|
||||
if self.period_type:
|
||||
spread_vals['period_type'] = self.period_type
|
||||
spread_vals["period_type"] = self.period_type
|
||||
if self.start_date:
|
||||
spread_vals['spread_date'] = self.start_date
|
||||
spread_vals["spread_date"] = self.start_date
|
||||
|
||||
spread_vals['invoice_type'] = invoice_type
|
||||
spread_vals["invoice_type"] = invoice_type
|
||||
return spread_vals
|
||||
|
||||
@api.constrains('auto_spread_ids', 'auto_spread')
|
||||
@api.constrains("auto_spread_ids", "auto_spread")
|
||||
def _check_auto_spread_ids_unique(self):
|
||||
query = """
|
||||
select product_id, account_id, analytic_account_id
|
||||
@ -141,43 +141,31 @@ class AccountSpreadTemplate(models.Model):
|
||||
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('%s / %s / %s' % (product.name, account.name, analytic.name))
|
||||
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)))
|
||||
_("Followings are duplicated combinations,\n\n%s" % "\n".join(results))
|
||||
)
|
||||
|
||||
|
||||
class AccountSpreadTemplateAuto(models.Model):
|
||||
_name = 'account.spread.template.auto'
|
||||
_description = 'Auto create spread, based on product/account/analytic'
|
||||
_name = "account.spread.template.auto"
|
||||
_description = "Auto create spread, based on product/account/analytic"
|
||||
|
||||
template_id = fields.Many2one(
|
||||
comodel_name='account.spread.template',
|
||||
string='Spread Template',
|
||||
comodel_name="account.spread.template",
|
||||
string="Spread Template",
|
||||
required=True,
|
||||
ondelete='cascade',
|
||||
ondelete="cascade",
|
||||
index=True,
|
||||
)
|
||||
company_id = fields.Many2one(
|
||||
related='template_id.company_id',
|
||||
store=True,
|
||||
)
|
||||
name = fields.Char(
|
||||
required=True,
|
||||
default='/',
|
||||
)
|
||||
product_id = fields.Many2one(
|
||||
comodel_name='product.product',
|
||||
string='Product',
|
||||
)
|
||||
account_id = fields.Many2one(
|
||||
comodel_name='account.account',
|
||||
string='Account',
|
||||
)
|
||||
company_id = fields.Many2one(related="template_id.company_id", store=True,)
|
||||
name = fields.Char(required=True, default="/",)
|
||||
product_id = fields.Many2one(comodel_name="product.product", string="Product",)
|
||||
account_id = fields.Many2one(comodel_name="account.account", string="Account",)
|
||||
analytic_account_id = fields.Many2one(
|
||||
comodel_name='account.analytic.account',
|
||||
string='Analytic',
|
||||
comodel_name="account.analytic.account", string="Analytic",
|
||||
)
|
||||
|
@ -5,29 +5,36 @@ from odoo import fields, models
|
||||
|
||||
|
||||
class ResCompany(models.Model):
|
||||
_inherit = 'res.company'
|
||||
_inherit = "res.company"
|
||||
|
||||
default_spread_revenue_account_id = fields.Many2one(
|
||||
'account.account', string='Revenue Spread Account')
|
||||
"account.account", string="Revenue Spread Account"
|
||||
)
|
||||
|
||||
default_spread_expense_account_id = fields.Many2one(
|
||||
'account.account', string='Expense Spread Account')
|
||||
"account.account", string="Expense Spread Account"
|
||||
)
|
||||
|
||||
default_spread_revenue_journal_id = fields.Many2one(
|
||||
'account.journal', string='Revenue Spread Journal')
|
||||
"account.journal", string="Revenue Spread Journal"
|
||||
)
|
||||
|
||||
default_spread_expense_journal_id = fields.Many2one(
|
||||
'account.journal', string='Expense Spread Journal')
|
||||
"account.journal", string="Expense Spread Journal"
|
||||
)
|
||||
|
||||
allow_spread_planning = fields.Boolean(
|
||||
default=True,
|
||||
help="Disable this option if you do not want to allow the "
|
||||
"spreading before the invoice is validated.")
|
||||
"spreading before the invoice is validated.",
|
||||
)
|
||||
force_move_auto_post = fields.Boolean(
|
||||
'Auto-post spread lines',
|
||||
"Auto-post spread lines",
|
||||
help="Enable this option if you want to post automatically the "
|
||||
"accounting moves of all the spreads.")
|
||||
"accounting moves of all the spreads.",
|
||||
)
|
||||
auto_archive = fields.Boolean(
|
||||
'Auto-archive spread',
|
||||
"Auto-archive spread",
|
||||
help="Enable this option if you want the cron job to automatically "
|
||||
"archive the spreads when all lines are posted.")
|
||||
"archive the spreads when all lines are posted.",
|
||||
)
|
||||
|
@ -1,27 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="account_spread_multi_company_rule" model="ir.rule">
|
||||
<field name="name">Account Spread multi-company</field>
|
||||
<field ref="model_account_spread" name="model_id" />
|
||||
<field eval="True" name="global" />
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="account_spread_template_multi_company_rule" model="ir.rule">
|
||||
<field name="name">Account Spread Template multi-company</field>
|
||||
<field ref="model_account_spread_template" name="model_id" />
|
||||
<field eval="True" name="global" />
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="account_spread_template_auto_multi_company_rule" model="ir.rule">
|
||||
<field name="name">Account Spread Tempalte Auto multi-company</field>
|
||||
<field ref="model_account_spread_template_auto" name="model_id" />
|
||||
<field eval="True" name="global" />
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
@ -1,15 +1,15 @@
|
||||
odoo.define('account_spread_cost_revenue.widget', function (require) {
|
||||
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 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',
|
||||
click: "_onClick",
|
||||
}),
|
||||
description: "",
|
||||
|
||||
@ -17,7 +17,7 @@ odoo.define('account_spread_cost_revenue.widget', function (require) {
|
||||
* @override
|
||||
*/
|
||||
isSet: function() {
|
||||
return this.value !== 'unavailable';
|
||||
return this.value !== "unavailable";
|
||||
},
|
||||
|
||||
/**
|
||||
@ -25,17 +25,17 @@ odoo.define('account_spread_cost_revenue.widget', function (require) {
|
||||
* @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');
|
||||
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');
|
||||
title = _t("Not linked to spread");
|
||||
}
|
||||
var $button = $('<button/>', {
|
||||
type: 'button',
|
||||
var $button = $("<button/>", {
|
||||
type: "button",
|
||||
title: title,
|
||||
}).addClass(style + className);
|
||||
this.$el.html($button);
|
||||
@ -47,10 +47,10 @@ odoo.define('account_spread_cost_revenue.widget', function (require) {
|
||||
*/
|
||||
_onClick: function(event) {
|
||||
event.stopPropagation();
|
||||
this.trigger_up('button_clicked', {
|
||||
this.trigger_up("button_clicked", {
|
||||
attrs: {
|
||||
name: 'spread_details',
|
||||
type: 'object',
|
||||
name: "spread_details",
|
||||
type: "object",
|
||||
},
|
||||
record: this.record,
|
||||
});
|
||||
@ -58,5 +58,4 @@ odoo.define('account_spread_cost_revenue.widget', function (require) {
|
||||
});
|
||||
|
||||
registry.add("spread_line_widget", AccountSpreadWidget);
|
||||
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
.o_web_client .o_spread_line {
|
||||
&.o_is_linked {
|
||||
color: theme-color('success');
|
||||
color: theme-color("success");
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<template id="assets_backend" name="account spread" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<link rel="stylesheet" href="/account_spread_cost_revenue/static/src/scss/account_spread.scss"/>
|
||||
<script type="text/javascript" src="/account_spread_cost_revenue/static/src/js/account_spread.js"></script>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="/account_spread_cost_revenue/static/src/scss/account_spread.scss"
|
||||
/>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="/account_spread_cost_revenue/static/src/js/account_spread.js"
|
||||
/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
@ -1,106 +1,127 @@
|
||||
# Copyright 2018-2019 Onestein (<https://www.onestein.eu>)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo.tools import convert_file
|
||||
from odoo.modules.module import get_resource_path
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.modules.module import get_resource_path
|
||||
from odoo.tests import common
|
||||
from odoo.tools import convert_file
|
||||
|
||||
|
||||
class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
|
||||
def _load(self, module, *args):
|
||||
convert_file(
|
||||
self.cr,
|
||||
'account_spread_cost_revenue',
|
||||
"account_spread_cost_revenue",
|
||||
get_resource_path(module, *args),
|
||||
{}, 'init', False, 'test', self.registry._assertion_report)
|
||||
{},
|
||||
"init",
|
||||
False,
|
||||
"test",
|
||||
self.registry._assertion_report,
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self._load('account', 'test', 'account_minimal_test.xml')
|
||||
self._load("account", "test", "account_minimal_test.xml")
|
||||
|
||||
type_receivable = self.env.ref('account.data_account_type_receivable')
|
||||
type_payable = self.env.ref('account.data_account_type_payable')
|
||||
type_revenue = self.env.ref('account.data_account_type_revenue')
|
||||
type_receivable = self.env.ref("account.data_account_type_receivable")
|
||||
type_payable = self.env.ref("account.data_account_type_payable")
|
||||
type_revenue = self.env.ref("account.data_account_type_revenue")
|
||||
|
||||
self.invoice_account = self.env['account.account'].create({
|
||||
'name': 'test_account_receivable',
|
||||
'code': '123',
|
||||
'user_type_id': type_receivable.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.invoice_account = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test_account_receivable",
|
||||
"code": "123",
|
||||
"user_type_id": type_receivable.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.account_payable = self.env['account.account'].create({
|
||||
'name': 'test_account_payable',
|
||||
'code': '321',
|
||||
'user_type_id': type_payable.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.account_payable = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test_account_payable",
|
||||
"code": "321",
|
||||
"user_type_id": type_payable.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.account_revenue = self.env['account.account'].create({
|
||||
'name': 'test_account_revenue',
|
||||
'code': '864',
|
||||
'user_type_id': type_revenue.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.account_revenue = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test_account_revenue",
|
||||
"code": "864",
|
||||
"user_type_id": type_revenue.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.invoice_line_account = self.account_payable
|
||||
|
||||
self.spread_account = self.env['account.account'].create({
|
||||
'name': 'test spread account_payable',
|
||||
'code': '765',
|
||||
'user_type_id': type_payable.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.spread_account = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test spread account_payable",
|
||||
"code": "765",
|
||||
"user_type_id": type_payable.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
|
||||
partner = self.env['res.partner'].create({
|
||||
'name': 'Partner Name',
|
||||
'supplier': True,
|
||||
})
|
||||
partner = self.env["res.partner"].create(
|
||||
{"name": "Partner Name", "supplier": True,}
|
||||
)
|
||||
|
||||
# Purchase Invoice
|
||||
self.invoice = self.env['account.invoice'].create({
|
||||
'partner_id': partner.id,
|
||||
'account_id': self.invoice_account.id,
|
||||
'type': 'in_invoice',
|
||||
})
|
||||
self.invoice_line = self.env['account.invoice.line'].create({
|
||||
'quantity': 1.0,
|
||||
'price_unit': 1000.0,
|
||||
'invoice_id': self.invoice.id,
|
||||
'name': 'product that cost 1000',
|
||||
'account_id': self.invoice_account.id,
|
||||
})
|
||||
self.invoice = self.env["account.invoice"].create(
|
||||
{
|
||||
"partner_id": partner.id,
|
||||
"account_id": self.invoice_account.id,
|
||||
"type": "in_invoice",
|
||||
}
|
||||
)
|
||||
self.invoice_line = self.env["account.invoice.line"].create(
|
||||
{
|
||||
"quantity": 1.0,
|
||||
"price_unit": 1000.0,
|
||||
"invoice_id": self.invoice.id,
|
||||
"name": "product that cost 1000",
|
||||
"account_id": self.invoice_account.id,
|
||||
}
|
||||
)
|
||||
|
||||
# Sales Invoice
|
||||
self.invoice_2 = self.env['account.invoice'].create({
|
||||
'partner_id': partner.id,
|
||||
'account_id': self.invoice_account.id,
|
||||
'type': 'out_invoice',
|
||||
})
|
||||
self.invoice_line_2 = self.env['account.invoice.line'].create({
|
||||
'quantity': 1.0,
|
||||
'price_unit': 1000.0,
|
||||
'invoice_id': self.invoice_2.id,
|
||||
'name': 'product that cost 1000',
|
||||
'account_id': self.invoice_line_account.id,
|
||||
})
|
||||
self.invoice_2 = self.env["account.invoice"].create(
|
||||
{
|
||||
"partner_id": partner.id,
|
||||
"account_id": self.invoice_account.id,
|
||||
"type": "out_invoice",
|
||||
}
|
||||
)
|
||||
self.invoice_line_2 = self.env["account.invoice.line"].create(
|
||||
{
|
||||
"quantity": 1.0,
|
||||
"price_unit": 1000.0,
|
||||
"invoice_id": self.invoice_2.id,
|
||||
"name": "product that cost 1000",
|
||||
"account_id": self.invoice_line_account.id,
|
||||
}
|
||||
)
|
||||
|
||||
def test_01_no_auto_spread_sheet(self):
|
||||
|
||||
self.env['account.spread.template'].create({
|
||||
'name': 'test',
|
||||
'spread_type': 'purchase',
|
||||
'period_number': 5,
|
||||
'period_type': 'month',
|
||||
'spread_account_id': self.account_payable.id,
|
||||
'spread_journal_id': self.ref(
|
||||
'account_spread_cost_revenue.expenses_journal'),
|
||||
'auto_spread': False, # Auto Spread = False
|
||||
'auto_spread_ids': [
|
||||
(0, 0, {'account_id': self.invoice_account.id})]
|
||||
})
|
||||
self.env["account.spread.template"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"spread_type": "purchase",
|
||||
"period_number": 5,
|
||||
"period_type": "month",
|
||||
"spread_account_id": self.account_payable.id,
|
||||
"spread_journal_id": self.ref(
|
||||
"account_spread_cost_revenue.expenses_journal"
|
||||
),
|
||||
"auto_spread": False, # Auto Spread = False
|
||||
"auto_spread_ids": [(0, 0, {"account_id": self.invoice_account.id})],
|
||||
}
|
||||
)
|
||||
|
||||
self.assertFalse(self.invoice_line.spread_id)
|
||||
self.invoice.action_invoice_open()
|
||||
@ -108,30 +129,34 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
|
||||
def test_02_new_auto_spread_sheet_purchase(self):
|
||||
|
||||
self.env['account.spread.template'].create({
|
||||
'name': 'test 1',
|
||||
'spread_type': 'purchase',
|
||||
'period_number': 5,
|
||||
'period_type': 'month',
|
||||
'spread_account_id': self.account_payable.id,
|
||||
'spread_journal_id': self.ref(
|
||||
'account_spread_cost_revenue.expenses_journal'),
|
||||
'auto_spread': True, # Auto Spread
|
||||
'auto_spread_ids': [
|
||||
(0, 0, {'account_id': self.invoice_account.id})]
|
||||
})
|
||||
template2 = self.env['account.spread.template'].create({
|
||||
'name': 'test 2',
|
||||
'spread_type': 'purchase',
|
||||
'period_number': 5,
|
||||
'period_type': 'month',
|
||||
'spread_account_id': self.account_payable.id,
|
||||
'spread_journal_id': self.ref(
|
||||
'account_spread_cost_revenue.expenses_journal'),
|
||||
'auto_spread': True, # Auto Spread
|
||||
'auto_spread_ids': [
|
||||
(0, 0, {'account_id': self.invoice_account.id})]
|
||||
})
|
||||
self.env["account.spread.template"].create(
|
||||
{
|
||||
"name": "test 1",
|
||||
"spread_type": "purchase",
|
||||
"period_number": 5,
|
||||
"period_type": "month",
|
||||
"spread_account_id": self.account_payable.id,
|
||||
"spread_journal_id": self.ref(
|
||||
"account_spread_cost_revenue.expenses_journal"
|
||||
),
|
||||
"auto_spread": True, # Auto Spread
|
||||
"auto_spread_ids": [(0, 0, {"account_id": self.invoice_account.id})],
|
||||
}
|
||||
)
|
||||
template2 = self.env["account.spread.template"].create(
|
||||
{
|
||||
"name": "test 2",
|
||||
"spread_type": "purchase",
|
||||
"period_number": 5,
|
||||
"period_type": "month",
|
||||
"spread_account_id": self.account_payable.id,
|
||||
"spread_journal_id": self.ref(
|
||||
"account_spread_cost_revenue.expenses_journal"
|
||||
),
|
||||
"auto_spread": True, # Auto Spread
|
||||
"auto_spread_ids": [(0, 0, {"account_id": self.invoice_account.id})],
|
||||
}
|
||||
)
|
||||
template2._check_auto_spread_ids_unique()
|
||||
|
||||
self.assertFalse(self.invoice_line.spread_id)
|
||||
@ -151,17 +176,22 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
|
||||
def test_03_new_auto_spread_sheet_sale(self):
|
||||
|
||||
self.env['account.spread.template'].create({
|
||||
'name': 'test',
|
||||
'spread_type': 'sale',
|
||||
'period_number': 5,
|
||||
'period_type': 'month',
|
||||
'spread_account_id': self.account_revenue.id,
|
||||
'spread_journal_id': self.ref(
|
||||
'account_spread_cost_revenue.sales_journal'),
|
||||
'auto_spread': True, # Auto Spread
|
||||
'auto_spread_ids': [(0, 0, {'account_id': self.invoice_line_account.id})]
|
||||
})
|
||||
self.env["account.spread.template"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"spread_type": "sale",
|
||||
"period_number": 5,
|
||||
"period_type": "month",
|
||||
"spread_account_id": self.account_revenue.id,
|
||||
"spread_journal_id": self.ref(
|
||||
"account_spread_cost_revenue.sales_journal"
|
||||
),
|
||||
"auto_spread": True, # Auto Spread
|
||||
"auto_spread_ids": [
|
||||
(0, 0, {"account_id": self.invoice_line_account.id})
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
self.assertFalse(self.invoice_line_2.spread_id)
|
||||
self.invoice_2.action_invoice_open()
|
||||
|
@ -3,123 +3,152 @@
|
||||
|
||||
import datetime
|
||||
|
||||
from odoo.tools import convert_file
|
||||
from odoo.modules.module import get_resource_path
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo.modules.module import get_resource_path
|
||||
from odoo.tests import common
|
||||
from odoo.tools import convert_file
|
||||
|
||||
|
||||
class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
|
||||
def _load(self, module, *args):
|
||||
convert_file(
|
||||
self.cr,
|
||||
'account_spread_cost_revenue',
|
||||
"account_spread_cost_revenue",
|
||||
get_resource_path(module, *args),
|
||||
{}, 'init', False, 'test', self.registry._assertion_report)
|
||||
{},
|
||||
"init",
|
||||
False,
|
||||
"test",
|
||||
self.registry._assertion_report,
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self._load('account', 'test', 'account_minimal_test.xml')
|
||||
self._load("account", "test", "account_minimal_test.xml")
|
||||
|
||||
type_receivable = self.env.ref('account.data_account_type_receivable')
|
||||
type_payable = self.env.ref('account.data_account_type_payable')
|
||||
type_revenue = self.env.ref('account.data_account_type_revenue')
|
||||
type_receivable = self.env.ref("account.data_account_type_receivable")
|
||||
type_payable = self.env.ref("account.data_account_type_payable")
|
||||
type_revenue = self.env.ref("account.data_account_type_revenue")
|
||||
|
||||
self.invoice_account = self.env['account.account'].create({
|
||||
'name': 'test_account_receivable',
|
||||
'code': '123',
|
||||
'user_type_id': type_receivable.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.invoice_account = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test_account_receivable",
|
||||
"code": "123",
|
||||
"user_type_id": type_receivable.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.account_payable = self.env['account.account'].create({
|
||||
'name': 'test_account_payable',
|
||||
'code': '321',
|
||||
'user_type_id': type_payable.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.account_payable = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test_account_payable",
|
||||
"code": "321",
|
||||
"user_type_id": type_payable.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.account_revenue = self.env['account.account'].create({
|
||||
'name': 'test_account_revenue',
|
||||
'code': '864',
|
||||
'user_type_id': type_revenue.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.account_revenue = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test_account_revenue",
|
||||
"code": "864",
|
||||
"user_type_id": type_revenue.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.invoice_line_account = self.account_payable
|
||||
|
||||
self.spread_account = self.env['account.account'].create({
|
||||
'name': 'test spread account_payable',
|
||||
'code': '765',
|
||||
'user_type_id': type_payable.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.spread_account = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test spread account_payable",
|
||||
"code": "765",
|
||||
"user_type_id": type_payable.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
|
||||
partner = self.env['res.partner'].create({
|
||||
'name': 'Partner Name',
|
||||
'supplier': True,
|
||||
})
|
||||
self.invoice = self.env['account.invoice'].create({
|
||||
'partner_id': partner.id,
|
||||
'account_id': self.invoice_account.id,
|
||||
'type': 'in_invoice',
|
||||
})
|
||||
self.invoice_line = self.env['account.invoice.line'].create({
|
||||
'quantity': 1.0,
|
||||
'price_unit': 1000.0,
|
||||
'invoice_id': self.invoice.id,
|
||||
'name': 'product that cost 1000',
|
||||
'account_id': self.invoice_account.id,
|
||||
})
|
||||
partner = self.env["res.partner"].create(
|
||||
{"name": "Partner Name", "supplier": True,}
|
||||
)
|
||||
self.invoice = self.env["account.invoice"].create(
|
||||
{
|
||||
"partner_id": partner.id,
|
||||
"account_id": self.invoice_account.id,
|
||||
"type": "in_invoice",
|
||||
}
|
||||
)
|
||||
self.invoice_line = self.env["account.invoice.line"].create(
|
||||
{
|
||||
"quantity": 1.0,
|
||||
"price_unit": 1000.0,
|
||||
"invoice_id": self.invoice.id,
|
||||
"name": "product that cost 1000",
|
||||
"account_id": self.invoice_account.id,
|
||||
}
|
||||
)
|
||||
|
||||
analytic_tags = [(6, 0, self.env.ref('analytic.tag_contract').ids)]
|
||||
self.analytic_account = self.env['account.analytic.account'].create({
|
||||
'name': 'test account',
|
||||
})
|
||||
self.spread = self.env['account.spread'].with_context(
|
||||
mail_create_nosubscribe=True
|
||||
).create([{
|
||||
'name': 'test',
|
||||
'debit_account_id': self.spread_account.id,
|
||||
'credit_account_id': self.invoice_line_account.id,
|
||||
'period_number': 12,
|
||||
'period_type': 'month',
|
||||
'spread_date': datetime.date(2017, 2, 1),
|
||||
'estimated_amount': 1000.0,
|
||||
'journal_id': self.invoice.journal_id.id,
|
||||
'invoice_type': 'in_invoice',
|
||||
'account_analytic_id': self.analytic_account.id,
|
||||
'analytic_tag_ids': analytic_tags,
|
||||
}])
|
||||
analytic_tags = [(6, 0, self.env.ref("analytic.tag_contract").ids)]
|
||||
self.analytic_account = self.env["account.analytic.account"].create(
|
||||
{"name": "test account",}
|
||||
)
|
||||
self.spread = (
|
||||
self.env["account.spread"]
|
||||
.with_context(mail_create_nosubscribe=True)
|
||||
.create(
|
||||
[
|
||||
{
|
||||
"name": "test",
|
||||
"debit_account_id": self.spread_account.id,
|
||||
"credit_account_id": self.invoice_line_account.id,
|
||||
"period_number": 12,
|
||||
"period_type": "month",
|
||||
"spread_date": datetime.date(2017, 2, 1),
|
||||
"estimated_amount": 1000.0,
|
||||
"journal_id": self.invoice.journal_id.id,
|
||||
"invoice_type": "in_invoice",
|
||||
"account_analytic_id": self.analytic_account.id,
|
||||
"analytic_tag_ids": analytic_tags,
|
||||
}
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
self.invoice_2 = self.env['account.invoice'].create({
|
||||
'partner_id': partner.id,
|
||||
'account_id': self.invoice_account.id,
|
||||
'type': 'out_invoice',
|
||||
})
|
||||
self.invoice_line_2 = self.env['account.invoice.line'].create({
|
||||
'quantity': 1.0,
|
||||
'price_unit': 1000.0,
|
||||
'invoice_id': self.invoice_2.id,
|
||||
'name': 'product that cost 1000',
|
||||
'account_id': self.invoice_line_account.id,
|
||||
})
|
||||
self.spread2 = self.env['account.spread'].create([{
|
||||
'name': 'test2',
|
||||
'debit_account_id': self.spread_account.id,
|
||||
'credit_account_id': self.invoice_line_account.id,
|
||||
'period_number': 12,
|
||||
'period_type': 'month',
|
||||
'spread_date': datetime.date(2017, 2, 1),
|
||||
'estimated_amount': 1000.0,
|
||||
'journal_id': self.invoice_2.journal_id.id,
|
||||
'invoice_type': 'out_invoice',
|
||||
}])
|
||||
self.invoice_2 = self.env["account.invoice"].create(
|
||||
{
|
||||
"partner_id": partner.id,
|
||||
"account_id": self.invoice_account.id,
|
||||
"type": "out_invoice",
|
||||
}
|
||||
)
|
||||
self.invoice_line_2 = self.env["account.invoice.line"].create(
|
||||
{
|
||||
"quantity": 1.0,
|
||||
"price_unit": 1000.0,
|
||||
"invoice_id": self.invoice_2.id,
|
||||
"name": "product that cost 1000",
|
||||
"account_id": self.invoice_line_account.id,
|
||||
}
|
||||
)
|
||||
self.spread2 = self.env["account.spread"].create(
|
||||
[
|
||||
{
|
||||
"name": "test2",
|
||||
"debit_account_id": self.spread_account.id,
|
||||
"credit_account_id": self.invoice_line_account.id,
|
||||
"period_number": 12,
|
||||
"period_type": "month",
|
||||
"spread_date": datetime.date(2017, 2, 1),
|
||||
"estimated_amount": 1000.0,
|
||||
"journal_id": self.invoice_2.journal_id.id,
|
||||
"invoice_type": "out_invoice",
|
||||
}
|
||||
]
|
||||
)
|
||||
|
||||
def test_01_wizard_defaults(self):
|
||||
my_company = self.env.user.company_id
|
||||
Wizard = self.env['account.spread.invoice.line.link.wizard']
|
||||
Wizard = self.env["account.spread.invoice.line.link.wizard"]
|
||||
wizard1 = Wizard.with_context(
|
||||
default_invoice_line_id=self.invoice_line.id,
|
||||
default_company_id=my_company.id,
|
||||
@ -128,10 +157,10 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
|
||||
self.assertEqual(wizard1.invoice_line_id, self.invoice_line)
|
||||
self.assertEqual(wizard1.invoice_line_id.invoice_id, self.invoice)
|
||||
self.assertEqual(wizard1.invoice_type, 'in_invoice')
|
||||
self.assertEqual(wizard1.invoice_type, "in_invoice")
|
||||
self.assertFalse(wizard1.spread_id)
|
||||
self.assertEqual(wizard1.company_id, my_company)
|
||||
self.assertEqual(wizard1.spread_action_type, 'link')
|
||||
self.assertEqual(wizard1.spread_action_type, "link")
|
||||
self.assertFalse(wizard1.spread_account_id)
|
||||
self.assertFalse(wizard1.spread_journal_id)
|
||||
|
||||
@ -142,21 +171,21 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
|
||||
self.assertEqual(wizard2.invoice_line_id, self.invoice_line_2)
|
||||
self.assertEqual(wizard2.invoice_line_id.invoice_id, self.invoice_2)
|
||||
self.assertEqual(wizard2.invoice_type, 'out_invoice')
|
||||
self.assertEqual(wizard2.invoice_type, "out_invoice")
|
||||
self.assertFalse(wizard2.spread_id)
|
||||
self.assertEqual(wizard2.company_id, my_company)
|
||||
self.assertEqual(wizard2.spread_action_type, 'template')
|
||||
self.assertEqual(wizard2.spread_action_type, "template")
|
||||
self.assertFalse(wizard2.spread_account_id)
|
||||
self.assertFalse(wizard2.spread_journal_id)
|
||||
|
||||
def test_02_wizard_defaults(self):
|
||||
my_company = self.env.user.company_id
|
||||
Wizard = self.env['account.spread.invoice.line.link.wizard']
|
||||
Wizard = self.env["account.spread.invoice.line.link.wizard"]
|
||||
|
||||
account_revenue = self.account_revenue
|
||||
account_payable = self.account_payable
|
||||
exp_journal = self.ref('account_spread_cost_revenue.expenses_journal')
|
||||
sales_journal = self.ref('account_spread_cost_revenue.sales_journal')
|
||||
exp_journal = self.ref("account_spread_cost_revenue.expenses_journal")
|
||||
sales_journal = self.ref("account_spread_cost_revenue.sales_journal")
|
||||
my_company.default_spread_revenue_account_id = account_revenue
|
||||
my_company.default_spread_expense_account_id = account_payable
|
||||
my_company.default_spread_revenue_journal_id = sales_journal
|
||||
@ -175,16 +204,16 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
|
||||
self.assertEqual(wizard1.invoice_line_id, self.invoice_line)
|
||||
self.assertEqual(wizard1.invoice_line_id.invoice_id, self.invoice)
|
||||
self.assertEqual(wizard1.invoice_type, 'in_invoice')
|
||||
self.assertEqual(wizard1.invoice_type, "in_invoice")
|
||||
self.assertFalse(wizard1.spread_id)
|
||||
self.assertEqual(wizard1.company_id, my_company)
|
||||
self.assertEqual(wizard1.spread_action_type, 'link')
|
||||
self.assertEqual(wizard1.spread_action_type, "link")
|
||||
self.assertFalse(wizard1.spread_account_id)
|
||||
self.assertFalse(wizard1.spread_journal_id)
|
||||
|
||||
res_onchange = wizard1.onchange_invoice_type()
|
||||
self.assertTrue(res_onchange)
|
||||
self.assertTrue(res_onchange.get('domain'))
|
||||
self.assertTrue(res_onchange.get("domain"))
|
||||
|
||||
wizard1._onchange_spread_journal_account()
|
||||
self.assertTrue(wizard1.spread_account_id)
|
||||
@ -199,16 +228,16 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
|
||||
self.assertEqual(wizard2.invoice_line_id, self.invoice_line_2)
|
||||
self.assertEqual(wizard2.invoice_line_id.invoice_id, self.invoice_2)
|
||||
self.assertEqual(wizard2.invoice_type, 'out_invoice')
|
||||
self.assertEqual(wizard2.invoice_type, "out_invoice")
|
||||
self.assertFalse(wizard2.spread_id)
|
||||
self.assertEqual(wizard2.company_id, my_company)
|
||||
self.assertEqual(wizard2.spread_action_type, 'template')
|
||||
self.assertEqual(wizard2.spread_action_type, "template")
|
||||
self.assertFalse(wizard2.spread_account_id)
|
||||
self.assertFalse(wizard2.spread_journal_id)
|
||||
|
||||
res_onchange = wizard2.onchange_invoice_type()
|
||||
self.assertTrue(res_onchange)
|
||||
self.assertTrue(res_onchange.get('domain'))
|
||||
self.assertTrue(res_onchange.get("domain"))
|
||||
|
||||
wizard2._onchange_spread_journal_account()
|
||||
self.assertTrue(wizard2.spread_account_id)
|
||||
@ -219,22 +248,23 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
def test_03_link_invoice_line_with_spread_sheet(self):
|
||||
|
||||
my_company = self.env.user.company_id
|
||||
Wizard = self.env['account.spread.invoice.line.link.wizard']
|
||||
Wizard = self.env["account.spread.invoice.line.link.wizard"]
|
||||
wizard1 = Wizard.with_context(
|
||||
default_invoice_line_id=self.invoice_line.id,
|
||||
default_company_id=my_company.id,
|
||||
allow_spread_planning=True,
|
||||
).create({})
|
||||
self.assertEqual(wizard1.spread_action_type, 'link')
|
||||
self.assertEqual(wizard1.spread_action_type, "link")
|
||||
|
||||
wizard1.spread_account_id = self.account_revenue
|
||||
wizard1.spread_journal_id = self.ref(
|
||||
'account_spread_cost_revenue.expenses_journal')
|
||||
"account_spread_cost_revenue.expenses_journal"
|
||||
)
|
||||
wizard1.spread_id = self.spread
|
||||
res_action = wizard1.confirm()
|
||||
self.assertTrue(isinstance(res_action, dict))
|
||||
self.assertTrue(res_action.get('res_id'))
|
||||
self.assertEqual(res_action.get('res_id'), self.spread.id)
|
||||
self.assertTrue(res_action.get("res_id"))
|
||||
self.assertEqual(res_action.get("res_id"), self.spread.id)
|
||||
self.assertTrue(self.spread.invoice_line_id)
|
||||
self.assertEqual(self.spread.invoice_line_id, self.invoice_line)
|
||||
|
||||
@ -252,7 +282,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
self.assertTrue(line.move_id.journal_id.update_posted)
|
||||
for ml in line.move_id.line_ids:
|
||||
ml_analytic_account = ml.analytic_account_id
|
||||
analytic_tag = self.env.ref('analytic.tag_contract')
|
||||
analytic_tag = self.env.ref("analytic.tag_contract")
|
||||
self.assertEqual(ml_analytic_account, self.analytic_account)
|
||||
self.assertEqual(ml.analytic_tag_ids, analytic_tag)
|
||||
|
||||
@ -268,35 +298,34 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
def test_04_new_spread_sheet(self):
|
||||
|
||||
my_company = self.env.user.company_id
|
||||
Wizard = self.env['account.spread.invoice.line.link.wizard']
|
||||
Wizard = self.env["account.spread.invoice.line.link.wizard"]
|
||||
|
||||
spread_account = self.account_revenue
|
||||
spread_journal_id = self.ref(
|
||||
'account_spread_cost_revenue.expenses_journal')
|
||||
spread_journal_id = self.ref("account_spread_cost_revenue.expenses_journal")
|
||||
|
||||
wizard1 = Wizard.with_context(
|
||||
default_invoice_line_id=self.invoice_line.id,
|
||||
default_company_id=my_company.id,
|
||||
).create({
|
||||
'spread_action_type': 'new',
|
||||
})
|
||||
self.assertEqual(wizard1.spread_action_type, 'new')
|
||||
).create({"spread_action_type": "new",})
|
||||
self.assertEqual(wizard1.spread_action_type, "new")
|
||||
|
||||
wizard1.write({
|
||||
'spread_account_id': spread_account.id,
|
||||
'spread_journal_id': spread_journal_id,
|
||||
})
|
||||
wizard1.write(
|
||||
{
|
||||
"spread_account_id": spread_account.id,
|
||||
"spread_journal_id": spread_journal_id,
|
||||
}
|
||||
)
|
||||
|
||||
res_action = wizard1.confirm()
|
||||
self.assertTrue(isinstance(res_action, dict))
|
||||
self.assertFalse(res_action.get('res_id'))
|
||||
self.assertTrue(res_action.get('context'))
|
||||
res_context = res_action.get('context')
|
||||
self.assertTrue(res_context.get('default_name'))
|
||||
self.assertTrue(res_context.get('default_invoice_type'))
|
||||
self.assertTrue(res_context.get('default_invoice_line_id'))
|
||||
self.assertTrue(res_context.get('default_debit_account_id'))
|
||||
self.assertTrue(res_context.get('default_credit_account_id'))
|
||||
self.assertFalse(res_action.get("res_id"))
|
||||
self.assertTrue(res_action.get("context"))
|
||||
res_context = res_action.get("context")
|
||||
self.assertTrue(res_context.get("default_name"))
|
||||
self.assertTrue(res_context.get("default_invoice_type"))
|
||||
self.assertTrue(res_context.get("default_invoice_line_id"))
|
||||
self.assertTrue(res_context.get("default_debit_account_id"))
|
||||
self.assertTrue(res_context.get("default_credit_account_id"))
|
||||
|
||||
spread_lines = self.spread.line_ids
|
||||
for line in spread_lines:
|
||||
@ -311,26 +340,26 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
wizard2 = Wizard.with_context(
|
||||
default_invoice_line_id=self.invoice_line_2.id,
|
||||
default_company_id=my_company.id,
|
||||
).create({
|
||||
'spread_action_type': 'new',
|
||||
})
|
||||
self.assertEqual(wizard2.spread_action_type, 'new')
|
||||
).create({"spread_action_type": "new",})
|
||||
self.assertEqual(wizard2.spread_action_type, "new")
|
||||
|
||||
wizard2.write({
|
||||
'spread_account_id': spread_account.id,
|
||||
'spread_journal_id': spread_journal_id,
|
||||
})
|
||||
wizard2.write(
|
||||
{
|
||||
"spread_account_id": spread_account.id,
|
||||
"spread_journal_id": spread_journal_id,
|
||||
}
|
||||
)
|
||||
|
||||
res_action = wizard2.confirm()
|
||||
self.assertTrue(isinstance(res_action, dict))
|
||||
self.assertFalse(res_action.get('res_id'))
|
||||
self.assertTrue(res_action.get('context'))
|
||||
res_context = res_action.get('context')
|
||||
self.assertTrue(res_context.get('default_name'))
|
||||
self.assertTrue(res_context.get('default_invoice_type'))
|
||||
self.assertTrue(res_context.get('default_invoice_line_id'))
|
||||
self.assertTrue(res_context.get('default_debit_account_id'))
|
||||
self.assertTrue(res_context.get('default_credit_account_id'))
|
||||
self.assertFalse(res_action.get("res_id"))
|
||||
self.assertTrue(res_action.get("context"))
|
||||
res_context = res_action.get("context")
|
||||
self.assertTrue(res_context.get("default_name"))
|
||||
self.assertTrue(res_context.get("default_invoice_type"))
|
||||
self.assertTrue(res_context.get("default_invoice_line_id"))
|
||||
self.assertTrue(res_context.get("default_debit_account_id"))
|
||||
self.assertTrue(res_context.get("default_credit_account_id"))
|
||||
|
||||
spread_lines = self.spread2.line_ids
|
||||
for line in spread_lines:
|
||||
@ -344,34 +373,32 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
def test_05_new_spread_sheet_from_template(self):
|
||||
|
||||
my_company = self.env.user.company_id
|
||||
Wizard = self.env['account.spread.invoice.line.link.wizard']
|
||||
Wizard = self.env["account.spread.invoice.line.link.wizard"]
|
||||
|
||||
spread_account = self.account_payable
|
||||
self.assertTrue(spread_account)
|
||||
spread_journal_id = self.ref(
|
||||
'account_spread_cost_revenue.expenses_journal')
|
||||
spread_journal_id = self.ref("account_spread_cost_revenue.expenses_journal")
|
||||
|
||||
template = self.env['account.spread.template'].create({
|
||||
'name': 'test',
|
||||
'spread_type': 'purchase',
|
||||
'period_number': 5,
|
||||
'period_type': 'month',
|
||||
'spread_account_id': spread_account.id,
|
||||
'spread_journal_id': spread_journal_id,
|
||||
})
|
||||
template = self.env["account.spread.template"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"spread_type": "purchase",
|
||||
"period_number": 5,
|
||||
"period_type": "month",
|
||||
"spread_account_id": spread_account.id,
|
||||
"spread_journal_id": spread_journal_id,
|
||||
}
|
||||
)
|
||||
|
||||
wizard1 = Wizard.with_context(
|
||||
default_invoice_line_id=self.invoice_line.id,
|
||||
default_company_id=my_company.id,
|
||||
).create({
|
||||
'spread_action_type': 'template',
|
||||
'template_id': template.id,
|
||||
})
|
||||
self.assertEqual(wizard1.spread_action_type, 'template')
|
||||
).create({"spread_action_type": "template", "template_id": template.id,})
|
||||
self.assertEqual(wizard1.spread_action_type, "template")
|
||||
|
||||
res_action = wizard1.confirm()
|
||||
self.assertTrue(isinstance(res_action, dict))
|
||||
self.assertTrue(res_action.get('res_id'))
|
||||
self.assertTrue(res_action.get("res_id"))
|
||||
|
||||
spread_lines = self.spread.line_ids
|
||||
for line in spread_lines:
|
||||
@ -386,26 +413,26 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
wizard2 = Wizard.with_context(
|
||||
default_invoice_line_id=self.invoice_line_2.id,
|
||||
default_company_id=my_company.id,
|
||||
).create({
|
||||
'spread_action_type': 'new',
|
||||
})
|
||||
self.assertEqual(wizard2.spread_action_type, 'new')
|
||||
).create({"spread_action_type": "new",})
|
||||
self.assertEqual(wizard2.spread_action_type, "new")
|
||||
|
||||
wizard2.write({
|
||||
'spread_account_id': spread_account.id,
|
||||
'spread_journal_id': spread_journal_id,
|
||||
})
|
||||
wizard2.write(
|
||||
{
|
||||
"spread_account_id": spread_account.id,
|
||||
"spread_journal_id": spread_journal_id,
|
||||
}
|
||||
)
|
||||
|
||||
res_action = wizard2.confirm()
|
||||
self.assertTrue(isinstance(res_action, dict))
|
||||
self.assertFalse(res_action.get('res_id'))
|
||||
self.assertTrue(res_action.get('context'))
|
||||
res_context = res_action.get('context')
|
||||
self.assertTrue(res_context.get('default_name'))
|
||||
self.assertTrue(res_context.get('default_invoice_type'))
|
||||
self.assertTrue(res_context.get('default_invoice_line_id'))
|
||||
self.assertTrue(res_context.get('default_debit_account_id'))
|
||||
self.assertTrue(res_context.get('default_credit_account_id'))
|
||||
self.assertFalse(res_action.get("res_id"))
|
||||
self.assertTrue(res_action.get("context"))
|
||||
res_context = res_action.get("context")
|
||||
self.assertTrue(res_context.get("default_name"))
|
||||
self.assertTrue(res_context.get("default_invoice_type"))
|
||||
self.assertTrue(res_context.get("default_invoice_line_id"))
|
||||
self.assertTrue(res_context.get("default_debit_account_id"))
|
||||
self.assertTrue(res_context.get("default_credit_account_id"))
|
||||
|
||||
spread_lines = self.spread2.line_ids
|
||||
for line in spread_lines:
|
||||
@ -420,8 +447,8 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
|
||||
res_action = self.invoice_line.spread_details()
|
||||
self.assertTrue(isinstance(res_action, dict))
|
||||
self.assertFalse(res_action.get('res_id'))
|
||||
self.assertTrue(res_action.get('context'))
|
||||
self.assertFalse(res_action.get("res_id"))
|
||||
self.assertTrue(res_action.get("context"))
|
||||
|
||||
def test_07_unlink_invoice_line_and_spread_sheet(self):
|
||||
|
||||
@ -465,7 +492,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
# Validate invoice
|
||||
self.invoice.action_invoice_open()
|
||||
|
||||
invoice_mls = self.invoice.move_id.mapped('line_ids')
|
||||
invoice_mls = self.invoice.move_id.mapped("line_ids")
|
||||
self.assertTrue(invoice_mls)
|
||||
for invoice_ml in invoice_mls:
|
||||
if invoice_ml.debit:
|
||||
@ -474,15 +501,17 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
def test_10_link_vendor_bill_line_with_spread_sheet(self):
|
||||
|
||||
copied_line = self.invoice_line.copy()
|
||||
copied_line.name = 'new test line'
|
||||
self.spread.write({
|
||||
'estimated_amount': 1000.0,
|
||||
'period_number': 12,
|
||||
'period_type': 'month',
|
||||
'spread_date': datetime.date(2017, 1, 7),
|
||||
'invoice_line_id': self.invoice_line.id,
|
||||
'move_line_auto_post': False,
|
||||
})
|
||||
copied_line.name = "new test line"
|
||||
self.spread.write(
|
||||
{
|
||||
"estimated_amount": 1000.0,
|
||||
"period_number": 12,
|
||||
"period_type": "month",
|
||||
"spread_date": datetime.date(2017, 1, 7),
|
||||
"invoice_line_id": self.invoice_line.id,
|
||||
"move_line_auto_post": False,
|
||||
}
|
||||
)
|
||||
|
||||
spread_lines = self.spread.line_ids
|
||||
for line in spread_lines:
|
||||
@ -498,7 +527,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
balance_sheet = self.spread.credit_account_id
|
||||
self.assertTrue(balance_sheet.reconcile)
|
||||
|
||||
spread_mls = self.spread.line_ids.mapped('move_id.line_ids')
|
||||
spread_mls = self.spread.line_ids.mapped("move_id.line_ids")
|
||||
self.assertTrue(spread_mls)
|
||||
for spread_ml in spread_mls:
|
||||
if spread_ml.debit:
|
||||
@ -509,16 +538,17 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
# Validate invoice
|
||||
self.invoice.action_invoice_open()
|
||||
|
||||
invoice_mls = self.invoice.move_id.mapped('line_ids')
|
||||
invoice_mls = self.invoice.move_id.mapped("line_ids")
|
||||
self.assertTrue(invoice_mls)
|
||||
|
||||
count_balance_sheet = len(invoice_mls.filtered(
|
||||
lambda x: x.account_id == balance_sheet))
|
||||
count_balance_sheet = len(
|
||||
invoice_mls.filtered(lambda x: x.account_id == balance_sheet)
|
||||
)
|
||||
self.assertEqual(count_balance_sheet, 1)
|
||||
|
||||
self.spread.line_ids.create_and_reconcile_moves()
|
||||
|
||||
spread_mls = self.spread.line_ids.mapped('move_id.line_ids')
|
||||
spread_mls = self.spread.line_ids.mapped("move_id.line_ids")
|
||||
self.assertTrue(spread_mls)
|
||||
for spread_ml in spread_mls:
|
||||
if spread_ml.debit:
|
||||
@ -528,19 +558,21 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
|
||||
action_reconcile_view = self.spread2.open_reconcile_view()
|
||||
self.assertTrue(isinstance(action_reconcile_view, dict))
|
||||
self.assertFalse(action_reconcile_view.get('domain')[0][2])
|
||||
self.assertTrue(action_reconcile_view.get('context'))
|
||||
self.assertFalse(action_reconcile_view.get("domain")[0][2])
|
||||
self.assertTrue(action_reconcile_view.get("context"))
|
||||
|
||||
def test_11_link_vendor_bill_line_with_spread_sheet(self):
|
||||
self.invoice_line.copy()
|
||||
self.spread.write({
|
||||
'estimated_amount': 1000.0,
|
||||
'period_number': 12,
|
||||
'period_type': 'month',
|
||||
'spread_date': datetime.date(2017, 1, 7),
|
||||
'invoice_line_id': self.invoice_line.id,
|
||||
'move_line_auto_post': False,
|
||||
})
|
||||
self.spread.write(
|
||||
{
|
||||
"estimated_amount": 1000.0,
|
||||
"period_number": 12,
|
||||
"period_type": "month",
|
||||
"spread_date": datetime.date(2017, 1, 7),
|
||||
"invoice_line_id": self.invoice_line.id,
|
||||
"move_line_auto_post": False,
|
||||
}
|
||||
)
|
||||
|
||||
spread_lines = self.spread.line_ids
|
||||
for line in spread_lines:
|
||||
@ -556,7 +588,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
balance_sheet = self.spread.credit_account_id
|
||||
self.assertTrue(balance_sheet.reconcile)
|
||||
|
||||
spread_mls = self.spread.line_ids.mapped('move_id.line_ids')
|
||||
spread_mls = self.spread.line_ids.mapped("move_id.line_ids")
|
||||
self.assertTrue(spread_mls)
|
||||
for spread_ml in spread_mls:
|
||||
if spread_ml.debit:
|
||||
@ -567,40 +599,43 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
# Validate invoice
|
||||
self.invoice.action_invoice_open()
|
||||
|
||||
invoice_mls = self.invoice.move_id.mapped('line_ids')
|
||||
invoice_mls = self.invoice.move_id.mapped("line_ids")
|
||||
self.assertTrue(invoice_mls)
|
||||
|
||||
count_balance_sheet = len(invoice_mls.filtered(
|
||||
lambda x: x.account_id == balance_sheet))
|
||||
count_balance_sheet = len(
|
||||
invoice_mls.filtered(lambda x: x.account_id == balance_sheet)
|
||||
)
|
||||
self.assertEqual(count_balance_sheet, 1)
|
||||
|
||||
self.spread.company_id.force_move_auto_post = True
|
||||
self.spread.line_ids.create_and_reconcile_moves()
|
||||
|
||||
spread_mls = self.spread.line_ids.mapped('move_id.line_ids')
|
||||
spread_mls = self.spread.line_ids.mapped("move_id.line_ids")
|
||||
self.assertTrue(spread_mls)
|
||||
for spread_ml in spread_mls:
|
||||
self.assertFalse(spread_ml.full_reconcile_id)
|
||||
|
||||
action_reconcile_view = self.spread.open_reconcile_view()
|
||||
self.assertTrue(isinstance(action_reconcile_view, dict))
|
||||
self.assertTrue(action_reconcile_view.get('domain')[0][2])
|
||||
self.assertTrue(action_reconcile_view.get('context'))
|
||||
self.assertTrue(action_reconcile_view.get("domain")[0][2])
|
||||
self.assertTrue(action_reconcile_view.get("context"))
|
||||
|
||||
action_spread_details = self.invoice_line.spread_details()
|
||||
self.assertTrue(isinstance(action_spread_details, dict))
|
||||
self.assertTrue(action_spread_details.get('res_id'))
|
||||
self.assertTrue(action_spread_details.get("res_id"))
|
||||
|
||||
def test_12_link_invoice_line_with_spread_sheet_full_reconcile(self):
|
||||
|
||||
self.spread2.write({
|
||||
'estimated_amount': 1000.0,
|
||||
'period_number': 12,
|
||||
'period_type': 'month',
|
||||
'spread_date': datetime.date(2017, 1, 7),
|
||||
'invoice_line_id': self.invoice_line_2.id,
|
||||
'move_line_auto_post': False,
|
||||
})
|
||||
self.spread2.write(
|
||||
{
|
||||
"estimated_amount": 1000.0,
|
||||
"period_number": 12,
|
||||
"period_type": "month",
|
||||
"spread_date": datetime.date(2017, 1, 7),
|
||||
"invoice_line_id": self.invoice_line_2.id,
|
||||
"move_line_auto_post": False,
|
||||
}
|
||||
)
|
||||
|
||||
spread_lines = self.spread2.line_ids
|
||||
for line in spread_lines:
|
||||
@ -616,7 +651,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
balance_sheet = self.spread.debit_account_id
|
||||
self.assertTrue(balance_sheet.reconcile)
|
||||
|
||||
spread_mls = self.spread2.line_ids.mapped('move_id.line_ids')
|
||||
spread_mls = self.spread2.line_ids.mapped("move_id.line_ids")
|
||||
self.assertTrue(spread_mls)
|
||||
for spread_ml in spread_mls:
|
||||
if spread_ml.debit:
|
||||
@ -627,7 +662,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
# Validate invoice
|
||||
self.invoice_2.action_invoice_open()
|
||||
|
||||
invoice_mls = self.invoice_2.move_id.mapped('line_ids')
|
||||
invoice_mls = self.invoice_2.move_id.mapped("line_ids")
|
||||
self.assertTrue(invoice_mls)
|
||||
for invoice_ml in invoice_mls:
|
||||
if invoice_ml.credit:
|
||||
@ -635,7 +670,7 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
|
||||
self.spread2.line_ids.create_and_reconcile_moves()
|
||||
|
||||
spread_mls = self.spread2.line_ids.mapped('move_id.line_ids')
|
||||
spread_mls = self.spread2.line_ids.mapped("move_id.line_ids")
|
||||
self.assertTrue(spread_mls)
|
||||
for spread_ml in spread_mls:
|
||||
if spread_ml.debit:
|
||||
@ -645,22 +680,24 @@ 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('res_id'))
|
||||
self.assertTrue(action_reconcile_view.get('context'))
|
||||
self.assertTrue(action_reconcile_view.get("domain")[0][2])
|
||||
self.assertFalse(action_reconcile_view.get("res_id"))
|
||||
self.assertTrue(action_reconcile_view.get("context"))
|
||||
|
||||
action_spread_details = self.invoice_line_2.spread_details()
|
||||
self.assertTrue(isinstance(action_spread_details, dict))
|
||||
self.assertTrue(action_spread_details.get('res_id'))
|
||||
self.assertTrue(action_spread_details.get("res_id"))
|
||||
|
||||
def test_13_link_invoice_line_with_spread_sheet_partial_reconcile(self):
|
||||
|
||||
self.spread2.write({
|
||||
'estimated_amount': 1000.0,
|
||||
'period_number': 12,
|
||||
'period_type': 'month',
|
||||
'spread_date': datetime.date(2017, 1, 7),
|
||||
})
|
||||
self.spread2.write(
|
||||
{
|
||||
"estimated_amount": 1000.0,
|
||||
"period_number": 12,
|
||||
"period_type": "month",
|
||||
"spread_date": datetime.date(2017, 1, 7),
|
||||
}
|
||||
)
|
||||
|
||||
self.spread2.compute_spread_board()
|
||||
spread_lines = self.spread2.line_ids
|
||||
@ -674,10 +711,10 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
spread_lines[2]._create_moves().post()
|
||||
spread_lines[3]._create_moves().post()
|
||||
|
||||
self.assertEqual(spread_lines[0].move_id.state, 'posted')
|
||||
self.assertEqual(spread_lines[1].move_id.state, 'posted')
|
||||
self.assertEqual(spread_lines[2].move_id.state, 'posted')
|
||||
self.assertEqual(spread_lines[3].move_id.state, 'posted')
|
||||
self.assertEqual(spread_lines[0].move_id.state, "posted")
|
||||
self.assertEqual(spread_lines[1].move_id.state, "posted")
|
||||
self.assertEqual(spread_lines[2].move_id.state, "posted")
|
||||
self.assertEqual(spread_lines[3].move_id.state, "posted")
|
||||
|
||||
spread_mls = spread_lines[0].move_id.line_ids
|
||||
self.assertTrue(spread_mls)
|
||||
@ -694,14 +731,14 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
balance_sheet = self.spread.debit_account_id
|
||||
self.assertTrue(balance_sheet.reconcile)
|
||||
|
||||
self.spread2.write({
|
||||
'invoice_line_id': self.invoice_line_2.id,
|
||||
})
|
||||
self.spread2.write(
|
||||
{"invoice_line_id": self.invoice_line_2.id,}
|
||||
)
|
||||
|
||||
# Validate invoice
|
||||
self.invoice_2.action_invoice_open()
|
||||
|
||||
invoice_mls = self.invoice_2.move_id.mapped('line_ids')
|
||||
invoice_mls = self.invoice_2.move_id.mapped("line_ids")
|
||||
self.assertTrue(invoice_mls)
|
||||
for invoice_ml in invoice_mls:
|
||||
if invoice_ml.credit:
|
||||
@ -719,8 +756,9 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
self.assertFalse(spread_ml.matched_credit_ids)
|
||||
self.assertFalse(spread_ml.full_reconcile_id)
|
||||
|
||||
other_journal = self.env['account.journal'].create({
|
||||
'name': 'Other Journal', 'type': 'general', 'code': 'test2'})
|
||||
other_journal = self.env["account.journal"].create(
|
||||
{"name": "Other Journal", "type": "general", "code": "test2"}
|
||||
)
|
||||
with self.assertRaises(ValidationError):
|
||||
self.spread2.journal_id = other_journal
|
||||
|
||||
@ -749,18 +787,19 @@ class TestAccountInvoiceSpread(common.TransactionCase):
|
||||
|
||||
# Validate invoice
|
||||
self.invoice.action_invoice_open()
|
||||
self.assertTrue(self.invoice.invoice_line_ids.mapped('spread_id'))
|
||||
self.assertTrue(self.invoice.invoice_line_ids.mapped("spread_id"))
|
||||
|
||||
# Create a refund for invoice.
|
||||
self.env['account.invoice.refund'].with_context({
|
||||
'active_model': 'account.invoice',
|
||||
'active_ids': [self.invoice.id],
|
||||
'active_id': self.invoice.id
|
||||
}).create(dict(
|
||||
description='Invoice Refund',
|
||||
filter_refund='refund',
|
||||
)).invoice_refund()
|
||||
self.env["account.invoice.refund"].with_context(
|
||||
{
|
||||
"active_model": "account.invoice",
|
||||
"active_ids": [self.invoice.id],
|
||||
"active_id": self.invoice.id,
|
||||
}
|
||||
).create(
|
||||
dict(description="Invoice Refund", filter_refund="refund",)
|
||||
).invoice_refund()
|
||||
|
||||
# Invoice lines do not contain the lint to the spread.
|
||||
refund = self.invoice.refund_invoice_ids[0]
|
||||
self.assertFalse(refund.invoice_line_ids.mapped('spread_id'))
|
||||
self.assertFalse(refund.invoice_line_ids.mapped("spread_id"))
|
||||
|
@ -5,68 +5,82 @@ import datetime
|
||||
|
||||
from psycopg2 import IntegrityError
|
||||
|
||||
from odoo.tools import convert_file, mute_logger
|
||||
from odoo.modules.module import get_resource_path
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.modules.module import get_resource_path
|
||||
from odoo.tests import common
|
||||
from odoo.tools import convert_file, mute_logger
|
||||
|
||||
|
||||
class TestAccountSpreadCostRevenue(common.TransactionCase):
|
||||
|
||||
def _load(self, module, *args):
|
||||
convert_file(
|
||||
self.cr,
|
||||
'account_spread_cost_revenue',
|
||||
"account_spread_cost_revenue",
|
||||
get_resource_path(module, *args),
|
||||
{}, 'init', False, 'test', self.registry._assertion_report)
|
||||
{},
|
||||
"init",
|
||||
False,
|
||||
"test",
|
||||
self.registry._assertion_report,
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self._load('account', 'test', 'account_minimal_test.xml')
|
||||
self._load("account", "test", "account_minimal_test.xml")
|
||||
|
||||
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')
|
||||
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.account_receivable = self.env['account.account'].create({
|
||||
'name': 'test_account_receivable',
|
||||
'code': '123',
|
||||
'user_type_id': type_receivable.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.account_receivable = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test_account_receivable",
|
||||
"code": "123",
|
||||
"user_type_id": type_receivable.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
self.credit_account = self.account_receivable
|
||||
|
||||
self.account_expenses = self.env['account.account'].create({
|
||||
'name': 'test account_expenses',
|
||||
'code': '765',
|
||||
'user_type_id': type_expenses.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.account_expenses = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test account_expenses",
|
||||
"code": "765",
|
||||
"user_type_id": type_expenses.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
self.debit_account = self.account_expenses
|
||||
|
||||
self.account_payable = self.env['account.account'].create({
|
||||
'name': 'test_account_payable',
|
||||
'code': '321',
|
||||
'user_type_id': type_payable.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.account_payable = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test_account_payable",
|
||||
"code": "321",
|
||||
"user_type_id": type_payable.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.account_revenue = self.env['account.account'].create({
|
||||
'name': 'test_account_revenue',
|
||||
'code': '864',
|
||||
'user_type_id': type_revenue.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.account_revenue = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test_account_revenue",
|
||||
"code": "864",
|
||||
"user_type_id": type_revenue.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
|
||||
def test_01_account_spread_defaults(self):
|
||||
this_year = datetime.date.today().year
|
||||
spread = self.env['account.spread'].create({
|
||||
'name': 'test',
|
||||
'invoice_type': 'out_invoice',
|
||||
'debit_account_id': self.debit_account.id,
|
||||
'credit_account_id': self.credit_account.id,
|
||||
})
|
||||
spread = self.env["account.spread"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"invoice_type": "out_invoice",
|
||||
"debit_account_id": self.debit_account.id,
|
||||
"credit_account_id": self.credit_account.id,
|
||||
}
|
||||
)
|
||||
my_company = self.env.user.company_id
|
||||
|
||||
self.assertTrue(spread)
|
||||
@ -77,21 +91,21 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
|
||||
self.assertFalse(spread.account_analytic_id)
|
||||
self.assertFalse(spread.analytic_tag_ids)
|
||||
self.assertTrue(spread.move_line_auto_post)
|
||||
self.assertEqual(spread.name, 'test')
|
||||
self.assertEqual(spread.invoice_type, 'out_invoice')
|
||||
self.assertEqual(spread.name, "test")
|
||||
self.assertEqual(spread.invoice_type, "out_invoice")
|
||||
self.assertEqual(spread.company_id, my_company)
|
||||
self.assertEqual(spread.currency_id, my_company.currency_id)
|
||||
self.assertEqual(spread.period_number, 12)
|
||||
self.assertEqual(spread.period_type, 'month')
|
||||
self.assertEqual(spread.period_type, "month")
|
||||
self.assertEqual(spread.debit_account_id, self.debit_account)
|
||||
self.assertEqual(spread.credit_account_id, self.credit_account)
|
||||
self.assertEqual(spread.unspread_amount, 0.)
|
||||
self.assertEqual(spread.unposted_amount, 0.)
|
||||
self.assertEqual(spread.total_amount, 0.)
|
||||
self.assertEqual(spread.estimated_amount, 0.)
|
||||
self.assertEqual(spread.unspread_amount, 0.0)
|
||||
self.assertEqual(spread.unposted_amount, 0.0)
|
||||
self.assertEqual(spread.total_amount, 0.0)
|
||||
self.assertEqual(spread.estimated_amount, 0.0)
|
||||
self.assertEqual(spread.spread_date, datetime.date(this_year, 1, 1))
|
||||
self.assertTrue(spread.journal_id)
|
||||
self.assertEqual(spread.journal_id.type, 'general')
|
||||
self.assertEqual(spread.journal_id.type, "general")
|
||||
|
||||
self.assertFalse(spread.display_create_all_moves)
|
||||
self.assertTrue(spread.display_recompute_buttons)
|
||||
@ -104,27 +118,26 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
|
||||
self.assertFalse(my_company.default_spread_revenue_journal_id)
|
||||
self.assertFalse(my_company.default_spread_expense_journal_id)
|
||||
|
||||
@mute_logger('odoo.sql_db')
|
||||
@mute_logger("odoo.sql_db")
|
||||
def test_03_no_defaults(self):
|
||||
with self.assertRaises(IntegrityError):
|
||||
self.env['account.spread'].create({
|
||||
'name': 'test',
|
||||
})
|
||||
self.env["account.spread"].create(
|
||||
{"name": "test",}
|
||||
)
|
||||
|
||||
@mute_logger('odoo.sql_db')
|
||||
@mute_logger("odoo.sql_db")
|
||||
def test_04_no_defaults(self):
|
||||
with self.assertRaises(IntegrityError):
|
||||
self.env['account.spread'].create({
|
||||
'name': 'test',
|
||||
'invoice_type': 'out_invoice',
|
||||
})
|
||||
self.env["account.spread"].create(
|
||||
{"name": "test", "invoice_type": "out_invoice",}
|
||||
)
|
||||
|
||||
def test_05_config_settings(self):
|
||||
my_company = self.env.user.company_id
|
||||
|
||||
account_revenue = self.account_revenue
|
||||
exp_journal = self.ref('account_spread_cost_revenue.expenses_journal')
|
||||
sales_journal = self.ref('account_spread_cost_revenue.sales_journal')
|
||||
exp_journal = self.ref("account_spread_cost_revenue.expenses_journal")
|
||||
sales_journal = self.ref("account_spread_cost_revenue.sales_journal")
|
||||
my_company.default_spread_revenue_account_id = account_revenue
|
||||
my_company.default_spread_expense_account_id = self.account_payable
|
||||
my_company.default_spread_revenue_journal_id = sales_journal
|
||||
@ -135,9 +148,7 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
|
||||
self.assertTrue(my_company.default_spread_revenue_journal_id)
|
||||
self.assertTrue(my_company.default_spread_expense_journal_id)
|
||||
|
||||
spread = self.env['account.spread'].new({
|
||||
'name': 'test',
|
||||
})
|
||||
spread = self.env["account.spread"].new({"name": "test",})
|
||||
|
||||
self.assertTrue(spread)
|
||||
self.assertFalse(spread.line_ids)
|
||||
@ -148,66 +159,71 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
|
||||
self.assertFalse(spread.analytic_tag_ids)
|
||||
self.assertFalse(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",]
|
||||
)
|
||||
|
||||
self.assertEqual(defaults['company_id'], my_company.id)
|
||||
self.assertEqual(defaults['currency_id'], my_company.currency_id.id)
|
||||
self.assertEqual(defaults["company_id"], my_company.id)
|
||||
self.assertEqual(defaults["currency_id"], my_company.currency_id.id)
|
||||
|
||||
spread.invoice_type = 'out_invoice'
|
||||
spread.invoice_type = "out_invoice"
|
||||
spread.company_id = my_company
|
||||
spread.onchange_invoice_type()
|
||||
self.assertEqual(spread.debit_account_id, account_revenue)
|
||||
self.assertFalse(spread.credit_account_id)
|
||||
self.assertEqual(spread.journal_id.id, sales_journal)
|
||||
self.assertEqual(spread.spread_type, 'sale')
|
||||
self.assertEqual(spread.spread_type, "sale")
|
||||
|
||||
spread.invoice_type = 'in_invoice'
|
||||
spread.invoice_type = "in_invoice"
|
||||
spread.onchange_invoice_type()
|
||||
self.assertEqual(spread.credit_account_id, self.account_payable)
|
||||
self.assertEqual(spread.journal_id.id, exp_journal)
|
||||
self.assertEqual(spread.spread_type, 'purchase')
|
||||
self.assertEqual(spread.spread_type, "purchase")
|
||||
|
||||
def test_06_invoice_line_compute_spread_check(self):
|
||||
invoice_account = self.account_receivable
|
||||
invoice_line_account = self.account_expenses
|
||||
invoice = self.env['account.invoice'].create({
|
||||
'partner_id': self.env.ref('base.res_partner_2').id,
|
||||
'account_id': invoice_account.id,
|
||||
'type': 'in_invoice',
|
||||
})
|
||||
invoice_line = self.env['account.invoice.line'].create({
|
||||
'product_id': self.env.ref('product.product_product_4').id,
|
||||
'quantity': 1.0,
|
||||
'price_unit': 100.0,
|
||||
'invoice_id': invoice.id,
|
||||
'name': 'product that cost 100',
|
||||
'account_id': invoice_line_account.id,
|
||||
})
|
||||
invoice = self.env["account.invoice"].create(
|
||||
{
|
||||
"partner_id": self.env.ref("base.res_partner_2").id,
|
||||
"account_id": invoice_account.id,
|
||||
"type": "in_invoice",
|
||||
}
|
||||
)
|
||||
invoice_line = self.env["account.invoice.line"].create(
|
||||
{
|
||||
"product_id": self.env.ref("product.product_product_4").id,
|
||||
"quantity": 1.0,
|
||||
"price_unit": 100.0,
|
||||
"invoice_id": invoice.id,
|
||||
"name": "product that cost 100",
|
||||
"account_id": invoice_line_account.id,
|
||||
}
|
||||
)
|
||||
invoice_line2 = invoice_line.copy()
|
||||
|
||||
self.assertFalse(invoice_line.spread_id)
|
||||
self.assertEqual(invoice_line.spread_check, 'unlinked')
|
||||
self.assertEqual(invoice_line.spread_check, "unlinked")
|
||||
|
||||
spread = self.env['account.spread'].create({
|
||||
'name': 'test',
|
||||
'invoice_type': 'in_invoice',
|
||||
'debit_account_id': self.debit_account.id,
|
||||
'credit_account_id': self.credit_account.id,
|
||||
})
|
||||
spread = self.env["account.spread"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"invoice_type": "in_invoice",
|
||||
"debit_account_id": self.debit_account.id,
|
||||
"credit_account_id": self.credit_account.id,
|
||||
}
|
||||
)
|
||||
invoice_line.spread_id = spread
|
||||
self.assertTrue(invoice_line.spread_id)
|
||||
self.assertEqual(invoice_line.spread_check, 'linked')
|
||||
self.assertEqual(invoice_line.spread_check, "linked")
|
||||
self.assertFalse(invoice_line2.spread_id)
|
||||
self.assertEqual(invoice_line2.spread_check, 'unlinked')
|
||||
self.assertEqual(invoice_line2.spread_check, "unlinked")
|
||||
|
||||
invoice.action_invoice_open()
|
||||
self.assertTrue(invoice_line.spread_id)
|
||||
self.assertEqual(invoice_line.spread_check, 'linked')
|
||||
self.assertEqual(invoice_line.spread_check, "linked")
|
||||
self.assertFalse(invoice_line2.spread_id)
|
||||
self.assertEqual(invoice_line2.spread_check, 'unavailable')
|
||||
self.assertEqual(invoice_line2.spread_check, "unavailable")
|
||||
|
||||
self.assertTrue(spread.display_create_all_moves)
|
||||
self.assertTrue(spread.display_recompute_buttons)
|
||||
@ -216,24 +232,26 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
|
||||
def test_07_create_spread_template(self):
|
||||
account_revenue = self.account_revenue
|
||||
account_payable = self.account_payable
|
||||
spread_template = self.env['account.spread.template'].create({
|
||||
'name': 'test',
|
||||
'spread_type': 'sale',
|
||||
'spread_account_id': account_revenue.id,
|
||||
})
|
||||
spread_template = self.env["account.spread.template"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"spread_type": "sale",
|
||||
"spread_account_id": account_revenue.id,
|
||||
}
|
||||
)
|
||||
|
||||
my_company = self.env.user.company_id
|
||||
self.assertEqual(spread_template.company_id, my_company)
|
||||
self.assertTrue(spread_template.spread_journal_id)
|
||||
|
||||
exp_journal = self.ref('account_spread_cost_revenue.expenses_journal')
|
||||
sales_journal = self.ref('account_spread_cost_revenue.sales_journal')
|
||||
exp_journal = self.ref("account_spread_cost_revenue.expenses_journal")
|
||||
sales_journal = self.ref("account_spread_cost_revenue.sales_journal")
|
||||
my_company.default_spread_revenue_account_id = account_revenue
|
||||
my_company.default_spread_expense_account_id = account_payable
|
||||
my_company.default_spread_revenue_journal_id = sales_journal
|
||||
my_company.default_spread_expense_journal_id = exp_journal
|
||||
|
||||
spread_template.spread_type = 'purchase'
|
||||
spread_template.spread_type = "purchase"
|
||||
spread_template.onchange_spread_type()
|
||||
self.assertTrue(spread_template.spread_journal_id)
|
||||
self.assertTrue(spread_template.spread_account_id)
|
||||
@ -241,14 +259,14 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
|
||||
self.assertEqual(spread_template.spread_journal_id.id, exp_journal)
|
||||
|
||||
spread_vals = spread_template._prepare_spread_from_template()
|
||||
self.assertTrue(spread_vals['name'])
|
||||
self.assertTrue(spread_vals['template_id'])
|
||||
self.assertTrue(spread_vals['journal_id'])
|
||||
self.assertTrue(spread_vals['company_id'])
|
||||
self.assertTrue(spread_vals['invoice_type'])
|
||||
self.assertTrue(spread_vals['credit_account_id'])
|
||||
self.assertTrue(spread_vals["name"])
|
||||
self.assertTrue(spread_vals["template_id"])
|
||||
self.assertTrue(spread_vals["journal_id"])
|
||||
self.assertTrue(spread_vals["company_id"])
|
||||
self.assertTrue(spread_vals["invoice_type"])
|
||||
self.assertTrue(spread_vals["credit_account_id"])
|
||||
|
||||
spread_template.spread_type = 'sale'
|
||||
spread_template.spread_type = "sale"
|
||||
spread_template.onchange_spread_type()
|
||||
self.assertTrue(spread_template.spread_journal_id)
|
||||
self.assertTrue(spread_template.spread_account_id)
|
||||
@ -256,68 +274,74 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
|
||||
self.assertEqual(spread_template.spread_journal_id.id, sales_journal)
|
||||
|
||||
spread_vals = spread_template._prepare_spread_from_template()
|
||||
self.assertTrue(spread_vals['name'])
|
||||
self.assertTrue(spread_vals['template_id'])
|
||||
self.assertTrue(spread_vals['journal_id'])
|
||||
self.assertTrue(spread_vals['company_id'])
|
||||
self.assertTrue(spread_vals['invoice_type'])
|
||||
self.assertTrue(spread_vals['debit_account_id'])
|
||||
self.assertTrue(spread_vals["name"])
|
||||
self.assertTrue(spread_vals["template_id"])
|
||||
self.assertTrue(spread_vals["journal_id"])
|
||||
self.assertTrue(spread_vals["company_id"])
|
||||
self.assertTrue(spread_vals["invoice_type"])
|
||||
self.assertTrue(spread_vals["debit_account_id"])
|
||||
|
||||
def test_08_check_template_invoice_type(self):
|
||||
account_revenue = self.account_revenue
|
||||
template_sale = self.env['account.spread.template'].create({
|
||||
'name': 'test',
|
||||
'spread_type': 'sale',
|
||||
'spread_account_id': account_revenue.id,
|
||||
})
|
||||
template_purchase = self.env['account.spread.template'].create({
|
||||
'name': 'test',
|
||||
'spread_type': 'purchase',
|
||||
'spread_account_id': self.account_payable.id,
|
||||
})
|
||||
spread = self.env['account.spread'].create({
|
||||
'name': 'test',
|
||||
'invoice_type': 'out_invoice',
|
||||
'debit_account_id': self.debit_account.id,
|
||||
'credit_account_id': self.credit_account.id,
|
||||
})
|
||||
template_sale = self.env["account.spread.template"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"spread_type": "sale",
|
||||
"spread_account_id": account_revenue.id,
|
||||
}
|
||||
)
|
||||
template_purchase = self.env["account.spread.template"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"spread_type": "purchase",
|
||||
"spread_account_id": self.account_payable.id,
|
||||
}
|
||||
)
|
||||
spread = self.env["account.spread"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"invoice_type": "out_invoice",
|
||||
"debit_account_id": self.debit_account.id,
|
||||
"credit_account_id": self.credit_account.id,
|
||||
}
|
||||
)
|
||||
spread.template_id = template_sale
|
||||
self.assertEqual(spread.template_id, template_sale)
|
||||
with self.assertRaises(ValidationError):
|
||||
spread.template_id = template_purchase
|
||||
self.assertEqual(spread.invoice_type, 'out_invoice')
|
||||
self.assertEqual(spread.invoice_type, "out_invoice")
|
||||
spread.onchange_template()
|
||||
self.assertEqual(spread.invoice_type, 'in_invoice')
|
||||
self.assertEqual(spread.invoice_type, "in_invoice")
|
||||
|
||||
spread.template_id = False
|
||||
spread.invoice_type = 'in_invoice'
|
||||
spread.invoice_type = "in_invoice"
|
||||
spread.template_id = template_purchase
|
||||
self.assertEqual(spread.template_id, template_purchase)
|
||||
with self.assertRaises(ValidationError):
|
||||
spread.template_id = template_sale
|
||||
self.assertEqual(spread.invoice_type, 'in_invoice')
|
||||
self.assertEqual(spread.invoice_type, "in_invoice")
|
||||
spread.onchange_template()
|
||||
self.assertEqual(spread.invoice_type, 'out_invoice')
|
||||
self.assertEqual(spread.invoice_type, "out_invoice")
|
||||
|
||||
spread.template_id = False
|
||||
spread.invoice_type = 'out_invoice'
|
||||
spread.invoice_type = "out_invoice"
|
||||
spread.template_id = template_sale
|
||||
self.assertEqual(spread.template_id, template_sale)
|
||||
with self.assertRaises(ValidationError):
|
||||
spread.invoice_type = 'in_invoice'
|
||||
self.assertEqual(spread.invoice_type, 'in_invoice')
|
||||
spread.invoice_type = "in_invoice"
|
||||
self.assertEqual(spread.invoice_type, "in_invoice")
|
||||
spread.onchange_template()
|
||||
self.assertEqual(spread.invoice_type, 'out_invoice')
|
||||
self.assertEqual(spread.invoice_type, "out_invoice")
|
||||
|
||||
spread.template_id = False
|
||||
spread.invoice_type = 'in_invoice'
|
||||
spread.invoice_type = "in_invoice"
|
||||
spread.template_id = template_purchase
|
||||
self.assertEqual(spread.template_id, template_purchase)
|
||||
with self.assertRaises(ValidationError):
|
||||
spread.invoice_type = 'out_invoice'
|
||||
self.assertEqual(spread.invoice_type, 'out_invoice')
|
||||
spread.invoice_type = "out_invoice"
|
||||
self.assertEqual(spread.invoice_type, "out_invoice")
|
||||
spread.onchange_template()
|
||||
self.assertEqual(spread.invoice_type, 'in_invoice')
|
||||
self.assertEqual(spread.invoice_type, "in_invoice")
|
||||
|
||||
self.assertFalse(spread.display_create_all_moves)
|
||||
self.assertTrue(spread.display_recompute_buttons)
|
||||
@ -326,80 +350,96 @@ class TestAccountSpreadCostRevenue(common.TransactionCase):
|
||||
def test_09_wrong_invoice_type(self):
|
||||
invoice_account = self.account_receivable
|
||||
invoice_line_account = self.account_expenses
|
||||
invoice = self.env['account.invoice'].create({
|
||||
'partner_id': self.env.ref('base.res_partner_2').id,
|
||||
'account_id': invoice_account.id,
|
||||
'type': 'in_invoice',
|
||||
})
|
||||
invoice_line = self.env['account.invoice.line'].create({
|
||||
'product_id': self.env.ref('product.product_product_4').id,
|
||||
'quantity': 1.0,
|
||||
'price_unit': 100.0,
|
||||
'invoice_id': invoice.id,
|
||||
'name': 'product that cost 100',
|
||||
'account_id': invoice_line_account.id,
|
||||
})
|
||||
spread = self.env['account.spread'].create({
|
||||
'name': 'test',
|
||||
'invoice_type': 'out_invoice',
|
||||
'debit_account_id': self.debit_account.id,
|
||||
'credit_account_id': self.credit_account.id,
|
||||
})
|
||||
invoice = self.env["account.invoice"].create(
|
||||
{
|
||||
"partner_id": self.env.ref("base.res_partner_2").id,
|
||||
"account_id": invoice_account.id,
|
||||
"type": "in_invoice",
|
||||
}
|
||||
)
|
||||
invoice_line = self.env["account.invoice.line"].create(
|
||||
{
|
||||
"product_id": self.env.ref("product.product_product_4").id,
|
||||
"quantity": 1.0,
|
||||
"price_unit": 100.0,
|
||||
"invoice_id": invoice.id,
|
||||
"name": "product that cost 100",
|
||||
"account_id": invoice_line_account.id,
|
||||
}
|
||||
)
|
||||
spread = self.env["account.spread"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"invoice_type": "out_invoice",
|
||||
"debit_account_id": self.debit_account.id,
|
||||
"credit_account_id": self.credit_account.id,
|
||||
}
|
||||
)
|
||||
with self.assertRaises(ValidationError):
|
||||
invoice_line.spread_id = spread
|
||||
|
||||
def test_10_account_spread_unlink(self):
|
||||
spread = self.env['account.spread'].create({
|
||||
'name': 'test',
|
||||
'invoice_type': 'out_invoice',
|
||||
'debit_account_id': self.debit_account.id,
|
||||
'credit_account_id': self.credit_account.id,
|
||||
})
|
||||
spread = self.env["account.spread"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"invoice_type": "out_invoice",
|
||||
"debit_account_id": self.debit_account.id,
|
||||
"credit_account_id": self.credit_account.id,
|
||||
}
|
||||
)
|
||||
spread.unlink()
|
||||
|
||||
def test_11_compute_display_fields(self):
|
||||
spread = self.env['account.spread'].create({
|
||||
'name': 'test',
|
||||
'invoice_type': 'out_invoice',
|
||||
'debit_account_id': self.debit_account.id,
|
||||
'credit_account_id': self.credit_account.id,
|
||||
})
|
||||
spread = self.env["account.spread"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"invoice_type": "out_invoice",
|
||||
"debit_account_id": self.debit_account.id,
|
||||
"credit_account_id": self.credit_account.id,
|
||||
}
|
||||
)
|
||||
spread.company_id.allow_spread_planning = True
|
||||
self.assertFalse(spread.display_create_all_moves)
|
||||
self.assertTrue(spread.display_recompute_buttons)
|
||||
self.assertTrue(spread.display_move_line_auto_post)
|
||||
|
||||
def test_12_compute_display_fields(self):
|
||||
spread = self.env['account.spread'].create({
|
||||
'name': 'test',
|
||||
'invoice_type': 'out_invoice',
|
||||
'debit_account_id': self.debit_account.id,
|
||||
'credit_account_id': self.credit_account.id,
|
||||
})
|
||||
spread = self.env["account.spread"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"invoice_type": "out_invoice",
|
||||
"debit_account_id": self.debit_account.id,
|
||||
"credit_account_id": self.credit_account.id,
|
||||
}
|
||||
)
|
||||
spread.company_id.allow_spread_planning = False
|
||||
self.assertFalse(spread.display_create_all_moves)
|
||||
self.assertTrue(spread.display_recompute_buttons)
|
||||
self.assertTrue(spread.display_move_line_auto_post)
|
||||
|
||||
def test_13_compute_display_fields(self):
|
||||
spread = self.env['account.spread'].create({
|
||||
'name': 'test',
|
||||
'invoice_type': 'out_invoice',
|
||||
'debit_account_id': self.debit_account.id,
|
||||
'credit_account_id': self.credit_account.id,
|
||||
})
|
||||
spread = self.env["account.spread"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"invoice_type": "out_invoice",
|
||||
"debit_account_id": self.debit_account.id,
|
||||
"credit_account_id": self.credit_account.id,
|
||||
}
|
||||
)
|
||||
spread.company_id.force_move_auto_post = True
|
||||
self.assertFalse(spread.display_create_all_moves)
|
||||
self.assertTrue(spread.display_recompute_buttons)
|
||||
self.assertFalse(spread.display_move_line_auto_post)
|
||||
|
||||
def test_14_compute_display_fields(self):
|
||||
spread = self.env['account.spread'].create({
|
||||
'name': 'test',
|
||||
'invoice_type': 'out_invoice',
|
||||
'debit_account_id': self.debit_account.id,
|
||||
'credit_account_id': self.credit_account.id,
|
||||
})
|
||||
spread = self.env["account.spread"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"invoice_type": "out_invoice",
|
||||
"debit_account_id": self.debit_account.id,
|
||||
"credit_account_id": self.credit_account.id,
|
||||
}
|
||||
)
|
||||
spread.company_id.force_move_auto_post = False
|
||||
self.assertFalse(spread.display_create_all_moves)
|
||||
self.assertTrue(spread.display_recompute_buttons)
|
||||
|
@ -3,64 +3,74 @@
|
||||
|
||||
import datetime
|
||||
|
||||
from odoo.tests import common
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tests import common
|
||||
|
||||
|
||||
class TestComputeSpreadBoard(common.TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
type_receivable = self.env.ref('account.data_account_type_receivable')
|
||||
type_expenses = self.env.ref('account.data_account_type_expenses')
|
||||
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({
|
||||
'name': 'Test', 'type': 'general', 'code': 'test'})
|
||||
journal = self.env["account.journal"].create(
|
||||
{"name": "Test", "type": "general", "code": "test"}
|
||||
)
|
||||
|
||||
self.receivable_account = self.env['account.account'].create({
|
||||
'name': 'test_account_receivable',
|
||||
'code': '123',
|
||||
'user_type_id': type_receivable.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.receivable_account = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test_account_receivable",
|
||||
"code": "123",
|
||||
"user_type_id": type_receivable.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.expense_account = self.env['account.account'].create({
|
||||
'name': 'test account_expenses',
|
||||
'code': '765',
|
||||
'user_type_id': type_expenses.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.expense_account = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test account_expenses",
|
||||
"code": "765",
|
||||
"user_type_id": type_expenses.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.spread_account = self.env['account.account'].create({
|
||||
'name': 'test spread account_expenses',
|
||||
'code': '321',
|
||||
'user_type_id': type_expenses.id,
|
||||
'reconcile': True
|
||||
})
|
||||
self.spread_account = self.env["account.account"].create(
|
||||
{
|
||||
"name": "test spread account_expenses",
|
||||
"code": "321",
|
||||
"user_type_id": type_expenses.id,
|
||||
"reconcile": True,
|
||||
}
|
||||
)
|
||||
|
||||
self.spread = self.env['account.spread'].create({
|
||||
'name': 'test',
|
||||
'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': 1000.0,
|
||||
'journal_id': journal.id,
|
||||
'invoice_type': 'in_invoice',
|
||||
})
|
||||
self.spread = self.env["account.spread"].create(
|
||||
{
|
||||
"name": "test",
|
||||
"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": 1000.0,
|
||||
"journal_id": journal.id,
|
||||
"invoice_type": "in_invoice",
|
||||
}
|
||||
)
|
||||
|
||||
self.spread2 = self.env['account.spread'].create({
|
||||
'name': 'test2',
|
||||
'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': 1000.0,
|
||||
'journal_id': journal.id,
|
||||
'invoice_type': 'out_invoice',
|
||||
})
|
||||
self.spread2 = self.env["account.spread"].create(
|
||||
{
|
||||
"name": "test2",
|
||||
"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": 1000.0,
|
||||
"journal_id": journal.id,
|
||||
"invoice_type": "out_invoice",
|
||||
}
|
||||
)
|
||||
|
||||
def test_01_supplier_invoice(self):
|
||||
self.spread.compute_spread_board()
|
||||
@ -111,11 +121,13 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
|
||||
def test_02_supplier_invoice(self):
|
||||
# spread date set
|
||||
self.spread.write({
|
||||
'period_number': 12,
|
||||
'period_type': 'month',
|
||||
'spread_date': datetime.date(2017, 1, 7)
|
||||
})
|
||||
self.spread.write(
|
||||
{
|
||||
"period_number": 12,
|
||||
"period_type": "month",
|
||||
"spread_date": datetime.date(2017, 1, 7),
|
||||
}
|
||||
)
|
||||
self.spread_account.reconcile = True
|
||||
self.assertTrue(self.spread_account.reconcile)
|
||||
|
||||
@ -163,12 +175,14 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
|
||||
def test_03_supplier_invoice(self):
|
||||
# spread date set
|
||||
self.spread.write({
|
||||
'period_number': 12,
|
||||
'period_type': 'month',
|
||||
'spread_date': datetime.date(2017, 1, 31),
|
||||
'move_line_auto_post': False
|
||||
})
|
||||
self.spread.write(
|
||||
{
|
||||
"period_number": 12,
|
||||
"period_type": "month",
|
||||
"spread_date": datetime.date(2017, 1, 31),
|
||||
"move_line_auto_post": False,
|
||||
}
|
||||
)
|
||||
|
||||
self.spread.compute_spread_board()
|
||||
spread_lines = self.spread.line_ids
|
||||
@ -249,13 +263,15 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
self.assertEqual(datetime.date(2018, 1, 31), spread_lines[12].date)
|
||||
|
||||
def test_04_supplier_invoice(self):
|
||||
self.spread.write({
|
||||
'credit_account_id': self.expense_account.id,
|
||||
'debit_account_id': self.spread_account.id,
|
||||
'period_number': 3,
|
||||
'period_type': 'year',
|
||||
'spread_date': datetime.date(2018, 10, 24)
|
||||
})
|
||||
self.spread.write(
|
||||
{
|
||||
"credit_account_id": self.expense_account.id,
|
||||
"debit_account_id": self.spread_account.id,
|
||||
"period_number": 3,
|
||||
"period_type": "year",
|
||||
"spread_date": datetime.date(2018, 10, 24),
|
||||
}
|
||||
)
|
||||
|
||||
# change the state of invoice to open by clicking Validate button
|
||||
self.spread.compute_spread_board()
|
||||
@ -280,11 +296,13 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
|
||||
def test_05_supplier_invoice(self):
|
||||
# spread date set
|
||||
self.spread.write({
|
||||
'period_number': 12,
|
||||
'period_type': 'month',
|
||||
'spread_date': datetime.date(2017, 2, 1)
|
||||
})
|
||||
self.spread.write(
|
||||
{
|
||||
"period_number": 12,
|
||||
"period_type": "month",
|
||||
"spread_date": datetime.date(2017, 2, 1),
|
||||
}
|
||||
)
|
||||
|
||||
self.spread.compute_spread_board()
|
||||
|
||||
@ -295,7 +313,7 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
self.assertTrue(isinstance(attrs, dict))
|
||||
|
||||
# post and then unlink all created moves
|
||||
self.spread.journal_id.write({'update_posted': True})
|
||||
self.spread.journal_id.write({"update_posted": True})
|
||||
for line in self.spread.line_ids:
|
||||
line.move_id.post()
|
||||
self.spread.line_ids.unlink_move()
|
||||
@ -307,11 +325,9 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
|
||||
def test_06_supplier_invoice(self):
|
||||
# spread date set
|
||||
self.spread.write({
|
||||
'period_number': 3,
|
||||
'period_type': 'quarter',
|
||||
'move_line_auto_post': False
|
||||
})
|
||||
self.spread.write(
|
||||
{"period_number": 3, "period_type": "quarter", "move_line_auto_post": False}
|
||||
)
|
||||
|
||||
self.spread.compute_spread_board()
|
||||
|
||||
@ -328,35 +344,37 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
|
||||
for line in self.spread.line_ids:
|
||||
self.assertTrue(line.move_id)
|
||||
self.assertFalse(line.move_id.state == 'posted')
|
||||
self.assertFalse(line.move_id.state == "posted")
|
||||
|
||||
self.assertEqual(self.spread.unspread_amount, 0.)
|
||||
self.assertEqual(self.spread.unposted_amount, 1000.)
|
||||
self.assertEqual(self.spread.unspread_amount, 0.0)
|
||||
self.assertEqual(self.spread.unposted_amount, 1000.0)
|
||||
|
||||
# try to create move lines again: an error is raised
|
||||
for line in self.spread.line_ids:
|
||||
with self.assertRaises(UserError):
|
||||
line.create_move()
|
||||
|
||||
self.spread.write({
|
||||
'move_line_auto_post': True,
|
||||
})
|
||||
self.spread.write(
|
||||
{"move_line_auto_post": True,}
|
||||
)
|
||||
self.spread.action_recalculate_spread()
|
||||
|
||||
for line in self.spread.line_ids:
|
||||
self.assertTrue(line.move_id)
|
||||
self.assertTrue(line.move_id.state == 'posted')
|
||||
self.assertTrue(line.move_id.state == "posted")
|
||||
|
||||
self.assertEqual(self.spread.unspread_amount, 0.)
|
||||
self.assertEqual(self.spread.unposted_amount, 0.)
|
||||
self.assertEqual(self.spread.unspread_amount, 0.0)
|
||||
self.assertEqual(self.spread.unposted_amount, 0.0)
|
||||
|
||||
def test_07_supplier_invoice(self):
|
||||
self.spread.write({
|
||||
'period_number': 3,
|
||||
'period_type': 'month',
|
||||
'spread_date': datetime.date(2017, 1, 1),
|
||||
'estimated_amount': 345.96,
|
||||
})
|
||||
self.spread.write(
|
||||
{
|
||||
"period_number": 3,
|
||||
"period_type": "month",
|
||||
"spread_date": datetime.date(2017, 1, 1),
|
||||
"estimated_amount": 345.96,
|
||||
}
|
||||
)
|
||||
|
||||
self.spread.compute_spread_board()
|
||||
spread_lines = self.spread.line_ids
|
||||
@ -376,11 +394,13 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
|
||||
def test_08_supplier_invoice(self):
|
||||
# spread date set
|
||||
self.spread.write({
|
||||
'period_number': 12,
|
||||
'period_type': 'month',
|
||||
'spread_date': datetime.date(2017, 2, 1)
|
||||
})
|
||||
self.spread.write(
|
||||
{
|
||||
"period_number": 12,
|
||||
"period_type": "month",
|
||||
"spread_date": datetime.date(2017, 2, 1),
|
||||
}
|
||||
)
|
||||
|
||||
self.spread.compute_spread_board()
|
||||
self.assertTrue(self.spread.line_ids)
|
||||
@ -392,11 +412,13 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
|
||||
def test_09_supplier_invoice(self):
|
||||
# spread date set
|
||||
self.spread.write({
|
||||
'period_number': 12,
|
||||
'period_type': 'month',
|
||||
'spread_date': datetime.date(2017, 2, 1)
|
||||
})
|
||||
self.spread.write(
|
||||
{
|
||||
"period_number": 12,
|
||||
"period_type": "month",
|
||||
"spread_date": datetime.date(2017, 2, 1),
|
||||
}
|
||||
)
|
||||
|
||||
self.spread.compute_spread_board()
|
||||
for line in self.spread.line_ids:
|
||||
@ -415,11 +437,11 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
self.assertEqual(self.spread.unposted_amount, 1000.0)
|
||||
|
||||
def test_10_create_entries(self):
|
||||
self.env['account.spread.line']._create_entries()
|
||||
self.env["account.spread.line"]._create_entries()
|
||||
self.assertFalse(self.spread.line_ids)
|
||||
|
||||
self.spread.compute_spread_board()
|
||||
self.env['account.spread.line']._create_entries()
|
||||
self.env["account.spread.line"]._create_entries()
|
||||
self.assertTrue(self.spread.line_ids)
|
||||
for line in self.spread.line_ids:
|
||||
self.assertTrue(line.move_id)
|
||||
@ -431,7 +453,7 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
self.assertFalse(line.move_id)
|
||||
line.create_move()
|
||||
self.assertTrue(line.move_id)
|
||||
self.assertFalse(line.move_id.state == 'posted')
|
||||
self.assertFalse(line.move_id.state == "posted")
|
||||
|
||||
self.spread2.action_undo_spread()
|
||||
for line in self.spread2.line_ids:
|
||||
@ -441,18 +463,16 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
for line in self.spread2.line_ids:
|
||||
self.assertTrue(line.move_id)
|
||||
self.assertTrue(line.move_id)
|
||||
self.assertFalse(line.move_id.state == 'posted')
|
||||
self.assertFalse(line.move_id.state == "posted")
|
||||
# try to create move lines again: an error is raised
|
||||
with self.assertRaises(UserError):
|
||||
line.create_move()
|
||||
|
||||
def test_12_supplier_invoice_auto_post(self):
|
||||
# spread date set
|
||||
self.spread.write({
|
||||
'period_number': 8,
|
||||
'period_type': 'month',
|
||||
'move_line_auto_post': True,
|
||||
})
|
||||
self.spread.write(
|
||||
{"period_number": 8, "period_type": "month", "move_line_auto_post": True,}
|
||||
)
|
||||
|
||||
self.spread.compute_spread_board()
|
||||
|
||||
@ -470,16 +490,15 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
self.assertTrue(self.spread.move_line_auto_post)
|
||||
for line in self.spread.line_ids:
|
||||
self.assertTrue(line.move_id)
|
||||
self.assertTrue(line.move_id.state == 'posted')
|
||||
self.assertTrue(line.move_id.state == "posted")
|
||||
|
||||
self.assertEqual(self.spread.unspread_amount, 0.)
|
||||
self.assertEqual(self.spread.unposted_amount, 0.)
|
||||
self.assertEqual(self.spread.unspread_amount, 0.0)
|
||||
self.assertEqual(self.spread.unposted_amount, 0.0)
|
||||
|
||||
def test_13_create_move_in_invoice_auto_post(self):
|
||||
self.spread2.write({
|
||||
'period_number': 4,
|
||||
'move_line_auto_post': True,
|
||||
})
|
||||
self.spread2.write(
|
||||
{"period_number": 4, "move_line_auto_post": True,}
|
||||
)
|
||||
self.spread_account.reconcile = True
|
||||
self.assertTrue(self.spread_account.reconcile)
|
||||
|
||||
@ -488,19 +507,21 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
self.assertFalse(line.move_id)
|
||||
line.create_move()
|
||||
self.assertTrue(line.move_id)
|
||||
self.assertTrue(line.move_id.state == 'posted')
|
||||
self.assertTrue(line.move_id.state == "posted")
|
||||
|
||||
self.assertEqual(self.spread.unspread_amount, 1000.0)
|
||||
self.assertEqual(self.spread.unposted_amount, 1000.0)
|
||||
|
||||
def test_14_negative_amount(self):
|
||||
# spread date set
|
||||
self.spread.write({
|
||||
'estimated_amount': -1000.0,
|
||||
'period_number': 12,
|
||||
'period_type': 'month',
|
||||
'spread_date': datetime.date(2017, 1, 7)
|
||||
})
|
||||
self.spread.write(
|
||||
{
|
||||
"estimated_amount": -1000.0,
|
||||
"period_number": 12,
|
||||
"period_type": "month",
|
||||
"spread_date": datetime.date(2017, 1, 7),
|
||||
}
|
||||
)
|
||||
self.spread.compute_spread_board()
|
||||
|
||||
spread_lines = self.spread.line_ids
|
||||
@ -541,11 +562,13 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
|
||||
def test_18_supplier_invoice(self):
|
||||
# spread date set
|
||||
self.spread.write({
|
||||
'period_number': 12,
|
||||
'period_type': 'month',
|
||||
'spread_date': datetime.date(2017, 1, 7)
|
||||
})
|
||||
self.spread.write(
|
||||
{
|
||||
"period_number": 12,
|
||||
"period_type": "month",
|
||||
"spread_date": datetime.date(2017, 1, 7),
|
||||
}
|
||||
)
|
||||
self.spread_account.reconcile = True
|
||||
self.assertTrue(self.spread_account.reconcile)
|
||||
|
||||
@ -561,10 +584,10 @@ class TestComputeSpreadBoard(common.TransactionCase):
|
||||
spread_lines[2]._create_moves().post()
|
||||
spread_lines[3]._create_moves().post()
|
||||
|
||||
self.assertEqual(spread_lines[0].move_id.state, 'posted')
|
||||
self.assertEqual(spread_lines[1].move_id.state, 'posted')
|
||||
self.assertEqual(spread_lines[2].move_id.state, 'posted')
|
||||
self.assertEqual(spread_lines[3].move_id.state, 'posted')
|
||||
self.assertEqual(spread_lines[0].move_id.state, "posted")
|
||||
self.assertEqual(spread_lines[1].move_id.state, "posted")
|
||||
self.assertEqual(spread_lines[2].move_id.state, "posted")
|
||||
self.assertEqual(spread_lines[3].move_id.state, "posted")
|
||||
|
||||
self.assertAlmostEqual(self.spread.unspread_amount, 682.81)
|
||||
self.assertAlmostEqual(self.spread.unposted_amount, 682.81)
|
||||
|
@ -1,24 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_supplier_invoice_spread" model="ir.ui.view">
|
||||
<field name="model">account.invoice</field>
|
||||
<field name="inherit_id" ref="account.invoice_supplier_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='quantity']" position="before">
|
||||
<field name="spread_check" widget="spread_line_widget" groups="account.group_account_user,account.group_account_manager"/>
|
||||
<xpath
|
||||
expr="//field[@name='invoice_line_ids']/tree/field[@name='quantity']"
|
||||
position="before"
|
||||
>
|
||||
<field
|
||||
name="spread_check"
|
||||
widget="spread_line_widget"
|
||||
groups="account.group_account_user,account.group_account_manager"
|
||||
/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_customer_invoice_spread" model="ir.ui.view">
|
||||
<field name="model">account.invoice</field>
|
||||
<field name="inherit_id" ref="account.invoice_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='invoice_line_ids']/tree/field[@name='quantity']" position="before">
|
||||
<field name="spread_check" widget="spread_line_widget" groups="account.group_account_user,account.group_account_manager"/>
|
||||
<xpath
|
||||
expr="//field[@name='invoice_line_ids']/tree/field[@name='quantity']"
|
||||
position="before"
|
||||
>
|
||||
<field
|
||||
name="spread_check"
|
||||
widget="spread_line_widget"
|
||||
groups="account.group_account_user,account.group_account_manager"
|
||||
/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
@ -1,39 +1,79 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_account_spread" model="ir.ui.view">
|
||||
<field name="model">account.spread</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<header>
|
||||
<button name="compute_spread_board" type="object" string="Recalculate unposted lines" class="oe_highlight" attrs="{'invisible': ['|',('debit_account_id', '=', False),('display_recompute_buttons', '=', False)]}" />
|
||||
<button name="action_recalculate_spread" type="object" string="Recalculate entire spread" attrs="{'invisible': ['|',('debit_account_id', '=', False),('display_recompute_buttons', '=', False)]}" groups="account.group_account_manager" />
|
||||
<button name="action_undo_spread" type="object" string="Undo spread" attrs="{'invisible': [('line_ids', '=', [])]}" groups="account.group_account_manager" />
|
||||
<button name="action_unlink_invoice_line" type="object" string="Unlink Invoice Line" attrs="{'invisible': [('invoice_line_id', '=', False)]}" groups="account.group_account_manager" />
|
||||
<button
|
||||
name="compute_spread_board"
|
||||
type="object"
|
||||
string="Recalculate unposted lines"
|
||||
class="oe_highlight"
|
||||
attrs="{'invisible': ['|',('debit_account_id', '=', False),('display_recompute_buttons', '=', False)]}"
|
||||
/>
|
||||
<button
|
||||
name="action_recalculate_spread"
|
||||
type="object"
|
||||
string="Recalculate entire spread"
|
||||
attrs="{'invisible': ['|',('debit_account_id', '=', False),('display_recompute_buttons', '=', False)]}"
|
||||
groups="account.group_account_manager"
|
||||
/>
|
||||
<button
|
||||
name="action_undo_spread"
|
||||
type="object"
|
||||
string="Undo spread"
|
||||
attrs="{'invisible': [('line_ids', '=', [])]}"
|
||||
groups="account.group_account_manager"
|
||||
/>
|
||||
<button
|
||||
name="action_unlink_invoice_line"
|
||||
type="object"
|
||||
string="Unlink Invoice Line"
|
||||
attrs="{'invisible': [('invoice_line_id', '=', False)]}"
|
||||
groups="account.group_account_manager"
|
||||
/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box">
|
||||
<button name="open_reconcile_view"
|
||||
<button
|
||||
name="open_reconcile_view"
|
||||
class="oe_stat_button"
|
||||
icon="fa-bars"
|
||||
type="object"
|
||||
string="Reconciled entries">
|
||||
string="Reconciled entries"
|
||||
>
|
||||
</button>
|
||||
<button name="toggle_active" type="object"
|
||||
<button
|
||||
name="toggle_active"
|
||||
type="object"
|
||||
attrs="{'invisible': [('all_posted','=',False)]}"
|
||||
class="oe_stat_button" icon="fa-archive">
|
||||
<field name="active" widget="boolean_button"
|
||||
options='{"terminology": "archive"}'/>
|
||||
class="oe_stat_button"
|
||||
icon="fa-archive"
|
||||
>
|
||||
<field
|
||||
name="active"
|
||||
widget="boolean_button"
|
||||
options='{"terminology": "archive"}'
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="name" string="Spread Board Name" />
|
||||
<h1><field name="name" placeholder="e.g. One year offices cleaning contract"/></h1>
|
||||
<h1>
|
||||
<field
|
||||
name="name"
|
||||
placeholder="e.g. One year offices cleaning contract"
|
||||
/>
|
||||
</h1>
|
||||
</div>
|
||||
<group name="header_info">
|
||||
<group name="spread_definitions">
|
||||
<field name="template_id" />
|
||||
<field name="invoice_type" attrs="{'readonly':[('invoice_line_id','!=',False)]}"/>
|
||||
<field
|
||||
name="invoice_type"
|
||||
attrs="{'readonly':[('invoice_line_id','!=',False)]}"
|
||||
/>
|
||||
<field name="display_recompute_buttons" invisible="1" />
|
||||
<field name="display_move_line_auto_post" invisible="1" />
|
||||
<field name="all_posted" invisible="1" />
|
||||
@ -43,82 +83,178 @@
|
||||
<group name="accounts">
|
||||
<group name="debits">
|
||||
<field name="is_debit_account_deprecated" invisible="1" />
|
||||
<label for="debit_account_id" colspan="3" string="Balance sheet account / Spread account"
|
||||
attrs="{'invisible':[('invoice_type','not in',('out_invoice','in_refund'))]}"/>
|
||||
<label for="debit_account_id" colspan="3" string="Expense account"
|
||||
attrs="{'invisible':[('invoice_type','not in',('in_invoice','out_refund'))]}"/>
|
||||
<div attrs="{'invisible': [('use_invoice_line_account', '=', True)]}" colspan="2">
|
||||
<span class="help-block" colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('out_invoice','in_refund'))]}">
|
||||
The Balance Sheet account used for the spreading.<br/>This account is the counterpart of the account in the invoice line.
|
||||
<label
|
||||
for="debit_account_id"
|
||||
colspan="3"
|
||||
string="Balance sheet account / Spread account"
|
||||
attrs="{'invisible':[('invoice_type','not in',('out_invoice','in_refund'))]}"
|
||||
/>
|
||||
<label
|
||||
for="debit_account_id"
|
||||
colspan="3"
|
||||
string="Expense account"
|
||||
attrs="{'invisible':[('invoice_type','not in',('in_invoice','out_refund'))]}"
|
||||
/>
|
||||
<div
|
||||
attrs="{'invisible': [('use_invoice_line_account', '=', True)]}"
|
||||
colspan="2"
|
||||
>
|
||||
<span
|
||||
class="help-block"
|
||||
colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('out_invoice','in_refund'))]}"
|
||||
>
|
||||
The Balance Sheet account used for the spreading.<br
|
||||
/>This account is the counterpart of the account in the invoice line.
|
||||
</span>
|
||||
<span class="help-block" colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('in_invoice','out_refund'))]}">
|
||||
The Expense account in the vendor bill line.<br/>Usually the same account of the vendor bill line.
|
||||
<span
|
||||
class="help-block"
|
||||
colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('in_invoice','out_refund'))]}"
|
||||
>
|
||||
The Expense account in the vendor bill line.<br
|
||||
/>Usually the same account of the vendor bill line.
|
||||
</span>
|
||||
</div>
|
||||
<div attrs="{'invisible': [('use_invoice_line_account', '!=', True)]}" colspan="2">
|
||||
<span class="help-block" colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('out_invoice','in_refund'))]}">
|
||||
The Balance Sheet account.<br/>This is the account in the invoice line.
|
||||
<div
|
||||
attrs="{'invisible': [('use_invoice_line_account', '!=', True)]}"
|
||||
colspan="2"
|
||||
>
|
||||
<span
|
||||
class="help-block"
|
||||
colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('out_invoice','in_refund'))]}"
|
||||
>
|
||||
The Balance Sheet account.<br
|
||||
/>This is the account in the invoice line.
|
||||
</span>
|
||||
<span class="help-block" colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('in_invoice','out_refund'))]}">
|
||||
The Expense account used for the spreading.<br/>This account is the counterpart of the account of the vendor bill line.
|
||||
<span
|
||||
class="help-block"
|
||||
colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('in_invoice','out_refund'))]}"
|
||||
>
|
||||
The Expense account used for the spreading.<br
|
||||
/>This account is the counterpart of the account of the vendor bill line.
|
||||
</span>
|
||||
</div>
|
||||
<field name="debit_account_id" required="1" domain="[('company_id', '=', company_id), ('deprecated', '=', False)]" attrs="{'readonly':[('invoice_line_id','!=',False)]}"/>
|
||||
<span class="help-block text-danger" colspan="2"
|
||||
attrs="{'invisible':[('is_debit_account_deprecated','!=',True)]}">
|
||||
<field
|
||||
name="debit_account_id"
|
||||
required="1"
|
||||
domain="[('company_id', '=', company_id), ('deprecated', '=', False)]"
|
||||
attrs="{'readonly':[('invoice_line_id','!=',False)]}"
|
||||
/>
|
||||
<span
|
||||
class="help-block text-danger"
|
||||
colspan="2"
|
||||
attrs="{'invisible':[('is_debit_account_deprecated','!=',True)]}"
|
||||
>
|
||||
This account in deprecated! The reconciliation will be NOT possible.
|
||||
</span>
|
||||
</group>
|
||||
<group name="credits">
|
||||
<field name="is_credit_account_deprecated" invisible="1" />
|
||||
<label for="credit_account_id" colspan="3" string="Revenue account"
|
||||
attrs="{'invisible':[('invoice_type','not in',('out_invoice','in_refund'))]}"/>
|
||||
<label for="credit_account_id" colspan="3" string="Balance sheet account / Spread account"
|
||||
attrs="{'invisible':[('invoice_type','not in',('in_invoice','out_refund'))]}"/>
|
||||
<div attrs="{'invisible': [('use_invoice_line_account', '=', True)]}" colspan="2">
|
||||
<span class="help-block" colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('out_invoice','in_refund'))]}">
|
||||
The Revenue account in the invoice line.<br/>Usually the same account of the invoice line.
|
||||
<label
|
||||
for="credit_account_id"
|
||||
colspan="3"
|
||||
string="Revenue account"
|
||||
attrs="{'invisible':[('invoice_type','not in',('out_invoice','in_refund'))]}"
|
||||
/>
|
||||
<label
|
||||
for="credit_account_id"
|
||||
colspan="3"
|
||||
string="Balance sheet account / Spread account"
|
||||
attrs="{'invisible':[('invoice_type','not in',('in_invoice','out_refund'))]}"
|
||||
/>
|
||||
<div
|
||||
attrs="{'invisible': [('use_invoice_line_account', '=', True)]}"
|
||||
colspan="2"
|
||||
>
|
||||
<span
|
||||
class="help-block"
|
||||
colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('out_invoice','in_refund'))]}"
|
||||
>
|
||||
The Revenue account in the invoice line.<br
|
||||
/>Usually the same account of the invoice line.
|
||||
</span>
|
||||
<span class="help-block" colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('in_invoice','out_refund'))]}">
|
||||
The Balance Sheet account used for the spreading.<br/>This account is the counterpart of the account in the vendor bill line.
|
||||
<span
|
||||
class="help-block"
|
||||
colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('in_invoice','out_refund'))]}"
|
||||
>
|
||||
The Balance Sheet account used for the spreading.<br
|
||||
/>This account is the counterpart of the account in the vendor bill line.
|
||||
</span>
|
||||
</div>
|
||||
<div attrs="{'invisible': [('use_invoice_line_account', '!=', True)]}" colspan="2">
|
||||
<span class="help-block" colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('out_invoice','in_refund'))]}">
|
||||
The Revenue account used for the spreading.<br/>This account is the counterpart of the account of the invoice line.
|
||||
<div
|
||||
attrs="{'invisible': [('use_invoice_line_account', '!=', True)]}"
|
||||
colspan="2"
|
||||
>
|
||||
<span
|
||||
class="help-block"
|
||||
colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('out_invoice','in_refund'))]}"
|
||||
>
|
||||
The Revenue account used for the spreading.<br
|
||||
/>This account is the counterpart of the account of the invoice line.
|
||||
</span>
|
||||
<span class="help-block" colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('in_invoice','out_refund'))]}">
|
||||
The Balance Sheet account.<br/>This is the account in the vendor bill line.
|
||||
<span
|
||||
class="help-block"
|
||||
colspan="2"
|
||||
attrs="{'invisible':[('invoice_type','not in',('in_invoice','out_refund'))]}"
|
||||
>
|
||||
The Balance Sheet account.<br
|
||||
/>This is the account in the vendor bill line.
|
||||
</span>
|
||||
</div>
|
||||
<field name="credit_account_id" required="1" domain="[('company_id', '=', company_id), ('deprecated', '=', False)]" attrs="{'readonly':[('invoice_line_id','!=',False)]}"/>
|
||||
<span class="help-block text-danger" colspan="2"
|
||||
attrs="{'invisible':[('is_credit_account_deprecated','!=',True)]}">
|
||||
<field
|
||||
name="credit_account_id"
|
||||
required="1"
|
||||
domain="[('company_id', '=', company_id), ('deprecated', '=', False)]"
|
||||
attrs="{'readonly':[('invoice_line_id','!=',False)]}"
|
||||
/>
|
||||
<span
|
||||
class="help-block text-danger"
|
||||
colspan="2"
|
||||
attrs="{'invisible':[('is_credit_account_deprecated','!=',True)]}"
|
||||
>
|
||||
This account in deprecated! The reconciliation will be NOT possible.
|
||||
</span>
|
||||
</group>
|
||||
</group>
|
||||
<group name="main_info">
|
||||
<group>
|
||||
<field name="invoice_id" attrs="{'invisible':[('invoice_id','=',False)]}"/>
|
||||
<field name="invoice_line_id" readonly="1" attrs="{'invisible':[('invoice_line_id','=',False)]}"/>
|
||||
<field name="estimated_amount" attrs="{'readonly':[('invoice_line_id','!=',False)],'invisible':[('estimated_amount','=',0.0),('invoice_line_id','!=',False)]}"/>
|
||||
<field name="total_amount" attrs="{'invisible':[('invoice_line_id','=',False)]}"/>
|
||||
<field name="move_line_auto_post" attrs="{'invisible':[('display_move_line_auto_post','=',False)]}"/>
|
||||
<field
|
||||
name="invoice_id"
|
||||
attrs="{'invisible':[('invoice_id','=',False)]}"
|
||||
/>
|
||||
<field
|
||||
name="invoice_line_id"
|
||||
readonly="1"
|
||||
attrs="{'invisible':[('invoice_line_id','=',False)]}"
|
||||
/>
|
||||
<field
|
||||
name="estimated_amount"
|
||||
attrs="{'readonly':[('invoice_line_id','!=',False)],'invisible':[('estimated_amount','=',0.0),('invoice_line_id','!=',False)]}"
|
||||
/>
|
||||
<field
|
||||
name="total_amount"
|
||||
attrs="{'invisible':[('invoice_line_id','=',False)]}"
|
||||
/>
|
||||
<field
|
||||
name="move_line_auto_post"
|
||||
attrs="{'invisible':[('display_move_line_auto_post','=',False)]}"
|
||||
/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="period_number" />
|
||||
<field name="period_type" />
|
||||
<field name="spread_date" />
|
||||
<field name="journal_id" domain="[('company_id', '=', company_id)]" widget="selection"/>
|
||||
<field
|
||||
name="journal_id"
|
||||
domain="[('company_id', '=', company_id)]"
|
||||
widget="selection"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook name="notebook">
|
||||
@ -126,39 +262,94 @@
|
||||
<field name="line_ids" readonly="1">
|
||||
<tree>
|
||||
<field name="name" readonly="1" />
|
||||
<field name="amount" attrs="{'readonly':[('move_id','!=',False)]}" sum="Total"/>
|
||||
<field
|
||||
name="amount"
|
||||
attrs="{'readonly':[('move_id','!=',False)]}"
|
||||
sum="Total"
|
||||
/>
|
||||
<field name="date" readonly="1" />
|
||||
<field name="move_id" readonly="1" />
|
||||
<button name="create_move" icon="fa-play" string="Create Move" type="object" groups="account.group_account_manager"
|
||||
attrs="{'invisible':['|',('move_id','!=',False)]}"/>
|
||||
<button name="open_move" icon="fa-plus-square-o" string="View Move" type="object"
|
||||
attrs="{'invisible':[('move_id','=',False)]}"/>
|
||||
<button name="unlink_move" icon="fa-times" string="Delete Move" type="object" confirm="This will delete the move. Are you sure ?" groups="account.group_account_manager"
|
||||
attrs="{'invisible':[('move_id','=',False)]}"/>
|
||||
<button
|
||||
name="create_move"
|
||||
icon="fa-play"
|
||||
string="Create Move"
|
||||
type="object"
|
||||
groups="account.group_account_manager"
|
||||
attrs="{'invisible':['|',('move_id','!=',False)]}"
|
||||
/>
|
||||
<button
|
||||
name="open_move"
|
||||
icon="fa-plus-square-o"
|
||||
string="View Move"
|
||||
type="object"
|
||||
attrs="{'invisible':[('move_id','=',False)]}"
|
||||
/>
|
||||
<button
|
||||
name="unlink_move"
|
||||
icon="fa-times"
|
||||
string="Delete Move"
|
||||
type="object"
|
||||
confirm="This will delete the move. Are you sure ?"
|
||||
groups="account.group_account_manager"
|
||||
attrs="{'invisible':[('move_id','=',False)]}"
|
||||
/>
|
||||
</tree>
|
||||
</field>
|
||||
<group name="extension">
|
||||
<group name="extension_left">
|
||||
</group>
|
||||
<group name="extension_right">
|
||||
<field name="display_create_all_moves" invisible="1"/>
|
||||
<button name="create_all_moves" string="Create All Moves" type="object"
|
||||
icon="fa-play" attrs="{'invisible':[('display_create_all_moves','!=',True)]}"/>
|
||||
<field name="unspread_amount" attrs="{'invisible': [('unspread_amount', '=', 0)]}" />
|
||||
<field name="unposted_amount" attrs="{'invisible': [('unposted_amount', '=', 0)]}" />
|
||||
<field name="posted_amount" attrs="{'invisible': [('posted_amount', '=', 0)]}" />
|
||||
<field
|
||||
name="display_create_all_moves"
|
||||
invisible="1"
|
||||
/>
|
||||
<button
|
||||
name="create_all_moves"
|
||||
string="Create All Moves"
|
||||
type="object"
|
||||
icon="fa-play"
|
||||
attrs="{'invisible':[('display_create_all_moves','!=',True)]}"
|
||||
/>
|
||||
<field
|
||||
name="unspread_amount"
|
||||
attrs="{'invisible': [('unspread_amount', '=', 0)]}"
|
||||
/>
|
||||
<field
|
||||
name="unposted_amount"
|
||||
attrs="{'invisible': [('unposted_amount', '=', 0)]}"
|
||||
/>
|
||||
<field
|
||||
name="posted_amount"
|
||||
attrs="{'invisible': [('posted_amount', '=', 0)]}"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
<page name="details" string="Details">
|
||||
<group name="extra_details">
|
||||
<group>
|
||||
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||
<field name="currency_id" groups="base.group_multi_currency"/>
|
||||
<field
|
||||
name="company_id"
|
||||
groups="base.group_multi_company"
|
||||
options="{'no_create': True}"
|
||||
/>
|
||||
<field
|
||||
name="currency_id"
|
||||
groups="base.group_multi_currency"
|
||||
/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="account_analytic_id" domain="[('company_id', '=', company_id)]" groups="analytic.group_analytic_accounting" options="{'no_create': True}"/>
|
||||
<field name="analytic_tag_ids" groups="analytic.group_analytic_accounting" widget="many2many_tags"/>
|
||||
<field
|
||||
name="account_analytic_id"
|
||||
domain="[('company_id', '=', company_id)]"
|
||||
groups="analytic.group_analytic_accounting"
|
||||
options="{'no_create': True}"
|
||||
/>
|
||||
<field
|
||||
name="analytic_tag_ids"
|
||||
groups="analytic.group_analytic_accounting"
|
||||
widget="many2many_tags"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
@ -171,7 +362,6 @@
|
||||
</form>
|
||||
</field>
|
||||
</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" />
|
||||
@ -188,7 +378,6 @@
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_account_spread_tree" model="ir.ui.view">
|
||||
<field name="model">account.spread</field>
|
||||
<field name="arch" type="xml">
|
||||
@ -198,16 +387,18 @@
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_account_spread_search" model="ir.ui.view">
|
||||
<field name="model">account.spread</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<filter string="Archived" name="inactive" domain="[('active','=',False)]"/>
|
||||
<filter
|
||||
string="Archived"
|
||||
name="inactive"
|
||||
domain="[('active','=',False)]"
|
||||
/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_account_spread_form" model="ir.actions.act_window">
|
||||
<field name="name">Spread Costs/Revenues</field>
|
||||
<field name="res_model">account.spread</field>
|
||||
@ -215,10 +406,10 @@
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_account_spread_tree" />
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_action_account_spread_form"
|
||||
<menuitem
|
||||
id="menu_action_account_spread_form"
|
||||
parent="account.menu_finance_entries_accounting_entries"
|
||||
action="action_account_spread_form"
|
||||
groups="account.group_account_user,account.group_account_manager"/>
|
||||
|
||||
groups="account.group_account_user,account.group_account_manager"
|
||||
/>
|
||||
</odoo>
|
||||
|
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_account_spread_template" model="ir.ui.view">
|
||||
<field name="model">account.spread.template</field>
|
||||
<field name="arch" type="xml">
|
||||
@ -10,22 +9,43 @@
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<label for="name" string="Spread Template Name" />
|
||||
<h1><field name="name" placeholder="e.g. Template cleaning contract"/></h1>
|
||||
<h1>
|
||||
<field
|
||||
name="name"
|
||||
placeholder="e.g. Template cleaning contract"
|
||||
/>
|
||||
</h1>
|
||||
</div>
|
||||
<group name="main_info">
|
||||
<group>
|
||||
<field name="spread_type" />
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field
|
||||
name="company_id"
|
||||
groups="base.group_multi_company"
|
||||
/>
|
||||
<field name="period_number" />
|
||||
<field name="period_type" />
|
||||
<field name="start_date" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="use_invoice_line_account" />
|
||||
<field name="spread_account_id" domain="[('company_id', '=', company_id), ('deprecated', '=', False)]" options="{'no_create': True}"
|
||||
attrs="{'required': [('use_invoice_line_account', '!=', True)], 'invisible': [('use_invoice_line_account', '=', True)]}" />
|
||||
<field name="exp_rev_account_id" attrs="{'invisible': ['|', ('use_invoice_line_account', '=', False)], 'required': [('use_invoice_line_account', '=', True)]}" domain="[('company_id', '=', company_id), ('deprecated', '=', False)]" options="{'no_create': True}"/>
|
||||
<field name="spread_journal_id" domain="[('company_id', '=', company_id)]" widget="selection"/>
|
||||
<field
|
||||
name="spread_account_id"
|
||||
domain="[('company_id', '=', company_id), ('deprecated', '=', False)]"
|
||||
options="{'no_create': True}"
|
||||
attrs="{'required': [('use_invoice_line_account', '!=', True)], 'invisible': [('use_invoice_line_account', '=', True)]}"
|
||||
/>
|
||||
<field
|
||||
name="exp_rev_account_id"
|
||||
attrs="{'invisible': ['|', ('use_invoice_line_account', '=', False)], 'required': [('use_invoice_line_account', '=', True)]}"
|
||||
domain="[('company_id', '=', company_id), ('deprecated', '=', False)]"
|
||||
options="{'no_create': True}"
|
||||
/>
|
||||
<field
|
||||
name="spread_journal_id"
|
||||
domain="[('company_id', '=', company_id)]"
|
||||
widget="selection"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
<div>
|
||||
@ -35,19 +55,25 @@
|
||||
<p attrs="{'invisible': [('auto_spread', '!=', True)]}">
|
||||
Automatically use this spread template on invoice validation for invoice lines using below product and/or account and/or analytic,
|
||||
</p>
|
||||
<field name="auto_spread_ids" attrs="{'invisible': [('auto_spread', '!=', True)]}" nolabel="1">
|
||||
<field
|
||||
name="auto_spread_ids"
|
||||
attrs="{'invisible': [('auto_spread', '!=', True)]}"
|
||||
nolabel="1"
|
||||
>
|
||||
<tree editable="bottom">
|
||||
<field name="name" />
|
||||
<field name="product_id" />
|
||||
<field name="account_id" />
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
|
||||
<field
|
||||
name="analytic_account_id"
|
||||
groups="analytic.group_analytic_accounting"
|
||||
/>
|
||||
</tree>
|
||||
</field>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_account_spread_template_tree" model="ir.ui.view">
|
||||
<field name="model">account.spread.template</field>
|
||||
<field name="arch" type="xml">
|
||||
@ -59,7 +85,6 @@
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_account_spread_template_form" model="ir.actions.act_window">
|
||||
<field name="name">Spread Templates</field>
|
||||
<field name="res_model">account.spread.template</field>
|
||||
@ -67,10 +92,10 @@
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_account_spread_template_tree" />
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_action_account_spread_template_form"
|
||||
<menuitem
|
||||
id="menu_action_account_spread_template_form"
|
||||
parent="account.account_account_menu"
|
||||
action="action_account_spread_template_form"
|
||||
groups="account.group_account_manager"/>
|
||||
|
||||
groups="account.group_account_manager"
|
||||
/>
|
||||
</odoo>
|
||||
|
@ -1,18 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_company_form" model="ir.ui.view">
|
||||
<field name="model">res.company</field>
|
||||
<field name="inherit_id" ref="base.view_company_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//notebook">
|
||||
<page name="account_spread_cost_revenue" string="Account Spread" groups="account.group_account_manager">
|
||||
<page
|
||||
name="account_spread_cost_revenue"
|
||||
string="Account Spread"
|
||||
groups="account.group_account_manager"
|
||||
>
|
||||
<group>
|
||||
<group string="Default Spread Accounts" name="default_spread_accounts">
|
||||
<group
|
||||
string="Default Spread Accounts"
|
||||
name="default_spread_accounts"
|
||||
>
|
||||
<field name="default_spread_revenue_account_id" />
|
||||
<field name="default_spread_expense_account_id" />
|
||||
</group>
|
||||
<group string="Default Spread Journals" name="default_spread_journals">
|
||||
<group
|
||||
string="Default Spread Journals"
|
||||
name="default_spread_journals"
|
||||
>
|
||||
<field name="default_spread_revenue_journal_id" />
|
||||
<field name="default_spread_expense_journal_id" />
|
||||
</group>
|
||||
@ -30,5 +39,4 @@
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
@ -5,90 +5,85 @@ from odoo import _, api, fields, models
|
||||
|
||||
|
||||
class AccountSpreadInvoiceLineLinkWizard(models.TransientModel):
|
||||
_name = 'account.spread.invoice.line.link.wizard'
|
||||
_description = 'Account Spread Invoice Line Link Wizard'
|
||||
_name = "account.spread.invoice.line.link.wizard"
|
||||
_description = "Account Spread Invoice Line Link Wizard"
|
||||
|
||||
def _selection_spread_action_type(self):
|
||||
base_selection = [
|
||||
('template', _('Create from spread template')),
|
||||
('new', _('Create new spread board'))
|
||||
("template", _("Create from spread template")),
|
||||
("new", _("Create new spread board")),
|
||||
]
|
||||
if not self.env.context.get('allow_spread_planning'):
|
||||
if not self.env.context.get("allow_spread_planning"):
|
||||
return base_selection
|
||||
|
||||
link_selection = [
|
||||
('link', _('Link to existing spread board')),
|
||||
("link", _("Link to existing spread board")),
|
||||
]
|
||||
return link_selection + base_selection
|
||||
|
||||
def _selection_default_spread_action_type(self):
|
||||
if not self.env.context.get('allow_spread_planning'):
|
||||
return 'template'
|
||||
return 'link'
|
||||
if not self.env.context.get("allow_spread_planning"):
|
||||
return "template"
|
||||
return "link"
|
||||
|
||||
invoice_line_id = fields.Many2one(
|
||||
'account.invoice.line',
|
||||
string='Invoice Line',
|
||||
"account.invoice.line",
|
||||
string="Invoice Line",
|
||||
readonly=True,
|
||||
required=True,
|
||||
ondelete='cascade')
|
||||
invoice_id = fields.Many2one(
|
||||
related='invoice_line_id.invoice_id',
|
||||
readonly=True)
|
||||
invoice_type = fields.Selection([
|
||||
('out_invoice', 'Customer Invoice'),
|
||||
('in_invoice', 'Vendor Bill'),
|
||||
('out_refund', 'Customer Credit Note'),
|
||||
('in_refund', 'Vendor Credit Note')],
|
||||
compute='_compute_invoice_type',
|
||||
store=True)
|
||||
spread_type = fields.Selection([
|
||||
('sale', 'Customer'),
|
||||
('purchase', 'Supplier')],
|
||||
compute='_compute_invoice_type',
|
||||
store=True)
|
||||
spread_id = fields.Many2one(
|
||||
'account.spread',
|
||||
string='Spread Board')
|
||||
company_id = fields.Many2one(
|
||||
'res.company',
|
||||
string='Company',
|
||||
required=True)
|
||||
ondelete="cascade",
|
||||
)
|
||||
invoice_id = fields.Many2one(related="invoice_line_id.invoice_id", readonly=True)
|
||||
invoice_type = fields.Selection(
|
||||
[
|
||||
("out_invoice", "Customer Invoice"),
|
||||
("in_invoice", "Vendor Bill"),
|
||||
("out_refund", "Customer Credit Note"),
|
||||
("in_refund", "Vendor Credit Note"),
|
||||
],
|
||||
compute="_compute_invoice_type",
|
||||
store=True,
|
||||
)
|
||||
spread_type = fields.Selection(
|
||||
[("sale", "Customer"), ("purchase", "Supplier")],
|
||||
compute="_compute_invoice_type",
|
||||
store=True,
|
||||
)
|
||||
spread_id = fields.Many2one("account.spread", string="Spread Board")
|
||||
company_id = fields.Many2one("res.company", string="Company", required=True)
|
||||
spread_action_type = fields.Selection(
|
||||
selection=_selection_spread_action_type,
|
||||
default=_selection_default_spread_action_type)
|
||||
template_id = fields.Many2one(
|
||||
'account.spread.template',
|
||||
string='Spread Template')
|
||||
default=_selection_default_spread_action_type,
|
||||
)
|
||||
template_id = fields.Many2one("account.spread.template", string="Spread Template")
|
||||
use_invoice_line_account = fields.Boolean(
|
||||
string="Use invoice line's account",
|
||||
help="Use invoice line's account as Balance sheet / spread account.\n"
|
||||
"In this case, user need to select expense/revenue account too.")
|
||||
"In this case, user need to select expense/revenue account too.",
|
||||
)
|
||||
spread_account_id = fields.Many2one(
|
||||
'account.account',
|
||||
string='Balance sheet account / Spread account',
|
||||
store=True)
|
||||
"account.account", string="Balance sheet account / Spread account", store=True
|
||||
)
|
||||
exp_rev_account_id = fields.Many2one(
|
||||
'account.account',
|
||||
string='Expense/revenue account',
|
||||
help="Optional account to overwrite the existing expense/revenue "
|
||||
"account")
|
||||
"account.account",
|
||||
string="Expense/revenue account",
|
||||
help="Optional account to overwrite the existing expense/revenue " "account",
|
||||
)
|
||||
spread_journal_id = fields.Many2one(
|
||||
'account.journal',
|
||||
string='Spread Journal',
|
||||
store=True)
|
||||
"account.journal", string="Spread Journal", store=True
|
||||
)
|
||||
|
||||
@api.depends('invoice_line_id')
|
||||
@api.depends("invoice_line_id")
|
||||
def _compute_invoice_type(self):
|
||||
for wizard in self:
|
||||
invoice = wizard.invoice_line_id.invoice_id
|
||||
wizard.invoice_type = invoice.type
|
||||
if invoice.type in ['out_invoice', 'out_refund']:
|
||||
wizard.spread_type = 'sale'
|
||||
if invoice.type in ["out_invoice", "out_refund"]:
|
||||
wizard.spread_type = "sale"
|
||||
else:
|
||||
wizard.spread_type = 'purchase'
|
||||
wizard.spread_type = "purchase"
|
||||
|
||||
@api.onchange('company_id', 'invoice_type')
|
||||
@api.onchange("company_id", "invoice_type")
|
||||
def _onchange_spread_journal_account(self):
|
||||
for wizard in self:
|
||||
company = wizard.company_id
|
||||
@ -96,7 +91,7 @@ class AccountSpreadInvoiceLineLinkWizard(models.TransientModel):
|
||||
acc_expense = company.default_spread_expense_account_id
|
||||
journal_revenue = company.default_spread_revenue_journal_id
|
||||
journal_expense = company.default_spread_expense_journal_id
|
||||
if wizard.invoice_type in ('out_invoice', 'in_refund'):
|
||||
if wizard.invoice_type in ("out_invoice", "in_refund"):
|
||||
wizard.spread_account_id = acc_revenue
|
||||
wizard.spread_journal_id = journal_revenue
|
||||
else:
|
||||
@ -108,47 +103,51 @@ class AccountSpreadInvoiceLineLinkWizard(models.TransientModel):
|
||||
"""Keep this for making the fields editable"""
|
||||
pass
|
||||
|
||||
@api.onchange('invoice_type')
|
||||
@api.onchange("invoice_type")
|
||||
def onchange_invoice_type(self):
|
||||
domain = [
|
||||
('invoice_id', '=', False),
|
||||
('invoice_type', '=', self.invoice_type),
|
||||
('company_id', '=', self.company_id.id)]
|
||||
res = {'domain': {'spread_id': domain}}
|
||||
("invoice_id", "=", False),
|
||||
("invoice_type", "=", self.invoice_type),
|
||||
("company_id", "=", self.company_id.id),
|
||||
]
|
||||
res = {"domain": {"spread_id": domain}}
|
||||
return res
|
||||
|
||||
@api.onchange('use_invoice_line_account')
|
||||
@api.onchange("use_invoice_line_account")
|
||||
def _onchange_user_invoice_line_account(self):
|
||||
self.spread_account_id = (self.use_invoice_line_account and
|
||||
self.invoice_line_id.account_id or False)
|
||||
self.spread_account_id = (
|
||||
self.use_invoice_line_account and self.invoice_line_id.account_id or False
|
||||
)
|
||||
self.exp_rev_account_id = False
|
||||
|
||||
@api.multi
|
||||
def confirm(self):
|
||||
self.ensure_one()
|
||||
|
||||
if self.spread_action_type == 'link':
|
||||
if self.spread_action_type == "link":
|
||||
if not self.invoice_line_id.spread_id:
|
||||
self.invoice_line_id.spread_id = self.spread_id
|
||||
|
||||
return {
|
||||
'name': _('Spread Details'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'account.spread',
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'current',
|
||||
'readonly': False,
|
||||
'res_id': self.invoice_line_id.spread_id.id,
|
||||
"name": _("Spread Details"),
|
||||
"view_type": "form",
|
||||
"view_mode": "form",
|
||||
"res_model": "account.spread",
|
||||
"type": "ir.actions.act_window",
|
||||
"target": "current",
|
||||
"readonly": False,
|
||||
"res_id": self.invoice_line_id.spread_id.id,
|
||||
}
|
||||
elif self.spread_action_type == 'new':
|
||||
elif self.spread_action_type == "new":
|
||||
debit_account = credit_account = self.spread_account_id
|
||||
if self.invoice_type in ('out_invoice', 'in_refund'):
|
||||
credit_account = (self.exp_rev_account_id or
|
||||
self.invoice_line_id.account_id)
|
||||
if self.invoice_type in ("out_invoice", "in_refund"):
|
||||
credit_account = (
|
||||
self.exp_rev_account_id or self.invoice_line_id.account_id
|
||||
)
|
||||
else:
|
||||
debit_account = (self.exp_rev_account_id or
|
||||
self.invoice_line_id.account_id)
|
||||
debit_account = (
|
||||
self.exp_rev_account_id or self.invoice_line_id.account_id
|
||||
)
|
||||
|
||||
analytic_account = self.invoice_line_id.account_analytic_id
|
||||
analytic_tags = self.invoice_line_id.analytic_tag_ids
|
||||
@ -156,27 +155,27 @@ class AccountSpreadInvoiceLineLinkWizard(models.TransientModel):
|
||||
use_il_account = self.use_invoice_line_account
|
||||
|
||||
return {
|
||||
'name': _('New Spread Board'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'account.spread',
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'current',
|
||||
'readonly': False,
|
||||
'context': {
|
||||
'default_name': self.invoice_line_id.name,
|
||||
'default_invoice_type': self.invoice_type,
|
||||
'default_invoice_line_id': self.invoice_line_id.id,
|
||||
'default_use_invoice_line_account': use_il_account,
|
||||
'default_debit_account_id': debit_account.id,
|
||||
'default_credit_account_id': credit_account.id,
|
||||
'default_journal_id': self.spread_journal_id.id,
|
||||
'default_account_analytic_id': analytic_account.id,
|
||||
'default_analytic_tag_ids': analytic_tags.ids,
|
||||
'default_spread_date': date_invoice,
|
||||
"name": _("New Spread Board"),
|
||||
"view_type": "form",
|
||||
"view_mode": "form",
|
||||
"res_model": "account.spread",
|
||||
"type": "ir.actions.act_window",
|
||||
"target": "current",
|
||||
"readonly": False,
|
||||
"context": {
|
||||
"default_name": self.invoice_line_id.name,
|
||||
"default_invoice_type": self.invoice_type,
|
||||
"default_invoice_line_id": self.invoice_line_id.id,
|
||||
"default_use_invoice_line_account": use_il_account,
|
||||
"default_debit_account_id": debit_account.id,
|
||||
"default_credit_account_id": credit_account.id,
|
||||
"default_journal_id": self.spread_journal_id.id,
|
||||
"default_account_analytic_id": analytic_account.id,
|
||||
"default_analytic_tag_ids": analytic_tags.ids,
|
||||
"default_spread_date": date_invoice,
|
||||
},
|
||||
}
|
||||
elif self.spread_action_type == 'template':
|
||||
elif self.spread_action_type == "template":
|
||||
if not self.invoice_line_id.spread_id:
|
||||
account = self.invoice_line_id.account_id
|
||||
spread_account_id = False
|
||||
@ -190,34 +189,34 @@ class AccountSpreadInvoiceLineLinkWizard(models.TransientModel):
|
||||
date_invoice = self.invoice_id.date_invoice
|
||||
date_invoice = date_invoice or self.template_id.start_date
|
||||
date_invoice = date_invoice or fields.Date.today()
|
||||
spread_vals['spread_date'] = date_invoice
|
||||
spread_vals["spread_date"] = date_invoice
|
||||
|
||||
spread_vals['name'] = ('%s %s') % (
|
||||
spread_vals['name'],
|
||||
self.invoice_line_id.name
|
||||
spread_vals["name"] = ("%s %s") % (
|
||||
spread_vals["name"],
|
||||
self.invoice_line_id.name,
|
||||
)
|
||||
|
||||
if spread_vals['invoice_type'] == 'out_invoice':
|
||||
spread_vals['credit_account_id'] = account.id
|
||||
if spread_vals["invoice_type"] == "out_invoice":
|
||||
spread_vals["credit_account_id"] = account.id
|
||||
else:
|
||||
spread_vals['debit_account_id'] = account.id
|
||||
spread_vals["debit_account_id"] = account.id
|
||||
|
||||
analytic_account = self.invoice_line_id.account_analytic_id
|
||||
spread_vals['account_analytic_id'] = analytic_account.id
|
||||
spread_vals["account_analytic_id"] = analytic_account.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
|
||||
return {
|
||||
'name': _('Spread Details'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'account.spread',
|
||||
'type': 'ir.actions.act_window',
|
||||
'target': 'current',
|
||||
'readonly': False,
|
||||
'res_id': self.invoice_line_id.spread_id.id,
|
||||
"name": _("Spread Details"),
|
||||
"view_type": "form",
|
||||
"view_mode": "form",
|
||||
"res_model": "account.spread",
|
||||
"type": "ir.actions.act_window",
|
||||
"target": "current",
|
||||
"readonly": False,
|
||||
"res_id": self.invoice_line_id.spread_id.id,
|
||||
}
|
||||
|
@ -1,13 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_account_spread_invoice_line_link_wizard" model="ir.ui.view">
|
||||
<field name="model">account.spread.invoice.line.link.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<group name="main_info">
|
||||
<group>
|
||||
<field name="company_id" readonly="1" groups="base.group_multi_company"/>
|
||||
<field
|
||||
name="company_id"
|
||||
readonly="1"
|
||||
groups="base.group_multi_company"
|
||||
/>
|
||||
<field name="invoice_type" readonly="1" />
|
||||
<field name="spread_type" invisible="1" />
|
||||
<field name="invoice_id" readonly="1" />
|
||||
@ -15,20 +18,52 @@
|
||||
</group>
|
||||
<group>
|
||||
<field name="spread_action_type" widget="radio" />
|
||||
<field name="spread_id" attrs="{'invisible': [('spread_action_type', '!=', 'link')],'required': [('spread_action_type', '=', 'link')]}" domain="[('invoice_type', '=', invoice_type)]" options="{'no_create': True}"/>
|
||||
<field name="template_id" attrs="{'invisible': [('spread_action_type', '!=', 'template')],'required': [('spread_action_type', '=', 'template')]}" domain="[('spread_type', '=', spread_type)]" options="{'no_create': True}"/>
|
||||
<field name="use_invoice_line_account" attrs="{'invisible': [('spread_action_type', '!=', 'new')]}"/>
|
||||
<field name="spread_account_id" attrs="{'invisible': [('spread_action_type', '!=', 'new')],'required': [('spread_action_type', '=', 'new')]}" domain="[('company_id', '=', company_id), ('deprecated', '=', False)]" options="{'no_create': True}"/>
|
||||
<field name="exp_rev_account_id" attrs="{'invisible': ['|', ('use_invoice_line_account', '=', False), ('spread_action_type', '!=', 'new')], 'required': [('use_invoice_line_account', '=', True)]}" domain="[('company_id', '=', company_id), ('deprecated', '=', False)]" options="{'no_create': True}"/>
|
||||
<field name="spread_journal_id" attrs="{'invisible': [('spread_action_type', '!=', 'new')],'required': [('spread_action_type', '=', 'new')]}" domain="[('company_id', '=', company_id)]" options="{'no_create': True}"/>
|
||||
<field
|
||||
name="spread_id"
|
||||
attrs="{'invisible': [('spread_action_type', '!=', 'link')],'required': [('spread_action_type', '=', 'link')]}"
|
||||
domain="[('invoice_type', '=', invoice_type)]"
|
||||
options="{'no_create': True}"
|
||||
/>
|
||||
<field
|
||||
name="template_id"
|
||||
attrs="{'invisible': [('spread_action_type', '!=', 'template')],'required': [('spread_action_type', '=', 'template')]}"
|
||||
domain="[('spread_type', '=', spread_type)]"
|
||||
options="{'no_create': True}"
|
||||
/>
|
||||
<field
|
||||
name="use_invoice_line_account"
|
||||
attrs="{'invisible': [('spread_action_type', '!=', 'new')]}"
|
||||
/>
|
||||
<field
|
||||
name="spread_account_id"
|
||||
attrs="{'invisible': [('spread_action_type', '!=', 'new')],'required': [('spread_action_type', '=', 'new')]}"
|
||||
domain="[('company_id', '=', company_id), ('deprecated', '=', False)]"
|
||||
options="{'no_create': True}"
|
||||
/>
|
||||
<field
|
||||
name="exp_rev_account_id"
|
||||
attrs="{'invisible': ['|', ('use_invoice_line_account', '=', False), ('spread_action_type', '!=', 'new')], 'required': [('use_invoice_line_account', '=', True)]}"
|
||||
domain="[('company_id', '=', company_id), ('deprecated', '=', False)]"
|
||||
options="{'no_create': True}"
|
||||
/>
|
||||
<field
|
||||
name="spread_journal_id"
|
||||
attrs="{'invisible': [('spread_action_type', '!=', 'new')],'required': [('spread_action_type', '=', 'new')]}"
|
||||
domain="[('company_id', '=', company_id)]"
|
||||
options="{'no_create': True}"
|
||||
/>
|
||||
</group>
|
||||
</group>
|
||||
<footer>
|
||||
<button string="Confirm" type="object" name="confirm" class="btn-primary"/>
|
||||
<button
|
||||
string="Confirm"
|
||||
type="object"
|
||||
name="confirm"
|
||||
class="btn-primary"
|
||||
/>
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
Loading…
Reference in New Issue
Block a user