[MIG] intrastat_product: Migration to 13.0

This commit is contained in:
Luc De Meyer
2020-02-26 22:16:50 +01:00
parent ba3cf5199b
commit 3da824f9c4
18 changed files with 941 additions and 817 deletions

View File

@@ -17,7 +17,7 @@
<record id="shipping_costs_exclude" model="product.product"> <record id="shipping_costs_exclude" model="product.product">
<field name="name">Shipping costs</field> <field name="name">Shipping costs</field>
<field name="default_code">SHIP</field> <field name="default_code">SHIP_S</field>
<field name="type">service</field> <field name="type">service</field>
<field name="categ_id" ref="product.product_category_all"/> <field name="categ_id" ref="product.product_category_all"/>
<field name="list_price">30</field> <field name="list_price">30</field>

View File

@@ -6,37 +6,36 @@
# @author Kumar Aberer <kumar.aberer@braintec-group.com> # @author Kumar Aberer <kumar.aberer@braintec-group.com>
{ {
'name': 'Intrastat Product', "name": "Intrastat Product",
'version': '12.0.1.0.0', "version": "13.0.1.0.0",
'category': 'Intrastat', "category": "Intrastat",
'license': 'AGPL-3', "license": "AGPL-3",
'summary': 'Base module for Intrastat Product', "summary": "Base module for Intrastat Product",
'author': 'brain-tec AG, Akretion, Noviat, ' "author": "brain-tec AG, Akretion, Noviat, " "Odoo Community Association (OCA)",
'Odoo Community Association (OCA)', "depends": [
'depends': [ "intrastat_base",
'intrastat_base', "product_harmonized_system",
'product_harmonized_system', "sale_stock",
'sale_stock', "purchase_stock",
'purchase_stock', "report_xlsx_helper",
'report_xlsx_helper',
], ],
'excludes': ['account_intrastat'], "excludes": ["account_intrastat"],
'data': [ "data": [
'views/hs_code.xml', "views/hs_code.xml",
'views/intrastat_region.xml', "views/intrastat_region.xml",
'views/intrastat_unit.xml', "views/intrastat_unit.xml",
'views/intrastat_transaction.xml', "views/intrastat_transaction.xml",
'views/intrastat_transport_mode.xml', "views/intrastat_transport_mode.xml",
'views/intrastat_product_declaration.xml', "views/intrastat_product_declaration.xml",
'views/res_config_settings.xml', "views/res_config_settings.xml",
'views/account_invoice.xml', "views/account_move.xml",
'views/sale_order.xml', "views/sale_order.xml",
'views/stock_warehouse.xml', "views/stock_warehouse.xml",
'security/intrastat_security.xml', "security/intrastat_security.xml",
'security/ir.model.access.csv', "security/ir.model.access.csv",
'data/intrastat_transport_mode.xml', "data/intrastat_transport_mode.xml",
'data/intrastat_unit.xml', "data/intrastat_unit.xml",
], ],
'demo': ['demo/intrastat_demo.xml'], "demo": ["demo/intrastat_demo.xml"],
'installable': True, "installable": True,
} }

View File

@@ -1,6 +1,6 @@
from . import res_company from . import res_company
from . import res_config_settings from . import res_config_settings
from . import account_invoice from . import account_move
from . import hs_code from . import hs_code
from . import intrastat_product_declaration from . import intrastat_product_declaration
from . import intrastat_region from . import intrastat_region

View File

