chore: clean up historical scripts, add MCP configurations, update agent rules
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user