diff --git a/docsource/modules180-190.rst b/docsource/modules180-190.rst index 4f22c5c25a56..31d1e5d3d8b2 100644 --- a/docsource/modules180-190.rst +++ b/docsource/modules180-190.rst @@ -560,7 +560,7 @@ Module coverage 18.0 -> 19.0 +---------------------------------------------------+----------------------+-------------------------------------------------+ | l10n_my | | | +---------------------------------------------------+----------------------+-------------------------------------------------+ -| l10n_my_edi | | | +| l10n_my_edi | Done | | +---------------------------------------------------+----------------------+-------------------------------------------------+ | |del| l10n_my_edi_extended | | | +---------------------------------------------------+----------------------+-------------------------------------------------+ diff --git a/openupgrade_scripts/scripts/l10n_my_edi/19.0.1.0/post-migration.py b/openupgrade_scripts/scripts/l10n_my_edi/19.0.1.0/post-migration.py new file mode 100644 index 000000000000..086e18f11ae6 --- /dev/null +++ b/openupgrade_scripts/scripts/l10n_my_edi/19.0.1.0/post-migration.py @@ -0,0 +1,82 @@ +from openupgradelib import openupgrade + +# Companion to pre-migration.py: the 18.0 account.move MyInvois EDI fields +# (preserved as openupgrade_legacy_19_0_* columns) become one myinvois.document +# row per move in 19.0, linked through the myinvois_document_invoice_rel m2m. +# 18.0 and 19.0 share the same state keys, so myinvois_state copies directly. +# company_id/currency_id are required on myinvois.document and are taken from +# the move. A scratch column maps each new document back to its source invoice +# to fill the m2m, then is dropped. + +# 18.0 account.move legacy column -> 19.0 myinvois.document column. The binary +# l10n_my_edi_file is attachment-backed (no column) and is moved separately by +# re-pointing its ir_attachment rows below. +_FIELD_MAP = [ + ("myinvois_state", "l10n_my_edi_state"), + ("myinvois_external_uuid", "l10n_my_edi_external_uuid"), + ("myinvois_retry_at", "l10n_my_edi_retry_at"), + ("myinvois_submission_uid", "l10n_my_edi_submission_uid"), + ("myinvois_validation_time", "l10n_my_edi_validation_time"), + ("myinvois_error_document_hash", "l10n_my_error_document_hash"), +] + + +@openupgrade.migrate() +def migrate(env, version): + legacy_uuid = openupgrade.get_legacy_name("l10n_my_edi_external_uuid") + if not openupgrade.column_exists(env.cr, "account_move", legacy_uuid): + return + + legacy = {new: openupgrade.get_legacy_name(old) for new, old in _FIELD_MAP} + # a move carries MyInvois data if any of the preserved columns is non-NULL + any_nonnull = " OR ".join(f"am.{c} IS NOT NULL" for c in legacy.values()) + dst_cols = ", ".join(legacy.keys()) + src_cols = ", ".join(f"am.{legacy[new]}" for new in legacy) + + openupgrade.logged_query( + env.cr, "ALTER TABLE myinvois_document ADD COLUMN _ou_src_invoice integer" + ) + openupgrade.logged_query( + env.cr, + f""" + INSERT INTO myinvois_document ( + company_id, currency_id, active, {dst_cols}, _ou_src_invoice, + create_uid, create_date, write_uid, write_date + ) + SELECT + am.company_id, am.currency_id, TRUE, {src_cols}, am.id, + COALESCE(am.write_uid, am.create_uid, 1), + COALESCE(am.write_date, am.create_date, NOW() AT TIME ZONE 'UTC'), + COALESCE(am.write_uid, am.create_uid, 1), + COALESCE(am.write_date, am.create_date, NOW() AT TIME ZONE 'UTC') + FROM account_move am + WHERE {any_nonnull} + """, + ) + openupgrade.logged_query( + env.cr, + """ + INSERT INTO myinvois_document_invoice_rel (document_id, invoice_id) + SELECT id, _ou_src_invoice FROM myinvois_document + WHERE _ou_src_invoice IS NOT NULL + """, + ) + # The MyInvois XML file is a binary attachment field: re-point its + # ir_attachment rows from account.move/l10n_my_edi_file to the new + # myinvois.document/myinvois_file (no column to copy). + openupgrade.logged_query( + env.cr, + """ + UPDATE ir_attachment a + SET res_model = 'myinvois.document', + res_field = 'myinvois_file', + res_id = d.id + FROM myinvois_document d + WHERE a.res_model = 'account.move' + AND a.res_field = 'l10n_my_edi_file' + AND a.res_id = d._ou_src_invoice + """, + ) + openupgrade.logged_query( + env.cr, "ALTER TABLE myinvois_document DROP COLUMN _ou_src_invoice" + ) diff --git a/openupgrade_scripts/scripts/l10n_my_edi/19.0.1.0/pre-migration.py b/openupgrade_scripts/scripts/l10n_my_edi/19.0.1.0/pre-migration.py new file mode 100644 index 000000000000..cdf64422e64e --- /dev/null +++ b/openupgrade_scripts/scripts/l10n_my_edi/19.0.1.0/pre-migration.py @@ -0,0 +1,65 @@ +from openupgradelib import openupgrade + +# l10n_my_edi 19.0 converges several changes (see PR body): the myinvois.document +# model (+ two transient wizards) moves out of l10n_my_edi_pos into l10n_my_edi, +# six xmlids move with them, and the eight account.move MyInvois EDI columns are +# preserved as legacy for post-migration.py to spawn myinvois.document rows. +# The l10n_my_edi_extended -> l10n_my_edi merge is handled by apriori. + +_MOVED_MODELS = [ + "myinvois.document", + "myinvois.consolidate.invoice.wizard", + "myinvois.document.status.update.wizard", +] + +_RENAMED_XMLIDS_FROM_POS = [ + ( + "l10n_my_edi_pos.action_generate_myinvois_document_file", + "l10n_my_edi.action_generate_myinvois_document_file", + ), + ( + "l10n_my_edi_pos.ir_cron_myinvois_document_sync", + "l10n_my_edi.ir_cron_myinvois_document_sync", + ), + ( + "l10n_my_edi_pos.access_myinvois_consolidate_invoice_wizard_user", + "l10n_my_edi.access_myinvois_consolidate_invoice_wizard_user", + ), + ( + "l10n_my_edi_pos.myinvois_document_comp_rule", + "l10n_my_edi.myinvois_document_comp_rule", + ), +] + +# 18.0 account.move columns owned by l10n_my_edi; DEL in 19.0 (the data moves to +# myinvois.document rows). l10n_my_edi_state was a stored Selection in 18.0 and +# is a non-stored compute in 19.0, so its column is dropped too -- preserve it +# to carry the state across. l10n_my_edi_file is a binary attachment field (no +# table column -- stored in ir_attachment), so it is NOT preserved here; +# post-migration.py re-points its attachment to the new myinvois.document. +_PRESERVED_ACCOUNT_MOVE = [ + "l10n_my_edi_external_uuid", + "l10n_my_edi_retry_at", + "l10n_my_edi_submission_uid", + "l10n_my_edi_validation_time", + "l10n_my_error_document_hash", + "l10n_my_edi_state", +] + + +@openupgrade.migrate() +def migrate(env, version): + for model in _MOVED_MODELS: + openupgrade.update_module_moved_models( + env.cr, model, "l10n_my_edi_pos", "l10n_my_edi" + ) + openupgrade.rename_xmlids(env.cr, _RENAMED_XMLIDS_FROM_POS) + # Preserve only columns that actually exist (an attachment-backed field has + # no column; a column may also be absent if its module isn't installed). + cols = [ + (c, None) + for c in _PRESERVED_ACCOUNT_MOVE + if openupgrade.column_exists(env.cr, "account_move", c) + ] + if cols: + openupgrade.rename_columns(env.cr, {"account_move": cols}) diff --git a/openupgrade_scripts/scripts/l10n_my_edi/19.0.1.0/upgrade_analysis_work.txt b/openupgrade_scripts/scripts/l10n_my_edi/19.0.1.0/upgrade_analysis_work.txt new file mode 100644 index 000000000000..b7f6105a4b04 --- /dev/null +++ b/openupgrade_scripts/scripts/l10n_my_edi/19.0.1.0/upgrade_analysis_work.txt @@ -0,0 +1,120 @@ +---Models in module 'l10n_my_edi'--- +obsolete model l10n_my_edi.document.status.update [transient] +model myinvois.consolidate.invoice.wizard (moved from l10n_my_edi_pos) [transient] +model myinvois.document (moved from l10n_my_edi_pos) +model myinvois.document.status.update.wizard (moved from l10n_my_edi_pos) [transient] + +# DONE: myinvois.document + 2 transient wizards moved from +# l10n_my_edi_pos via update_module_moved_models (pre-migration). + +---Fields in module 'l10n_my_edi'--- +l10n_my_edi / account.move / l10n_my_edi_document_ids (many2many): NEW relation: myinvois.document +l10n_my_edi / account.move / l10n_my_edi_external_uuid (char): DEL +l10n_my_edi / account.move / l10n_my_edi_file (binary) : DEL attachment: True +l10n_my_edi / account.move / l10n_my_edi_retry_at (char) : DEL +l10n_my_edi / account.move / l10n_my_edi_state (selection) : now a function +l10n_my_edi / account.move / l10n_my_edi_submission_uid (char): DEL +l10n_my_edi / account.move / l10n_my_edi_validation_time (datetime): DEL +l10n_my_edi / account.move / l10n_my_error_document_hash (char): DEL +l10n_my_edi / account.tax / l10n_my_tax_exemption_reason (char): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / _order : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / active (boolean) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / activity_calendar_event_id (many2one): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / activity_date_deadline (date) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / activity_exception_decoration (selection): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / activity_exception_icon (char): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / activity_ids (one2many) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / activity_state (selection) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / activity_summary (char) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / activity_type_icon (char) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / activity_type_id (many2one) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / activity_user_id (many2one) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / company_currency_id (many2one): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / company_id (many2one) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / currency_id (many2one) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / display_name (char) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / has_message (boolean) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / invoice_ids (many2many) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / message_attachment_count (integer): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / message_follower_ids (one2many): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / message_has_error (boolean) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / message_has_error_counter (integer): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / message_has_sms_error (boolean): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / message_ids (one2many) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / message_is_follower (boolean) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / message_needaction (boolean) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / message_needaction_counter (integer): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / message_partner_ids (many2many): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / my_activity_date_deadline (date): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / myinvois_custom_form_reference (char): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / myinvois_document_long_id (char): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / myinvois_error_document_hash (char): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / myinvois_exemption_reason (char): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / myinvois_external_uuid (char) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / myinvois_file (binary) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / myinvois_file_id (many2one) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / myinvois_issuance_date (date) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / myinvois_retry_at (char) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / myinvois_state (selection) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / myinvois_submission_uid (char): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / myinvois_validation_time (datetime): previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / name (char) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / rating_ids (one2many) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / sequence_number (integer) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / sequence_prefix (char) : previously in module l10n_my_edi_pos +l10n_my_edi / myinvois.document / website_message_ids (one2many): previously in module l10n_my_edi_pos +l10n_my_edi / res.company / l10n_my_edi_industrial_classification (many2one): not stored anymore +l10n_my_edi / res.company / l10n_my_edi_industrial_classification (many2one): now related +l10n_my_edi_extended / account.move / l10n_my_edi_invoice_long_id (char): DEL + +# DONE: account.move MyInvois EDI columns preserved in pre-migration +# and copied into new myinvois.document rows (post-migration), linked +# via the myinvois_document_invoice_rel m2m. myinvois.document fields +# marked 'previously in module l10n_my_edi_pos' ride the model move. +# res.company.l10n_my_edi_industrial_classification is now related +# (non-stored) -- recomputed by the ORM, nothing to do. + +---XML records in module 'l10n_my_edi'--- +NEW ir.actions.server: l10n_my_edi.action_generate_myinvois_document_file [renamed from l10n_my_edi_pos module] +NEW ir.actions.server: l10n_my_edi.invoice_send_to_myinvois [renamed from l10n_my_edi_extended module] +DEL ir.actions.server: l10n_my_edi_extended.invoice_send_to_myinvois [renamed to l10n_my_edi module] +NEW ir.cron: l10n_my_edi.ir_cron_myinvois_document_sync [renamed from l10n_my_edi_pos module] +DEL ir.cron: l10n_my_edi.ir_cron_myinvois_sync +NEW ir.model.access: l10n_my_edi.access_myinvois_consolidate_invoice_wizard_user [renamed from l10n_my_edi_pos module] +NEW ir.model.access: l10n_my_edi.access_myinvois_document_invoice +NEW ir.model.access: l10n_my_edi.access_myinvois_document_readonly +NEW ir.model.access: l10n_my_edi.access_myinvois_document_status_update_wizard_invoice +DEL ir.model.access: l10n_my_edi.access_l10n_my_edi_document_status_update_invoice +DEL ir.model.access: l10n_my_edi.access_l10n_my_edi_document_status_update_manager +DEL ir.model.access: l10n_my_edi.access_l10n_my_edi_document_status_update_readonly +NEW ir.rule: l10n_my_edi.myinvois_document_comp_rule [renamed from l10n_my_edi_pos module] (noupdate) +NEW ir.ui.view: l10n_my_edi.myinvois_consolidate_invoice_wizard_form +NEW ir.ui.view: l10n_my_edi.myinvois_document_form_view +NEW ir.ui.view: l10n_my_edi.myinvois_document_list_view +NEW ir.ui.view: l10n_my_edi.myinvois_document_status_update_form +NEW ir.ui.view: l10n_my_edi.portal_my_details_fields +NEW ir.ui.view: l10n_my_edi.report_invoice +NEW ir.ui.view: l10n_my_edi.report_invoice_document +DEL ir.ui.view: l10n_my_edi.l10n_my_edi_document_status_update_form +DEL ir.ui.view: l10n_my_edi.ubl_20_DeliveryType_my +DEL ir.ui.view: l10n_my_edi.ubl_20_InvoiceLineType_my +DEL ir.ui.view: l10n_my_edi.ubl_21_InvoiceType_my +DEL ir.ui.view: l10n_my_edi_extended.portal_my_details_fields +DEL ir.ui.view: l10n_my_edi_extended.report_invoice +DEL ir.ui.view: l10n_my_edi_extended.report_invoice_document +DEL ir.ui.view: l10n_my_edi_extended.view_move_form_inherit_l10n_my_myinvois_extended +DEL ir.ui.view: l10n_my_edi_extended.view_partner_form_inherit_l10n_my_myinvois_extended +NEW l10n_my_edi.industry_classification: l10n_my_edi.class_16100 +NEW l10n_my_edi.industry_classification: l10n_my_edi.class_16212 +NEW l10n_my_edi.industry_classification: l10n_my_edi.class_47411 +NEW l10n_my_edi.industry_classification: l10n_my_edi.class_47520 +NEW l10n_my_edi.industry_classification: l10n_my_edi.class_47620 +NEW l10n_my_edi.industry_classification: l10n_my_edi.class_47892 +NEW l10n_my_edi.industry_classification: l10n_my_edi.class_47991 +NEW l10n_my_edi.industry_classification: l10n_my_edi.class_56101 +NEW l10n_my_edi.industry_classification: l10n_my_edi.class_56102 +DEL l10n_my_edi.industry_classification: l10n_my_edi.class_16221 + +# DONE: xmlids moved from l10n_my_edi_pos renamed in pre-migration +# (action/cron/access/rule). The l10n_my_edi_extended records are +# handled by apriori. NEW views/access are auto-created on install.