@@ -6,44 +6,51 @@
from odoo import api, fields, models from odoo import api, fields, models
class AccountInvoice(models.Model): class AccountMove(models.Model):
_inherit = 'account.invoice' _inherit = "account.move"
intrastat_transaction_id = fields.Many2one( intrastat_transaction_id = fields.Many2one(
comodel_name='intrastat.transaction', comodel_name="intrastat.transaction",
string='Intrastat Transaction Type', string="Intrastat Transaction Type",
ondelete='restrict', track_visibility='onchange', ondelete="restrict",
help="Intrastat nature of transaction") track_visibility="onchange",
help="Intrastat nature of transaction",
)
intrastat_transport_id = fields.Many2one( intrastat_transport_id = fields.Many2one(
comodel_name='intrastat.transport_mode', comodel_name="intrastat.transport_mode",
string='Intrastat Transport Mode', string="Intrastat Transport Mode",
ondelete='restrict') ondelete="restrict",
)
src_dest_country_id = fields.Many2one( src_dest_country_id = fields.Many2one(
comodel_name='res.country', comodel_name="res.country",
string='Origin/Destination Country', string="Origin/Destination Country",
compute='_compute_intrastat_country', compute="_compute_intrastat_country",
store=True, compute_sudo=True, store=True,
help="Destination country for dispatches. Origin country for " compute_sudo=True,
"arrivals.") help="Destination country for dispatches. Origin country for " "arrivals.",
)
intrastat_country = fields.Boolean( intrastat_country = fields.Boolean(
compute='_compute_intrastat_country', string='Intrastat Country', compute="_compute_intrastat_country",
store=True, compute_sudo=True) string="Intrastat Country",
store=True,
compute_sudo=True,
)
src_dest_region_id = fields.Many2one( src_dest_region_id = fields.Many2one(
comodel_name='intrastat.region', comodel_name="intrastat.region",
string='Origin/Destination Region', string="Origin/Destination Region",
default=lambda self: self._default_src_dest_region_id(), default=lambda self: self._default_src_dest_region_id(),
help="Origin region for dispatches, destination region for " help="Origin region for dispatches, destination region for "
"arrivals. This field is used for the Intrastat Declaration.", "arrivals. This field is used for the Intrastat Declaration.",
ondelete='restrict') ondelete="restrict",
)
intrastat = fields.Char( intrastat = fields.Char(
string='Intrastat Declaration', string="Intrastat Declaration", related="company_id.intrastat"
related='company_id.intrastat') )
@api.depends('partner_shipping_id.country_id', 'partner_id.country_id') @api.depends("partner_shipping_id.country_id", "partner_id.country_id")
def _compute_intrastat_country(self): def _compute_intrastat_country(self):
for inv in self: for inv in self:
country = inv.partner_shipping_id.country_id\ country = inv.partner_shipping_id.country_id or inv.partner_id.country_id
or inv.partner_id.country_id
if not country: if not country:
country = inv.company_id.country_id country = inv.company_id.country_id
inv.src_dest_country_id = country.id inv.src_dest_country_id = country.id
@@ -51,19 +58,19 @@ class AccountInvoice(models.Model):
@api.model @api.model
def _default_src_dest_region_id(self): def _default_src_dest_region_id(self):
rco = self.env['res.company'] rco = self.env["res.company"]
company = rco._company_default_get() company = rco._company_default_get()
return company.intrastat_region_id return company.intrastat_region_id
class AccountInvoiceLine(models.Model): class AccountMoveLine(models.Model):
_inherit = 'account.invoice.line' _inherit = "account.move.line"
hs_code_id = fields.Many2one( hs_code_id = fields.Many2one(
comodel_name='hs.code', comodel_name="hs.code", string="Intrastat Code", ondelete="restrict"
string='Intrastat Code', ondelete='restrict') )
@api.onchange('product_id') @api.onchange("product_id")
def intrastat_product_id_change(self): def intrastat_product_id_change(self):
if self.product_id: if self.product_id:
hs_code = self.product_id.get_hs_code_recursively() hs_code = self.product_id.get_hs_code_recursively()

View File

@@ -3,7 +3,7 @@
# @author Alexis de Lattre <alexis.delattre@akretion.com> # @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.com> # @author Luc de Meyer <info@noviat.com>
from odoo import api, fields, models, _ from odoo import _, api, fields, models
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
@@ -11,20 +11,26 @@ class HSCode(models.Model):
_inherit = "hs.code" _inherit = "hs.code"
intrastat_unit_id = fields.Many2one( intrastat_unit_id = fields.Many2one(
comodel_name='intrastat.unit', comodel_name="intrastat.unit", string="Intrastat Supplementary Unit"
string='Intrastat Supplementary Unit') )
@api.constrains('local_code') @api.constrains("local_code")
def _hs_code(self): def _hs_code(self):
if self.company_id.country_id.intrastat: if self.company_id.country_id.intrastat:
if not self.local_code.isdigit(): if not self.local_code.isdigit():
raise ValidationError(_( raise ValidationError(
"Intrastat Codes should only contain digits. " _(
"This is not the case for code '%s'.") "Intrastat Codes should only contain digits. "
% self.local_code) "This is not the case for code '%s'."
)
% self.local_code
)
if len(self.local_code) != 8: if len(self.local_code) != 8:
raise ValidationError(_( raise ValidationError(
"Intrastat Codes should " _(
"contain 8 digits. This is not the case for " "Intrastat Codes should "
"Intrastat Code '%s' which has %d digits.") "contain 8 digits. This is not the case for "
% (self.local_code, len(self.local_code))) "Intrastat Code '%s' which has %d digits."
)
% (self.local_code, len(self.local_code))
)

File diff suppressed because it is too large Load Diff

View File

@@ -5,19 +5,24 @@ from odoo import fields, models
class IntrastatRegion(models.Model): class IntrastatRegion(models.Model):
_name = 'intrastat.region' _name = "intrastat.region"
_description = "Intrastat Region" _description = "Intrastat Region"
_sql_constraints = [ _sql_constraints = [
('intrastat_region_code_unique', (
'UNIQUE(code, country_id)', # TODO add company_id ? "intrastat_region_code_unique",
'Code must be unique.')] "UNIQUE(code, country_id)", # TODO add company_id ?
"Code must be unique.",
)
]
code = fields.Char(string='Code', required=True) code = fields.Char(string="Code", required=True)
country_id = fields.Many2one( country_id = fields.Many2one(
comodel_name='res.country', comodel_name="res.country", string="Country", required=True
string='Country', required=True) )
name = fields.Char(string='Name', translate=True) name = fields.Char(string="Name", translate=True)
description = fields.Char(string='Description') description = fields.Char(string="Description")
company_id = fields.Many2one( company_id = fields.Many2one(
comodel_name='res.company', string='Company', comodel_name="res.company",
default=lambda self: self.env['res.company']._company_default_get()) string="Company",
default=lambda self: self.env["res.company"]._company_default_get(),
)

