Skip to content

Commit 8e1ee29

Browse files
committed
[FIX] l10n_in_ewaybill: data-bearing WHERE, generated state, computed backfill
- Integer distance is ORM-written 0 (never NULL) and mode '0' means managed-by-transporter, so IS-NOT-NULL matched essentially every move: require meaningful values instead. - 18.0 did generate real e-waybills via account_edi; migrate those as generated/cancel with the NIC number + dates from the response attachment instead of an all-pending fleet (duplicate-generation risk). - recompute the four stored computed partner fields on the SQL-inserted rows and enable l10n_in_ewaybill_feature for companies owning e-waybills.
1 parent 0ca557b commit 8e1ee29

2 files changed

Lines changed: 141 additions & 35 deletions

File tree

Lines changed: 133 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,57 @@
1+
import json
2+
import logging
3+
from datetime import datetime
4+
15
from openupgradelib import openupgrade
26

3-
# Companion to pre-migration.py: the 18.0 account.move ewaybill transport
4-
# fields (preserved as openupgrade_legacy_19_0_* columns) become one
5-
# l10n.in.ewaybill row per move in 19.0, linked via account_move_id. Rows
6-
# enter state='pending' (the 19.0 default) -- 18.0 tracked only transport
7-
# details on the move, never an e-Waybill number, so nothing was generated.
8-
# company_id is a stored computed field (compute from account_move_id); set
9-
# it explicitly from the move so the row isn't left NULL until a recompute.
7+
_logger = logging.getLogger(__name__)
108

9+
# Companion to pre-migration.py: the 18.0 account.move ewaybill data becomes
10+
# one l10n.in.ewaybill row per move, linked via account_move_id. A move
11+
# carries data when a transport field is meaningfully set (Integer distance
12+
# is ORM-written as 0, never NULL; mode '0' means managed-by-transporter) or
13+
# when an in_ewaybill_1_03 EDI document exists: 18.0 generated real e-waybills
14+
# through account_edi, so those rows get state generated/cancel and their NIC
15+
# number + dates from the EDI response attachment instead of looking
16+
# never-generated (which would invite duplicate re-generation against NIC).
1117

12-
@openupgrade.migrate()
13-
def migrate(env, version):
14-
legacy_distance = openupgrade.get_legacy_name("l10n_in_distance")
15-
env.cr.execute(
16-
"""
17-
SELECT column_name FROM information_schema.columns
18-
WHERE table_name = 'account_move' AND column_name = %s
19-
""",
20-
(legacy_distance,),
21-
)
22-
if not env.cr.fetchone():
23-
return
18+
_NIC_DATE_FORMATS = ("%d/%m/%Y %I:%M:%S %p", "%d/%m/%Y %H:%M:%S", "%d/%m/%Y")
2419

