-
-
Notifications
You must be signed in to change notification settings - Fork 108
/
account_move.py
209 lines (192 loc) · 7.34 KB
/
account_move.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# Copyright 2011-2020 Akretion France (http://www.akretion.com)
# Copyright 2009-2022 Noviat (http://www.noviat.com)
# @author Alexis de Lattre <alexis.delattre@akretion.com>
# @author Luc de Meyer <info@noviat.com>
from odoo import Command, api, fields, models
class AccountMove(models.Model):
_inherit = "account.move"
intrastat_transaction_id = fields.Many2one(
comodel_name="intrastat.transaction",
string="Intrastat Transaction Type",
ondelete="restrict",
tracking=True,
check_company=True,
help="Intrastat Nature of Transaction",
domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]",
)
intrastat_transport_id = fields.Many2one(
comodel_name="intrastat.transport_mode",
string="Intrastat Transport Mode",
ondelete="restrict",
)
src_dest_country_id = fields.Many2one(
comodel_name="res.country",
string="Origin/Destination Country",
compute="_compute_src_dest_country_id",
store=True,
help="Destination country for dispatches. Origin country for arrivals.",
)
src_dest_region_id = fields.Many2one(
comodel_name="intrastat.region",
string="Origin/Destination Region",
default=lambda self: self.env.company.intrastat_region_id,
help="Origin region for dispatches, destination region for "
"arrivals. This field is used for the Intrastat Declaration.",
ondelete="restrict",
)
intrastat = fields.Char(
string="Intrastat Declaration", related="company_id.intrastat"
)
intrastat_line_ids = fields.One2many(
comodel_name="account.move.intrastat.line",
inverse_name="move_id",
string="Intrastat Declaration Details",
)
@api.depends("partner_shipping_id.country_id", "partner_id.country_id")
def _compute_src_dest_country_id(self):
for inv in self:
country = inv.partner_shipping_id.country_id or inv.partner_id.country_id
if not country:
country = inv.company_id.country_id
inv.src_dest_country_id = country.id
def compute_intrastat_lines(self):
"""
Compute the Intrastat Lines so that they can be modified
when encoding the Customer/Supplier Invoice.
"""
self.mapped("intrastat_line_ids").unlink()
for inv in self:
if inv.move_type not in (
"out_invoice",
"out_refund",
"in_invoice",
"in_refund",
):
continue
line_vals = []
for line in inv.invoice_line_ids:
vals = self._get_intrastat_line_vals(line)
if vals:
line_vals.append(Command.create(vals))
if line_vals:
inv.intrastat_line_ids = line_vals
def _get_intrastat_line_vals(self, line):
vals = {}
decl_model = self.env["intrastat.product.declaration"]
notedict, key2label = decl_model._prepare_notedict()
if decl_model._is_product(line):
hs_code = line.product_id.get_hs_code_recursively()
if not hs_code:
return vals
weight, qty = decl_model._get_weight_and_supplunits(line, hs_code, notedict)
vals.update(
{
"invoice_line_id": line.id,
"hs_code_id": hs_code.id,
"transaction_weight": weight,
"transaction_suppl_unit_qty": qty,
"product_origin_country_id": line.product_id.origin_country_id.id,
}
)
return vals
def _prepare_intrastat_line_info(self, line):
is_intrastat_line = bool(line._name == "account.move.intrastat.line")
product = line.product_id
return {
"product_id": product,
"hs_code_id": (
line.hs_code_id if is_intrastat_line else product.hs_code_id
),
"weight": (
line.transaction_weight
if is_intrastat_line
else self._get_intrastat_line_vals(line)["transaction_weight"]
),
"origin_country_id": (
line.product_origin_country_id
if is_intrastat_line
else product.origin_country_id
),
}
def _get_intrastat_lines_info(self):
"""We obtain a list of information that we will need to group at the end by
product and sum weight.
"""
res = {}
for line in (
self.invoice_line_ids.filtered(
lambda x: x.product_id.hs_code_id and x.product_id.origin_country_id
)
if not self.intrastat_line_ids
else self.intrastat_line_ids
):
res.setdefault(line.product_id.id, {"weight": 0})
vals = self._prepare_intrastat_line_info(line)
weight = vals.pop("weight")
res[line.product_id.id].update(vals)
res[line.product_id.id]["weight"] += weight
return res.values()
class AccountMoveLine(models.Model):
_inherit = "account.move.line"
hs_code_id = fields.Many2one(
comodel_name="hs.code",
compute="_compute_hs_code_id",
string="Intrastat Code",
)
def _compute_hs_code_id(self):
for rec in self:
intrastat_line = self.move_id.intrastat_line_ids.filtered(
lambda r, rec=rec: r.invoice_line_id == rec
)
rec.hs_code_id = (
intrastat_line.hs_code_id or rec.product_id.get_hs_code_recursively()
)
class AccountMoveIntrastatLine(models.Model):
_name = "account.move.intrastat.line"
_description = "Intrastat declaration details"
_order = "sequence"
move_id = fields.Many2one(
comodel_name="account.move",
string="Invoice",
ondelete="cascade",
required=True,
)
invoice_line_id = fields.Many2one(
comodel_name="account.move.line",
string="Invoice Line",
ondelete="cascade",
required=True,
)
sequence = fields.Integer(related="invoice_line_id.sequence", store=True)
product_id = fields.Many2one(
comodel_name="product.product",
string="Product",
related="invoice_line_id.product_id",
)
quantity = fields.Float(related="invoice_line_id.quantity")
transaction_suppl_unit_qty = fields.Float(
help="Transaction quantity in Intrastat Supplementary Unit"
)
hs_code_id = fields.Many2one(
comodel_name="hs.code",
string="Intrastat Code",
ondelete="restrict",
required=True,
)
transaction_weight = fields.Integer(
help="Transaction weight in Kg: Quantity x Product Weight"
)
product_origin_country_id = fields.Many2one(
comodel_name="res.country",
string="Country of Origin of the Product",
help="Country of origin of the product i.e. product " "'made in ____'.",
)
@api.onchange("invoice_line_id")
def _onchange_move_id(self):
moves = self.mapped("move_id")
dom = [
("display_type", "=", "product"),
("id", "in", moves.mapped("invoice_line_ids").ids),
("id", "not in", moves.mapped("intrastat_line_ids.invoice_line_id").ids),
]
return {"domain": {"invoice_line_id": dom}}