View File

@@ -7,27 +7,32 @@ from odoo import api, fields, models
class IntrastatTransaction(models.Model): class IntrastatTransaction(models.Model):
_name = 'intrastat.transaction' _name = "intrastat.transaction"
_description = "Intrastat Transaction" _description = "Intrastat Transaction"
_order = 'code' _order = "code"
_sql_constraints = [( _sql_constraints = [
'intrastat_transaction_code_unique', (
'UNIQUE(code, company_id)', "intrastat_transaction_code_unique",
'Code must be unique.')] "UNIQUE(code, company_id)",
"Code must be unique.",
)
]
code = fields.Char(string='Code', required=True) code = fields.Char(string="Code", required=True)
description = fields.Text(string='Description') description = fields.Text(string="Description")
company_id = fields.Many2one( company_id = fields.Many2one(
comodel_name='res.company', string='Company', comodel_name="res.company",
default=lambda self: self.env['res.company']._company_default_get()) string="Company",
default=lambda self: self.env["res.company"]._company_default_get(),
)
@api.depends('code', 'description') @api.depends("code", "description")
def name_get(self): def name_get(self):
res = [] res = []
for this in self: for this in self:
name = this.code name = this.code
if this.description: if this.description:
name += ' ' + this.description name += " " + this.description
name = len(name) > 55 and name[:55] + '...' or name name = len(name) > 55 and name[:55] + "..." or name
res.append((this.id, name)) res.append((this.id, name))
return res return res

View File

@@ -7,22 +7,21 @@ from odoo import api, fields, models
class IntrastatTransportMode(models.Model): class IntrastatTransportMode(models.Model):
_name = 'intrastat.transport_mode' _name = "intrastat.transport_mode"
_description = "Intrastat Transport Mode" _description = "Intrastat Transport Mode"
_order = 'code' _order = "code"
_sql_constraints = [( _sql_constraints = [
'intrastat_transport_code_unique', ("intrastat_transport_code_unique", "UNIQUE(code)", "Code must be unique.")
'UNIQUE(code)', ]
'Code must be unique.')]
code = fields.Char(string='Code', required=True) code = fields.Char(string="Code", required=True)
name = fields.Char(string='Name', required=True, translate=True) name = fields.Char(string="Name", required=True, translate=True)
description = fields.Char(string='Description', translate=True) description = fields.Char(string="Description", translate=True)
@api.depends('name', 'code') @api.depends("name", "code")
def name_get(self): def name_get(self):
res = [] res = []
for mode in self: for mode in self:
name = '%s. %s' % (mode.code, mode.name) name = "{}. {}".format(mode.code, mode.name)
res.append((mode.id, name)) res.append((mode.id, name))
return res return res

View File

@@ -7,13 +7,15 @@ from odoo import fields, models
class IntrastatUnit(models.Model): class IntrastatUnit(models.Model):
_name = 'intrastat.unit' _name = "intrastat.unit"
_description = 'Intrastat Supplementary Units' _description = "Intrastat Supplementary Units"
name = fields.Char(string='Name', required=True) name = fields.Char(string="Name", required=True)
description = fields.Char(string='Description', required=True) description = fields.Char(string="Description", required=True)
uom_id = fields.Many2one( uom_id = fields.Many2one(
comodel_name='uom.uom', string='Regular UoM', comodel_name="uom.uom",
string="Regular UoM",
help="Select the regular Unit of Measure of Odoo that corresponds " help="Select the regular Unit of Measure of Odoo that corresponds "
"to this Intrastat Supplementary Unit.") "to this Intrastat Supplementary Unit.",
)
active = fields.Boolean(default=True) active = fields.Boolean(default=True)

View File

