Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
064be20
imp(l10n_do_banks): migration scripts updated as needed for luminatti
gerald-pcg Nov 4, 2025
87ecedb
imp(l10n_do_banks): views added to activate_views_list function
gerald-pcg Nov 5, 2025
910632f
imp(l10n_do_banks): views added to activate_views_list function
gerald-pcg Nov 5, 2025
9d754e8
imp(l10n_do_banks): pre-drop-constraint-product-code script and ks_da…
gerald-pcg Nov 6, 2025
ae77cf5
imp(l10n_do_banks): validations for pre-drop-constraint-product-code …
gerald-pcg Nov 7, 2025
609f01e
imp(l10n_do_banks): validations for pre-drop-constraint-product-code …
gerald-pcg Nov 7, 2025
15b1db9
fix(l10n_do_banks): validations for module product_code_unique as ins…
gerald-pcg Nov 7, 2025
c04502f
fix(l10n_do_banks): validations for pre-drop-constraint-product-code …
gerald-pcg Nov 7, 2025
8b91dfc
add(l10n_do_banks): verifications pre-drop-constraint-product-code sc…
gerald-pcg Nov 7, 2025
311b4d0
imp(product_sequence): adding product_sequence directory with end-mig…
gerald-pcg Nov 13, 2025
f730d4c
imp(product_sequence): loggers not needed deleted
gerald-pcg Nov 13, 2025
edc38c9
imp(product_sequence): pre-remove_constraint.py replaced by post-remo…
gerald-pcg Nov 13, 2025
baf3efc
imp (upgrade-utils): modules added to uninstall list not needed for L…
gerald-pcg Dec 3, 2025
ffc42a2
imp (upgrade-utils): function added to clean qztray module data
gerald-pcg Dec 3, 2025
eeffe73
imp(upgrade_utils): delete access function improved and new assets to…
gerald-pcg Dec 3, 2025
12beebf
imp(upgrade_utils): custom assets added to delete_custom_assets function
gerald-pcg Dec 3, 2025
9e75da7
Merge branch 'master' into master-add-views-gr
fernando-pcg Dec 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 47 additions & 17 deletions src/l10n_do_banks/17.0.1.0.0/end-migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,45 @@
_logger = logging.getLogger(__name__)


def delete_advanced_web_domain_widget_assets(cr):
def delete_custom_assets(cr):
"""
Script to delete advanced_web_domain_widget assets.
Script to delete several custom backend assets:
- advanced_web_domain_widget
- ks_dashboard_ninja
- report_xlsx
- web_m2x_options
- alan_customize
- qztray_base
- ncf_manager
- interface_invoicing
- protocol_message
- dgii_reports
- l10n_do_ecommerce

"""
env = api.Environment(cr, SUPERUSER_ID, {})
assets = env['ir.asset'].search([('name', 'like', 'advanced_web_domain_widget.assets_backend%')])
for asset in assets:
asset.unlink()
_logger.info("Advanced Web Domain Widget assets deleted")

assets_to_delete = [
('advanced_web_domain_widget.assets_backend%', "Advanced Web Domain Widget assets deleted"),
('ks_dashboard_ninja.assets_backend%', "Dashboard Ninja assets deleted"),
('report_xlsx.assets_backend%', "Report xlsx assets deleted"),
('web_m2x_options.assets_backend%', "Web m2x options assets deleted"),
('alan_customize%', "Alan Customize assets deleted"),
('qztray_base.assets_backend%', "QZ Tray Base assets deleted"),
('ncf_manager.assets_backend%', "NCF Manager assets deleted"),
('interface_invoicing.%', "Interface Invoicing assets deleted"),
('protocol_message.%', "Protocol Message assets deleted"),
('dgii_reports%', "DGII Reports assets deleted"),
('l10n_do_ecommerce%', "Ecommerce assets deleted"),
('web_editor%', "Custom assets deleted"),
]

for name_pattern, log_message in assets_to_delete:
assets = env['ir.asset'].search([('name', 'like', name_pattern)])
for asset in assets:
asset.unlink()
_logger.info(log_message)


