chore: clean up historical scripts, add MCP configurations, update agent rules

This commit is contained in:
2026-07-08 14:13:58 -06:00
parent a2908167e6
commit 52470a44cb
52 changed files with 2181 additions and 2328 deletions
@@ -92,5 +92,37 @@
<field name="priority">8</field>
</record>
<!-- ================================================================
CRON 6: Procesar Cola de Sincronización de Inventario (Shopify Stock Queue)
================================================================ -->
<record id="ir_cron_shopify_process_stock_queue" model="ir.cron">
<field name="name">Shopify: Procesar Cola de Inventario</field>
<field name="model_id" ref="model_shopify_stock_queue"/>
<field name="state">code</field>
<field name="code">model.process_queue_batch()</field>
<field name="interval_number">5</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field name="active">True</field>
<field name="user_id" ref="base.user_root"/>
<field name="priority">5</field>
</record>
<!-- ================================================================
CRON 7: Limpiar Cola de Inventario (Shopify Stock Queue)
================================================================ -->
<record id="ir_cron_shopify_clean_stock_queue" model="ir.cron">
<field name="name">Shopify: Limpiar Cola de Inventario</field>
<field name="model_id" ref="model_shopify_stock_queue"/>
<field name="state">code</field>
<field name="code">model.clean_done_queue()</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="active">True</field>
<field name="user_id" ref="base.user_root"/>
<field name="priority">15</field>
</record>
</data>
</odoo>
@@ -9,3 +9,5 @@ from . import shopify_config
from . import res_users
from . import shopify_cost_line
from . import product_label_layout
from . import shopify_stock_queue
from . import stock_quant
@@ -644,48 +644,9 @@ class StockPicking(models.Model):
except Exception:
pass # No romper el flujo si el chatter falla
# 2. ── AUTO-STOCK SYNC (Traslados y Movimientos de Stock) ──
products = picking.move_ids.mapped('product_id').filtered(lambda p: p.shopify_inventory_item_id)
if products:
config = self.env['shopify.config'].sudo().search([('state', '=', 'confirmed')], limit=1)
if config and config.auto_sync_products:
_logger.info(
"[Shopify Stock Auto-Sync] Albarán '%s' validado. "
"Sincronizando stock de %s variantes vinculadas a Shopify.",
picking.name, len(products)
)
try:
import threading
import odoo
# 2. ── AUTO-STOCK SYNC ──
# ELIMINADO: Ahora se maneja de forma global mediante shopify.stock.queue
# al sobrescribir stock.quant._update_available_quantity, lo cual
# cubre ajustes de inventario, ventas y traslados.
def sync_bg(dbname, p_ids, c_id):
try:
registry = odoo.registry(dbname)
with registry.cursor() as cr:
env = odoo.api.Environment(cr, odoo.SUPERUSER_ID, {})
prods = env['product.product'].browse(p_ids)
conf = env['shopify.config'].browse(c_id)
if conf and prods:
conf._sync_variants_stock_to_shopify(prods)
except Exception as exc:
import logging
logging.getLogger(__name__).error("[Shopify Stock Auto-Sync Async] Fallo: %s", exc)
if hasattr(self.env.cr, 'postcommit'):
self.env.cr.postcommit.add(
lambda: threading.Thread(
target=sync_bg,
args=(self.env.cr.dbname, products.ids, config.id)
).start()
)
else:
threading.Thread(
target=sync_bg,
args=(self.env.cr.dbname, products.ids, config.id)
).start()
except Exception as e:
_logger.warning(
"[Shopify Stock Auto-Sync] Error al iniciar hilo de sincronización para '%s': %s",
picking.name, str(e)
)
return res
@@ -0,0 +1,54 @@
from odoo import models, fields, api
import logging
from datetime import timedelta
_logger = logging.getLogger(__name__)
class ShopifyStockQueue(models.Model):
_name = 'shopify.stock.queue'
_description = 'Shopify Stock Sync Queue'
product_id = fields.Many2one('product.product', string='Product', required=True, ondelete='cascade')
state = fields.Selection([
('pending', 'Pendiente'),
('done', 'Realizado'),
('failed', 'Fallido')
], string='Estado', default='pending', required=True)
error_message = fields.Text(string='Mensaje de Error')
@api.model
def enqueue_product(self, product_id):
existing = self.search([
('product_id', '=', product_id),
('state', 'in', ['pending', 'failed'])
], limit=1)
if not existing:
self.create({'product_id': product_id, 'state': 'pending'})
@api.model
def process_queue_batch(self):
records = self.search([('state', 'in', ['pending', 'failed'])], limit=15)
if not records:
return
config = self.env['shopify.config'].sudo().search([('state', '=', 'confirmed')], limit=1)
if not config or not config.auto_sync_products:
return
products = records.mapped('product_id').filtered(lambda p: p.shopify_inventory_item_id)
if products:
try:
config._sync_variants_stock_to_shopify(products)
records.write({'state': 'done', 'error_message': False})
except Exception as e:
_logger.error("[Shopify Stock Queue] Falló sincronización de lote: %s", str(e))
records.write({'state': 'failed', 'error_message': str(e)})
else:
records.write({'state': 'done', 'error_message': 'No Shopify Inventory Item ID'})
@api.model
def clean_done_queue(self):
threshold_date = fields.Datetime.now() - timedelta(days=7)
old_records = self.search([('state', '=', 'done'), ('create_date', '<', threshold_date)])
if old_records:
old_records.unlink()
@@ -0,0 +1,23 @@
from odoo import models, api
class StockQuant(models.Model):
_inherit = 'stock.quant'
@api.model
def _update_available_quantity(self, product_id, location_id, quantity, lot_id=None, package_id=None, owner_id=None, in_date=None):
res = super(StockQuant, self)._update_available_quantity(
product_id=product_id,
location_id=location_id,
quantity=quantity,
lot_id=lot_id,
package_id=package_id,
owner_id=owner_id,
in_date=in_date
)
if product_id.shopify_inventory_item_id:
config = self.env['shopify.config'].sudo().search([('state', '=', 'confirmed')], limit=1)
if config and config.auto_sync_products:
self.env['shopify.stock.queue'].sudo().enqueue_product(product_id.id)
return res