@@ -7,66 +7,89 @@ from odoo import api, fields, models
class ResCompany(models.Model): class ResCompany(models.Model):
_inherit = 'res.company' _inherit = "res.company"
intrastat_incoterm_id = fields.Many2one( intrastat_incoterm_id = fields.Many2one(
comodel_name='account.incoterms', comodel_name="account.incoterms",
string='Default Incoterm for Intrastat', string="Default Incoterm for Intrastat",
help="International Commercial Terms are a series of " help="International Commercial Terms are a series of "
"predefined commercial terms used in international " "predefined commercial terms used in international "
"transactions.") "transactions.",
)
intrastat_arrivals = fields.Selection( intrastat_arrivals = fields.Selection(
selection='_intrastat_arrivals', string='Arrivals', selection="_intrastat_arrivals",
default='extended', required=True) string="Arrivals",
default="extended",
required=True,
)
intrastat_dispatches = fields.Selection( intrastat_dispatches = fields.Selection(
selection='_intrastat_dispatches', string='Dispatches', selection="_intrastat_dispatches",
default='extended', required=True) string="Dispatches",
default="extended",
required=True,
)
intrastat_transport_id = fields.Many2one( intrastat_transport_id = fields.Many2one(
comodel_name='intrastat.transport_mode', comodel_name="intrastat.transport_mode",
string='Default Transport Mode', ondelete='restrict') string="Default Transport Mode",
ondelete="restrict",
)
intrastat = fields.Char( intrastat = fields.Char(
string='Intrastat Declaration', store=True, readonly=True, string="Intrastat Declaration",
compute='_compute_intrastat') store=True,
readonly=True,
compute="_compute_intrastat",
)
intrastat_region_id = fields.Many2one( intrastat_region_id = fields.Many2one(
comodel_name='intrastat.region', comodel_name="intrastat.region", string="Default Intrastat Region"
string='Default Intrastat Region') )
intrastat_transaction_out_invoice = fields.Many2one( intrastat_transaction_out_invoice = fields.Many2one(
comodel_name='intrastat.transaction', comodel_name="intrastat.transaction",
string='Default Intrastat Transaction For Customer Invoice') string="Default Intrastat Transaction For Customer Invoice",
)
intrastat_transaction_out_refund = fields.Many2one( intrastat_transaction_out_refund = fields.Many2one(
comodel_name='intrastat.transaction', comodel_name="intrastat.transaction",
string='Default Intrastat Transaction for Customer Refunds') string="Default Intrastat Transaction for Customer Refunds",
)
intrastat_transaction_in_invoice = fields.Many2one( intrastat_transaction_in_invoice = fields.Many2one(
comodel_name='intrastat.transaction', comodel_name="intrastat.transaction",
string='Default Intrastat Transaction For Supplier Invoices') string="Default Intrastat Transaction For Supplier Invoices",
)
intrastat_transaction_in_refund = fields.Many2one( intrastat_transaction_in_refund = fields.Many2one(
comodel_name='intrastat.transaction', comodel_name="intrastat.transaction",
string='Default Intrastat Transaction For Supplier Refunds') string="Default Intrastat Transaction For Supplier Refunds",
)
intrastat_accessory_costs = fields.Boolean( intrastat_accessory_costs = fields.Boolean(
string='Include Accessory Costs in Fiscal Value of Product') string="Include Accessory Costs in Fiscal Value of Product"
)
@api.model @api.model
def _intrastat_arrivals(self): def _intrastat_arrivals(self):
return [ return [
('exempt', 'Exempt'), ("exempt", "Exempt"),
('standard', 'Standard'), ("standard", "Standard"),
('extended', 'Extended')] ("extended", "Extended"),
]
@api.model @api.model
def _intrastat_dispatches(self): def _intrastat_dispatches(self):
return [ return [
('exempt', 'Exempt'), ("exempt", "Exempt"),
('standard', 'Standard'), ("standard", "Standard"),
('extended', 'Extended')] ("extended", "Extended"),
]
@api.depends('intrastat_arrivals', 'intrastat_dispatches') @api.depends("intrastat_arrivals", "intrastat_dispatches")
def _compute_intrastat(self): def _compute_intrastat(self):
for this in self: for this in self:
if this.intrastat_arrivals == 'exempt' \ if (
and this.intrastat_dispatches == 'exempt': this.intrastat_arrivals == "exempt"
this.intrastat = 'exempt' and this.intrastat_dispatches == "exempt"
elif this.intrastat_arrivals == 'extended' \ ):
or this.intrastat_dispatches == 'extended': this.intrastat = "exempt"
this.intrastat = 'extended' elif (
this.intrastat_arrivals == "extended"
or this.intrastat_dispatches == "extended"
):
this.intrastat = "extended"
else: else:
this.intrastat = 'standard' this.intrastat = "standard"

View File

@@ -6,28 +6,38 @@ from odoo import fields, models
class ResConfigSettings(models.TransientModel): class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings' _inherit = "res.config.settings"
intrastat_incoterm_id = fields.Many2one( intrastat_incoterm_id = fields.Many2one(
related='company_id.intrastat_incoterm_id', readonly=False) related="company_id.intrastat_incoterm_id", readonly=False
)
intrastat_arrivals = fields.Selection( intrastat_arrivals = fields.Selection(
related='company_id.intrastat_arrivals', readonly=False) related="company_id.intrastat_arrivals", readonly=False
)
intrastat_dispatches = fields.Selection( intrastat_dispatches = fields.Selection(
related='company_id.intrastat_dispatches', readonly=False) related="company_id.intrastat_dispatches", readonly=False
intrastat = fields.Char(related='company_id.intrastat') )
intrastat = fields.Char(related="company_id.intrastat")
intrastat_transport_id = fields.Many2one( intrastat_transport_id = fields.Many2one(
related='company_id.intrastat_transport_id', readonly=False) related="company_id.intrastat_transport_id", readonly=False
)
intrastat_region_id = fields.Many2one( intrastat_region_id = fields.Many2one(
related='company_id.intrastat_region_id', readonly=False) related="company_id.intrastat_region_id", readonly=False
)
intrastat_transaction_out_invoice = fields.Many2one( intrastat_transaction_out_invoice = fields.Many2one(
related='company_id.intrastat_transaction_out_invoice', readonly=False) related="company_id.intrastat_transaction_out_invoice", readonly=False
)
intrastat_transaction_out_refund = fields.Many2one( intrastat_transaction_out_refund = fields.Many2one(
related='company_id.intrastat_transaction_out_refund', readonly=False) related="company_id.intrastat_transaction_out_refund", readonly=False
)
intrastat_transaction_in_invoice = fields.Many2one( intrastat_transaction_in_invoice = fields.Many2one(
related='company_id.intrastat_transaction_in_invoice', readonly=False) related="company_id.intrastat_transaction_in_invoice", readonly=False
)
intrastat_transaction_in_refund = fields.Many2one( intrastat_transaction_in_refund = fields.Many2one(
related='company_id.intrastat_transaction_in_refund', readonly=False) related="company_id.intrastat_transaction_in_refund", readonly=False
)
intrastat_accessory_costs = fields.Boolean( intrastat_accessory_costs = fields.Boolean(
related='company_id.intrastat_accessory_costs', readonly=False) related="company_id.intrastat_accessory_costs", readonly=False
country_id = fields.Many2one(related='company_id.country_id') )
country_code = fields.Char(related='company_id.country_id.code') country_id = fields.Many2one(related="company_id.country_id")
country_code = fields.Char(related="company_id.country_id.code")