def deactivate_studio_views(cr):
"""
Expand Down Expand Up @@ -47,23 +77,24 @@ def deactivate_studio_views(cr):
for view in studio_views:
try:
view_obj = env['ir.ui.view'].browse(view['id'])

inherited_views = env['ir.ui.view'].search([
('inherit_id', '=', view_obj.id),
('active', '=', True)
])

for inherited in inherited_views:
inherited.write({'active': False, 'inherit_id': False})
_logger.info(f"Inherited View Deactivated: {inherited.name} (ID: {inherited.id})")

view_obj.write({'active': False, 'inherit_id': False})
_logger.info(f"View Deactivated and Inherited Deactivated: {view['name']} (ID: {view['id']})")
_logger.info(f"View Deactivated and Inherited Deactivated: {view['name']} (ID: {view['id']})")
env.cr.commit()

except Exception as e:
_logger.warning(f"Error deactivating view {view['name']} (ID: {view['id']}): {e}")



def deactivate_automated_actions(cr):
"""
Script on end-migration to deactivate automated actions.
Expand All @@ -73,22 +104,21 @@ def deactivate_automated_actions(cr):
"""

env = api.Environment(cr, SUPERUSER_ID, {})

# Get all active automated actions
automated_actions = env['base.automation'].search([('active', '=', True)])

# Deactivate each automated action
for action in automated_actions:
try:
action.write({'active': False})
_logger.info(f"Automated action deactivated: {action.name} (ID: {action.id})")
except Exception as e:
_logger.error(f"Error deactivating automated action {action.name} (ID: {action.id}): {e}")




def migrate(cr, version):
delete_advanced_web_domain_widget_assets(cr)
delete_custom_assets(cr)
deactivate_studio_views(cr)
deactivate_automated_actions(cr)

78 changes: 78 additions & 0 deletions src/l10n_do_banks/17.0.1.0.0/end-views-activation.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,84 @@ def migrate(cr, version):
'website_stock_availability.res_config_settings_view_form_inherit',
'operating_unit.view_user_form',
'sale_discount_display_amount.sale_order_view_form_display_discount',
'operating_unit.view_users_form'
'sale_order_transit_notification.res_config_settings_view_form_transit_inherit'
'whatsapp_connector.res_config_settings_view_form'
'sale_order_rate.res_config_settings_view_form'
'l10n_do_hr_payroll.res_config_settings_view_form'
'product_sequence.res_config_settings_view_form'
'bi_warranty_registration.res_config_settings_view_form_stock'
'bi_warranty_registration.res_config_settings_view_form'
'product_price_checker.res_config_settings_view_form_checker'
'purchase_request.purchase_order_line_form2_sub'
'product_stock_qty_date_widgets.product_product_tree_view_inherit_widget_qty'
'product_brand.view_product_variant_kanban_brand'
'recurring_sale_order_app.recurring_order_view_form'
'stock.stock_location_view_form_editable'
'stock.stock_location_view_tree2_editable'
'sale_pos_backend_card_bin_promotion.view_order_form_inherited'
'sale_pos_session_link.view_order_sales_pos_backend_inherit_form'
'sale_pos_backend_advance_payment.sale_pos_backend_order_form_advance_inherit'
'l10n_do_sale_pos_backend.view_order_form_inherited'
'sale_pos_backend_warranty_reports.view_order_form_warranty_inherit'
'cecomsa_sale_control.view_order_sales_pos_backend_form_inherit'
'sale_pos_backend.view_partner_form_sale_cashier'
'l10n_do_account_bank_payment_se.account_payment_line_mixed_view_form',
'l10n_do_account_bank_payment_se.account_payment_line_view_form',
'l10n_do_chase.account_move_form_inherit_view',
'l10n_do_chase.journal_payment_view_form',
'l10n_do_electronic_invoice.autorized_xml_file_4e_view_form',
'l10n_do_fiscal_printer.ir_sequence_view_form',
'l10n_do_fiscal_printer.res_config_settings_view_form',
'l10n_do_fiscal_printer_ir_series_move_form',
'l10n_do_fleet_vehicle_journal.inherit_fleet_vehicle_view_form',
'l10n_do_fleet_vehicle_journal.journal_entry_view_form',
'l10n_do_hr_payroll_inherit.res_config_settings_view_form',
'l10n_do_hr_payroll_inherit.sheet_import_line_form_view',
'l10n_do_hr_payroll_inherit.sheet_import_view_form',
'l10n_do_hr_payroll_inherit.sheet_import_view_tree',
'l10n_do_income_statement.report_line_form_view',
'l10n_do_income_statement.wizard_income_statement_config_view',
'l10n_do_isr_retention.wizard_view_form',
'l10n_do_pos_bank_statement.l10n_do_pos_bank_statement_form_view',
'l10n_do_pos_return.order_form_view',
'l10n_do_project_sale.project_project_view_form_inherit',
'l10n_do_purchase.document_type_wizard_view_form',
'l10n_do_purchase.requisition_view_form',
'l10n_do_sale.purchase_order_line_inherit_view',
'l10n_do_sale_order_extension.res_config_settings_view_form',
'l10n_do_sale_order_view.line_inherit_view_form',
'l10n_do_sale_order_view.order_view_form',
'l10n_do_sale_payment_method.form_view_payment_inherit',
'l10n_do_sale_payment_method.sale_order_form_view_payment_inherit',
'l10n_do_supplier_invoice.res_config_settings_view_form_supplier_invoice',
'l10n_do_supplier_invoice.view_account_move_supplier_invoice_form',
'l10n_do_supplier_payment.advance_payment_inherit_form_view',
'l10n_do_supplier_payment.res_partner_form_inherit_view',
'l10n_do_supplier_payment.view_account_move_supplier_form_inherit',
'l10n_do_supplier_payment.wizard_supplier_payment_view_form',
'l10n_do_supplier_withholding.account_move_form_supplier_withholding',
'l10n_do_supplier_withholding.partner_supplier_withholding_view_form',
'l10n_do_supplier_withholding.res_config_settings_supplier_withholding_view_form',
'pm_bank_transfer_order.view_bank_transfer_order_form',
'pm_bank_transfer_order.view_res_partner_bank_inherit_form',
'pm_bank_transfer_order.wizard_view_form',
'pm_bank_transfer_order_line.view_bank_transfer_order_line_form',
'pm_bank_transfer_order_line_inherit.view_bank_transfer_order_line_form_inherit',
'pos_backend_order.line_inherit_view_form',
'pos_backend_order.order_view_form',
'pos_journal_control.wizard_view_form',
'pos_journal_control.view_session_journal_control_form',
'pos_payment_method_extension.payment_method_inherit_form_view',
'pos_payment_method_extension.pos_payment_method_view_form',
'pos_payment_method_extension.wizard_view_form',
'pos_sale_report.order_sale_report_wizard_form_view',
'sale_cashier_inherit.view_sale_cashier_form',
'sale_cashier_inherit.view_sale_cashier_session_form',
'sale_cashier_inherit.view_sale_cashier_session_inherit_form',
'sale_cashier_inherit.view_sale_cashier_session_return_form',
'sale_cashier_inherit.view_users_form',

]

remove_inherit_views_list = [
Expand Down
69 changes: 69 additions & 0 deletions src/l10n_do_banks/17.0.1.0.0/pre-modules-uninstall.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,47 @@
_logger = logging.getLogger(__name__)


def _cleanup_qztray_data(cr):
"""Remove qztray printer records that block keypair deletion.

