[IMP] : black, isort, prettier

This commit is contained in:
Pedro M. Baeza
2020-07-13 18:28:03 +02:00
parent 7051ca78c1
commit 1e66a22c61
46 changed files with 2703 additions and 2811 deletions

View File

@@ -6,68 +6,61 @@
# Copyright 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models, fields
from odoo import api, fields, models
class ContractAbstractContract(models.AbstractModel):
_name = 'contract.abstract.contract'
_description = 'Abstract Recurring Contract'
_name = "contract.abstract.contract"
_description = "Abstract Recurring Contract"
# These fields will not be synced to the contract
NO_SYNC = ['name', 'partner_id', 'company_id']
NO_SYNC = ["name", "partner_id", "company_id"]
name = fields.Char(required=True)
# Needed for avoiding errors on several inherited behaviors
partner_id = fields.Many2one(
comodel_name="res.partner", string="Partner", index=True
)
pricelist_id = fields.Many2one(
comodel_name='product.pricelist', string='Pricelist'
)
pricelist_id = fields.Many2one(comodel_name="product.pricelist", string="Pricelist")
contract_type = fields.Selection(
selection=[('sale', 'Customer'), ('purchase', 'Supplier')],
default='sale',
selection=[("sale", "Customer"), ("purchase", "Supplier")],
default="sale",
index=True,
)
journal_id = fields.Many2one(
'account.journal',
string='Journal',
"account.journal",
string="Journal",
default=lambda s: s._default_journal(),
domain="[('type', '=', contract_type),"
"('company_id', '=', company_id)]",
domain="[('type', '=', contract_type)," "('company_id', '=', company_id)]",
index=True,
)
company_id = fields.Many2one(
'res.company',
string='Company',
"res.company",
string="Company",
required=True,
default=lambda self: self.env['res.company']._company_default_get(
self._name
),
default=lambda self: self.env["res.company"]._company_default_get(self._name),
)
@api.onchange('contract_type')
@api.onchange("contract_type")
def _onchange_contract_type(self):
if self.contract_type == 'purchase':
self.contract_line_ids.filtered('automatic_price').update(
{'automatic_price': False}
if self.contract_type == "purchase":
self.contract_line_ids.filtered("automatic_price").update(
{"automatic_price": False}
)
self.journal_id = self.env['account.journal'].search(
self.journal_id = self.env["account.journal"].search(
[
('type', '=', self.contract_type),
('company_id', '=', self.company_id.id),
("type", "=", self.contract_type),
("company_id", "=", self.company_id.id),
],
limit=1,
)
@api.model
def _default_journal(self):
company_id = self.env.context.get(
'company_id', self.env.user.company_id.id
)
company_id = self.env.context.get("company_id", self.env.user.company_id.id)
domain = [
('type', '=', self.contract_type),
('company_id', '=', company_id),
("type", "=", self.contract_type),
("company_id", "=", company_id),
]
return self.env['account.journal'].search(domain, limit=1)
return self.env["account.journal"].search(domain, limit=1)

View File

@@ -6,47 +6,44 @@
# Copyright 2018 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models, fields
from odoo.addons import decimal_precision as dp
from odoo import api, fields, models
from odoo.exceptions import ValidationError
from odoo.tools.translate import _
from odoo.addons import decimal_precision as dp
class ContractAbstractContractLine(models.AbstractModel):
_name = 'contract.abstract.contract.line'
_description = 'Abstract Recurring Contract Line'
_name = "contract.abstract.contract.line"
_description = "Abstract Recurring Contract Line"
product_id = fields.Many2one(
'product.product', string='Product'
)
product_id = fields.Many2one("product.product", string="Product")
name = fields.Text(string='Description', required=True)
name = fields.Text(string="Description", required=True)
quantity = fields.Float(default=1.0, required=True)
uom_id = fields.Many2one(
'uom.uom', string='Unit of Measure'
)
uom_id = fields.Many2one("uom.uom", string="Unit of Measure")
automatic_price = fields.Boolean(
string="Auto-price?",
help="If this is marked, the price will be obtained automatically "
"applying the pricelist to the product. If not, you will be "
"able to introduce a manual price",
)
specific_price = fields.Float(string='Specific Price')
specific_price = fields.Float(string="Specific Price")
price_unit = fields.Float(
string='Unit Price',
string="Unit Price",
compute="_compute_price_unit",
inverse="_inverse_price_unit",
)
price_subtotal = fields.Float(
compute='_compute_price_subtotal',
digits=dp.get_precision('Account'),
string='Sub Total',
compute="_compute_price_subtotal",
digits=dp.get_precision("Account"),
string="Sub Total",
)
discount = fields.Float(
string='Discount (%)',
digits=dp.get_precision('Discount'),
help='Discount that is applied in generated invoices.'
' It should be less or equal to 100',
string="Discount (%)",
digits=dp.get_precision("Discount"),
help="Discount that is applied in generated invoices."
" It should be less or equal to 100",
)
sequence = fields.Integer(
string="Sequence",
@@ -55,23 +52,23 @@ class ContractAbstractContractLine(models.AbstractModel):
)
recurring_rule_type = fields.Selection(
[
('daily', 'Day(s)'),
('weekly', 'Week(s)'),
('monthly', 'Month(s)'),
('monthlylastday', 'Month(s) last day'),
('quarterly', 'Quarter(s)'),
('semesterly', 'Semester(s)'),
('yearly', 'Year(s)'),
("daily", "Day(s)"),
("weekly", "Week(s)"),
("monthly", "Month(s)"),
("monthlylastday", "Month(s) last day"),
("quarterly", "Quarter(s)"),
("semesterly", "Semester(s)"),
("yearly", "Year(s)"),
],
default='monthly',
string='Recurrence',
default="monthly",
string="Recurrence",
help="Specify Interval for automatic invoice generation.",
required=True,
)
recurring_invoicing_type = fields.Selection(
[('pre-paid', 'Pre-paid'), ('post-paid', 'Post-paid')],
default='pre-paid',
string='Invoicing type',
[("pre-paid", "Pre-paid"), ("post-paid", "Post-paid")],
default="pre-paid",
string="Invoicing type",
help=(
"Specify if the invoice must be generated at the beginning "
"(pre-paid) or end (post-paid) of the period."
@@ -84,68 +81,63 @@ class ContractAbstractContractLine(models.AbstractModel):
help=(
"Number of days to offset the invoice from the period end "
"date (in post-paid mode) or start date (in pre-paid mode)."
)
),
)
recurring_interval = fields.Integer(
default=1,
string='Invoice Every',
string="Invoice Every",
help="Invoice every (Days/Week/Month/Year)",
required=True,
)
date_start = fields.Date(string='Date Start')
recurring_next_date = fields.Date(string='Date of Next Invoice')
last_date_invoiced = fields.Date(string='Last Date Invoiced')
date_start = fields.Date(string="Date Start")
recurring_next_date = fields.Date(string="Date of Next Invoice")
last_date_invoiced = fields.Date(string="Last Date Invoiced")
is_canceled = fields.Boolean(string="Canceled", default=False)
is_auto_renew = fields.Boolean(string="Auto Renew", default=False)
auto_renew_interval = fields.Integer(
default=1,
string='Renew Every',
help="Renew every (Days/Week/Month/Year)",
default=1, string="Renew Every", help="Renew every (Days/Week/Month/Year)",
)
auto_renew_rule_type = fields.Selection(
[
('daily', 'Day(s)'),
('weekly', 'Week(s)'),
('monthly', 'Month(s)'),
('yearly', 'Year(s)'),
("daily", "Day(s)"),
("weekly", "Week(s)"),
("monthly", "Month(s)"),
("yearly", "Year(s)"),
],
default='yearly',
string='Renewal type',
default="yearly",
string="Renewal type",
help="Specify Interval for automatic renewal.",
)
termination_notice_interval = fields.Integer(
default=1, string='Termination Notice Before'
default=1, string="Termination Notice Before"
)
termination_notice_rule_type = fields.Selection(
[('daily', 'Day(s)'), ('weekly', 'Week(s)'), ('monthly', 'Month(s)')],
default='monthly',
string='Termination Notice type',
[("daily", "Day(s)"), ("weekly", "Week(s)"), ("monthly", "Month(s)")],
default="monthly",
string="Termination Notice type",
)
contract_id = fields.Many2one(
string='Contract',
comodel_name='contract.abstract.contract',
string="Contract",
comodel_name="contract.abstract.contract",
required=True,
ondelete='cascade',
ondelete="cascade",
)
display_type = fields.Selection(
selection=[
('line_section', "Section"),
('line_note', "Note"),
],
selection=[("line_section", "Section"), ("line_note", "Note"),],
default=False,
help="Technical field for UX purpose."
help="Technical field for UX purpose.",
)
note_invoicing_mode = fields.Selection(
selection=[
('with_previous_line', 'With previous line'),
('with_next_line', 'With next line'),
('custom', 'Custom'),
("with_previous_line", "With previous line"),
("with_next_line", "With next line"),
("custom", "Custom"),
],
default='with_previous_line',
default="with_previous_line",
help="Defines when the Note is invoiced:\n"
"- With previous line: If the previous line can be invoiced.\n"
"- With next line: If the next line can be invoiced.\n"
"- Custom: Depending on the recurrence to be define."
"- With previous line: If the previous line can be invoiced.\n"
"- With next line: If the next line can be invoiced.\n"
"- Custom: Depending on the recurrence to be define.",
)
is_recurring_note = fields.Boolean(compute="_compute_is_recurring_note")
@@ -154,8 +146,8 @@ class ContractAbstractContractLine(models.AbstractModel):
self, recurring_invoicing_type, recurring_rule_type
):
if (
recurring_invoicing_type == 'pre-paid'
or recurring_rule_type == 'monthlylastday'
recurring_invoicing_type == "pre-paid"
or recurring_rule_type == "monthlylastday"
):
return 0
else:
@@ -164,26 +156,24 @@ class ContractAbstractContractLine(models.AbstractModel):
def is_recurring_note(self):
for record in self:
record.is_recurring_note = (
record.display_type == 'line_note'
and record.note_invoicing_mode == 'custom'
record.display_type == "line_note"
and record.note_invoicing_mode == "custom"
)
@api.depends('recurring_invoicing_type', 'recurring_rule_type')
@api.depends("recurring_invoicing_type", "recurring_rule_type")
def _compute_recurring_invoicing_offset(self):
for rec in self:
rec.recurring_invoicing_offset = (
self._get_default_recurring_invoicing_offset(
rec.recurring_invoicing_type, rec.recurring_rule_type
)
rec.recurring_invoicing_offset = self._get_default_recurring_invoicing_offset(
rec.recurring_invoicing_type, rec.recurring_rule_type
)
@api.depends(
'automatic_price',
'specific_price',
'product_id',
'quantity',
'contract_id.pricelist_id',
'contract_id.partner_id',
"automatic_price",
"specific_price",
"product_id",
"quantity",
"contract_id.pricelist_id",
"contract_id.partner_id",
)
def _compute_price_unit(self):
"""Get the specific price if no auto-price, and the price obtained
@@ -192,20 +182,17 @@ class ContractAbstractContractLine(models.AbstractModel):
for line in self:
if line.automatic_price:
pricelist = (
line.contract_id.pricelist_id or
line.contract_id.partner_id.with_context(
line.contract_id.pricelist_id
or line.contract_id.partner_id.with_context(
force_company=line.contract_id.company_id.id,
).property_product_pricelist
)
product = line.product_id.with_context(
quantity=line.env.context.get(
'contract_line_qty',
line.quantity,
),
quantity=line.env.context.get("contract_line_qty", line.quantity,),
pricelist=pricelist.id,
partner=line.contract_id.partner_id.id,
date=line.env.context.get(
'old_date', fields.Date.context_today(line)
"old_date", fields.Date.context_today(line)
),
)
line.price_unit = product.price
@@ -213,14 +200,14 @@ class ContractAbstractContractLine(models.AbstractModel):
line.price_unit = line.specific_price
# Tip in https://github.com/odoo/odoo/issues/23891#issuecomment-376910788
@api.onchange('price_unit')
@api.onchange("price_unit")
def _inverse_price_unit(self):
"""Store the specific price in the no auto-price records."""
for line in self.filtered(lambda x: not x.automatic_price):
line.specific_price = line.price_unit
@api.multi
@api.depends('quantity', 'price_unit', 'discount')
@api.depends("quantity", "price_unit", "discount")
def _compute_price_subtotal(self):
for line in self:
subtotal = line.quantity * line.price_unit
@@ -233,30 +220,26 @@ class ContractAbstractContractLine(models.AbstractModel):
line.price_subtotal = subtotal
@api.multi
@api.constrains('discount')
@api.constrains("discount")
def _check_discount(self):
for line in self:
if line.discount > 100:
raise ValidationError(
_("Discount should be less or equal to 100")
)
raise ValidationError(_("Discount should be less or equal to 100"))
@api.multi
@api.onchange('product_id')
@api.onchange("product_id")
def _onchange_product_id(self):
if not self.product_id:
return {'domain': {'uom_id': []}}
return {"domain": {"uom_id": []}}
vals = {}
domain = {
'uom_id': [
('category_id', '=', self.product_id.uom_id.category_id.id)
]
"uom_id": [("category_id", "=", self.product_id.uom_id.category_id.id)]
}
if not self.uom_id or (
self.product_id.uom_id.category_id.id != self.uom_id.category_id.id
):
vals['uom_id'] = self.product_id.uom_id
vals["uom_id"] = self.product_id.uom_id
date = self.recurring_next_date or fields.Date.context_today(self)
partner = self.contract_id.partner_id or self.env.user.partner_id
@@ -268,7 +251,7 @@ class ContractAbstractContractLine(models.AbstractModel):
pricelist=self.contract_id.pricelist_id.id,
uom=self.uom_id.id,
)
vals['name'] = self.product_id.get_product_multiline_description_sale()
vals['price_unit'] = product.price
vals["name"] = self.product_id.get_product_multiline_description_sale()
vals["price_unit"] = product.price
self.update(vals)
return {'domain': domain}
return {"domain": domain}

View File

@@ -5,8 +5,7 @@ from odoo import fields, models
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
_inherit = "account.invoice"
# We keep this field for migration purpose
old_contract_id = fields.Many2one(
'contract.contract', oldname='contract_id')
old_contract_id = fields.Many2one("contract.contract", oldname="contract_id")

View File

@@ -5,8 +5,8 @@ from odoo import fields, models
class AccountInvoiceLine(models.Model):
_inherit = 'account.invoice.line'
_inherit = "account.invoice.line"
contract_line_id = fields.Many2one(
'contract.line', string='Contract Line', index=True
"contract.line", string="Contract Line", index=True
)

View File

@@ -7,30 +7,24 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
from odoo.exceptions import ValidationError, UserError
from odoo.exceptions import UserError, ValidationError
from odoo.tools.translate import _
class ContractContract(models.Model):
_name = 'contract.contract'
_name = "contract.contract"
_description = "Contract"
_order = 'code, name asc'
_order = "code, name asc"
_inherit = [
'mail.thread',
'mail.activity.mixin',
'contract.abstract.contract',
"mail.thread",
"mail.activity.mixin",
"contract.abstract.contract",
]
active = fields.Boolean(
default=True,
)
code = fields.Char(
string="Reference",
)
active = fields.Boolean(default=True,)
code = fields.Char(string="Reference",)
group_id = fields.Many2one(
string="Group",
comodel_name='account.analytic.account',
ondelete='restrict',
string="Group", comodel_name="account.analytic.account", ondelete="restrict",
)
currency_id = fields.Many2one(
compute="_compute_currency_id",
@@ -38,70 +32,59 @@ class ContractContract(models.Model):
comodel_name="res.currency",
string="Currency",
)
manual_currency_id = fields.Many2one(
comodel_name="res.currency",
readonly=True,
)
manual_currency_id = fields.Many2one(comodel_name="res.currency", readonly=True,)
contract_template_id = fields.Many2one(
string='Contract Template', comodel_name='contract.template'
string="Contract Template", comodel_name="contract.template"
)
contract_line_ids = fields.One2many(
string='Contract lines',
comodel_name='contract.line',
inverse_name='contract_id',
string="Contract lines",
comodel_name="contract.line",
inverse_name="contract_id",
copy=True,
)
user_id = fields.Many2one(
comodel_name='res.users',
string='Responsible',
comodel_name="res.users",
string="Responsible",
index=True,
default=lambda self: self.env.user,
)
create_invoice_visibility = fields.Boolean(
compute='_compute_create_invoice_visibility'
compute="_compute_create_invoice_visibility"
)
recurring_next_date = fields.Date(
compute='_compute_recurring_next_date',
string='Date of Next Invoice',
compute="_compute_recurring_next_date",
string="Date of Next Invoice",
store=True,
)
date_end = fields.Date(
compute='_compute_date_end', string='Date End', store=True
)
date_end = fields.Date(compute="_compute_date_end", string="Date End", store=True)
payment_term_id = fields.Many2one(
comodel_name='account.payment.term', string='Payment Terms', index=True
comodel_name="account.payment.term", string="Payment Terms", index=True
)
invoice_count = fields.Integer(compute="_compute_invoice_count")
fiscal_position_id = fields.Many2one(
comodel_name='account.fiscal.position',
string='Fiscal Position',
ondelete='restrict',
comodel_name="account.fiscal.position",
string="Fiscal Position",
ondelete="restrict",
)
invoice_partner_id = fields.Many2one(
string="Invoicing contact",
comodel_name='res.partner',
ondelete='restrict',
string="Invoicing contact", comodel_name="res.partner", ondelete="restrict",
)
partner_id = fields.Many2one(
comodel_name='res.partner',
inverse='_inverse_partner_id',
required=True
comodel_name="res.partner", inverse="_inverse_partner_id", required=True
)
commercial_partner_id = fields.Many2one(
'res.partner',
"res.partner",
compute_sudo=True,
related='partner_id.commercial_partner_id',
related="partner_id.commercial_partner_id",
store=True,
string='Commercial Entity',
index=True
string="Commercial Entity",
index=True,
)
tag_ids = fields.Many2many(comodel_name="contract.tag", string="Tags")
note = fields.Text(string="Notes")
is_terminated = fields.Boolean(
string="Terminated", readonly=True, copy=False
)
is_terminated = fields.Boolean(string="Terminated", readonly=True, copy=False)
terminate_reason_id = fields.Many2one(
comodel_name="contract.terminate.reason",
string="Termination Reason",
@@ -127,55 +110,40 @@ class ContractContract(models.Model):
def _inverse_partner_id(self):
for rec in self:
if not rec.invoice_partner_id:
rec.invoice_partner_id = rec.partner_id.address_get(
['invoice']
)['invoice']
rec.invoice_partner_id = rec.partner_id.address_get(["invoice"])[
"invoice"
]
@api.multi
def _get_related_invoices(self):
self.ensure_one()
invoices = (
self.env['account.invoice.line']
.search(
[
(
'contract_line_id',
'in',
self.contract_line_ids.ids,
)
]
)
.mapped('invoice_id')
self.env["account.invoice.line"]
.search([("contract_line_id", "in", self.contract_line_ids.ids,)])
.mapped("invoice_id")
)
invoices |= self.env['account.invoice'].search(
[('old_contract_id', '=', self.id)]
invoices |= self.env["account.invoice"].search(
[("old_contract_id", "=", self.id)]
)
return invoices
def _get_computed_currency(self):
"""Helper method for returning the theoretical computed currency."""
self.ensure_one()
currency = self.env['res.currency']
if any(self.contract_line_ids.mapped('automatic_price')):
currency = self.env["res.currency"]
if any(self.contract_line_ids.mapped("automatic_price")):
# Use pricelist currency
currency = (
self.pricelist_id.currency_id or
self.partner_id.with_context(
self.pricelist_id.currency_id
or self.partner_id.with_context(
force_company=self.company_id.id,
).property_product_pricelist.currency_id
)
return (
currency or self.journal_id.currency_id or
self.company_id.currency_id
)
return currency or self.journal_id.currency_id or self.company_id.currency_id
@api.depends(
"manual_currency_id",
"pricelist_id",
"partner_id",
"journal_id",
"company_id",
"manual_currency_id", "pricelist_id", "partner_id", "journal_id", "company_id",
)
def _compute_currency_id(self):
for rec in self:
@@ -203,60 +171,60 @@ class ContractContract(models.Model):
def action_show_invoices(self):
self.ensure_one()
tree_view_ref = (
'account.invoice_supplier_tree'
if self.contract_type == 'purchase'
else 'account.invoice_tree_with_onboarding'
"account.invoice_supplier_tree"
if self.contract_type == "purchase"
else "account.invoice_tree_with_onboarding"
)
form_view_ref = (
'account.invoice_supplier_form'
if self.contract_type == 'purchase'
else 'account.invoice_form'
"account.invoice_supplier_form"
if self.contract_type == "purchase"
else "account.invoice_form"
)
tree_view = self.env.ref(tree_view_ref, raise_if_not_found=False)
form_view = self.env.ref(form_view_ref, raise_if_not_found=False)
action = {
'type': 'ir.actions.act_window',
'name': 'Invoices',
'res_model': 'account.invoice',
'view_type': 'form',
'view_mode': 'tree,kanban,form,calendar,pivot,graph,activity',
'domain': [('id', 'in', self._get_related_invoices().ids)],
"type": "ir.actions.act_window",
"name": "Invoices",
"res_model": "account.invoice",
"view_type": "form",
"view_mode": "tree,kanban,form,calendar,pivot,graph,activity",
"domain": [("id", "in", self._get_related_invoices().ids)],
}
if tree_view and form_view:
action['views'] = [(tree_view.id, 'tree'), (form_view.id, 'form')]
action["views"] = [(tree_view.id, "tree"), (form_view.id, "form")]
return action
@api.depends('contract_line_ids.date_end')
@api.depends("contract_line_ids.date_end")
def _compute_date_end(self):
for contract in self:
contract.date_end = False
date_end = contract.contract_line_ids.mapped('date_end')
date_end = contract.contract_line_ids.mapped("date_end")
if date_end and all(date_end):
contract.date_end = max(date_end)
@api.depends(
'contract_line_ids.recurring_next_date',
'contract_line_ids.is_canceled',
"contract_line_ids.recurring_next_date", "contract_line_ids.is_canceled",
)
def _compute_recurring_next_date(self):
for contract in self:
recurring_next_date = contract.contract_line_ids.filtered(
lambda l: (l.recurring_next_date and not l.is_canceled
and (not l.display_type or l.is_recurring_note))
).mapped('recurring_next_date')
lambda l: (
l.recurring_next_date
and not l.is_canceled
and (not l.display_type or l.is_recurring_note)
)
).mapped("recurring_next_date")
if recurring_next_date:
contract.recurring_next_date = min(recurring_next_date)
@api.depends('contract_line_ids.create_invoice_visibility')
@api.depends("contract_line_ids.create_invoice_visibility")
def _compute_create_invoice_visibility(self):
for contract in self:
contract.create_invoice_visibility = any(
contract.contract_line_ids.mapped(
'create_invoice_visibility'
)
contract.contract_line_ids.mapped("create_invoice_visibility")
)
@api.onchange('contract_template_id')
@api.onchange("contract_template_id")
def _onchange_contract_template_id(self):
"""Update the contract fields with that of the template.
@@ -269,7 +237,7 @@ class ContractContract(models.Model):
if not contract_template_id:
return
for field_name, field in contract_template_id._fields.items():
if field.name == 'contract_line_ids':
if field.name == "contract_line_ids":
lines = self._convert_contract_lines(contract_template_id)
self.contract_line_ids += lines
elif not any(
@@ -285,7 +253,7 @@ class ContractContract(models.Model):
if self.contract_template_id[field_name]:
self[field_name] = self.contract_template_id[field_name]
@api.onchange('partner_id', 'company_id')
@api.onchange("partner_id", "company_id")
def _onchange_partner_id(self):
partner = (
self.partner_id
@@ -294,21 +262,19 @@ class ContractContract(models.Model):
)
self.pricelist_id = partner.property_product_pricelist.id
self.fiscal_position_id = partner.env[
'account.fiscal.position'
"account.fiscal.position"
].get_fiscal_position(partner.id)
if self.contract_type == 'purchase':
if self.contract_type == "purchase":
self.payment_term_id = partner.property_supplier_payment_term_id
else:
self.payment_term_id = partner.property_payment_term_id
self.invoice_partner_id = self.partner_id.address_get(['invoice'])[
'invoice'
]
self.invoice_partner_id = self.partner_id.address_get(["invoice"])["invoice"]
return {
'domain': {
'invoice_partner_id': [
'|',
('id', 'parent_of', self.partner_id.id),
('id', 'child_of', self.partner_id.id),
"domain": {
"invoice_partner_id": [
"|",
("id", "parent_of", self.partner_id.id),
("id", "child_of", self.partner_id.id),
]
}
}
@@ -316,16 +282,14 @@ class ContractContract(models.Model):
@api.multi
def _convert_contract_lines(self, contract):
self.ensure_one()
new_lines = self.env['contract.line']
contract_line_model = self.env['contract.line']
new_lines = self.env["contract.line"]
contract_line_model = self.env["contract.line"]
for contract_line in contract.contract_line_ids:
vals = contract_line._convert_to_write(contract_line.read()[0])
# Remove template link field
vals.pop('contract_template_id', False)
vals['date_start'] = fields.Date.context_today(contract_line)
vals['recurring_next_date'] = fields.Date.context_today(
contract_line
)
vals.pop("contract_template_id", False)
vals["date_start"] = fields.Date.context_today(contract_line)
vals["recurring_next_date"] = fields.Date.context_today(contract_line)
new_lines += contract_line_model.new(vals)
new_lines._onchange_date_start()
new_lines._onchange_is_auto_renew()
@@ -338,10 +302,10 @@ class ContractContract(models.Model):
journal = (
self.journal_id
if self.journal_id.type == self.contract_type
else self.env['account.journal'].search(
else self.env["account.journal"].search(
[
('type', '=', self.contract_type),
('company_id', '=', self.company_id.id),
("type", "=", self.contract_type),
("company_id", "=", self.company_id.id),
],
limit=1,
)
@@ -349,56 +313,62 @@ class ContractContract(models.Model):
if not journal:
raise ValidationError(
_("Please define a %s journal for the company '%s'.")
% (self.contract_type, self.company_id.name or '')
% (self.contract_type, self.company_id.name or "")
)
invoice_type = 'out_invoice'
if self.contract_type == 'purchase':
invoice_type = 'in_invoice'
vinvoice = self.env['account.invoice'].with_context(
force_company=self.company_id.id,
).new({
'company_id': self.company_id.id,
'partner_id': self.invoice_partner_id.id,
'type': invoice_type,
})
invoice_type = "out_invoice"
if self.contract_type == "purchase":
invoice_type = "in_invoice"
vinvoice = (
self.env["account.invoice"]
.with_context(force_company=self.company_id.id,)
.new(
{
"company_id": self.company_id.id,
"partner_id": self.invoice_partner_id.id,
"type": invoice_type,
}
)
)
vinvoice._onchange_partner_id()
invoice_vals = vinvoice._convert_to_write(vinvoice._cache)
invoice_vals.update({
'name': self.code,
'currency_id': self.currency_id.id,
'date_invoice': date_invoice,
'journal_id': journal.id,
'origin': self.name,
'user_id': self.user_id.id,
})
invoice_vals.update(
{
"name": self.code,
"currency_id": self.currency_id.id,
"date_invoice": date_invoice,
"journal_id": journal.id,
"origin": self.name,
"user_id": self.user_id.id,
}
)
if self.payment_term_id:
invoice_vals['payment_term_id'] = self.payment_term_id.id
invoice_vals["payment_term_id"] = self.payment_term_id.id
if self.fiscal_position_id:
invoice_vals['fiscal_position_id'] = self.fiscal_position_id.id
invoice_vals["fiscal_position_id"] = self.fiscal_position_id.id
return invoice_vals
@api.multi
def action_contract_send(self):
self.ensure_one()
template = self.env.ref('contract.email_contract_template', False)
compose_form = self.env.ref('mail.email_compose_message_wizard_form')
template = self.env.ref("contract.email_contract_template", False)
compose_form = self.env.ref("mail.email_compose_message_wizard_form")
ctx = dict(
default_model='contract.contract',
default_model="contract.contract",
default_res_id=self.id,
default_use_template=bool(template),
default_template_id=template and template.id or False,
default_composition_mode='comment',
default_composition_mode="comment",
)
return {
'name': _('Compose Email'),
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'mail.compose.message',
'views': [(compose_form.id, 'form')],
'view_id': compose_form.id,
'target': 'new',
'context': ctx,
"name": _("Compose Email"),
"type": "ir.actions.act_window",
"view_type": "form",
"view_mode": "form",
"res_model": "mail.compose.message",
"views": [(compose_form.id, "form")],
"view_id": compose_form.id,
"target": "new",
"context": ctx,
}
@api.model
@@ -430,10 +400,8 @@ class ContractContract(models.Model):
final_invoices_values = []
# TODO: This call must be removed in >=13.0
for invoice_values in invoices_values:
final_invoices_values.append(
self._finalize_invoice_values(invoice_values)
)
invoices = self.env['account.invoice'].create(final_invoices_values)
final_invoices_values.append(self._finalize_invoice_values(invoice_values))
invoices = self.env["account.invoice"].create(final_invoices_values)
self._finalize_invoice_creation(invoices)
return invoices
@@ -448,7 +416,7 @@ class ContractContract(models.Model):
domain = []
if not date_ref:
date_ref = fields.Date.context_today(self)
domain.extend([('recurring_next_date', '<=', date_ref)])
domain.extend([("recurring_next_date", "<=", date_ref)])
return domain
@api.multi
@@ -462,16 +430,18 @@ class ContractContract(models.Model):
self.ensure_one()
def can_be_invoiced(l):
return (not l.is_canceled and l.recurring_next_date
and l.recurring_next_date <= date_ref)
return (
not l.is_canceled
and l.recurring_next_date
and l.recurring_next_date <= date_ref
)
lines2invoice = previous = self.env['contract.line']
lines2invoice = previous = self.env["contract.line"]
current_section = current_note = False
for line in self.contract_line_ids:
if line.display_type == 'line_section':
if line.display_type == "line_section":
current_section = line
elif (line.display_type == 'line_note' and
not line.is_recurring_note):
elif line.display_type == "line_note" and not line.is_recurring_note:
if line.note_invoicing_mode == "with_previous_line":
if previous in lines2invoice:
lines2invoice |= line
@@ -511,12 +481,12 @@ class ContractContract(models.Model):
continue
invoice_values = contract._prepare_invoice(date_ref)
for line in contract_lines:
invoice_values.setdefault('invoice_line_ids', [])
invoice_values.setdefault("invoice_line_ids", [])
invoice_line_values = line._prepare_invoice_line(
invoice_values=invoice_values,
)
if invoice_line_values:
invoice_values['invoice_line_ids'].append(
invoice_values["invoice_line_ids"].append(
(0, 0, invoice_line_values)
)
invoices_values.append(invoice_values)
@@ -533,9 +503,9 @@ class ContractContract(models.Model):
if invoice:
self.message_post(
body=_(
'Contract manually invoiced: '
"Contract manually invoiced: "
'<a href="#" data-oe-model="%s" data-oe-id="%s">Invoice'
'</a>'
"</a>"
)
% (invoice._name, invoice.id)
)
@@ -566,13 +536,13 @@ class ContractContract(models.Model):
self.ensure_one()
context = {"default_contract_id": self.id}
return {
'type': 'ir.actions.act_window',
'name': _('Terminate Contract'),
'res_model': 'contract.contract.terminate',
'view_type': 'form',
'view_mode': 'form',
'target': 'new',
'context': context,
"type": "ir.actions.act_window",
"name": _("Terminate Contract"),
"res_model": "contract.contract.terminate",
"view_type": "form",
"view_mode": "form",
"target": "new",
"context": context,
}
@api.multi
@@ -581,22 +551,26 @@ class ContractContract(models.Model):
):
self.ensure_one()
if not self.env.user.has_group("contract.can_terminate_contract"):
raise UserError(_('You are not allowed to terminate contracts.'))
self.contract_line_ids.filtered('is_stop_allowed').stop(terminate_date)
self.write({
'is_terminated': True,
'terminate_reason_id': terminate_reason_id.id,
'terminate_comment': terminate_comment,
'terminate_date': terminate_date,
})
raise UserError(_("You are not allowed to terminate contracts."))
self.contract_line_ids.filtered("is_stop_allowed").stop(terminate_date)
self.write(
{
"is_terminated": True,
"terminate_reason_id": terminate_reason_id.id,
"terminate_comment": terminate_comment,
"terminate_date": terminate_date,
}
)
return True
@api.multi
def action_cancel_contract_termination(self):
self.ensure_one()
self.write({
'is_terminated': False,
'terminate_reason_id': False,
'terminate_comment': False,
'terminate_date': False,
})
self.write(
{
"is_terminated": False,
"terminate_reason_id": False,
"terminate_comment": False,
"terminate_date": False,
}
)

File diff suppressed because it is too large Load Diff

View File

@@ -3,17 +3,18 @@
import itertools
from collections import namedtuple
from odoo.fields import Date
Criteria = namedtuple(
'Criteria',
"Criteria",
[
'when', # Contract line relatively to today (BEFORE, IN, AFTER)
'has_date_end', # Is date_end set on contract line (bool)
'has_last_date_invoiced', # Is last_date_invoiced set on contract line
'is_auto_renew', # Is is_auto_renew set on contract line (bool)
'has_successor', # Is contract line has_successor (bool)
'predecessor_has_successor',
"when", # Contract line relatively to today (BEFORE, IN, AFTER)
"has_date_end", # Is date_end set on contract line (bool)
"has_last_date_invoiced", # Is last_date_invoiced set on contract line
"is_auto_renew", # Is is_auto_renew set on contract line (bool)
"has_successor", # Is contract line has_successor (bool)
"predecessor_has_successor",
# Is contract line predecessor has successor (bool)
# In almost of the cases
# contract_line.predecessor.successor == contract_line
@@ -23,12 +24,11 @@ Criteria = namedtuple(
# If contract_line.predecessor.successor != False
# and contract_line is canceled, we don't allow uncancel
# else we re-link contract_line and its predecessor
'canceled', # Is contract line canceled (bool)
"canceled", # Is contract line canceled (bool)
],
)
Allowed = namedtuple(
'Allowed',
['plan_successor', 'stop_plan_successor', 'stop', 'cancel', 'uncancel'],
"Allowed", ["plan_successor", "stop_plan_successor", "stop", "cancel", "uncancel"],
)
@@ -36,8 +36,8 @@ def _expand_none(criteria):
variations = []
for attribute, value in criteria._asdict().items():
if value is None:
if attribute == 'when':
variations.append(['BEFORE', 'IN', 'AFTER'])
if attribute == "when":
variations.append(["BEFORE", "IN", "AFTER"])
else:
variations.append([True, False])
else:
@@ -53,7 +53,7 @@ def _add(matrix, criteria, allowed):
CRITERIA_ALLOWED_DICT = {
Criteria(
when='BEFORE',
when="BEFORE",
has_date_end=True,
has_last_date_invoiced=False,
is_auto_renew=True,
@@ -68,7 +68,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='BEFORE',
when="BEFORE",
has_date_end=True,
has_last_date_invoiced=False,
is_auto_renew=False,
@@ -83,7 +83,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='BEFORE',
when="BEFORE",
has_date_end=True,
has_last_date_invoiced=False,
is_auto_renew=False,
@@ -98,7 +98,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='BEFORE',
when="BEFORE",
has_date_end=False,
has_last_date_invoiced=False,
is_auto_renew=False,
@@ -113,7 +113,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='IN',
when="IN",
has_date_end=True,
has_last_date_invoiced=False,
is_auto_renew=True,
@@ -128,7 +128,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='IN',
when="IN",
has_date_end=True,
has_last_date_invoiced=False,
is_auto_renew=False,
@@ -143,7 +143,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='IN',
when="IN",
has_date_end=True,
has_last_date_invoiced=False,
is_auto_renew=False,
@@ -158,7 +158,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='IN',
when="IN",
has_date_end=False,
has_last_date_invoiced=False,
is_auto_renew=False,
@@ -173,7 +173,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='BEFORE',
when="BEFORE",
has_date_end=True,
has_last_date_invoiced=True,
is_auto_renew=True,
@@ -188,7 +188,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='BEFORE',
when="BEFORE",
has_date_end=True,
has_last_date_invoiced=True,
is_auto_renew=False,
@@ -203,7 +203,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='BEFORE',
when="BEFORE",
has_date_end=True,
has_last_date_invoiced=True,
is_auto_renew=False,
@@ -218,7 +218,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='BEFORE',
when="BEFORE",
has_date_end=False,
has_last_date_invoiced=True,
is_auto_renew=False,
@@ -233,7 +233,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='IN',
when="IN",
has_date_end=True,
has_last_date_invoiced=True,
is_auto_renew=True,
@@ -248,7 +248,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='IN',
when="IN",
has_date_end=True,
has_last_date_invoiced=True,
is_auto_renew=False,
@@ -263,7 +263,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='IN',
when="IN",
has_date_end=True,
has_last_date_invoiced=True,
is_auto_renew=False,
@@ -278,7 +278,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='IN',
when="IN",
has_date_end=False,
has_last_date_invoiced=True,
is_auto_renew=False,
@@ -293,7 +293,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='AFTER',
when="AFTER",
has_date_end=True,
has_last_date_invoiced=None,
is_auto_renew=True,
@@ -308,7 +308,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='AFTER',
when="AFTER",
has_date_end=True,
has_last_date_invoiced=None,
is_auto_renew=False,
@@ -323,7 +323,7 @@ CRITERIA_ALLOWED_DICT = {
uncancel=False,
),
Criteria(
when='AFTER',
when="AFTER",
has_date_end=True,
has_last_date_invoiced=None,
is_auto_renew=False,
@@ -377,10 +377,10 @@ for c in CRITERIA_ALLOWED_DICT:
def compute_when(date_start, date_end):
today = Date.today()
if today < date_start:
return 'BEFORE'
return "BEFORE"
if date_end and today > date_end:
return 'AFTER'
return 'IN'
return "AFTER"
return "IN"
def compute_criteria(

View File

@@ -6,12 +6,10 @@ from odoo import fields, models
class ContractTag(models.Model):
_name = 'contract.tag'
_description = 'Contract Tag'
_name = "contract.tag"
_description = "Contract Tag"
name = fields.Char(requirment=True)
company_id = fields.Many2one(
'res.company',
string='Company',
default=lambda self: self.env.user.company_id,
"res.company", string="Company", default=lambda self: self.env.user.company_id,
)

View File

@@ -10,13 +10,13 @@ from odoo import fields, models
class ContractTemplate(models.Model):
_name = 'contract.template'
_inherit = 'contract.abstract.contract'
_name = "contract.template"
_inherit = "contract.abstract.contract"
_description = "Contract Template"
contract_line_ids = fields.One2many(
comodel_name='contract.template.line',
inverse_name='contract_id',
comodel_name="contract.template.line",
inverse_name="contract_id",
copy=True,
string='Contract template lines',
string="Contract template lines",
)

View File

@@ -10,15 +10,15 @@ from odoo import fields, models
class ContractTemplateLine(models.Model):
_name = 'contract.template.line'
_inherit = 'contract.abstract.contract.line'
_name = "contract.template.line"
_inherit = "contract.abstract.contract.line"
_description = "Contract Template Line"
_order = "sequence,id"
contract_id = fields.Many2one(
string='Contract',
comodel_name='contract.template',
string="Contract",
comodel_name="contract.template",
required=True,
ondelete='cascade',
oldname='analytic_account_id',
ondelete="cascade",
oldname="analytic_account_id",
)

View File

@@ -6,8 +6,8 @@ from odoo import fields, models
class ContractTerminateReason(models.Model):
_name = 'contract.terminate.reason'
_description = 'Contract Termination Reason'
_name = "contract.terminate.reason"
_description = "Contract Termination Reason"
name = fields.Char(required=True)
terminate_comment_required = fields.Boolean(

View File

@@ -13,7 +13,9 @@ class IrUiView(models.Model):
# TODO Delete this method in v13; it's upstream there
result = super()._prepare_qcontext()
if self.env.context.get("allowed_company_ids"):
result["res_company"] = self.env["res.company"].browse(
self.env.context["allowed_company_ids"][0]
).sudo()
result["res_company"] = (
self.env["res.company"]
.browse(self.env.context["allowed_company_ids"][0])
.sudo()
)
return result

View File

@@ -6,7 +6,7 @@ from odoo import fields, models
class ResCompany(models.Model):
_inherit = 'res.company'
_inherit = "res.company"
create_new_line_at_contract_line_renew = fields.Boolean(
string="Create New Line At Contract Line Renew",

View File

@@ -6,7 +6,7 @@ from odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
_inherit = "res.config.settings"
create_new_line_at_contract_line_renew = fields.Boolean(
related="company_id.create_new_line_at_contract_line_renew",

View File

@@ -5,45 +5,49 @@ from odoo import fields, models
class ResPartner(models.Model):
_inherit = 'res.partner'
_inherit = "res.partner"
sale_contract_count = fields.Integer(
string='Sale Contracts',
compute='_compute_contract_count',
string="Sale Contracts", compute="_compute_contract_count",
)
purchase_contract_count = fields.Integer(
string='Purchase Contracts',
compute='_compute_contract_count',
string="Purchase Contracts", compute="_compute_contract_count",
)
contract_ids = fields.One2many(
comodel_name='contract.contract',
inverse='partner_id',
string="Contracts",
comodel_name="contract.contract", inverse="partner_id", string="Contracts",
)
def _compute_contract_count(self):
contract_model = self.env['contract.contract']
fetch_data = contract_model.read_group([
('partner_id', 'child_of', self.ids)],
['partner_id', 'contract_type'], ['partner_id', 'contract_type'],
lazy=False)
result = [[data['partner_id'][0], data['contract_type'],
data['__count']] for data in fetch_data]
contract_model = self.env["contract.contract"]
fetch_data = contract_model.read_group(
[("partner_id", "child_of", self.ids)],
["partner_id", "contract_type"],
["partner_id", "contract_type"],
lazy=False,
)
result = [
[data["partner_id"][0], data["contract_type"], data["__count"]]
for data in fetch_data
]
for partner in self:
partner_child_ids = partner.child_ids.ids + partner.ids
partner.sale_contract_count = sum([
r[2] for r in result
if r[0] in partner_child_ids and r[1] == 'sale'])
partner.purchase_contract_count = sum([
r[2] for r in result
if r[0] in partner_child_ids and r[1] == 'purchase'])
partner.sale_contract_count = sum(
[r[2] for r in result if r[0] in partner_child_ids and r[1] == "sale"]
)
partner.purchase_contract_count = sum(
[
r[2]
for r in result
if r[0] in partner_child_ids and r[1] == "purchase"
]
)
def act_show_contract(self):
""" This opens contract view
@return: the contract view
"""
self.ensure_one()
contract_type = self._context.get('contract_type')
contract_type = self._context.get("contract_type")
res = self._get_act_window_contract_xml(contract_type)
res.update(
@@ -57,11 +61,11 @@ class ResPartner(models.Model):
return res
def _get_act_window_contract_xml(self, contract_type):
if contract_type == 'purchase':
return self.env['ir.actions.act_window'].for_xml_id(
'contract', 'action_supplier_contract'
if contract_type == "purchase":
return self.env["ir.actions.act_window"].for_xml_id(
"contract", "action_supplier_contract"
)
else:
return self.env['ir.actions.act_window'].for_xml_id(
'contract', 'action_customer_contract'
return self.env["ir.actions.act_window"].for_xml_id(
"contract", "action_customer_contract"
)