Merge pull request #5444 from expsa/migration

migration
This commit is contained in:
esam-sermah 2025-11-18 17:02:08 +03:00 committed by GitHub
commit baa27c5ea4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 356 additions and 0 deletions

View File

@ -0,0 +1,356 @@
import logging
_logger = logging.getLogger(__name__)
def migrate(cr, version):
"""
Migrate old CoC data to new structure
"""
from odoo import api, SUPERUSER_ID
env = api.Environment(cr, SUPERUSER_ID, {})
_logger.info("Starting CoC data migration...")
# Get all old CoC records without lines
cr.execute("""
SELECT id FROM purchase_coc
WHERE id NOT IN (
SELECT DISTINCT coc_id FROM purchase_coc_line WHERE coc_id IS NOT NULL
)
""")
old_coc_ids = [row[0] for row in cr.fetchall()]
_logger.info(f"Found {len(old_coc_ids)} CoC records to migrate")
success_count = 0
error_count = 0
for coc_id in old_coc_ids:
savepoint_name = f"coc_migration_{coc_id}"
try:
cr.execute(f"SAVEPOINT {savepoint_name}")
coc = env['purchase.coc'].browse(coc_id)
if not coc.exists() or not coc.po_id:
cr.execute(f"RELEASE SAVEPOINT {savepoint_name}")
continue
_logger.info(f"Migrating CoC {coc.name} (ID: {coc.id})")
cr.execute("""
SELECT COUNT(*)
FROM purchase_coc
WHERE po_id = %s AND (is_return IS NULL OR is_return = false)
""", (coc.po_id.id,))
total_cocs_for_po = cr.fetchone()[0]
is_single_coc = (total_cocs_for_po == 1)
# التحقق من وجود حقل is_return
cr.execute("""
SELECT EXISTS (
SELECT FROM information_schema.columns
WHERE table_name = 'purchase_coc'
AND column_name = 'is_return'
)
""")
has_is_return = cr.fetchone()[0]
is_not_return = True
if has_is_return:
cr.execute("SELECT COALESCE(is_return, false) FROM purchase_coc WHERE id = %s", (coc.id,))
is_not_return = not cr.fetchone()[0]
# Get service lines from PO with qty_received_fake
# التحقق من وجود حقل qty_received_fake أولاً
cr.execute("""
SELECT EXISTS (
SELECT FROM information_schema.columns
WHERE table_name = 'purchase_order_line'
AND column_name = 'qty_received_fake'
)
""")
has_qty_received_fake = cr.fetchone()[0]
if has_qty_received_fake:
# استخدام qty_received_fake من البنية القديمة
cr.execute("""
SELECT pol.id, pol.product_id, pol.name, pol.product_qty,
COALESCE(pol.qty_received, 0) as qty_received,
COALESCE(pol.qty_received_fake, 0) as qty_received_fake,
pol.price_unit, pol.product_uom, pol.date_planned
FROM purchase_order_line pol
JOIN product_product pp ON pol.product_id = pp.id
JOIN product_template pt ON pp.product_tmpl_id = pt.id
WHERE pol.order_id = %s AND pt.type = 'service'
""", (coc.po_id.id,))
po_lines = cr.fetchall()
else:
# البنية الجديدة - بدون qty_received_fake
cr.execute("""
SELECT pol.id, pol.product_id, pol.name, pol.product_qty,
COALESCE(pol.qty_received, 0) as qty_received,
0 as qty_received_fake,
pol.price_unit, pol.product_uom, pol.date_planned
FROM purchase_order_line pol
JOIN product_product pp ON pol.product_id = pp.id
JOIN product_template pt ON pp.product_tmpl_id = pt.id
WHERE pol.order_id = %s AND pt.type = 'service'
""", (coc.po_id.id,))
po_lines = cr.fetchall()
if not po_lines:
_logger.warning(f"No service lines found for CoC {coc.name}")
cr.execute(f"RELEASE SAVEPOINT {savepoint_name}")
continue
lines_created = 0
for line_data in po_lines:
po_line_id, product_id, name, product_qty, qty_received, qty_received_fake, price_unit, product_uom, date_planned = line_data
po_line = env['purchase.order.line'].browse(po_line_id)
if not po_line.exists():
continue
# Calculate received quantities from history
qty_received_total = 0.0
cr.execute("""
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_name = 'purchase_order_line_history'
)
""")
if cr.fetchone()[0]:
cr.execute("""
SELECT COALESCE(SUM(qty_received), 0)
FROM purchase_order_line_history
WHERE po_line_id = %s
""", (po_line_id,))
history_total = cr.fetchone()[0] or 0.0
# استخدام أكبر قيمة بين التاريخ و qty_received
qty_received_total = max(history_total, qty_received)
else:
qty_received_total = qty_received
qty_remaining = product_qty - qty_received_total
qty_to_receive = qty_received_fake if qty_received_fake > 0 else 0.0
if is_not_return and is_single_coc:
# ✅ إذا كانت شهادة واحدة وليست إرجاع، استخدم qty_received كـ qty_to_receive
qty_to_receive = qty_received if qty_received > 0 else 0.0
# qty_remaining = 0.0
# qty_received_total = 0.0
_logger.info(
f"Single CoC detected for PO {coc.po_id.name}: qty_to_receive={qty_to_receive}, qty_remaining={qty_remaining}")
# qty_remaining = product_qty - qty_received_total
#
# # استخدام qty_received_fake كـ qty_to_receive إذا كانت موجودة
# qty_to_receive = qty_received_fake if qty_received_fake > 0 else 0.0
# Create new CoC line
coc_line_vals = {
'coc_id': coc.id,
'po_line_id': po_line_id,
'product_id': product_id,
'name': name,
'product_qty': product_qty,
'qty_ordered': product_qty,
'qty_received_total': qty_received_total,
'qty_remaining': max(0, qty_remaining),
'qty_to_receive': qty_to_receive, # ← استخدام القيمة من qty_received_fake
'price_unit': price_unit,
'product_uom': product_uom,
'partner_id': coc.vendor_id.id if coc.vendor_id else coc.po_id.partner_id.id,
'date_planned': date_planned,
'currency_id': coc.po_id.currency_id.id,
'sub_price_total': price_unit * product_qty,
}
env['purchase.coc.line'].create(coc_line_vals)
lines_created += 1
cr.execute(f"RELEASE SAVEPOINT {savepoint_name}")
_logger.info(f"Successfully migrated CoC {coc.name} with {lines_created} lines")
success_count += 1
except Exception as e:
cr.execute(f"ROLLBACK TO SAVEPOINT {savepoint_name}")
_logger.error(f"Error migrating CoC {coc_id}: {str(e)}")
error_count += 1
continue
_logger.info(f"CoC data migration completed! Success: {success_count}, Errors: {error_count}")
# # -*- coding: utf-8 -*-
# import logging
#
# _logger = logging.getLogger(__name__)
#
#
# def migrate(cr, version):
# """
# Migrate old CoC data to new structure
# """
# from odoo import api, SUPERUSER_ID
#
# env = api.Environment(cr, SUPERUSER_ID, {})
#
# _logger.info("Starting CoC data migration...")
#
# # Get all old CoC records without lines
# cr.execute("""
# SELECT id FROM purchase_coc
# WHERE id NOT IN (
# SELECT DISTINCT coc_id FROM purchase_coc_line WHERE coc_id IS NOT NULL
# )
# """)
#
# old_coc_ids = [row[0] for row in cr.fetchall()]
# _logger.info(f"Found {len(old_coc_ids)} CoC records to migrate")
#
# success_count = 0
# error_count = 0
#
# for coc_id in old_coc_ids:
# savepoint_name = f"coc_migration_{coc_id}"
#
# try:
# cr.execute(f"SAVEPOINT {savepoint_name}")
#
# coc = env['purchase.coc'].browse(coc_id)
# if not coc.exists() or not coc.po_id:
# cr.execute(f"RELEASE SAVEPOINT {savepoint_name}")
# continue
#
# _logger.info(f"Migrating CoC {coc.name} (ID: {coc.id})")
#
# # Get service lines from PO with qty_received_fake
# # التحقق من وجود حقل qty_received_fake أولاً
# cr.execute("""
# SELECT EXISTS (
# SELECT FROM information_schema.columns
# WHERE table_name = 'purchase_order_line'
# AND column_name = 'qty_received_fake'
# )
# """)
#
# has_qty_received_fake = cr.fetchone()[0]
#
# if has_qty_received_fake:
# # استخدام qty_received_fake من البنية القديمة
# cr.execute("""
# SELECT pol.id, pol.product_id, pol.name, pol.product_qty,
# COALESCE(pol.qty_received, 0) as qty_received,
# COALESCE(pol.qty_received_fake, 0) as qty_received_fake,
# pol.price_unit, pol.product_uom, pol.date_planned
# FROM purchase_order_line pol
# JOIN product_product pp ON pol.product_id = pp.id
# JOIN product_template pt ON pp.product_tmpl_id = pt.id
# WHERE pol.order_id = %s AND pt.type = 'service'
# """, (coc.po_id.id,))
#
# po_lines = cr.fetchall()
# else:
# # البنية الجديدة - بدون qty_received_fake
# cr.execute("""
# SELECT pol.id, pol.product_id, pol.name, pol.product_qty,
# COALESCE(pol.qty_received, 0) as qty_received,
# 0 as qty_received_fake,
# pol.price_unit, pol.product_uom, pol.date_planned
# FROM purchase_order_line pol
# JOIN product_product pp ON pol.product_id = pp.id
# JOIN product_template pt ON pp.product_tmpl_id = pt.id
# WHERE pol.order_id = %s AND pt.type = 'service'
# """, (coc.po_id.id,))
#
# po_lines = cr.fetchall()
#
# if not po_lines:
# _logger.warning(f"No service lines found for CoC {coc.name}")
# cr.execute(f"RELEASE SAVEPOINT {savepoint_name}")
# continue
#
# lines_created = 0
# for line_data in po_lines:
# po_line_id, product_id, name, product_qty, qty_received, qty_received_fake, price_unit, product_uom, date_planned = line_data
#
# po_line = env['purchase.order.line'].browse(po_line_id)
# if not po_line.exists():
# continue
#
# # Calculate received quantities from history
# qty_received_total = 0.0
# cr.execute("""
# SELECT EXISTS (
# SELECT FROM information_schema.tables
# WHERE table_name = 'purchase_order_line_history'
# )
# """)
#
# if cr.fetchone()[0]:
# cr.execute("""
# SELECT COALESCE(SUM(qty_received), 0)
# FROM purchase_order_line_history
# WHERE po_line_id = %s
# """, (po_line_id,))
# history_total = cr.fetchone()[0] or 0.0
#
# # استخدام أكبر قيمة بين التاريخ و qty_received
# qty_received_total = max(history_total, qty_received)
# else:
# qty_received_total = qty_received
#
# qty_remaining = product_qty - qty_received_total
#
# # استخدام qty_received_fake كـ qty_to_receive إذا كانت موجودة
# qty_to_receive = qty_received_fake if qty_received_fake > 0 else 0.0
#
# # Create new CoC line
# coc_line_vals = {
# 'coc_id': coc.id,
# 'po_line_id': po_line_id,
# 'product_id': product_id,
# 'name': name,
# 'product_qty': product_qty,
# 'qty_ordered': product_qty,
# 'qty_received_total': qty_received_total,
# 'qty_remaining': max(0, qty_remaining),
# 'qty_to_receive': qty_to_receive, # ← استخدام القيمة من qty_received_fake
# 'price_unit': price_unit,
# 'product_uom': product_uom,
# 'partner_id': coc.vendor_id.id if coc.vendor_id else coc.po_id.partner_id.id,
# 'date_planned': date_planned,
# 'currency_id': coc.po_id.currency_id.id,
# 'sub_price_total': price_unit * product_qty,
# }
#
# env['purchase.coc.line'].create(coc_line_vals)
# lines_created += 1
#
# cr.execute(f"RELEASE SAVEPOINT {savepoint_name}")
# _logger.info(f"Successfully migrated CoC {coc.name} with {lines_created} lines")
# success_count += 1
#
# except Exception as e:
# cr.execute(f"ROLLBACK TO SAVEPOINT {savepoint_name}")
# _logger.error(f"Error migrating CoC {coc_id}: {str(e)}")
# error_count += 1
# continue
#
# _logger.info(f"CoC data migration completed! Success: {success_count}, Errors: {error_count}")
#