Some databases have a NOT NULL constraint on ``qztray_printer.keypair_id``
while the foreign key uses ``ON DELETE SET NULL``. When uninstalling the
qztray modules, the upgrade utility tries to delete records from
``qztray_keypair``, which triggers ``SET NULL`` on ``qztray_printer`` and
crashes on the NOT NULL constraint.

We proactively delete the printer records that reference any keypair so the
module uninstall can proceed.
"""
# Solo ejecutamos esta limpieza si el módulo qztray_printer (o qztray)
# está instalado en la base de datos.
if not (
util.module_installed(cr, "qztray_printer")
or util.module_installed(cr, "qztray")
):
_logger.debug(
"qztray_printer/qztray no instalados; se omite la limpieza previa."
)
return

try:
cr.execute(
"""
DELETE FROM qztray_printer
WHERE keypair_id IN (SELECT id FROM qztray_keypair)
"""
)
_logger.info("Deleted qztray_printer records referencing qztray_keypair.")
except Exception:
# If tables don't exist or deletion fails, ignore and let normal
# uninstall logic handle it.
_logger.debug(
"qztray_printer/qztray_keypair tables not found or deletion failed, "
"continuing with module uninstall.",
exc_info=True,
)


def uninstall_modules(cr):
"""
Script to uninstall modules that are no longer needed or compatible with version 17.0.
Expand Down Expand Up @@ -81,6 +122,33 @@ def uninstall_modules(cr):
'stock_account_product_cost_security',
'product_code_unique',
'account_ecf_auto_post',
'qztray_base',
'professional_templates',
'stock_available_unreserved',
'product_warehouse_quantity',
'sale_discount_limit',
'sales_product_warehouse_quantity',
'account_invoice_migration_scripts',
'alan_customize',
'config_interface',
'database_cleanup',
'dev_sale_product_stock_restrict',
'interface_invoicing',
'ncf_sale',
'negative_stock_sale',
'non_moving_product_ept',
'payment_backend_refund',
'product_hide_sale_cost_price',
'protocol_message',
'qztray',
'qztray_base',
'qztray_location_labels',
'qztray_partner_labels',
'qztray_product_inventory',
'qztray_product_labels',
'qztray_product_purchase',
'required_requested_date',
'stock_inventory_chatter'
'cecomsa_account_followup',
]