View File

@@ -9,17 +9,19 @@ class SaleOrder(models.Model):
_inherit = "sale.order" _inherit = "sale.order"
intrastat_transport_id = fields.Many2one( intrastat_transport_id = fields.Many2one(
comodel_name='intrastat.transport_mode', string='Transport Mode', comodel_name="intrastat.transport_mode",
help="This information is used in Intrastat reports") string="Transport Mode",
help="This information is used in Intrastat reports",
)
intrastat = fields.Selection( intrastat = fields.Selection(
string='Intrastat Declaration', string="Intrastat Declaration", related="company_id.intrastat_dispatches"
related='company_id.intrastat_dispatches') )
def _prepare_invoice(self): def _prepare_invoice(self):
'''Copy destination country to invoice''' """Copy destination country to invoice"""
vals = super(SaleOrder, self)._prepare_invoice() vals = super(SaleOrder, self)._prepare_invoice()
if self.intrastat_transport_id: if self.intrastat_transport_id:
vals['intrastat_transport_id'] = self.intrastat_transport_id.id vals["intrastat_transport_id"] = self.intrastat_transport_id.id
if self.warehouse_id.region_id: if self.warehouse_id.region_id:
vals['src_dest_region_id'] = self.warehouse_id.region_id.id vals["src_dest_region_id"] = self.warehouse_id.region_id.id
return vals return vals

View File

@@ -6,21 +6,22 @@ from odoo import fields, models
class StockWarehouse(models.Model): class StockWarehouse(models.Model):
_inherit = 'stock.warehouse' _inherit = "stock.warehouse"
region_id = fields.Many2one( region_id = fields.Many2one(
comodel_name='intrastat.region', string='Intrastat Region') comodel_name="intrastat.region", string="Intrastat Region"
)
class StockLocation(models.Model): class StockLocation(models.Model):
_inherit = 'stock.location' _inherit = "stock.location"
def get_intrastat_region(self): def get_intrastat_region(self):
self.ensure_one() self.ensure_one()
locations = self.search([('id', 'parent_of', self.id)]) locations = self.search([("id", "parent_of", self.id)])
warehouses = self.env['stock.warehouse'].search([ warehouses = self.env["stock.warehouse"].search(
('lot_stock_id', 'in', locations.ids), [("lot_stock_id", "in", locations.ids), ("region_id", "!=", False)]
('region_id', '!=', False)]) )
if warehouses: if warehouses:
return warehouses[0].region_id return warehouses[0].region_id
return None return None

View File