25-
legacy = {
26-
new_name: openupgrade.get_legacy_name(old_name)
27-
for new_name, old_name in (
28-
("distance", "l10n_in_distance"),
29-
("mode", "l10n_in_mode"),
30-
("transportation_doc_date", "l10n_in_transportation_doc_date"),
31-
("transportation_doc_no", "l10n_in_transportation_doc_no"),
32-
("transporter_id", "l10n_in_transporter_id"),
33-
("type_id", "l10n_in_type_id"),
34-
("vehicle_no", "l10n_in_vehicle_no"),
35-
("vehicle_type", "l10n_in_vehicle_type"),
20+
21+
def _nic_date(value):
22+
for fmt in _NIC_DATE_FORMATS:
23+
try:
24+
return datetime.strptime(str(value), fmt).date()
25+
except (TypeError, ValueError):
26+
continue
27+
return None
28+
29+
30+
def _insert_ewaybills(env, legacy):
31+
data_preds = [
32+
f"COALESCE(am.{legacy['distance']}, 0) <> 0",
33+
f"COALESCE(am.{legacy['mode']}, '0') <> '0'",
34+
] + [
35+
f"am.{legacy[c]} IS NOT NULL"
36+
for c in (
37+
"transportation_doc_date",
38+
"transportation_doc_no",
39+
"transporter_id",
40+
"type_id",
41+
"vehicle_no",
42+
"vehicle_type",
3643
)
37-
}
38-
any_nonnull = " OR ".join(f"am.{c} IS NOT NULL" for c in legacy.values())
44+
]
45+
any_data = " OR ".join(data_preds)
46+
if openupgrade.table_exists(env.cr, "account_edi_document"):
47+
any_data += """
48+
OR am.id IN (
49+
SELECT d.move_id
50+
FROM account_edi_document d
51+
JOIN account_edi_format f ON f.id = d.edi_format_id
52+
WHERE f.code = 'in_ewaybill_1_03'
53+
AND d.state IN ('sent', 'to_cancel', 'cancelled')
54+
)"""
3955

4056
openupgrade.logged_query(
4157
env.cr,
@@ -65,6 +81,90 @@ def migrate(env, version):
6581
COALESCE(am.write_uid, am.create_uid, 1),
6682
COALESCE(am.write_date, am.create_date, NOW() AT TIME ZONE 'UTC')
6783
FROM account_move am
68-
WHERE {any_nonnull}
84+
WHERE {any_data}
85+
""",
86+
)
87+
88+
89+
def _mark_generated_from_edi(env):
90+
"""E-waybills 18.0 actually generated: state + NIC number/dates from the
91+
EDI response JSON (the attachment stores the response's data object)."""
92+
if not openupgrade.table_exists(env.cr, "account_edi_document"):
93+
return
94+
env.cr.execute(
95+
"""
96+
SELECT d.move_id, d.state, d.attachment_id
97+
FROM account_edi_document d
98+
JOIN account_edi_format f ON f.id = d.edi_format_id
99+
WHERE f.code = 'in_ewaybill_1_03'
100+
AND d.state IN ('sent', 'to_cancel', 'cancelled')
101+
"""
102+
)
103+
Ewaybill = env["l10n.in.ewaybill"].with_context(tracking_disable=True)
104+
for move_id, edi_state, att_id in env.cr.fetchall():
105+
ewaybill = Ewaybill.search([("account_move_id", "=", move_id)], limit=1)
106+
if not ewaybill:
107+
continue
108+
vals = {"state": "cancel" if edi_state == "cancelled" else "generated"}
109+
response = {}
110+
if att_id:
111+
raw = env["ir.attachment"].browse(att_id).raw
112+
try:
113+
response = json.loads(raw.decode("utf-8"))
114+
except (ValueError, UnicodeDecodeError, AttributeError):
115+
_logger.info("unparsable ewaybill response for move %s", move_id)
116+
if response.get("ewayBillNo"):
117+
vals["name"] = str(response["ewayBillNo"])
118+
ewaybill_date = _nic_date(response.get("ewayBillDate"))
119+
if ewaybill_date:
120+
vals["ewaybill_date"] = ewaybill_date
121+
expiry = _nic_date(response.get("validUpto"))
122+
if expiry:
123+
vals["ewaybill_expiry_date"] = expiry
124+
ewaybill.write(vals)
125+
126+
127+
def _backfill_computed_and_feature(env):
128+
ewaybills = env["l10n.in.ewaybill"].search([("account_move_id", "!=", False)])
129+
for fname in (
130+
"partner_bill_from_id",
131+
"partner_bill_to_id",
132+
"partner_ship_from_id",
133+
"partner_ship_to_id",
134+
):
135+
env.add_to_compute(ewaybills._fields[fname], ewaybills)
136+
ewaybills.env.flush_all()
137+
# the UI gate: enable for companies that own migrated e-waybills
138+
openupgrade.logged_query(
139+
env.cr,
140+
"""
141+
UPDATE res_company c
142+
SET l10n_in_ewaybill_feature = TRUE
143+
WHERE EXISTS (
144+
SELECT 1 FROM l10n_in_ewaybill e WHERE e.company_id = c.id
145+
)
69146
""",
70147
)
148+
149+
150+
@openupgrade.migrate()
151+
def migrate(env, version):
152+
legacy_distance = openupgrade.get_legacy_name("l10n_in_distance")
153+
if not openupgrade.column_exists(env.cr, "account_move", legacy_distance):
154+
return
155+
legacy = {
156+
new_name: openupgrade.get_legacy_name(old_name)
157+
for new_name, old_name in (
158+
("distance", "l10n_in_distance"),
159+
("mode", "l10n_in_mode"),
160+
("transportation_doc_date", "l10n_in_transportation_doc_date"),
161+
("transportation_doc_no", "l10n_in_transportation_doc_no"),
162+
("transporter_id", "l10n_in_transporter_id"),
163+
("type_id", "l10n_in_type_id"),
164+
("vehicle_no", "l10n_in_vehicle_no"),
165+
("vehicle_type", "l10n_in_vehicle_type"),
166+
)
167+
}
168+
_insert_ewaybills(env, legacy)
169+
_mark_generated_from_edi(env)
170+
_backfill_computed_and_feature(env)

openupgrade_scripts/scripts/l10n_in_ewaybill/19.0.2.0/upgrade_analysis_work.txt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ l10n_in_edi_ewaybill / account.move / l10n_in_type_id (many2one)
1414
l10n_in_edi_ewaybill / account.move / l10n_in_vehicle_no (char) : DEL
1515
l10n_in_edi_ewaybill / account.move / l10n_in_vehicle_type (selection): DEL selection_keys: ['O', 'R']
1616

17-
# DONE: preserved as legacy columns in pre-migration; post-migration spawns one l10n.in.ewaybill row per move (mode '0' coerced to NULL).
17+
# DONE: preserved as legacy columns in pre-migration; post-migration spawns one
18+
# l10n.in.ewaybill row per move with meaningful data (distance<>0, mode<>'0',
19+
# or an in_ewaybill_1_03 EDI document); 18-generated e-waybills get state
20+
# generated/cancel + NIC number/dates from the EDI response attachment, and
21+
# the stored computed partner fields are recomputed.
1822

1923
l10n_in_edi_ewaybill / res.company / l10n_in_edi_ewaybill_auth_validity (datetime): DEL
2024
l10n_in_edi_ewaybill / res.company / l10n_in_edi_ewaybill_password (char): DEL
@@ -96,7 +100,9 @@ l10n_in_ewaybill / res.company / l10n_in_ewaybill_feature (boolean)
96100
l10n_in_ewaybill / res.company / l10n_in_ewaybill_password (char): NEW
97101
l10n_in_ewaybill / res.company / l10n_in_ewaybill_username (char): NEW
98102

99-
# DONE: auth_validity / password / username receive values from the renamed _edi_ columns; l10n_in_ewaybill_feature is a NEW flag handled by update_db.
103+
# DONE: auth_validity / password / username receive values from the renamed
104+
# _edi_ columns; l10n_in_ewaybill_feature is enabled in post-migration for
105+
# companies owning migrated e-waybills (update_db's default leaves it off).
100106

101107
l10n_in_ewaybill_stock / l10n.in.ewaybill / company_id (many2one) : is now stored
102108
l10n_in_ewaybill_stock / l10n.in.ewaybill / company_id (many2one) : not related anymore

0 commit comments

Comments
 (0)