Expand All @@ -91,4 +159,5 @@ def uninstall_modules(cr):


def migrate(cr, version):
_cleanup_qztray_data(cr)
uninstall_modules(cr)
5 changes: 5 additions & 0 deletions src/l10n_do_banks/17.0.1.0.0/pre-view-delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ def migrate(cr, version):
'studio_customization.odoo_studio_warranty_5e101e7c-e388-4589-b9b8-628b03ca43f1',
'studio_customization.odoo_studio_warranty_64540003-0f78-4e15-8bba-6d3475418fed',
'product_product_price_widget.product_product_tree_view_inherit_widget',
'website_livechat.channel_list_page',
'__export__.ir_ui_view_4053_9a82b3d7',
'professional_templates.view_sale_order_inherit_customized',
'professional_templates.view_rfq_inherit_customized',
'professional_templates.purchase_order_inherited_customized',
]

for xml_id in views_to_delete:
Expand Down
45 changes: 45 additions & 0 deletions src/product_sequence/17.0.1.0.0/end-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import logging

_logger = logging.getLogger(__name__)

CONSTRAINT_NAME = 'product_product_default_code_uniq'
TABLE_NAME = 'product_product'
CONSTRAINT_EXISTS_SQL = """
SELECT 1
FROM pg_constraint c
JOIN pg_class t ON c.conrelid = t.oid
JOIN pg_namespace n ON t.relnamespace = n.oid
WHERE c.conname = %s AND t.relname = %s AND n.nspname = 'public'
"""
DUPLICATES_SQL = """
SELECT default_code, COUNT(*) AS qty
FROM product_product
WHERE default_code IS NOT NULL AND default_code != ''
GROUP BY default_code
HAVING COUNT(*) > 1
"""


def migrate(cr, version):
"""Recreate the unique constraint on product_product.default_code."""
_logger.info('POST-MIGRATION: Restoring %s on %s.default_code', CONSTRAINT_NAME, TABLE_NAME)

cr.execute(CONSTRAINT_EXISTS_SQL, (CONSTRAINT_NAME, TABLE_NAME))
if cr.fetchone():
_logger.info('Constraint %s already exists. Nothing to do.', CONSTRAINT_NAME)
return

cr.execute(DUPLICATES_SQL)
duplicates = cr.fetchall()
if duplicates:
sample = ', '.join(f'"{code}" ({qty}x)' for code, qty in duplicates[:5])
if len(duplicates) > 5:
sample += f', ... (+{len(duplicates) - 5})'
_logger.error('Cannot recreate %s; duplicate default_code values detected: %s', CONSTRAINT_NAME, sample)
raise Exception('Resolve duplicate product_product.default_code values before rerunning the migration.')

_logger.info('Dropping constraint %s (if it exists) and recreating it.', CONSTRAINT_NAME)
cr.execute(f"ALTER TABLE {TABLE_NAME} DROP CONSTRAINT IF EXISTS {CONSTRAINT_NAME}")
cr.execute(f"ALTER TABLE {TABLE_NAME} ADD CONSTRAINT {CONSTRAINT_NAME} UNIQUE (default_code)")
_logger.info('Constraint %s restored successfully.', CONSTRAINT_NAME)

39 changes: 39 additions & 0 deletions src/product_sequence/17.0.1.0.0/pre-remove_constraint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-

from odoo.addons.base.maintenance.migrations import util
import logging

_logger = logging.getLogger(__name__)

CONSTRAINT_NAME = 'product_product_default_code_uniq'


def migrate(cr, version):
"""Drop the product default_code unique constraint when needed."""
_logger.info('PRE-MIGRATION: Dropping %s constraint', CONSTRAINT_NAME)

if not util.module_installed(cr, 'product_code_unique'):
_logger.info('Module product_code_unique is not installed. Nothing to do.')
return

cr.execute(
"""
SELECT COUNT(*)
FROM product_product
WHERE default_code IS NULL OR default_code = ''
"""
)
missing_codes = cr.fetchone()[0]

if not missing_codes:
_logger.info('No products without default_code found. Skipping constraint drop.')
return

_logger.info('Dropping constraint %s to allow temporary duplicates.', CONSTRAINT_NAME)
cr.execute(
"""
ALTER TABLE product_product
DROP CONSTRAINT IF EXISTS product_product_default_code_uniq
"""
)
_logger.info('Constraint %s dropped (if it existed).', CONSTRAINT_NAME)