@@ -4,192 +4,145 @@
import logging import logging
from odoo import models from odoo import models
from odoo.tools.translate import translate, _ from odoo.tools.translate import _, translate
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
IR_TRANSLATION_NAME = 'intrastat.product.report' IR_TRANSLATION_NAME = "intrastat.product.report"
class IntrastatProductDeclarationXlsx(models.AbstractModel): class IntrastatProductDeclarationXlsx(models.AbstractModel):
_name = 'report.intrastat_product.product_declaration_xls' _name = "report.intrastat_product.product_declaration_xls"
_inherit = 'report.report_xlsx.abstract' _inherit = "report.report_xlsx.abstract"
def _(self, src): def _(self, src):
lang = self.env.context.get('lang', 'en_US') lang = self.env.context.get("lang", "en_US")
val = translate( val = translate(self.env.cr, IR_TRANSLATION_NAME, "report", lang, src) or src
self.env.cr, IR_TRANSLATION_NAME, 'report', lang, src) or src
return val return val
def _get_template(self, declaration): def _get_template(self, declaration):
template = { template = {
'product': { "product": {
'header': { "header": {"type": "string", "value": self._("Product")},
'type': 'string', "line": {
'value': self._('Product'), "value": self._render("line.product_id and line.product_id.name")
}, },
'line': { "width": 36,
'value': self._render(
"line.product_id and line.product_id.name"),
},
'width': 36,
}, },
'product_origin_country': { "product_origin_country": {
'header': { "header": {"type": "string", "value": self._("Product C/O")},
'type': 'string', "line": {
'value': self._('Product C/O'), "type": "string",
"value": self._render("line.product_origin_country_id.name or ''"),
}, },
'line': { "width": 28,
'type': 'string',
'value': self._render(
"line.product_origin_country_id.name or ''"),
},
'width': 28,
}, },
'hs_code': { "hs_code": {
'header': { "header": {"type": "string", "value": self._("Intrastat Code")},
'type': 'string', "line": {
'value': self._('Intrastat Code'), "type": "string",
"value": self._render("line.hs_code_id.local_code"),
}, },
'line': { "width": 14,
'type': 'string',
'value': self._render(
"line.hs_code_id.local_code"),
},
'width': 14,
}, },
'src_dest_country': { "src_dest_country": {
'header': { "header": {
'type': 'string', "type": "string",
'value': self._('Country of Origin/Destination'), "value": self._("Country of Origin/Destination"),
}, },
'line': { "line": {
'type': 'string', "type": "string",
'value': self._render( "value": self._render("line.src_dest_country_id.name"),
"line.src_dest_country_id.name"),
}, },
'width': 28, "width": 28,
}, },
'amount_company_currency': { "amount_company_currency": {
'header': { "header": {
'type': 'string', "type": "string",
'value': self._('Fiscal Value'), "value": self._("Fiscal Value"),
'format': self.format_theader_yellow_right, "format": self.format_theader_yellow_right,
}, },
'line': { "line": {
'type': 'number', "type": "number",
'value': self._render("line.amount_company_currency"), "value": self._render("line.amount_company_currency"),
'format': self.format_tcell_amount_right, "format": self.format_tcell_amount_right,
}, },
'width': 18, "width": 18,
}, },
'accessory_cost': { "accessory_cost": {
'header': { "header": {
'type': 'string', "type": "string",
'value': self._('Accessory Costs'), "value": self._("Accessory Costs"),
'format': self.format_theader_yellow_right, "format": self.format_theader_yellow_right,
}, },
'line': { "line": {
'type': 'number', "type": "number",
'value': self._render( "value": self._render(
"line.amount_accessory_cost_company_currency"), "line.amount_accessory_cost_company_currency"
'format': self.format_tcell_amount_right, ),
"format": self.format_tcell_amount_right,
}, },
'width': 18, "width": 18,
}, },
'transaction': { "transaction": {
'header': { "header": {"type": "string", "value": self._("Intrastat Transaction")},
'type': 'string', "line": {"value": self._render("line.transaction_id.display_name")},
'value': self._('Intrastat Transaction'), "width": 36,
},
'line': {
'value': self._render(
"line.transaction_id.display_name"),
},
'width': 36,
}, },
'weight': { "weight": {
'header': { "header": {
'type': 'string', "type": "string",
'value': self._('Weight'), "value": self._("Weight"),
'format': self.format_theader_yellow_right, "format": self.format_theader_yellow_right,
}, },
'line': { "line": {
'type': 'number', "type": "number",
'value': self._render( "value": self._render("line.weight"),
"line.weight"), "format": self.format_tcell_amount_right,
'format': self.format_tcell_amount_right,
}, },
'width': 18, "width": 18,
}, },
'suppl_unit_qty': { "suppl_unit_qty": {
'header': { "header": {
'type': 'string', "type": "string",
'value': self._('Suppl. Unit Qty'), "value": self._("Suppl. Unit Qty"),
'format': self.format_theader_yellow_right, "format": self.format_theader_yellow_right,
}, },
'line': { "line": {
# we don't specify a type here and rely on the # we don't specify a type here and rely on the
# report_xlsx_helper type detection to use # report_xlsx_helper type detection to use
# write_string when suppl_unit_qty is zero # write_string when suppl_unit_qty is zero
'value': self._render( "value": self._render("line.suppl_unit_qty or ''"),
"line.suppl_unit_qty or ''"), "format": self.format_tcell_amount_right,
'format': self.format_tcell_amount_right,
}, },
'width': 18, "width": 18,
}, },
'suppl_unit': { "suppl_unit": {
'header': { "header": {"type": "string", "value": self._("Suppl. Unit")},
'type': 'string', "line": {"value": self._render("line.intrastat_unit_id.name or ''")},
'value': self._('Suppl. Unit'), "width": 14,
},
'line': {
'value': self._render(
"line.intrastat_unit_id.name or ''"),
},
'width': 14,
}, },
'incoterm': { "incoterm": {
'header': { "header": {"type": "string", "value": self._("Incoterm")},
'type': 'string', "line": {"value": self._render("line.incoterm_id.name or ''")},
'value': self._('Incoterm'), "width": 14,
},
'line': {
'value': self._render("line.incoterm_id.name or ''"),
},
'width': 14,
}, },
'transport': { "transport": {
'header': { "header": {"type": "string", "value": self._("Transport Mode")},
'type': 'string', "line": {"value": self._render("line.transport_id.name or ''")},
'value': self._('Transport Mode'), "width": 14,
},
'line': {
'value': self._render("line.transport_id.name or ''"),
},
'width': 14,
}, },
'region': { "region": {
'header': { "header": {"type": "string", "value": self._("Intrastat Region")},
'type': 'string', "line": {"value": self._render("line.region_id.name or ''")},
'value': self._('Intrastat Region'), "width": 28,
},
'line': {
'value': self._render("line.region_id.name or ''"),
},
'width': 28,
}, },
'invoice': { "invoice": {
'header': { "header": {"type": "string", "value": self._("Invoice")},
'type': 'string', "line": {"value": self._render("line.invoice_id.number")},
'value': self._('Invoice'), "width": 18,
},
'line': {
'value': self._render("line.invoice_id.number"),
},
'width': 18,
}, },
} }
template.update(declaration._xls_template()) template.update(declaration._xls_template())
@@ -198,80 +151,86 @@ class IntrastatProductDeclarationXlsx(models.AbstractModel):
def _get_ws_params(self, wb, data, declaration): def _get_ws_params(self, wb, data, declaration):
template = self._get_template(declaration) template = self._get_template(declaration)
if self.env.context.get('computation_lines'): if self.env.context.get("computation_lines"):
wl = declaration._xls_computation_line_fields() wl = declaration._xls_computation_line_fields()
report = 'computation' report = "computation"
else: else:
wl = declaration._xls_declaration_line_fields() wl = declaration._xls_declaration_line_fields()
report = 'declaration' report = "declaration"
title = self._get_title(declaration, report, title_format='normal') title = self._get_title(declaration, report, title_format="normal")
title_short = self._get_title(declaration, report, title_short = self._get_title(declaration, report, title_format="short")
title_format='short') sheet_name = title_short[:31].replace("/", "-")
sheet_name = title_short[:31].replace('/', '-')
params = { params = {
'ws_name': sheet_name, "ws_name": sheet_name,
'generate_ws_method': '_intrastat_report', "generate_ws_method": "_intrastat_report",
'title': title, "title": title,
'wanted_list': wl, "wanted_list": wl,
'col_specs': template, "col_specs": template,
} }
return [params] return [params]
def _get_title(self, declaration, report, title_format='normal'): def _get_title(self, declaration, report, title_format="normal"):
title = declaration.year_month title = declaration.year_month
if title_format == 'normal': if title_format == "normal":
if report == 'computation': if report == "computation":
title += ' : ' + _('Computation Lines') title += " : " + _("Computation Lines")
else: else:
title += ' : ' + _('Declaration Lines') title += " : " + _("Declaration Lines")
return title return title
def _report_title(self, ws, row_pos, ws_params, data, declaration): def _report_title(self, ws, row_pos, ws_params, data, declaration):
return self._write_ws_title(ws, row_pos, ws_params) return self._write_ws_title(ws, row_pos, ws_params)
def _empty_report(self, ws, row_pos, ws_params, data, declaration, def _empty_report(self, ws, row_pos, ws_params, data, declaration, report):
report): if report == "computation":
if report == 'computation': lines = _("Computation Lines")
lines = _('Computation Lines')
else: else:
lines = _('Declaration Lines') lines = _("Declaration Lines")
no_entries = _("No") + " " + lines + " " + _("for period %s") \ no_entries = (
% declaration.year_month _("No") + " " + lines + " " + _("for period %s") % declaration.year_month
)
ws.write_string(row_pos, 0, no_entries, self.format_left_bold) ws.write_string(row_pos, 0, no_entries, self.format_left_bold)
def _intrastat_report(self, workbook, ws, ws_params, data, declaration): def _intrastat_report(self, workbook, ws, ws_params, data, declaration):
ws.set_landscape() ws.set_landscape()
ws.fit_to_pages(1, 0) ws.fit_to_pages(1, 0)
ws.set_header(self.xls_headers['standard']) ws.set_header(self.xls_headers["standard"])
ws.set_footer(self.xls_footers['standard']) ws.set_footer(self.xls_footers["standard"])
self._set_column_width(ws, ws_params) self._set_column_width(ws, ws_params)
row_pos = 0 row_pos = 0
row_pos = self._report_title(ws, row_pos, ws_params, data, declaration) row_pos = self._report_title(ws, row_pos, ws_params, data, declaration)
if self.env.context.get('computation_lines'): if self.env.context.get("computation_lines"):
report = 'computation' report = "computation"
lines = declaration.computation_line_ids lines = declaration.computation_line_ids
else: else:
report = 'declaration' report = "declaration"
lines = declaration.declaration_line_ids lines = declaration.declaration_line_ids
if not lines: if not lines:
return self._empty_report( return self._empty_report(ws, row_pos, ws_params, data, declaration, report)
ws, row_pos, ws_params, data, declaration, report)
row_pos = self._write_line( row_pos = self._write_line(
ws, row_pos, ws_params, col_specs_section='header', ws,
default_format=self.format_theader_yellow_left) row_pos,
ws_params,
col_specs_section="header",
default_format=self.format_theader_yellow_left,
)
ws.freeze_panes(row_pos, 0) ws.freeze_panes(row_pos, 0)
for line in lines: for line in lines:
row_pos = self._write_line( row_pos = self._write_line(
ws, row_pos, ws_params, col_specs_section='line', ws,
render_space={'line': line}, row_pos,
default_format=self.format_tcell_left) ws_params,
col_specs_section="line",
render_space={"line": line},
default_format=self.format_tcell_left,
)

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<record id="invoice_form" model="ir.ui.view"> <record id="view_move_form" model="ir.ui.view">
<field name="name">intrastat.invoice.form</field> <field name="name">intrastat.invoice.form</field>
<field name="model">account.invoice</field> <field name="model">account.move</field>
<field name="inherit_id" ref="account.invoice_form"/> <field name="inherit_id" ref="account.view_move_form"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//page[@name='other_info']//field[@name='name']" position="after"> <xpath expr="//page[@name='other_info']//field[@name='invoice_incoterm_id']" position="after">
<field name="intrastat_transaction_id"/> <field name="intrastat_transaction_id"/>
<field name="intrastat" invisible="1"/> <field name="intrastat" invisible="1"/>
<field name="intrastat_transport_id" <field name="intrastat_transport_id"
@@ -21,6 +21,7 @@
</field> </field>
</record> </record>
<!--
<record id="invoice_supplier_form" model="ir.ui.view"> <record id="invoice_supplier_form" model="ir.ui.view">
<field name="name">intrastat.invoice.supplier.form</field> <field name="name">intrastat.invoice.supplier.form</field>
<field name="model">account.invoice</field> <field name="model">account.invoice</field>
@@ -44,5 +45,6 @@
</xpath> </xpath>
</field> </field>
</record> </record>
-->
</odoo> </odoo>

