Files
Autoparts-DB/scripts/sync_estrada_to_marketplace.py
consultoria-as a236187f3a feat: MercadoLibre integration + inventory bulk publish + WhatsApp bridge fixes
- Add MercadoLibre OAuth, listings, orders, webhooks and category search
- New marketplace_external_bp.py, meli_service.py, marketplace_external_service.py
- New marketplace_external.html/js with ML management UI
- Inventory: bulk publish to ML with category autocomplete, listing type and shipping selectors
- Inventory: new .btn--meli styles, select/label CSS fixes
- WhatsApp bridge: rate limiting, 440/515/408 error handling, stale watchdog
- DB migration v3.4_meli_integration.sql for marketplace_listings, orders, sync_queue
- Add Celery tasks for ML sync and webhook processing
- Sidebar: MercadoLibre navigation link
2026-05-26 04:24:07 +00:00

83 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""
Sync Strada inventory to marketplace warehouse_inventory.
Matches by OEM part_number and cross-references.
"""
import os, sys, io
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'pos'))
from tenant_db import get_tenant_conn, get_master_conn
BODEGA_ID = 7
USER_ID = 1 # admin user in master DB
CURRENCY = 'MXN'
def main():
tenant_conn = get_tenant_conn(28)
tenant_cur = tenant_conn.cursor()
# Get active inventory with stock
tenant_cur.execute("""
SELECT i.id, i.part_number, i.price_1, i.cost, COALESCE(iss.stock, 0) as stock
FROM inventory i
LEFT JOIN inventory_stock_summary iss ON iss.inventory_id = i.id
WHERE i.is_active = true
""")
items = {r[0]: {'pn': r[1], 'price': r[2], 'cost': r[3], 'stock': r[4]} for r in tenant_cur.fetchall()}
print(f"Active inventory: {len(items)}")
tenant_cur.close()
tenant_conn.close()
# Get catalog mappings from master
master = get_master_conn()
master_cur = master.cursor()
master_cur.execute("SELECT id_part, oem_part_number FROM parts WHERE oem_part_number IS NOT NULL")
oem_map = {r[1]: r[0] for r in master_cur.fetchall()}
master_cur.execute("SELECT part_id, cross_reference_number FROM part_cross_references")
cross_map = {r[1]: r[0] for r in master_cur.fetchall()}
print(f"OEM parts: {len(oem_map)}, Cross-references: {len(cross_map)}")
# Build match list
matched = []
seen_parts = set()
for item_id, data in items.items():
pn = data['pn']
raw = pn.split('-', 1)[1] if '-' in pn else pn
part_id = oem_map.get(raw) or oem_map.get(pn) or cross_map.get(raw) or cross_map.get(pn)
if part_id and part_id not in seen_parts:
seen_parts.add(part_id)
price = data['price'] or data['cost'] or 0
stock = data['stock'] or 0
matched.append((USER_ID, part_id, price, stock, 1, 'Principal', BODEGA_ID, CURRENCY))
print(f"Matched items: {len(matched)}")
if not matched:
print("Nothing to sync")
return
# Bulk insert via COPY
csv_buffer = io.StringIO()
for row in matched:
csv_buffer.write(','.join(str(c) for c in row) + '\n')
csv_buffer.seek(0)
master_cur.copy_expert(
"""COPY warehouse_inventory (user_id, part_id, price, stock_quantity, min_order_quantity, warehouse_location, bodega_id, currency)
FROM STDIN WITH (FORMAT CSV)""",
csv_buffer
)
master.commit()
master_cur.close()
master.close()
print(f"Synced {len(matched)} items to warehouse_inventory")
if __name__ == '__main__':
main()