Files
enterprise-addons/account_intrastat/models/product.py
T

149 lines
6.9 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo.addons.account_intrastat.models.account_intrastat_code import SUPPLEMENTARY_UNITS
from odoo.exceptions import ValidationError
class ProductTemplate(models.Model):
_inherit = 'product.template'
intrastat_code_id = fields.Many2one(
'account.intrastat.code',
compute='_compute_intrastat_values',
inverse='_inverse_intrastat_code_id',
string='Commodity Code',
readonly=False,
)
intrastat_supplementary_unit = fields.Selection(selection=SUPPLEMENTARY_UNITS, compute='_compute_intrastat_values')
intrastat_supplementary_unit_amount = fields.Float(
compute='_compute_intrastat_values',
inverse='_inverse_intrastat_supplementary_unit_amount',
help='The number of supplementary units per product quantity.',
readonly=False,
)
intrastat_origin_country_id = fields.Many2one(
'res.country',
compute='_compute_intrastat_values',
inverse='_inverse_intrastat_origin_country_id',
string='Country of Origin',
readonly=False,
)
# remove in master
valid_intrastat_code_ids = fields.Many2many(
string="Intrastat Code IDs",
comodel_name='account.intrastat.code',
compute="_compute_valid_intrastat_code_ids",
)
intrastat_code_domain = fields.Char(
compute='_compute_intrastat_code_domain',
)
account_fiscal_country_group_codes = fields.Json(related="company_id.account_fiscal_country_group_codes")
@api.depends('type')
def _compute_intrastat_code_domain(self):
"""Dynamically compute the domain for intrastat_code_id."""
country_id = self.env.company.account_fiscal_country_id.id
service_codes_available = self.env["account.intrastat.code"].search_count(
[
("country_id", "in", (country_id, False)),
("type", "=", "service"),
],
limit=1,
)
for product in self:
code_type = 'service' if service_codes_available and product.type == 'service' else 'commodity'
product.intrastat_code_domain = str([
("country_id", "in", (country_id, False)),
("type", "=", code_type),
])
@api.depends('product_variant_ids')
def _compute_intrastat_values(self):
for product_template in self:
variant = product_template.product_variant_ids[:1]
product_template.intrastat_code_id = variant.intrastat_code_id
product_template.intrastat_supplementary_unit = variant.intrastat_code_id.supplementary_unit
product_template.intrastat_supplementary_unit_amount = variant.intrastat_supplementary_unit_amount
product_template.intrastat_origin_country_id = variant.intrastat_origin_country_id
# remove in master
@api.depends('type')
def _compute_valid_intrastat_code_ids(self):
valid_intrastat_code = dict(self.env['account.intrastat.code']._read_group(
domain=[('country_id', 'in', (self.env.company.account_fiscal_country_id.id, False))],
groupby=['type'],
aggregates=['id:recordset'],
))
for product in self:
if 'service' in valid_intrastat_code and product.type == 'service':
valid_codes = valid_intrastat_code['service']
else:
valid_codes = valid_intrastat_code['commodity']
product.valid_intrastat_code_ids = valid_codes
@api.constrains('product_variant_ids', 'intrastat_code_id')
def _check_variant_for_intrastat(self):
for product_template in self:
if (not product_template.product_variant_ids and product_template.intrastat_code_id and
any(attribute.create_variant == 'dynamic' for attribute in product_template.attribute_line_ids.attribute_id)):
raise ValidationError(_("The product template has no products/variants. At least one variant is required to set the Intrastat values."))
@api.onchange('intrastat_code_id')
def _onchange_intrastat_code_id(self):
return self._check_active_intrastat_code()
def _check_active_intrastat_code(self):
expired = self.intrastat_code_id.expiry_date and fields.Date.context_today(self) >= self.intrastat_code_id.expiry_date
not_yet_active = self.intrastat_code_id.start_date and fields.Date.context_today(self) < self.intrastat_code_id.start_date
if expired or not_yet_active:
return {
'warning': {
'title': _("Invalid Intrastat Code"),
'message': _("Note that the selected commodity code is invalid based on its start or expiry date. You can still select it.")
}
}
def _inverse_intrastat_code_id(self):
for product_template in self:
product_template.product_variant_ids.intrastat_code_id = product_template.intrastat_code_id
def _inverse_intrastat_supplementary_unit_amount(self):
for product_template in self:
product_template.product_variant_ids.intrastat_supplementary_unit_amount = product_template.intrastat_supplementary_unit_amount
def _inverse_intrastat_origin_country_id(self):
for product_template in self:
product_template.product_variant_ids.intrastat_origin_country_id = product_template.intrastat_origin_country_id
def _get_related_fields_variant_template(self):
fields = super()._get_related_fields_variant_template()
fields += ['intrastat_code_id', 'intrastat_origin_country_id', 'intrastat_supplementary_unit', 'intrastat_supplementary_unit_amount']
return fields
class ProductProduct(models.Model):
_inherit = 'product.product'
intrastat_code_id = fields.Many2one(comodel_name='account.intrastat.code')
# The supplementary unit of the current commodity code
intrastat_supplementary_unit = fields.Selection(related='intrastat_code_id.supplementary_unit')
# The ratio of product to the number of supplementary units
intrastat_supplementary_unit_amount = fields.Float(
string='Supplementary Units',
help='The number of supplementary units per product quantity.',
)
intrastat_origin_country_id = fields.Many2one('res.country', string='Country of Origin')
@api.depends('intrastat_supplementary_unit')
def _compute_intrastat_supplementary_unit_amount(self):
""" In the case when the product has no supplementary unit (i.e. we are using weight) the supplementary unit amount is set to 0 """
for product in self:
if not product.intrastat_supplementary_unit:
product.intrastat_supplementary_unit_amount = 0
@api.onchange('intrastat_code_id')
def _onchange_intrastat_code_id(self):
return self.product_tmpl_id._check_active_intrastat_code()