View File

@@ -87,7 +87,7 @@
<field name="name">intrastat.product.declaration.tree</field> <field name="name">intrastat.product.declaration.tree</field>
<field name="model">intrastat.product.declaration</field> <field name="model">intrastat.product.declaration</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Intrastat Product Declarations" colors="blue:state=='draft'"> <tree string="Intrastat Product Declarations" decoration-info="state=='draft'">
<field name="year_month"/> <field name="year_month"/>
<field name="revision"/> <field name="revision"/>
<field name="type"/> <field name="type"/>

View File

@@ -10,60 +10,57 @@
<odoo> <odoo>
<!-- Intrastat Supplementary Unit --> <!-- Intrastat Supplementary Unit -->
<record id="intrastat_unit_form" model="ir.ui.view"> <record id="intrastat_unit_form" model="ir.ui.view">
<field name="name">intrastat.unit.form</field> <field name="name">intrastat.unit.form</field>
<field name="model">intrastat.unit</field> <field name="model">intrastat.unit</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="Intrastat Supplementary Unit"> <form string="Intrastat Supplementary Unit">
<div class="oe_button_box" name="button_box"> <field name="active" invisible="1"/>
<button name="toggle_active" type="object" <widget name="web_ribbon" text="Archived"
class="oe_stat_button" icon="fa-archive"> bg_color="bg-danger"
<field name="active" widget="boolean_button" attrs="{'invisible': [('active', '=', True)]}"/>
options='{"terminology": "archive"}'/> <group name="main">
</button> <field name="name"/>
</div> <field name="uom_id" required="1"/>
<group name="main"> <field name="description"/>
<field name="name"/> </group>
<field name="uom_id" required="1"/> </form>
<field name="description"/> </field>
</group>
</form>
</field>
</record> </record>
<record id="intrastat_unit_tree" model="ir.ui.view"> <record id="intrastat_unit_tree" model="ir.ui.view">
<field name="name">intrastat.unit.tree</field> <field name="name">intrastat.unit.tree</field>
<field name="model">intrastat.unit</field> <field name="model">intrastat.unit</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="Intrastat Supplementary Units"> <tree string="Intrastat Supplementary Units">
<field name="name"/> <field name="name"/>
<field name="uom_id"/> <field name="uom_id"/>
<field name="description"/> <field name="description"/>
</tree> </tree>
</field> </field>
</record> </record>
<record id="intrastat_unit_search" model="ir.ui.view"> <record id="intrastat_unit_search" model="ir.ui.view">
<field name="name">intrastat.unit.search</field> <field name="name">intrastat.unit.search</field>
<field name="model">intrastat.unit</field> <field name="model">intrastat.unit</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="Search Intrastat Supplementary Units"> <search string="Search Intrastat Supplementary Units">
<field name="name" <field name="name"
filter_domain="['|', ('name', 'ilike', self), ('description', 'ilike', self)]"/> filter_domain="['|', ('name', 'ilike', self), ('description', 'ilike', self)]"/>
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/> <filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
<group string="Group By" name="groupby"> <group string="Group By" name="groupby">
<filter name="uom_groupby" string="Regular UoM" <filter name="uom_groupby" string="Regular UoM"
context="{'group_by': 'uom_id'}"/> context="{'group_by': 'uom_id'}"/>
</group> </group>
</search> </search>
</field> </field>
</record> </record>
<record id="intrastat_unit_action" model="ir.actions.act_window"> <record id="intrastat_unit_action" model="ir.actions.act_window">
<field name="name">Supplementary Units</field> <field name="name">Supplementary Units</field>
<field name="res_model">intrastat.unit</field> <field name="res_model">intrastat.unit</field>
<field name="view_mode">tree,form</field> <field name="view_mode">tree,form</field>
</record> </record>
<menuitem id="intrastat_unit_menu" <menuitem id="intrastat_unit_menu"