feat: add custom/not_specified shipping modes with cost input for ML publish
- build_item_payload supports shipping_cost for custom mode with costs array - Add shipping mode selector: me2, custom, not_specified - Show shipping cost input when custom is selected - Backend passes shipping_cost through custom_data to payload builder
This commit is contained in:
@@ -144,6 +144,7 @@ def build_item_payload(
|
|||||||
listing_type_id: str = "gold_special",
|
listing_type_id: str = "gold_special",
|
||||||
custom_title: str = None,
|
custom_title: str = None,
|
||||||
extra_attributes: list = None,
|
extra_attributes: list = None,
|
||||||
|
shipping_cost: float = None,
|
||||||
) -> dict:
|
) -> dict:
|
||||||
"""Convert a Nexus inventory row into a MercadoLibre item payload."""
|
"""Convert a Nexus inventory row into a MercadoLibre item payload."""
|
||||||
title = custom_title or f"{inventory_row['name']} {inventory_row['brand'] or ''} {inventory_row['part_number'] or ''}".strip()
|
title = custom_title or f"{inventory_row['name']} {inventory_row['brand'] or ''} {inventory_row['part_number'] or ''}".strip()
|
||||||
@@ -152,9 +153,11 @@ def build_item_payload(
|
|||||||
title = title[:57] + "..."
|
title = title[:57] + "..."
|
||||||
|
|
||||||
shipping_payload = {"mode": shipping_mode}
|
shipping_payload = {"mode": shipping_mode}
|
||||||
if shipping_mode == "me2":
|
if shipping_mode == "custom" and shipping_cost is not None:
|
||||||
# Let ML determine free_shipping/local_pick_up defaults based on account config
|
shipping_payload["local_pick_up"] = False
|
||||||
pass
|
shipping_payload["free_shipping"] = False
|
||||||
|
shipping_payload["methods"] = []
|
||||||
|
shipping_payload["costs"] = [{"description": "Envio", "cost": str(shipping_cost)}]
|
||||||
payload = {
|
payload = {
|
||||||
"title": title,
|
"title": title,
|
||||||
"category_id": meli_category_id,
|
"category_id": meli_category_id,
|
||||||
@@ -375,11 +378,13 @@ def validate_items(
|
|||||||
extra_attrs = (custom_data.get("attributes") or {}).get(str(inv_id))
|
extra_attrs = (custom_data.get("attributes") or {}).get(str(inv_id))
|
||||||
price = (custom_data.get("prices") or {}).get(str(inv_id), inv["price_1"])
|
price = (custom_data.get("prices") or {}).get(str(inv_id), inv["price_1"])
|
||||||
item_stock = (custom_data.get("stocks") or {}).get(str(inv_id), stock)
|
item_stock = (custom_data.get("stocks") or {}).get(str(inv_id), stock)
|
||||||
|
shipping_cost = custom_data.get("shipping_cost")
|
||||||
|
|
||||||
payload = build_item_payload(
|
payload = build_item_payload(
|
||||||
inv, images, meli_category_id, price, item_stock,
|
inv, images, meli_category_id, price, item_stock,
|
||||||
shipping_mode=shipping_mode, listing_type_id=listing_type_id,
|
shipping_mode=shipping_mode, listing_type_id=listing_type_id,
|
||||||
custom_title=title, extra_attributes=extra_attrs,
|
custom_title=title, extra_attributes=extra_attrs,
|
||||||
|
shipping_cost=shipping_cost,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -480,11 +485,13 @@ def publish_items(
|
|||||||
extra_attrs = (custom_data.get("attributes") or {}).get(str(inv_id))
|
extra_attrs = (custom_data.get("attributes") or {}).get(str(inv_id))
|
||||||
price = (custom_data.get("prices") or {}).get(str(inv_id), inv["price_1"])
|
price = (custom_data.get("prices") or {}).get(str(inv_id), inv["price_1"])
|
||||||
item_stock = (custom_data.get("stocks") or {}).get(str(inv_id), stock)
|
item_stock = (custom_data.get("stocks") or {}).get(str(inv_id), stock)
|
||||||
|
shipping_cost = custom_data.get("shipping_cost")
|
||||||
|
|
||||||
payload = build_item_payload(
|
payload = build_item_payload(
|
||||||
inv, images, meli_category_id, price, item_stock,
|
inv, images, meli_category_id, price, item_stock,
|
||||||
shipping_mode=shipping_mode, listing_type_id=listing_type_id,
|
shipping_mode=shipping_mode, listing_type_id=listing_type_id,
|
||||||
custom_title=title, extra_attributes=extra_attrs,
|
custom_title=title, extra_attributes=extra_attrs,
|
||||||
|
shipping_cost=shipping_cost,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -993,9 +993,20 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.onMeliShippingChange = function() {
|
||||||
|
var mode = document.getElementById('meliShippingMode').value;
|
||||||
|
var costField = document.getElementById('meliShippingCostField');
|
||||||
|
if (costField) costField.style.display = (mode === 'custom') ? 'block' : 'none';
|
||||||
|
};
|
||||||
|
|
||||||
function _collectMeliCustomData() {
|
function _collectMeliCustomData() {
|
||||||
var ids = Array.from(selectedItems);
|
var ids = Array.from(selectedItems);
|
||||||
var customData = { titles: {}, prices: {}, stocks: {}, attributes: {} };
|
var customData = { titles: {}, prices: {}, stocks: {}, attributes: {} };
|
||||||
|
var mode = document.getElementById('meliShippingMode').value;
|
||||||
|
if (mode === 'custom') {
|
||||||
|
var costEl = document.getElementById('meliShippingCost');
|
||||||
|
if (costEl) customData.shipping_cost = parseFloat(costEl.value) || 0;
|
||||||
|
}
|
||||||
ids.forEach(function(id) {
|
ids.forEach(function(id) {
|
||||||
var titleEl = document.getElementById('meliTitle-' + id);
|
var titleEl = document.getElementById('meliTitle-' + id);
|
||||||
var priceEl = document.getElementById('meliPrice-' + id);
|
var priceEl = document.getElementById('meliPrice-' + id);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<link rel="manifest" href="/pos/static/pwa/manifest.json" />
|
<link rel="manifest" href="/pos/static/pwa/manifest.json" />
|
||||||
<meta name="theme-color" content="#F5A623" />
|
<meta name="theme-color" content="#F5A623" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="/pos/static/css/inventory.css?v=7">
|
<link rel="stylesheet" href="/pos/static/css/inventory.css?v=8">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -871,10 +871,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="inv-field">
|
<div class="inv-field">
|
||||||
<label>Modo de Envío</label>
|
<label>Modo de Envío</label>
|
||||||
<select id="meliShippingMode">
|
<select id="meliShippingMode" onchange="onMeliShippingChange()">
|
||||||
<option value="me2" selected>MercadoEnvíos (me2)</option>
|
<option value="me2" selected>MercadoEnvíos (me2)</option>
|
||||||
|
<option value="custom">Propio (custom)</option>
|
||||||
|
<option value="not_specified">No especificado</option>
|
||||||
</select>
|
</select>
|
||||||
<small style="color:var(--color-text-muted);font-size:var(--text-caption);">Tu cuenta requiere ME2 obligatoriamente.</small>
|
<small style="color:var(--color-text-muted);font-size:var(--text-caption);">Si no puedes activar ME1/ME2 en ML, prueba 'Propio' o 'No especificado'.</small>
|
||||||
|
</div>
|
||||||
|
<div class="inv-field" id="meliShippingCostField" style="display:none;">
|
||||||
|
<label>Costo de Envío (MXN)</label>
|
||||||
|
<input type="number" id="meliShippingCost" value="150" min="0" step="1" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -908,7 +914,7 @@
|
|||||||
<script src="/pos/static/js/pos-utils.js" defer></script>
|
<script src="/pos/static/js/pos-utils.js" defer></script>
|
||||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||||
<script src="/pos/static/js/virtual-scroll.js?v=2" defer></script>
|
<script src="/pos/static/js/virtual-scroll.js?v=2" defer></script>
|
||||||
<script src="/pos/static/js/inventory.js?v=13" defer></script>
|
<script src="/pos/static/js/inventory.js?v=14" defer></script>
|
||||||
<script src="/pos/static/js/offline-banner.js" defer></script>
|
<script src="/pos/static/js/offline-banner.js" defer></script>
|
||||||
<script src="/pos/static/js/sync-engine.js" defer></script>
|
<script src="/pos/static/js/sync-engine.js" defer></script>
|
||||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user