(function () {
	'use strict';

	var PEDIDOS_MAX_ENTREGA_SLOTS_DEFAULT = 50;
	var PEDIDOS_MIN_ENTREGA_SLOTS = 3;
	var PEDIDOS_ORDEN_OC_BASE_COLS = 14;
	var PEDIDOS_INVENTARIO_BASE_COLS = 9;

	function getConfig() {
		var node = document.getElementById('logistica-pedidos-board-config');
		if (!node) {
			return { boards: [], estadoOptions: {}, clientes: [] };
		}
		try {
			var parsed = JSON.parse(node.textContent || '{}');
			if (!Array.isArray(parsed.clientes)) {
				parsed.clientes = [];
			}
			return parsed;
		} catch (error) {
			return { boards: [], estadoOptions: {}, clientes: [] };
		}
	}

	function setConfigClientes(clientes) {
		var node = document.getElementById('logistica-pedidos-board-config');
		if (!node) {
			return;
		}
		try {
			var parsed = JSON.parse(node.textContent || '{}');
			parsed.clientes = Array.isArray(clientes) ? clientes : [];
			node.textContent = JSON.stringify(parsed);
		} catch (error) {
			// ignore
		}
	}

	function getPedidosClientesList() {
		return (getConfig().clientes || []).slice();
	}

	function setPedidosClientesList(clientes) {
		setConfigClientes(clientes);
	}

	function adminConfig() {
		return window.LogisticaAdmin || {};
	}

	function postPedidos(action, payload) {
		var cfg = adminConfig();
		if (!cfg.ajaxUrl || !window.fetch) {
			return Promise.reject(new Error('Panel no disponible.'));
		}
		var data = new FormData();
		data.set('action', action);
		data.set('nonce', cfg.pedidosBoardNonce || '');
		Object.keys(payload || {}).forEach(function (key) {
			data.set(key, payload[key] == null ? '' : String(payload[key]));
		});
		return window.fetch(cfg.ajaxUrl, {
			method: 'POST',
			credentials: 'same-origin',
			body: data
		}).then(function (response) {
			return response.json().catch(function () {
				throw new Error('Respuesta no válida del servidor.');
			}).then(function (payload) {
				if (!response.ok && payload && payload.data && payload.data.message) {
					throw new Error(payload.data.message);
				}
				return payload;
			});
		});
	}

	function setBoardStatus(message, isError) {
		var status = document.querySelector('[data-pedidos-board-status]');
		if (!status) {
			return;
		}
		if (!message) {
			status.hidden = true;
			status.textContent = '';
			status.classList.remove('is-error');
			return;
		}
		status.hidden = false;
		status.textContent = message;
		status.classList.toggle('is-error', !!isError);
	}

	function getPedidosSheetRoot(fromNode) {
		if (fromNode) {
			if (fromNode.matches && fromNode.matches('[data-pedidos-sheet-root]')) {
				return fromNode;
			}
			if (fromNode.closest) {
				var scoped = fromNode.closest('[data-pedidos-sheet-root]');
				if (scoped) {
					return scoped;
				}
			}
		}

		var activeSheet = document.querySelector('[data-pedidos-board-sheet]:not([hidden]) [data-pedidos-sheet-root]');
		if (activeSheet) {
			return activeSheet;
		}

		return document.querySelector('[data-pedidos-sheet-root]') || document.querySelector('[data-pedidos-hornitos]');
	}

	function getHornitosRoot() {
		return getPedidosSheetRoot();
	}

	function getBoardSlug(root) {
		return root ? String(root.getAttribute('data-board-slug') || 'hornitos') : 'hornitos';
	}

	var PEDIDOS_BOARD_STORAGE_KEY = 'logistica_pedidos_board_slug';
	var PEDIDOS_BOARD_VIEW_STORAGE_KEY = 'logistica_pedidos_board_view';

	function escapeHtml(value) {
		return String(value == null ? '' : value)
			.replace(/&/g, '&amp;')
			.replace(/</g, '&lt;')
			.replace(/>/g, '&gt;')
			.replace(/"/g, '&quot;');
	}

	function syncPedidosBoardConfig(boards) {
		var node = document.getElementById('logistica-pedidos-board-config');
		if (node) {
			var current = getConfig();
			current.boards = boards || [];
			node.textContent = JSON.stringify(current);
		}
	}

	function getPedidosBoardLabel(boards, slug) {
		var match = (boards || []).find(function (entry) {
			return String(entry.slug || '') === String(slug || '');
		});
		return match ? String(match.label || match.slug || '') : String(slug || '');
	}

	function resolvePedidosBoardSlug(board, boards, preferred) {
		var slugs = (boards || []).map(function (entry) {
			return String(entry.slug || '');
		}).filter(Boolean);

		if (!slugs.length) {
			return '';
		}

		if (preferred && slugs.indexOf(preferred) !== -1) {
			return preferred;
		}

		try {
			var stored = window.localStorage.getItem(PEDIDOS_BOARD_STORAGE_KEY);
			if (stored && slugs.indexOf(stored) !== -1) {
				return stored;
			}
		} catch (error) {
			// ignore
		}

		if (window.location.hash && window.location.hash.indexOf('#logistica-calc-') === 0) {
			var hashSlug = window.location.hash.replace('#logistica-calc-', '');
			if (slugs.indexOf(hashSlug) !== -1) {
				return hashSlug;
			}
		}

		return slugs[0];
	}

	function renderPedidosBoardSelect(board, activeSlug) {
		var nav = board ? board.querySelector('[data-pedidos-board-select-nav]') : null;
		var config = getConfig();
		var boards = config.boards || [];
		var html;

		if (!nav || !boards.length) {
			return;
		}

		html = '<div class="logistica-planeacion__machine-select-wrap">';
		html += '<label class="logistica-planeacion__machine-select-label">';
		html += '<span class="logistica-planeacion__machine-select-text">' + escapeHtml('Estilo de pedido') + '</span>';
		html += '<select class="logistica-planeacion__machine-select" data-pedidos-board-select>';
		boards.forEach(function (entry) {
			var slug = String(entry.slug || '');
			var label = String(entry.label || slug);
			html += '<option value="' + escapeHtml(slug) + '"' + (slug === activeSlug ? ' selected' : '') + '>' + escapeHtml(label) + '</option>';
		});
		html += '</select>';
		html += '</label>';
		html += '<button type="button" class="logistica-planeacion__btn logistica-planeacion__btn--secondary logistica-planeacion__btn--compact logistica-planeacion__machine-select-edit" data-action="pedidos-edit-board-style" data-pedidos-board-slug="' + escapeHtml(activeSlug || '') + '" title="Editar estilo" aria-label="Editar estilo seleccionado">';
		html += '<span class="dashicons dashicons-edit" aria-hidden="true"></span>';
		html += '</button>';
		html += '<button type="button" class="logistica-planeacion__btn logistica-planeacion__btn--secondary logistica-planeacion__btn--compact logistica-planeacion__machine-select-add" data-action="pedidos-add-board-style" title="Nuevo estilo" aria-label="Nuevo estilo de pedido">+</button>';
		html += '</div>';
		nav.innerHTML = html;
	}

	function updatePedidosBoardSheetTitles(board, boards) {
		if (!board) {
			return;
		}

		(boards || []).forEach(function (entry) {
			var sheet = board.querySelector('[data-pedidos-board-sheet="' + entry.slug + '"]');
			var title;

			if (!sheet) {
				return;
			}

			title = sheet.querySelector('[data-pedidos-board-sheet-title]') || sheet.querySelector('.logistica-pedidos-sheet > h2');
			if (title) {
				title.textContent = String(entry.label || entry.slug || '');
			}
		});
	}

	function setActivePedidosBoard(board, slug, options) {
		var sheets;
		var activeSheet;

		if (!board || !slug) {
			return;
		}

		options = options || {};
		board._pedidosActiveBoardSlug = slug;

		try {
			window.localStorage.setItem(PEDIDOS_BOARD_STORAGE_KEY, slug);
		} catch (error) {
			// ignore
		}

		sheets = board.querySelectorAll('[data-pedidos-board-sheet]');
		sheets.forEach(function (sheet) {
			var isActive = sheet.getAttribute('data-pedidos-board-sheet') === slug;
			sheet.hidden = !isActive;
			sheet.classList.toggle('is-active', isActive);
		});

		activeSheet = board.querySelector('[data-pedidos-board-sheet="' + slug + '"]');
		if (activeSheet && options.scroll !== false) {
			activeSheet.scrollIntoView({ block: 'start' });
		}

		if (window.history && window.history.replaceState) {
			var url = new URL(window.location.href);
			url.hash = 'logistica-calc-' + slug;
			window.history.replaceState(null, '', url.toString());
		}

		if (!options.skipRender) {
			renderPedidosBoardSelect(board, slug);
		}
	}

	function setPedidosBoardStyleModalMode(board, slug) {
		var modal = board ? board.querySelector('[data-pedidos-board-style-modal]') : null;
		var title = modal ? modal.querySelector('[data-pedidos-board-style-modal-title]') : null;
		var hint = modal ? modal.querySelector('[data-pedidos-board-style-modal-hint]') : null;
		var slugInput = modal ? modal.querySelector('[data-pedidos-board-style-slug]') : null;
		var submitBtn = modal ? modal.querySelector('[data-pedidos-board-style-submit]') : null;
		var deleteBtn = modal ? modal.querySelector('[data-action="pedidos-delete-board-style"]') : null;
		var isEdit = !!slug;

		if (title) {
			title.textContent = isEdit ? 'Editar estilo de pedido' : 'Nuevo estilo de pedido';
		}
		if (hint) {
			hint.textContent = isEdit
				? 'Cambia el nombre visible del estilo. Al eliminarlo dejará de aparecer en el selector (los datos guardados se conservan).'
				: 'Cada estilo de pedido tiene su propio cuadro de órdenes de compra e inventario.';
		}
		if (slugInput) {
			slugInput.value = isEdit ? slug : '';
		}
		if (submitBtn) {
			submitBtn.textContent = isEdit ? 'Guardar cambios' : 'Crear estilo';
		}
		if (deleteBtn) {
			deleteBtn.hidden = !isEdit;
		}
	}

	function openPedidosBoardStyleModal(board, slug) {
		var modal = board ? board.querySelector('[data-pedidos-board-style-modal]') : null;
		var form = board ? board.querySelector('[data-pedidos-board-style-form]') : null;
		var nameInput = form ? form.querySelector('[data-pedidos-board-style-name]') : null;
		var config = getConfig();
		var editSlug = slug && (config.boards || []).some(function (entry) {
			return String(entry.slug || '') === String(slug || '');
		}) ? slug : '';

		if (!modal || !form) {
			return;
		}

		setPedidosBoardStyleModalMode(board, editSlug);
		if (nameInput) {
			nameInput.value = editSlug ? getPedidosBoardLabel(config.boards, editSlug) : '';
		}

		if (typeof modal.showModal === 'function') {
			modal.showModal();
		} else {
			modal.setAttribute('open', 'open');
		}

		if (nameInput) {
			window.requestAnimationFrame(function () {
				nameInput.focus();
				nameInput.select();
			});
		}
	}

	function closePedidosBoardStyleModal(board) {
		var modal = board ? board.querySelector('[data-pedidos-board-style-modal]') : null;
		if (!modal) {
			return;
		}
		if (typeof modal.close === 'function') {
			modal.close();
		} else {
			modal.removeAttribute('open');
		}
	}

	function initPedidosBoardSelectNav(board) {
		var config;
		var activeSlug;

		if (!board || board.dataset.pedidosBoardSelectBound === '1') {
			if (board && board._pedidosActiveBoardSlug) {
				setActivePedidosBoard(board, board._pedidosActiveBoardSlug, { scroll: false });
			}
			return;
		}

		config = getConfig();
		activeSlug = resolvePedidosBoardSlug(board, config.boards, board._pedidosActiveBoardSlug || '');
		board.dataset.pedidosBoardSelectBound = '1';

		renderPedidosBoardSelect(board, activeSlug);
		setActivePedidosBoard(board, activeSlug, { scroll: false });

		board.addEventListener('change', function (event) {
			var select = event.target.closest('[data-pedidos-board-select]');
			if (!select || !board.contains(select)) {
				return;
			}
			setActivePedidosBoard(board, select.value);
		});

		board.addEventListener('click', function (event) {
			var editBtn = event.target.closest('[data-action="pedidos-edit-board-style"]');
			var addBtn = event.target.closest('[data-action="pedidos-add-board-style"]');
			var closeBtn = event.target.closest('[data-action="pedidos-close-board-style-modal"]');
			var deleteBtn = event.target.closest('[data-action="pedidos-delete-board-style"]');

			if (editBtn && board.contains(editBtn)) {
				event.preventDefault();
				openPedidosBoardStyleModal(board, editBtn.getAttribute('data-pedidos-board-slug') || board._pedidosActiveBoardSlug || '');
				return;
			}

			if (addBtn && board.contains(addBtn)) {
				event.preventDefault();
				openPedidosBoardStyleModal(board, '');
				return;
			}

			if (closeBtn && board.contains(closeBtn)) {
				event.preventDefault();
				closePedidosBoardStyleModal(board);
				return;
			}

			if (deleteBtn && board.contains(deleteBtn)) {
				event.preventDefault();
				var slugInput = board.querySelector('[data-pedidos-board-style-slug]');
				var slug = slugInput ? String(slugInput.value || '').trim() : '';
				var label = getPedidosBoardLabel(getConfig().boards, slug);
				if (!slug) {
					return;
				}
				if (!window.confirm('¿Eliminar el estilo "' + label + '" del selector? Los datos guardados se conservan.')) {
					return;
				}
				postPedidos('logistica_delete_pedidos_board', { slug: slug }).then(function (payload) {
					if (!payload || !payload.success) {
						throw new Error((payload && payload.data && payload.data.message) || 'No se pudo eliminar.');
					}
					closePedidosBoardStyleModal(board);
					setBoardStatus(payload.data.message || 'Estilo eliminado.', false);
					window.location.hash = '';
					window.location.reload();
				}).catch(function (error) {
					setBoardStatus(error.message || 'Error.', true);
				});
			}
		});

		var styleForm = board.querySelector('[data-pedidos-board-style-form]');
		if (styleForm && styleForm.dataset.pedidosBoardStyleFormBound !== '1') {
			styleForm.dataset.pedidosBoardStyleFormBound = '1';
			styleForm.addEventListener('submit', function (event) {
				event.preventDefault();
				var slugInput = styleForm.querySelector('[data-pedidos-board-style-slug]');
				var nameInput = styleForm.querySelector('[data-pedidos-board-style-name]');
				var slug = slugInput ? String(slugInput.value || '').trim() : '';
				var name = nameInput ? String(nameInput.value || '').trim() : '';
				var action = slug ? 'logistica_update_pedidos_board' : 'logistica_add_pedidos_board';
				var params = slug ? { slug: slug, label: name } : { label: name };

				if (!name) {
					setBoardStatus('El nombre del estilo es obligatorio.', true);
					return;
				}

				postPedidos(action, params).then(function (payload) {
					if (!payload || !payload.success) {
						throw new Error((payload && payload.data && payload.data.message) || 'No se pudo guardar.');
					}

					if (payload.data.boards) {
						syncPedidosBoardConfig(payload.data.boards);
					}

					closePedidosBoardStyleModal(board);
					setBoardStatus(payload.data.message || 'Estilo guardado.', false);

					if (slug) {
						updatePedidosBoardSheetTitles(board, payload.data.boards || getConfig().boards);
						setActivePedidosBoard(board, slug);
						return;
					}

					if (payload.data.board && payload.data.board.slug) {
						try {
							window.localStorage.setItem(PEDIDOS_BOARD_STORAGE_KEY, payload.data.board.slug);
						} catch (saveError) {
							// ignore
						}
					}
					window.location.reload();
				}).catch(function (error) {
					setBoardStatus(error.message || 'Error.', true);
				});
			});
		}
	}

	function getOrdenReferenciaCell(row) {
		return row ? row.querySelector('[data-pedidos-orden-referencia-cell]') : null;
	}

	function getOrdenReferenciaInput(row) {
		var cell = getOrdenReferenciaCell(row);
		return cell ? cell.querySelector('[data-field="descripcion"]') : null;
	}

	function syncPedidosOrdenReferenciaDisplayFromAttrs(row) {
		if (!row) {
			return;
		}
		var input = getOrdenReferenciaInput(row);
		if (!input) {
			return;
		}
		var stored = row.getAttribute('data-pedidos-orden-sort-descripcion');
		if (stored === null) {
			return;
		}
		if (String(input.value || '') !== String(stored)) {
			input.value = stored;
		}
	}

	function fieldValue(row, name) {
		if (!row) {
			return '';
		}
		if (name === 'articulo') {
			var hidden = row.querySelector('input[type="hidden"][data-field="articulo"]');
			if (hidden) {
				return String(hidden.value || '').trim();
			}
			var select = row.querySelector('select[data-field="articulo"]');
			return select ? String(select.value || '').trim() : '';
		}
		if (name === 'descripcion') {
			var referenciaInput = getOrdenReferenciaInput(row);
			if (referenciaInput) {
				return String(referenciaInput.value || '').trim();
			}
		}
		var field = row.querySelector('[data-field="' + name + '"]');
		return field ? String(field.value || '').trim() : '';
	}

	function rowHasLockedReferencia(row) {
		return !!(row && row.querySelector('.logistica-pedidos-locked-value'));
	}

	function parsePedidosQuantity(value) {
		var text = String(value == null ? '' : value).trim();
		if (!text) {
			return 0;
		}

		text = text.replace(/[^\d,.\-\s]/g, '').replace(/[\s\u00a0\u202f\u2007]/g, '');
		if (!text || text === '-') {
			return 0;
		}

		var hasComma = text.indexOf(',') !== -1;
		var hasDot = text.indexOf('.') !== -1;

		if (hasComma && hasDot) {
			if (text.lastIndexOf(',') > text.lastIndexOf('.')) {
				text = text.replace(/\./g, '').replace(',', '.');
			} else {
				text = text.replace(/,/g, '');
			}
		} else if (hasComma) {
			if (/^\d{1,3}(,\d{3})+$/.test(text)) {
				text = text.replace(/,/g, '');
			} else {
				text = text.replace(',', '.');
			}
		} else if (hasDot) {
			var dotParts = text.split('.');
			if (dotParts.length > 1 && dotParts.every(function (part, index) {
				return index === 0 ? /^\d+$/.test(part) : /^\d{3}$/.test(part);
			})) {
				text = dotParts.join('');
			} else if (/^\d{1,3}(\.\d{3})+$/.test(text)) {
			text = text.replace(/\./g, '');
			}
		}

		var number = parseFloat(text);
		return isNaN(number) ? 0 : number;
	}

	function formatPedidosQuantity(value) {
		var number = parsePedidosQuantity(value);
		if (!isFinite(number)) {
			return '';
		}
		if (String(value || '').trim() === '' && number === 0) {
			return '';
		}
		if (Math.abs(number - Math.round(number)) < 0.00001) {
			return new Intl.NumberFormat(undefined, { maximumFractionDigits: 0 }).format(Math.round(number));
		}
		return new Intl.NumberFormat(undefined, { minimumFractionDigits: 0, maximumFractionDigits: 2 }).format(number);
	}

	function parsePedidosToleranciaPct(value) {
		var text = String(value == null ? '' : value).replace(/[±+%\s]/g, '').trim();
		if (!text) {
			return 0;
		}
		return Math.max(0, parsePedidosQuantity(text));
	}

	function formatPedidosToleranciaPct(value) {
		return formatPedidosQuantity(parsePedidosToleranciaPct(value));
	}

	function formatPedidosQuantityField(field) {
		if (!field) {
			return;
		}
		var formatted = formatPedidosQuantity(field.value);
		if (formatted !== '') {
			field.value = formatted;
		}
	}

	function parsePedidosMoney(value) {
		return parsePedidosQuantity(String(value == null ? '' : value).replace(/\$/g, '').replace(/\s*(COP|cop)\s*$/g, '').trim());
	}

	function formatPedidosMoney(value) {
		var number = parsePedidosMoney(value);
		if (!isFinite(number)) {
			return '';
		}
		if (String(value || '').trim() === '' && number === 0) {
			return '';
		}
		var formatted;
		if (Math.abs(number - Math.round(number)) < 0.00001) {
			formatted = new Intl.NumberFormat(undefined, { maximumFractionDigits: 0 }).format(Math.round(number));
		} else {
			formatted = new Intl.NumberFormat(undefined, { minimumFractionDigits: 0, maximumFractionDigits: 2 }).format(number);
		}
		return '$' + formatted;
	}

	function formatPedidosMoneyField(field) {
		if (!field) {
			return;
		}
		var formatted = formatPedidosMoney(field.value);
		if (formatted !== '') {
			field.value = formatted;
		}
	}

	function setFieldValue(row, name, value) {
		var field = row.querySelector('[data-field="' + name + '"]');
		if (field) {
			field.value = value == null ? '' : String(value);
		}
	}

	function collectInventarioPayload(row) {
		var root = getPedidosSheetRoot(row);
		return {
			id: row.getAttribute('data-inventario-id') || '0',
			board_slug: getBoardSlug(root),
			item: fieldValue(row, 'item'),
			referencia: fieldValue(row, 'referencia'),
			cantidad_op: fieldValue(row, 'cantidad_op'),
			fecha_op: fieldValue(row, 'fecha_op'),
			reporte_hornitos: fieldValue(row, 'reporte_hornitos'),
			valor_und: fieldValue(row, 'valor_und'),
			stock_latingraf: fieldValue(row, 'stock_latingraf'),
			en_produccion: fieldValue(row, 'en_produccion')
		};
	}

	function updateInventarioRowUI(row, inventario) {
		if (!row || !inventario) {
			return;
		}
		row.setAttribute('data-inventario-id', String(inventario.id || 0));
		row.setAttribute('data-referencia', String(inventario.referencia || ''));

		var disponibleCell = row.querySelector('[data-pedidos-disponible]');
		if (disponibleCell) {
			disponibleCell.textContent = inventario.reporte_disponible_fmt || inventario.reporte_disponible || '0';
		}
		var stockDisp = row.querySelector('[data-pedidos-stock-disponible]');
		if (stockDisp) {
			stockDisp.textContent = 'Disp. ' + (inventario.stock_disponible_fmt || inventario.stock_disponible || '0');
		}

		setFieldValue(row, 'reporte_hornitos', inventario.reporte_hornitos_fmt || inventario.reporte_hornitos);
		setFieldValue(row, 'stock_latingraf', inventario.stock_latingraf_fmt || inventario.stock_latingraf);
		setFieldValue(row, 'valor_und', inventario.valor_und_fmt || inventario.valor_und);
		setFieldValue(row, 'item', inventario.item || '');
		setFieldValue(row, 'referencia', inventario.referencia || '');

		row.classList.toggle('is-en-produccion', String(inventario.en_produccion || '') === 'si');

		var entregas = inventario.entregas || [];
		var slotsSeen = {};
		entregas.forEach(function (entrega) {
			var slot = String(entrega.slot_index || 0);
			slotsSeen[slot] = true;
			var qtyInput = row.querySelector('[data-field="entrega_cantidad"][data-slot="' + slot + '"]');
			var remInput = row.querySelector('[data-field="entrega_remision"][data-slot="' + slot + '"]');
			if (qtyInput) {
				qtyInput.setAttribute('data-entrega-id', String(entrega.id || 0));
				qtyInput.value = entrega.cantidad_fmt || entrega.cantidad || '';
			}
			if (remInput) {
				remInput.setAttribute('data-entrega-id', String(entrega.id || 0));
				remInput.value = entrega.remision || '';
			}
		});
		row.querySelectorAll('[data-field="entrega_cantidad"]').forEach(function (input) {
			var slot = input.getAttribute('data-slot') || '0';
			if (!slotsSeen[slot]) {
				input.setAttribute('data-entrega-id', '0');
				input.value = '';
				var remInput = row.querySelector('[data-field="entrega_remision"][data-slot="' + slot + '"]');
				if (remInput) {
					remInput.setAttribute('data-entrega-id', '0');
					remInput.value = '';
				}
			}
		});
	}

	function sheetUsesInventario(sheetRoot) {
		var root = getPedidosSheetRoot(sheetRoot);
		return root ? root.getAttribute('data-uses-inventario') !== '0' : true;
	}

	function getReferenciaSource(sheetRoot) {
		var root = getPedidosSheetRoot(sheetRoot);
		return root ? String(root.getAttribute('data-referencia-source') || 'inventario') : 'inventario';
	}

	function getReferenciaOptions(sheetRoot) {
		var root = getPedidosSheetRoot(sheetRoot);
		if (!root) {
			return [];
		}
		try {
			return JSON.parse(root.getAttribute('data-referencia-options') || root.getAttribute('data-inventario-articulos') || '[]');
		} catch (error) {
			return [];
		}
	}

	function setReferenciaOptions(options, sheetRoot) {
		var root = getPedidosSheetRoot(sheetRoot);
		if (root) {
			root.setAttribute('data-referencia-options', JSON.stringify(options || []));
		}
	}

	function getInventarioArticuloOptions(sheetRoot) {
		return getReferenciaOptions(sheetRoot);
	}

	function setInventarioArticuloOptions(options, sheetRoot) {
		setReferenciaOptions(options, sheetRoot);
	}

	function normalizeReferencia(value) {
		return String(value || '').toLowerCase().trim();
	}

	function buildArticuloOptionLabel(item, referencia) {
		var ref = String(referencia || '').trim();
		var name = String(item || '').trim();
		if (!ref) {
			return '';
		}
		if (name !== '' && name !== ref) {
			return name + ' — ' + ref;
		}
		return ref;
	}

	function sortArticuloOptions(options) {
		return (options || []).slice().sort(function (a, b) {
			return String(a.label || a.value || '').localeCompare(String(b.label || b.value || ''), 'es', { sensitivity: 'base' });
		});
	}

	function mergeArticuloOptions(baseOptions, extraOptions) {
		var map = {};

		(baseOptions || []).forEach(function (opt) {
			var value = String(opt.value || '').trim();
			if (!value) {
				return;
			}
			map[normalizeReferencia(value)] = {
				value: value,
				label: String(opt.label || value)
			};
		});

		(extraOptions || []).forEach(function (opt) {
			var value = String(opt.value || '').trim();
			if (!value) {
				return;
			}
			map[normalizeReferencia(value)] = {
				value: value,
				label: String(opt.label || value)
			};
		});

		return sortArticuloOptions(Object.keys(map).map(function (key) {
			return map[key];
		}));
	}

	function collectInventarioArticuloOptionsFromDom(sheetRoot) {
		var root = getPedidosSheetRoot(sheetRoot);
		var options = [];
		var rows = root
			? root.querySelectorAll('[data-pedidos-inventario-row]')
			: document.querySelectorAll('[data-pedidos-inventario-row]');

		rows.forEach(function (row) {
			if ((row.getAttribute('data-inventario-id') || '0') === '0') {
				return;
			}
			var referencia = fieldValue(row, 'referencia');
			if (!referencia) {
				return;
			}
			options.push({
				value: referencia,
				label: buildArticuloOptionLabel(fieldValue(row, 'item'), referencia)
			});
		});

		return options;
	}

	function buildArticuloFieldHtml(selected, sheetRoot) {
		return buildArticuloSelectHtml(selected, sheetRoot);
	}

	function buildArticuloSelectHtml(selected, sheetRoot) {
		var options = getReferenciaOptions(sheetRoot);
		var strict = getReferenciaSource(sheetRoot) === 'formado_yield';
		var selectedNorm = normalizeReferencia(selected);
		var hasSelected = false;
		var html = '<select data-field="articulo"><option value="">Seleccionar…</option>';

		options.forEach(function (opt) {
			var val = String(opt.value || '');
			var isSelected = selectedNorm !== '' && normalizeReferencia(val) === selectedNorm;
			if (isSelected) {
				hasSelected = true;
			}
			html += '<option value="' + val.replace(/"/g, '&quot;') + '"' + (isSelected ? ' selected' : '') + '>' + String(opt.label || val).replace(/</g, '&lt;') + '</option>';
		});

		if (!strict && selectedNorm !== '' && !hasSelected) {
			html += '<option value="' + String(selected).replace(/"/g, '&quot;') + '" selected>' + String(selected).replace(/</g, '&lt;') + '</option>';
		}

		html += '</select>';
		return html;
	}

	function refreshOrdenArticuloSelects(sheetRoot) {
		var root = getPedidosSheetRoot(sheetRoot);
		if (!root) {
			return;
		}
		var rows = root.querySelectorAll('[data-pedidos-orden-row]');

		rows.forEach(function (row) {
			if (rowHasLockedReferencia(row)) {
				return;
			}
			var select = row.querySelector('select[data-field="articulo"]');
			if (!select) {
				return;
			}
			var current = select.value;
			var cell = select.closest('td');
			if (cell) {
				cell.innerHTML = buildArticuloSelectHtml(current, root);
			}
			syncOrdenEntregaFields(row);
		});
	}

	function refreshAllOrdenArticuloSelects() {
		document.querySelectorAll('[data-pedidos-sheet-root]').forEach(function (sheetRoot) {
			refreshOrdenArticuloSelects(sheetRoot);
		});
	}

	function applyInventarioArticuloOptions(serverOptions, sheetRoot) {
		var root = getPedidosSheetRoot(sheetRoot);
		if (!root || getReferenciaSource(root) === 'formado_yield') {
			return;
		}
		var options;

		if (Array.isArray(serverOptions)) {
			options = sortArticuloOptions(
				serverOptions.map(function (opt) {
					return {
						value: String(opt.value || '').trim(),
						label: String(opt.label || opt.value || '').trim()
					};
				}).filter(function (opt) {
					return opt.value !== '';
				})
			);
		} else {
			options = mergeArticuloOptions(getInventarioArticuloOptions(root), collectInventarioArticuloOptionsFromDom(root));
		}

		setInventarioArticuloOptions(options, root);
		refreshOrdenArticuloSelects(root);
	}

	function ordenRowHasOc(row) {
		return getOrdenOcNumero(row) !== '';
	}

	function ordenRowAllowsEntrega(row) {
		var estado = fieldValue(row, 'estado') || 'sin_confirmar';
		if (!ordenRowHasOc(row) || fieldValue(row, 'articulo') === '') {
			return false;
		}
		return estado === 'entregado' || estado === 'despacho';
	}

	function ordenRowAllowsCantidadFinalizadaEdit(row) {
		return (fieldValue(row, 'estado') || 'sin_confirmar') === 'finalizado';
	}

	var PEDIDOS_ORDEN_OP_ESTADOS = {
		conversion: true,
		impresion: true,
		troquelado: true,
		descartone: true,
		formado: true,
		embalaje: true,
		despacho: true,
		entregado: true,
		finalizado: true
	};

	function ordenRowAllowsOp(row) {
		var estado = fieldValue(row, 'estado') || 'sin_confirmar';
		return Boolean(PEDIDOS_ORDEN_OP_ESTADOS[estado]);
	}

	function getOrdenOpInput(row) {
		var cell = row ? row.querySelector('[data-pedidos-orden-op]') : null;
		return cell ? cell.querySelector('[data-field="op"]') : null;
	}

	function ordenRowHasOp(row) {
		if (!row) {
			return false;
		}
		var input = getOrdenOpInput(row);
		var value = input ? String(input.value || '').trim() : '';
		if (value) {
			return true;
		}
		return String(row.getAttribute('data-pedidos-orden-sort-op') || '').trim() !== '';
	}

	function opFieldHtml(value, estado) {
		var allows = Boolean(PEDIDOS_ORDEN_OP_ESTADOS[String(estado || 'sin_confirmar')]);
		var display = String(value || '').trim();
		var hasOp = display !== '';
		var title = allows
			? (hasOp ? 'Editar OP' : 'Indica la OP')
			: 'Disponible cuando el estado sea Conversión o Impresión';
		return ''
			+ '<div class="logistica-pedidos-op-field">'
			+ '<input type="text" data-field="op" class="is-computed-locked is-modal-locked"'
			+ ' value="' + escapeAttr(allows ? display : '') + '" readonly tabindex="-1" aria-readonly="true"'
			+ ' placeholder="' + escapeAttr(allows && !hasOp ? 'Sin OP' : '') + '">'
			+ '<button type="button" class="logistica-pedidos-op-btn logistica-table-icon-btn"'
			+ ' data-action="pedidos-edit-op"'
			+ ' aria-label="' + escapeAttr(title) + '" title="' + escapeAttr(title) + '"'
			+ (allows && hasOp ? '' : ' disabled')
			+ (allows && !hasOp ? ' hidden' : '')
			+ '><span class="dashicons dashicons-edit" aria-hidden="true"></span></button>'
			+ '</div>';
	}

	function syncOrdenOpField(row, options) {
		options = options || {};
		if (!row) {
			return;
		}
		var allows = ordenRowAllowsOp(row);
		var input = getOrdenOpInput(row);
		var button = row.querySelector('[data-action="pedidos-edit-op"]');
		var fieldWrap = row.querySelector('.logistica-pedidos-op-field');
		var hasOp = ordenRowHasOp(row);
		var title = allows
			? (hasOp ? 'Editar OP' : 'Indica la OP')
			: 'Disponible cuando el estado sea Conversión o Impresión';

		if (input) {
			input.readOnly = true;
			input.tabIndex = -1;
			input.classList.add('is-modal-locked', 'is-computed-locked');
			input.classList.toggle('is-op-locked', !allows);
			input.setAttribute('aria-readonly', 'true');
			if (!allows) {
				input.value = '';
				input.setAttribute('placeholder', '');
			} else if (!String(input.value || '').trim()) {
				var storedOp = String(row.getAttribute('data-pedidos-orden-sort-op') || '').trim();
				if (storedOp) {
					input.value = storedOp;
					hasOp = true;
				} else {
					input.setAttribute('placeholder', 'Sin OP');
				}
			}
		}

		if (fieldWrap) {
			fieldWrap.classList.toggle('is-op-pending', allows && !hasOp);
			fieldWrap.setAttribute('title', allows && !hasOp ? 'Haz clic para indicar la OP' : '');
		}

		if (button) {
			button.disabled = !allows || !hasOp;
			button.classList.toggle('is-disabled', !allows || !hasOp);
			button.hidden = allows && !hasOp;
			button.setAttribute('title', title);
			button.setAttribute('aria-label', title);
		}

		if (options.promptIfMissing && allows && !hasOp && !opModalDismissedRows.has(row)) {
			window.setTimeout(function () {
				if (row && ordenRowAllowsOp(row) && !ordenRowHasOp(row) && !isOpModalOpen()) {
					openOpModal(row, { auto: true });
				}
			}, 0);
		}
	}

	var PEDIDOS_ORDEN_FECHA_APROBACION_ESTADOS = {
		aprobado: true
	};

	function ordenRowAllowsFechaAprobacion(row) {
		var estado = fieldValue(row, 'estado') || 'sin_confirmar';
		return Boolean(PEDIDOS_ORDEN_FECHA_APROBACION_ESTADOS[estado]);
	}

	function getOrdenFechaAprobacionInput(row) {
		var cell = row ? row.querySelector('[data-pedidos-orden-fecha-aprobacion]') : null;
		return cell ? cell.querySelector('[data-field="fecha_aprobacion"]') : null;
	}

	function ordenRowHasFechaAprobacion(row) {
		if (!row) {
			return false;
		}
		var input = getOrdenFechaAprobacionInput(row);
		var value = input ? String(input.value || '').trim() : '';
		if (value) {
			return true;
		}
		return String(row.getAttribute('data-pedidos-orden-sort-fecha-aprobacion') || '').trim() !== '';
	}

	function ordenRowNeedsFechaAprobacionBeforeSave(row) {
		return ordenRowAllowsFechaAprobacion(row) && !ordenRowHasFechaAprobacion(row);
	}

	function promptOrdenFechaAprobacionIfNeeded(row, options) {
		options = options || {};
		if (!row || !ordenRowNeedsFechaAprobacionBeforeSave(row)) {
			return false;
		}
		faModalDismissedRows.delete(row);
		if (isFechaAprobacionModalOpen()) {
			return true;
		}
		openFechaAprobacionModal(row, {
			auto: true,
			requireConfirm: Boolean(options.requireConfirm),
			previousEstado: options.previousEstado || getPersistedOrdenLineaEstado(row) || 'sin_confirmar',
			estadoSelect: options.estadoSelect || row.querySelector('[data-field="estado"]')
		});
		return true;
	}

	function fechaAprobacionFieldHtml(value, estado) {
		var allows = Boolean(PEDIDOS_ORDEN_FECHA_APROBACION_ESTADOS[String(estado || 'sin_confirmar')]);
		var display = String(value || '').trim();
		var hasFa = display !== '';
		var title = allows
			? (hasFa ? 'Editar fecha de aprobación' : 'Indica la fecha de aprobación')
			: 'Disponible cuando el estado sea Aprobado';
		return ''
			+ '<div class="logistica-pedidos-fa-field">'
			+ '<input type="text" data-field="fecha_aprobacion" class="is-computed-locked is-modal-locked"'
			+ ' value="' + escapeAttr(allows ? display : '') + '" readonly tabindex="-1" aria-readonly="true"'
			+ ' placeholder="' + escapeAttr(allows && !hasFa ? 'Sin fecha' : '') + '">'
			+ '<button type="button" class="logistica-pedidos-fa-btn logistica-table-icon-btn"'
			+ ' data-action="pedidos-edit-fecha-aprobacion"'
			+ ' aria-label="' + escapeAttr(title) + '" title="' + escapeAttr(title) + '"'
			+ (allows && hasFa ? '' : ' disabled')
			+ (allows && !hasFa ? ' hidden' : '')
			+ '><span class="dashicons dashicons-edit" aria-hidden="true"></span></button>'
			+ '</div>';
	}

	function syncOrdenFechaAprobacionField(row, options) {
		options = options || {};
		if (!row) {
			return;
		}
		var allows = ordenRowAllowsFechaAprobacion(row);
		var input = getOrdenFechaAprobacionInput(row);
		var button = row.querySelector('[data-action="pedidos-edit-fecha-aprobacion"]');
		var fieldWrap = row.querySelector('.logistica-pedidos-fa-field');
		var hasFa = ordenRowHasFechaAprobacion(row);
		var title = allows
			? (hasFa ? 'Editar fecha de aprobación' : 'Indica la fecha de aprobación')
			: 'Disponible cuando el estado sea Aprobado';

		if (input) {
			input.readOnly = true;
			input.tabIndex = -1;
			input.classList.add('is-modal-locked', 'is-computed-locked');
			input.classList.toggle('is-fa-locked', !allows);
			input.setAttribute('aria-readonly', 'true');
			if (!allows) {
				input.value = '';
				input.setAttribute('placeholder', '');
			} else if (!String(input.value || '').trim()) {
				var storedFa = String(row.getAttribute('data-pedidos-orden-sort-fecha-aprobacion') || '').trim();
				if (storedFa) {
					input.value = storedFa;
					hasFa = true;
				} else {
					input.setAttribute('placeholder', 'Sin fecha');
				}
			}
		}

		if (fieldWrap) {
			fieldWrap.classList.toggle('is-fa-pending', allows && !hasFa);
			fieldWrap.setAttribute('title', allows && !hasFa ? 'Haz clic para indicar la fecha de aprobación' : '');
		}

		if (button) {
			button.disabled = !allows || !hasFa;
			button.classList.toggle('is-disabled', !allows || !hasFa);
			button.hidden = allows && !hasFa;
			button.setAttribute('title', title);
			button.setAttribute('aria-label', title);
		}

		if (options.promptIfMissing && allows && !hasFa && !faModalDismissedRows.has(row)) {
			window.setTimeout(function () {
				if (row && ordenRowAllowsFechaAprobacion(row) && !ordenRowHasFechaAprobacion(row) && !isFechaAprobacionModalOpen()) {
					openFechaAprobacionModal(row, { auto: true });
				}
			}, 0);
		}

		updateFechaEntregaCell(row, getOrdenFechaEntregaLineaFromRow(row));
	}

	function getOrdenFechaEntregaLineaFromRow(row) {
		if (!row) {
			return {};
		}
		var faInput = getOrdenFechaAprobacionInput(row);
		var faValue = faInput ? String(faInput.value || '').trim() : '';
		if (!faValue) {
			faValue = String(row.getAttribute('data-pedidos-orden-sort-fecha-aprobacion') || '').trim();
		}
		return {
			fecha_entrega: fieldValue(row, 'fecha_entrega'),
			fecha_prorroga: fieldValue(row, 'fecha_prorroga'),
			fecha_aprobacion: faValue
		};
	}

	function computePedidosDiasEntregaDesdeAprobacion(fechaEntregaEffective, fechaAprobacion) {
		var entrega = parsePedidosIsoDate(fechaEntregaEffective);
		var aprob = parsePedidosIsoDate(fechaAprobacion);
		if (!entrega || !aprob) {
			return null;
		}
		return Math.round((entrega.getTime() - aprob.getTime()) / 86400000);
	}

	function formatPedidosDiasEntregaLabel(dias) {
		if (dias == null || isNaN(dias)) {
			return '';
		}
		var n = parseInt(dias, 10);
		return n + (Math.abs(n) === 1 ? ' día' : ' días');
	}

	function getCantidadFinalizadaInput(row) {
		var cell = row ? row.querySelector('[data-pedidos-orden-cantidad-finalizada]') : null;
		return cell ? cell.querySelector('[data-field="cantidad_entregada"]') : null;
	}

	function getRowDespachadaTotal(row, linea) {
		if (linea && linea.cantidad_despachada != null) {
			return parsePedidosQuantity(linea.cantidad_despachada);
		}
		if (!row) {
			return 0;
		}
		var total = 0;
		row.querySelectorAll('[data-field="parcial_cantidad"]').forEach(function (input) {
			total += parsePedidosQuantity(input.value);
		});
		return total;
	}

	var ORDEN_ESTADO_ROW_CLASS_SLUGS = [
		'sin-confirmar',
		'aprobado',
		'cancelado',
		'programado',
		'conversion',
		'impresion',
		'troquelado',
		'descartone',
		'formado',
		'embalaje',
		'finalizado',
		'despacho',
		'entregado'
	];

	function ordenEstadoToRowClassSlug(estado) {
		return String(estado || 'sin_confirmar').replace(/_/g, '-');
	}

	function syncOrdenRowEstadoClass(row, estado) {
		if (!row) {
			return;
		}
		var slug = ordenEstadoToRowClassSlug(estado);
		ORDEN_ESTADO_ROW_CLASS_SLUGS.forEach(function (item) {
			row.classList.remove('is-estado-' + item);
		});
		if (ORDEN_ESTADO_ROW_CLASS_SLUGS.indexOf(slug) !== -1) {
			row.classList.add('is-estado-' + slug);
		} else {
			row.classList.add('is-estado-sin-confirmar');
			slug = 'sin-confirmar';
		}
		row.classList.toggle('is-entregado', slug === 'entregado');
		row.classList.toggle('is-despacho', slug === 'despacho');
	}

	function maxEntregaSlots(sheetRoot) {
		var root = getPedidosSheetRoot(sheetRoot);
		if (!root) {
			return 3;
		}
		var count = parseInt(root.getAttribute('data-entrega-slots') || '3', 10);
		return isFinite(count) && count > 0 ? count : 3;
	}

	function maxOrdenEntregaSlots(sheetRoot) {
		return maxEntregaSlots(sheetRoot);
	}

	function getMaxEntregaSlotsLimit(sheetRoot) {
		var root = getPedidosSheetRoot(sheetRoot);
		if (!root) {
			return PEDIDOS_MAX_ENTREGA_SLOTS_DEFAULT;
		}
		var limit = parseInt(root.getAttribute('data-max-entrega-slots') || String(PEDIDOS_MAX_ENTREGA_SLOTS_DEFAULT), 10);
		return isFinite(limit) && limit > 0 ? limit : PEDIDOS_MAX_ENTREGA_SLOTS_DEFAULT;
	}

	function getEntregaSlotsStorageKey(boardSlug) {
		return 'logistica_pedidos_entrega_slots_' + String(boardSlug || 'default');
	}

	function getStoredEntregaSlotCount(boardSlug) {
		try {
			var stored = window.localStorage.getItem(getEntregaSlotsStorageKey(boardSlug));
			if (stored == null || stored === '') {
				return 0;
			}
			var count = parseInt(stored, 10);
			return isFinite(count) && count > 0 ? count : 0;
		} catch (error) {
			return 0;
		}
	}

	function setStoredEntregaSlotCount(boardSlug, count) {
		try {
			window.localStorage.setItem(getEntregaSlotsStorageKey(boardSlug), String(count));
		} catch (error) {
			// Sin almacenamiento local disponible.
		}
	}

	function buildOrdenParcialPairHtml(slot, slotLabel, values) {
		values = values || {};
		var qty = values.cantidad != null ? values.cantidad : '';
		var fac = values.factura != null ? values.factura : '';
		var parcialId = values.parcialId != null ? values.parcialId : '0';
		slotLabel = slotLabel || (parseInt(slot, 10) + 1);
		return ''
			+ '<div class="logistica-pedidos-parcial-pair" data-pedidos-parcial-pair data-slot="' + slot + '">'
			+ '<div class="logistica-pedidos-parcial-pair__field">'
			+ '<span class="logistica-pedidos-parcial-pair__label">Cant. ' + slotLabel + '</span>'
			+ '<input type="text" inputmode="numeric" class="logistica-pedidos-orden-parcial-cell is-modal-locked is-computed-locked" readonly tabindex="-1" aria-readonly="true"'
			+ ' data-field="parcial_cantidad" data-slot="' + slot + '" data-parcial-id="' + parcialId + '" value="' + escapeHtml(String(qty)) + '">'
			+ '</div>'
			+ '<div class="logistica-pedidos-parcial-pair__field">'
			+ '<span class="logistica-pedidos-parcial-pair__label">Factura ' + slotLabel + '</span>'
			+ '<input type="text" class="logistica-pedidos-orden-parcial-cell is-modal-locked is-computed-locked" readonly tabindex="-1" aria-readonly="true"'
			+ ' data-field="parcial_factura" data-slot="' + slot + '" data-parcial-id="' + parcialId + '" value="' + escapeHtml(String(fac)) + '">'
			+ '</div>'
			+ '<button type="button" class="logistica-pedidos-parcial-edit-btn logistica-table-icon-btn"'
			+ ' data-action="pedidos-edit-parcial-slot" data-slot="' + slot + '"'
			+ ' aria-label="Editar cantidad y factura de despacho" title="Editar cantidad y factura de despacho">'
			+ '<span class="dashicons dashicons-edit" aria-hidden="true"></span></button>'
			+ '</div>';
	}

	function buildOrdenParcialesControlsHtml() {
		return ''
			+ '<div class="logistica-pedidos-parcial-controls">'
			+ '<button type="button" class="logistica-pedidos-parcial-slot-btn logistica-pedidos-parcial-slot-btn--add" data-action="pedidos-add-orden-parcial-slot" title="Agregar par Cantidad / Factura" aria-label="Agregar par Cantidad / Factura">+</button>'
			+ '<button type="button" class="logistica-pedidos-parcial-slot-btn logistica-pedidos-parcial-slot-btn--remove" data-action="pedidos-remove-orden-parcial-slot" title="Quitar último par vacío" aria-label="Quitar último par vacío">−</button>'
			+ '</div>';
	}

	function computeRowVisibleParcialSlotsFromParciales(parcialesBySlot) {
		var maxUsed = -1;
		Object.keys(parcialesBySlot || {}).forEach(function (slotKey) {
			var parcial = parcialesBySlot[slotKey];
			var has = parseInt(parcial && parcial.id ? parcial.id : 0, 10) > 0
				|| parsePedidosQuantity(parcial && parcial.cantidad != null ? parcial.cantidad : 0) > 0
				|| String(parcial && parcial.factura != null ? parcial.factura : '').trim() !== '';
			if (has) {
				maxUsed = Math.max(maxUsed, parseInt(slotKey, 10));
			}
		});
		return Math.min(
			PEDIDOS_MAX_ENTREGA_SLOTS_DEFAULT,
			Math.max(PEDIDOS_MIN_ENTREGA_SLOTS, maxUsed + 2)
		);
	}

	function getRowVisibleParcialSlots(row) {
		var wrap = row ? row.querySelector('[data-pedidos-parciales-row]') : null;
		if (!wrap) {
			return PEDIDOS_MIN_ENTREGA_SLOTS;
		}
		var count = parseInt(wrap.getAttribute('data-visible-parcial-slots') || String(PEDIDOS_MIN_ENTREGA_SLOTS), 10);
		return isFinite(count) && count >= PEDIDOS_MIN_ENTREGA_SLOTS ? count : PEDIDOS_MIN_ENTREGA_SLOTS;
	}

	function getMaxVisibleParcialSlotsInSheet(sheetRoot) {
		sheetRoot = getPedidosSheetRoot(sheetRoot);
		if (!sheetRoot) {
			return PEDIDOS_MIN_ENTREGA_SLOTS;
		}
		var max = PEDIDOS_MIN_ENTREGA_SLOTS;
		sheetRoot.querySelectorAll('[data-pedidos-parciales-row]').forEach(function (wrap) {
			var count = parseInt(wrap.getAttribute('data-visible-parcial-slots') || String(PEDIDOS_MIN_ENTREGA_SLOTS), 10);
			if (isFinite(count) && count > max) {
				max = count;
			}
		});
		return max;
	}

	function syncRowParcialSlotButtons(row) {
		if (!row) {
			return;
		}
		var wrap = row.querySelector('[data-pedidos-parciales-row]');
		if (!wrap) {
			return;
		}
		var visible = getRowVisibleParcialSlots(row);
		var maxLimit = getMaxEntregaSlotsLimit(getPedidosSheetRoot(row));
		var addBtn = wrap.querySelector('[data-action="pedidos-add-orden-parcial-slot"]');
		var removeBtn = wrap.querySelector('[data-action="pedidos-remove-orden-parcial-slot"]');
		var atMax = visible >= maxLimit;
		var atMin = visible <= PEDIDOS_MIN_ENTREGA_SLOTS;
		if (addBtn) {
			addBtn.disabled = atMax;
			addBtn.classList.toggle('is-disabled', atMax);
			addBtn.title = atMax ? 'Máximo de entregas parciales alcanzado.' : 'Agregar par Cantidad / Factura';
		}
		if (removeBtn) {
			removeBtn.disabled = atMin;
			removeBtn.classList.toggle('is-disabled', atMin);
			removeBtn.title = atMin ? 'Debe conservar al menos ' + PEDIDOS_MIN_ENTREGA_SLOTS + ' pares.' : 'Quitar último par vacío';
		}
	}

	function addOrdenParcialSlotToRow(row) {
		if (!row) {
			return false;
		}
		var wrap = row.querySelector('[data-pedidos-parciales-row]');
		if (!wrap) {
			return false;
		}
		var visible = getRowVisibleParcialSlots(row);
		var maxLimit = getMaxEntregaSlotsLimit(getPedidosSheetRoot(row));
		if (visible >= maxLimit) {
			setBoardStatus('Máximo de ' + maxLimit + ' entregas parciales por línea.', true);
			syncRowParcialSlotButtons(row);
			return false;
		}
		var newSlot = visible;
		var controls = wrap.querySelector('.logistica-pedidos-parcial-controls');
		var html = buildOrdenParcialPairHtml(newSlot, newSlot + 1);
		if (controls) {
			controls.insertAdjacentHTML('beforebegin', html);
		} else {
			wrap.insertAdjacentHTML('beforeend', html);
		}
		wrap.setAttribute('data-visible-parcial-slots', String(visible + 1));
		syncOrdenEntregaFields(row);
		syncRowParcialSlotButtons(row);
		syncInventarioEntregaSlotsFromOrdenRows(getPedidosSheetRoot(row));
		return true;
	}

	function slotParcialHasData(row, slot) {
		var snap = ordenParcialSnapshot(row, slot);
		return snap.parcialId !== '0' || snap.cantidad !== '' || snap.factura !== '';
	}

	function removeOrdenParcialSlotFromRow(row) {
		if (!row) {
			return false;
		}
		var wrap = row.querySelector('[data-pedidos-parciales-row]');
		if (!wrap) {
			return false;
		}
		var visible = getRowVisibleParcialSlots(row);
		if (visible <= PEDIDOS_MIN_ENTREGA_SLOTS) {
			setBoardStatus('Debe conservar al menos ' + PEDIDOS_MIN_ENTREGA_SLOTS + ' pares Cant/Factura.', true);
			return false;
		}
		var lastSlot = visible - 1;
		if (slotParcialHasData(row, lastSlot)) {
			setBoardStatus('No se puede quitar: el último par tiene datos registrados.', true);
			return false;
		}
		var lastPair = wrap.querySelector('[data-pedidos-parcial-pair][data-slot="' + lastSlot + '"]');
		if (lastPair) {
			lastPair.remove();
		}
		wrap.setAttribute('data-visible-parcial-slots', String(visible - 1));
		syncRowParcialSlotButtons(row);
		return true;
	}

	function ensureRowParcialSlotsForLinea(row, linea) {
		if (!row || !linea) {
			return;
		}
		var parcialesBySlot = {};
		var maxUsed = -1;
		(linea.entregas_parciales || []).forEach(function (parcial) {
			var slot = parseInt(parcial.slot_index || 0, 10);
			parcialesBySlot[slot] = parcial;
			maxUsed = Math.max(maxUsed, slot);
		});
		var needed = computeRowVisibleParcialSlotsFromParciales(parcialesBySlot);
		while (getRowVisibleParcialSlots(row) < needed) {
			if (!addOrdenParcialSlotToRow(row)) {
				break;
			}
		}
	}

	function buildOrdenParcialesWrapHtml(visibleSlots, parcialesBySlot) {
		parcialesBySlot = parcialesBySlot || {};
		var html = '<td data-pedidos-orden-parciales-wrap><div class="logistica-pedidos-parciales-row" data-pedidos-parciales-row data-visible-parcial-slots="' + visibleSlots + '">';
		for (var slot = 0; slot < visibleSlots; slot++) {
			var parcial = parcialesBySlot[slot] || parcialesBySlot[String(slot)] || null;
			html += buildOrdenParcialPairHtml(slot, slot + 1, {
				cantidad: parcial ? (parcial.cantidad_fmt || parcial.cantidad || '') : '',
				factura: parcial ? (parcial.factura || '') : '',
				parcialId: parcial ? String(parcial.id || 0) : '0'
			});
		}
		html += buildOrdenParcialesControlsHtml();
		html += '</div></td>';
		return html;
	}

	function buildInventarioEntregaSlotCellsHtml(slot) {
		return ''
			+ '<td><input type="text" inputmode="numeric" class="is-sync-readonly" readonly tabindex="-1" data-field="entrega_cantidad" data-slot="' + slot + '" data-entrega-id="0" title="Sincronizado desde órdenes de compra"></td>'
			+ '<td><input type="text" class="is-sync-readonly" readonly tabindex="-1" data-field="entrega_remision" data-slot="' + slot + '" data-entrega-id="0" title="Sincronizado desde órdenes de compra"></td>';
	}

	function buildInventarioEntregaHeaderPairHtml() {
		return '<th>Cantidad</th><th>Remisión</th>';
	}

	function getOrdenTableColspan() {
		return PEDIDOS_ORDEN_OC_BASE_COLS + 1 + 2;
	}

	function getInventarioTableColspan(slots) {
		return PEDIDOS_INVENTARIO_BASE_COLS + (slots * 2) + 1;
	}

	function updateOrdenTableColspans(sheetRoot) {
		var colspan = getOrdenTableColspan();
		sheetRoot = getPedidosSheetRoot(sheetRoot);
		if (!sheetRoot) {
			return;
		}
		sheetRoot.querySelectorAll('[data-pedidos-ordenes-rows] [data-pedidos-empty-row] td, [data-pedidos-orden-filter-empty] td').forEach(function (td) {
			td.colSpan = colspan;
		});
	}

	function updateInventarioTableColspans(sheetRoot, slots) {
		var colspan = getInventarioTableColspan(slots);
		sheetRoot = getPedidosSheetRoot(sheetRoot);
		if (!sheetRoot) {
			return;
		}
		sheetRoot.querySelectorAll('[data-pedidos-inventario-rows] [data-pedidos-empty-row] td').forEach(function (td) {
			td.colSpan = colspan;
		});
	}

	function syncInventarioEntregaSlotsFromOrdenRows(sheetRoot) {
		sheetRoot = getPedidosSheetRoot(sheetRoot);
		if (!sheetRoot) {
			return;
		}
		var maxFromRows = getMaxVisibleParcialSlotsInSheet(sheetRoot);
		var storedCount = getStoredEntregaSlotCount(getBoardSlug(sheetRoot));
		var targetCount = Math.max(maxEntregaSlots(sheetRoot), storedCount || 0, maxFromRows);
		ensureEntregaSlotCount(sheetRoot, targetCount);
	}

	function appendInventarioEntregaSlotToSheet(sheetRoot) {
		sheetRoot = getPedidosSheetRoot(sheetRoot);
		if (!sheetRoot || sheetRoot.getAttribute('data-uses-inventario') !== '1') {
			return false;
		}

		var current = maxEntregaSlots(sheetRoot);
		var maxLimit = getMaxEntregaSlotsLimit(sheetRoot);
		if (current >= maxLimit) {
			return false;
		}

		var newSlot = current;
		var nextCount = newSlot + 1;
		var invTable = sheetRoot.querySelector('[data-pedidos-inventario-table]');
		if (!invTable) {
			return false;
		}

		var invHeaderRow = invTable.querySelector('thead tr:last-child');
		var invGroupHead = invTable.querySelector('[data-pedidos-inventario-entregas-group-head]');
		if (invHeaderRow) {
			invHeaderRow.insertAdjacentHTML('beforeend', buildInventarioEntregaHeaderPairHtml());
		}
		if (invGroupHead) {
			invGroupHead.colSpan = nextCount * 2;
		}
		sheetRoot.querySelectorAll('[data-pedidos-inventario-row]').forEach(function (row) {
			var actionsCell = row.querySelector('.logistica-pedidos-table__actions-col');
			if (actionsCell) {
				actionsCell.insertAdjacentHTML('beforebegin', buildInventarioEntregaSlotCellsHtml(newSlot));
			}
		});
		updateInventarioTableColspans(sheetRoot, nextCount);

		sheetRoot.setAttribute('data-entrega-slots', String(nextCount));
		setStoredEntregaSlotCount(getBoardSlug(sheetRoot), nextCount);
		return true;
	}

	function ensureEntregaSlotCount(sheetRoot, targetCount) {
		sheetRoot = getPedidosSheetRoot(sheetRoot);
		if (!sheetRoot) {
			return;
		}
		targetCount = parseInt(targetCount, 10);
		if (!isFinite(targetCount) || targetCount < 1) {
			return;
		}
		targetCount = Math.min(getMaxEntregaSlotsLimit(sheetRoot), targetCount);
		while (maxEntregaSlots(sheetRoot) < targetCount) {
			if (!appendInventarioEntregaSlotToSheet(sheetRoot)) {
				break;
			}
		}
	}

	function initPedidosEntregaSlots(sheetRoot) {
		sheetRoot = getPedidosSheetRoot(sheetRoot);
		if (!sheetRoot) {
			return;
		}
		updateOrdenTableColspans(sheetRoot);
		var phpCount = maxEntregaSlots(sheetRoot);
		var maxFromRows = getMaxVisibleParcialSlotsInSheet(sheetRoot);
		var storedCount = getStoredEntregaSlotCount(getBoardSlug(sheetRoot));
		var targetCount = Math.max(phpCount, storedCount || 0, maxFromRows);
		if (targetCount > phpCount) {
			ensureEntregaSlotCount(sheetRoot, targetCount);
		}
		sheetRoot.querySelectorAll('[data-pedidos-orden-row]').forEach(function (row) {
			syncRowParcialSlotButtons(row);
		});
	}

	function buildInventarioEntregaCellsHtml(sheetRoot) {
		var html = '';
		var slots = maxEntregaSlots(sheetRoot);
		for (var slot = 0; slot < slots; slot++) {
			html += buildInventarioEntregaSlotCellsHtml(slot);
		}
		return html;
	}

	function buildOrdenParcialCellsHtml(sheetRoot, linea) {
		linea = linea || {};
		var parcialesBySlot = {};
		(linea.entregas_parciales || []).forEach(function (parcial) {
			parcialesBySlot[String(parcial.slot_index || 0)] = parcial;
		});
		var visibleSlots = computeRowVisibleParcialSlotsFromParciales(parcialesBySlot);
		var html = buildOrdenParcialesWrapHtml(visibleSlots, parcialesBySlot);
		html += '<td class="is-auto" data-pedidos-orden-total-entregado data-cantidad-pedida="0">0 / 0</td>';
		return html;
	}

	function updateOrdenLineaComputedQuantities(row, linea) {
		var pedida;
		var despachada;
		var pendiente;
		var finalCell;
		var pendienteCell;
		var finalInput;
		var finalValue;
		var pendienteValue;
		var despachadaValue;

		if (!row) {
			return;
		}

		linea = linea || {};
		pedida = linea.cantidad != null ? parsePedidosQuantity(linea.cantidad) : parsePedidosQuantity(fieldValue(row, 'cantidad'));
		finalCell = row.querySelector('[data-pedidos-orden-cantidad-finalizada]');
		pendienteCell = row.querySelector('[data-pedidos-orden-pendiente]');
		finalInput = getCantidadFinalizadaInput(row);

		if (linea.cantidad_entregada != null) {
			finalValue = linea.cantidad_entregada_fmt || formatPedidosQuantity(linea.cantidad_entregada) || '0';
		} else if (finalInput) {
			finalValue = formatPedidosQuantity(parsePedidosQuantity(finalInput.value)) || '0';
		} else {
			finalValue = '0';
		}

		despachada = getRowDespachadaTotal(row, linea);
		despachadaValue = linea.cantidad_despachada_fmt || formatPedidosQuantity(despachada) || '0';
		row.setAttribute('data-pedidos-cantidad-despachada', String(despachada));

		if (finalInput && document.activeElement !== finalInput) {
			finalInput.value = finalValue;
		}

		pendiente = Math.max(0, pedida - despachada);
		pendienteValue = linea.cantidad_pendiente_fmt || formatPedidosQuantity(pendiente) || '0';
		if (pendienteCell) {
			setComputedCellValue(pendienteCell, pendienteValue);
		}
		row.setAttribute('data-pedidos-orden-sort-cantidad-finalizada', finalValue);
		row.setAttribute('data-pedidos-orden-sort-pendiente', pendienteValue);
		syncOrdenCantidadFinalizadaField(row);
		syncFinalizadaAccuracyBadge(row, linea);
		updatePedidosOrdenesTotals(getPedidosSheetRoot(row));
	}

	function computeFinalizadaAccuracyBadge(linea, row) {
		linea = linea || {};
		var pedida = linea.cantidad != null
			? parsePedidosQuantity(linea.cantidad)
			: parsePedidosQuantity(fieldValue(row, 'cantidad'));
		var finalizada = linea.cantidad_entregada != null
			? parsePedidosQuantity(linea.cantidad_entregada)
			: parsePedidosQuantity(fieldValue(row, 'cantidad_entregada'));
		var tolerancia = linea.cantidad_maxima_recibida != null
			? parsePedidosToleranciaPct(linea.cantidad_maxima_recibida)
			: parsePedidosToleranciaPct(fieldValue(row, 'cantidad_maxima_recibida'));
		if (!tolerancia || tolerancia <= 0) {
			tolerancia = 10;
		}
		if (pedida <= 0 || finalizada <= 0) {
			return { label: '', className: 'is-empty', withinTolerance: true };
		}
		var diff = ((finalizada - pedida) / pedida) * 100;
		var within = Math.abs(diff) <= tolerancia;
		var absFmt = (Math.round(Math.abs(diff) * 10) / 10).toFixed(1);
		var tolFmt = String(Math.round(tolerancia));
		var label;
		var className = within ? 'is-within-tolerance' : 'is-over-tolerance';
		if (Math.abs(diff) < 0.05) {
			label = '0% (±' + tolFmt + '%)';
		} else if (within) {
			label = (diff > 0 ? '+' : '−') + absFmt + '% (dentro ±' + tolFmt + '%)';
		} else {
			label = (diff > 0 ? '+' : '−') + absFmt + '% (' + (diff > 0 ? 'supera' : 'falta') + ' ±' + tolFmt + '%)';
		}
		return { label: label, className: className, withinTolerance: within };
	}

	function syncFinalizadaAccuracyBadge(row, linea) {
		if (!row) {
			return;
		}
		var cell = row.querySelector('[data-pedidos-orden-cantidad-finalizada]');
		var badge = cell ? cell.querySelector('[data-pedidos-finalizada-accuracy]') : null;
		if (!badge) {
			return;
		}
		if (linea && linea.finalizada_accuracy && linea.finalizada_accuracy.label) {
			badge.textContent = linea.finalizada_accuracy.label;
			badge.className = 'logistica-pedidos-finalizada-accuracy ' + (linea.finalizada_accuracy.class || 'is-within-tolerance');
			badge.hidden = false;
			badge.setAttribute('title', linea.finalizada_accuracy.label);
			return;
		}
		var computed = computeFinalizadaAccuracyBadge(linea || {}, row);
		if (!computed.label) {
			badge.textContent = '';
			badge.className = 'logistica-pedidos-finalizada-accuracy is-empty';
			badge.hidden = true;
			badge.removeAttribute('title');
			return;
		}
		badge.textContent = computed.label;
		badge.className = 'logistica-pedidos-finalizada-accuracy ' + computed.className;
		badge.hidden = false;
		badge.setAttribute('title', computed.label);
	}

	function syncPedidosOrdenRowFilterAttrs(row, orden, linea) {
		if (!row) {
			return;
		}
		orden = orden || {};
		linea = linea || {};
		var cfg = getConfig();
		var estadoOptions = cfg.estadoOptions || {};
		var ocNumero = String(orden.oc_numero || '');
		var cliente = String(orden.cliente || '');
		var referencia = String(linea.articulo || '');
		var descripcion = String(linea.descripcion || '');
		var observaciones = String(linea.observaciones || '');
		var op = String(linea.op || '');
		var fechaAprobacion = String(linea.fecha_aprobacion || '');
		var estado = String(linea.estado || 'sin_confirmar');
		var cantidadFinalizada = linea.cantidad_entregada_fmt || formatPedidosQuantity(linea.cantidad_entregada) || '0';
		var cantidadPendiente = linea.cantidad_pendiente_fmt || formatPedidosQuantity(
			Math.max(0, parsePedidosQuantity(linea.cantidad) - getRowDespachadaTotal(null, linea))
		) || '0';
		var searchBits = [ocNumero, cliente, referencia, descripcion, op, fechaAprobacion, observaciones].filter(Boolean).join(' ').toLowerCase();

		row.setAttribute('data-pedidos-orden-search', searchBits);
		row.setAttribute('data-pedidos-orden-oc', ocNumero);
		row.setAttribute('data-pedidos-orden-cliente', cliente.toLowerCase());
		row.setAttribute('data-pedidos-orden-referencia', referencia.toLowerCase());
		row.setAttribute('data-pedidos-orden-estado', estado);
		row.setAttribute('data-pedidos-orden-sort-fecha-oc', String(orden.fecha_oc || ''));
		row.setAttribute('data-pedidos-orden-sort-oc', ocNumero);
		row.setAttribute('data-pedidos-orden-sort-cliente', cliente);
		row.setAttribute('data-pedidos-orden-sort-referencia', referencia);
		row.setAttribute('data-pedidos-orden-sort-descripcion', descripcion);
		row.setAttribute('data-pedidos-orden-sort-cantidad', linea.cantidad_fmt || formatPedidosQuantity(linea.cantidad) || '');
		row.setAttribute('data-pedidos-orden-sort-cantidad-finalizada', cantidadFinalizada);
		row.setAttribute('data-pedidos-orden-sort-pendiente', cantidadPendiente);
		row.setAttribute('data-pedidos-orden-sort-cantidad-maxima', linea.cantidad_maxima_recibida_fmt || formatPedidosToleranciaPct(linea.cantidad_maxima_recibida) || '');
		row.setAttribute('data-pedidos-orden-sort-precio', linea.precio_unit_fmt || formatPedidosMoney(linea.precio_unit) || '');
		row.setAttribute('data-pedidos-orden-fecha-entrega', String(linea.fecha_entrega || ''));
		row.setAttribute('data-pedidos-orden-fecha-prorroga', String(linea.fecha_prorroga || ''));
		row.setAttribute('data-pedidos-orden-sort-fecha-entrega', String(linea.fecha_prorroga || linea.fecha_entrega || ''));
		row.setAttribute('data-pedidos-orden-sort-observaciones', observaciones);
		row.setAttribute('data-pedidos-orden-sort-op', op);
		row.setAttribute('data-pedidos-orden-sort-fecha-aprobacion', fechaAprobacion);
		row.setAttribute('data-pedidos-orden-sort-estado', estadoOptions[estado] || estado);
		syncOrdenRowEntregadoAt(row, linea);
	}

	function ordenRowCountsForTotals(row) {
		var cantidad = parsePedidosQuantity(fieldValue(row, 'cantidad'));
		var finalInput = getCantidadFinalizadaInput(row);
		var finalizada = finalInput ? parsePedidosQuantity(finalInput.value) : 0;
		var despachada = getRowDespachadaTotal(row);
		return {
			cantidad: cantidad,
			finalizada: finalizada,
			pendiente: Math.max(0, cantidad - despachada),
			entregada: despachada
		};
	}

	function updatePedidosOrdenesTotals(sheetRoot) {
		sheetRoot = getPedidosSheetRoot(sheetRoot);
		if (!sheetRoot) {
			return;
		}
		var totalsRow = sheetRoot.querySelector('[data-pedidos-orden-totals-row]');
		if (!totalsRow) {
			return;
		}

		var sums = {
			cantidad: 0,
			finalizada: 0,
			pendiente: 0,
			entregada: 0
		};
		var visibleCount = 0;
		var allRows = sheetRoot.querySelectorAll('[data-pedidos-orden-row]');

		allRows.forEach(function (row) {
			if (row.hidden || row.dataset.logisticaFilterVisible === '0') {
				return;
			}
			visibleCount += 1;
			var counts = ordenRowCountsForTotals(row);
			sums.cantidad += counts.cantidad;
			sums.finalizada += counts.finalizada;
			sums.pendiente += counts.pendiente;
			sums.entregada += counts.entregada;
		});

		totalsRow.hidden = visibleCount === 0;

		var cantCell = totalsRow.querySelector('[data-pedidos-orden-total-cantidad]');
		var finCell = totalsRow.querySelector('[data-pedidos-orden-total-cantidad-finalizada]');
		var pendCell = totalsRow.querySelector('[data-pedidos-orden-total-pendiente]');
		var entCell = totalsRow.querySelector('[data-pedidos-orden-total-entregado]');
		var labelCell = totalsRow.querySelector('[data-pedidos-orden-totals-label]');

		if (cantCell) {
			cantCell.textContent = formatPedidosQuantity(sums.cantidad) || '0';
		}
		if (finCell) {
			finCell.textContent = formatPedidosQuantity(sums.finalizada) || '0';
		}
		if (pendCell) {
			pendCell.textContent = formatPedidosQuantity(sums.pendiente) || '0';
		}
		if (entCell) {
			entCell.textContent = (formatPedidosQuantity(sums.entregada) || '0') + ' / ' + (formatPedidosQuantity(sums.cantidad) || '0');
		}
		if (labelCell) {
			labelCell.innerHTML = visibleCount > 0 && visibleCount < allRows.length
				? '<strong>Totales (visibles)</strong>'
				: '<strong>Totales</strong>';
		}
	}

	function updateOrdenTotalCell(row, linea) {
		var totalCell = row.querySelector('[data-pedidos-orden-total-entregado]');
		if (!totalCell) {
			return;
		}
		var pedida = fieldValue(row, 'cantidad') || totalCell.getAttribute('data-cantidad-pedida') || '0';
		totalCell.setAttribute('data-cantidad-pedida', pedida);
		var despachada = getRowDespachadaTotal(row, linea || null);
		totalCell.textContent = (formatPedidosQuantity(despachada) || '0') + ' / ' + pedida;
		updateOrdenLineaComputedQuantities(row, linea || null);
	}

	function ordenLineaEditButtonHtml() {
		return ''
			+ '<button type="button" class="button button-small logistica-table-icon-btn" data-action="pedidos-edit-orden-linea" aria-label="Editar" title="Editar">'
			+ '<span class="dashicons dashicons-edit" aria-hidden="true"></span>'
			+ '</button>';
	}

	function ordenLineaDeleteButtonHtml() {
		return ''
			+ '<button type="button" class="button button-small logistica-table-icon-btn" data-action="pedidos-delete-orden-linea" aria-label="Eliminar" title="Eliminar">'
			+ '<span class="dashicons dashicons-trash" aria-hidden="true"></span>'
			+ '</button>';
	}

	function ensureOrdenLineaActionButtons(row) {
		if (!row) {
			return;
		}
		var actions = row.querySelector('.logistica-pedidos-table__actions-col');
		if (!actions) {
			return;
		}
		if (!actions.querySelector('[data-action="pedidos-edit-orden-linea"]')) {
			actions.insertAdjacentHTML('afterbegin', ordenLineaEditButtonHtml());
		}
		ensureOrdenLineaDeleteButton(row);
	}

	function ensureOrdenLineaDeleteButton(row) {
		if (!row) {
			return;
		}
		var actions = row.querySelector('.logistica-pedidos-table__actions-col');
		if (!actions || actions.querySelector('[data-action="pedidos-delete-orden-linea"]')) {
			return;
		}
		actions.insertAdjacentHTML('beforeend', ordenLineaDeleteButtonHtml());
	}

	function ensureAllOrdenLineaActionButtons() {
		document.querySelectorAll('[data-pedidos-orden-row]').forEach(ensureOrdenLineaActionButtons);
	}

	function ensureAllOrdenLineaDeleteButtons() {
		ensureAllOrdenLineaActionButtons();
	}

	function getOrdenOcNumero(row) {
		if (!row) {
			return '';
		}
		var fromAttr = row.getAttribute('data-pedidos-orden-oc');
		if (fromAttr != null && String(fromAttr).trim() !== '') {
			return String(fromAttr).trim();
		}
		var local = row.querySelector('[data-field="oc_numero"]');
		if (local) {
			return String(local.value || '').trim();
		}
		return '';
	}

	function getOrdenGroupKey(row) {
		if (!row) {
			return '';
		}
		var ocNumero = normalizeReferencia(getOrdenOcNumero(row));
		var ordenId = row.getAttribute('data-orden-id') || '0';
		if (ocNumero) {
			return 'oc:' + ocNumero + '|id:' + ordenId;
		}
		if (ordenId !== '0') {
			return 'id:' + ordenId;
		}
		return 'row:' + String(row.rowIndex || 0);
	}

	function propagateOrdenIdInGroup(row, ordenId) {
		if (!row || !ordenId) {
			return;
		}
		var ocNumero = getOrdenOcNumero(row);
		var sheetRoot = getPedidosSheetRoot(row);
		var currentOrdenId = row.getAttribute('data-orden-id') || '0';
		getOrdenRowsInGroup(sheetRoot, currentOrdenId !== '0' ? currentOrdenId : '', ocNumero).forEach(function (targetRow) {
			if (normalizeReferencia(getOrdenOcNumero(targetRow)) !== normalizeReferencia(ocNumero)) {
				return;
			}
			targetRow.setAttribute('data-orden-id', String(ordenId));
		});
	}

	function escapeAttr(value) {
		return String(value == null ? '' : value).replace(/"/g, '&quot;').replace(/</g, '&lt;');
	}

	function escapeText(value) {
		return String(value == null ? '' : value).replace(/</g, '&lt;');
	}

	function lockedInputHtml(field, value, type) {
		type = type || 'text';
		return ''
			+ '<input type="' + type + '" class="is-modal-locked" readonly tabindex="-1" data-field="' + field + '"'
			+ ' value="' + escapeAttr(value) + '" title="Editar con el icono de editar">';
	}

	function lockedReferenciaHtml(value) {
		var text = String(value || '').trim();
		return ''
			+ '<input type="hidden" data-field="articulo" value="' + escapeAttr(text) + '">'
			+ '<span class="logistica-pedidos-locked-value" title="Editar con el icono de editar">'
			+ escapeText(text || '—')
			+ '</span>';
	}

	function lockedToleranciaPctHtml(field, value) {
		var display = formatPedidosToleranciaPct(value);
		return ''
			+ '<span class="logistica-pedidos-pct-field" title="Tolerancia ± % sobre la cantidad solicitada">'
			+ '<span class="logistica-pedidos-pct-field__sign" aria-hidden="true">±</span>'
			+ '<input type="text" class="is-modal-locked logistica-pedidos-pct-field__input" readonly tabindex="-1"'
			+ ' data-field="' + field + '" value="' + escapeAttr(display) + '" title="Editar con el icono de editar">'
			+ '<span class="logistica-pedidos-pct-field__suffix" aria-hidden="true">%</span>'
			+ '</span>';
	}

	function lockedComputedHtml(value) {
		return ''
			+ '<input type="text" class="is-modal-locked is-computed-locked" readonly tabindex="-1"'
			+ ' value="' + escapeAttr(value == null ? '' : value) + '" aria-readonly="true">';
	}

	function cantidadFinalizadaFieldHtml(value, estado, linea) {
		var display = formatPedidosQuantity(value) || '0';
		var editable = estado === 'finalizado';
		var title = editable ? 'Editar cantidad finalizada' : 'Solo editable con estado Finalizado';
		var accuracy = computeFinalizadaAccuracyBadge(linea || { cantidad_entregada: value }, null);
		var badgeHtml = accuracy.label
			? '<span class="logistica-pedidos-finalizada-accuracy ' + escapeAttr(accuracy.className) + '" data-pedidos-finalizada-accuracy title="' + escapeAttr(accuracy.label) + '">' + escapeHtml(accuracy.label) + '</span>'
			: '<span class="logistica-pedidos-finalizada-accuracy is-empty" data-pedidos-finalizada-accuracy hidden></span>';
		return ''
			+ '<div class="logistica-pedidos-cantidad-finalizada-wrap">'
			+ '<div class="logistica-pedidos-cantidad-finalizada-field">'
			+ '<input type="text" inputmode="numeric" data-field="cantidad_entregada"'
			+ ' class="is-computed-locked is-modal-locked"'
			+ ' value="' + escapeAttr(display) + '" readonly tabindex="-1" aria-readonly="true">'
			+ '<button type="button" class="logistica-pedidos-cantidad-finalizada-btn logistica-table-icon-btn"'
			+ ' data-action="pedidos-edit-cantidad-finalizada"'
			+ ' aria-label="' + escapeAttr(title) + '" title="' + escapeAttr(title) + '"'
			+ (editable ? '' : ' disabled')
			+ '><span class="dashicons dashicons-edit" aria-hidden="true"></span></button>'
			+ '</div>'
			+ badgeHtml
			+ '</div>';
	}

	function syncOrdenCantidadFinalizadaField(row) {
		var input = getCantidadFinalizadaInput(row);
		var button = row ? row.querySelector('[data-action="pedidos-edit-cantidad-finalizada"]') : null;
		var allows = ordenRowAllowsCantidadFinalizadaEdit(row);
		var title = allows ? 'Editar cantidad finalizada' : 'Solo editable con estado Finalizado';
		if (input) {
			input.readOnly = true;
			input.tabIndex = -1;
			input.classList.add('is-modal-locked', 'is-computed-locked');
			input.classList.remove('is-computed-editable');
			input.setAttribute('aria-readonly', 'true');
			input.removeAttribute('title');
		}
		if (button) {
			button.disabled = !allows;
			button.classList.toggle('is-disabled', !allows);
			button.setAttribute('title', title);
			button.setAttribute('aria-label', title);
		}
	}

	function setComputedCellValue(cell, value) {
		var text = value == null ? '' : String(value);
		if (!cell) {
			return text;
		}
		var input = cell.querySelector('input.is-computed-locked');
		if (input) {
			input.value = text;
		} else {
			cell.textContent = text;
		}
		return text;
	}

	function setLockedFieldInContainer(container, field, value, type) {
		if (!container) {
			return;
		}
		if (field === 'articulo') {
			var hidden = container.querySelector('input[type="hidden"][data-field="articulo"]');
			var span = container.querySelector('.logistica-pedidos-locked-value');
			var text = String(value || '').trim();
			if (hidden) {
				hidden.value = text;
			}
			if (span) {
				span.textContent = text || '—';
			}
			return;
		}
		if (field === 'descripcion') {
			var referenciaHost = container.matches('[data-pedidos-orden-referencia-cell]')
				? container
				: container.querySelector('[data-pedidos-orden-referencia-cell]');
			var referenciaInput = referenciaHost
				? referenciaHost.querySelector('[data-field="descripcion"]')
				: container.querySelector('[data-field="descripcion"]');
			var referenciaValue = value == null ? '' : String(value);
			if (referenciaInput) {
				referenciaInput.value = referenciaValue;
			}
			var referenciaRow = container.closest ? container.closest('[data-pedidos-orden-row]') : null;
			if (referenciaRow) {
				referenciaRow.setAttribute('data-pedidos-orden-sort-descripcion', referenciaValue);
			}
			return;
		}
		var input = container.querySelector('[data-field="' + field + '"]');
		if (input) {
			input.value = value == null ? '' : String(value);
		}
	}

	function buildFechaEntregaCellHtml(linea) {
		linea = linea || {};
		var fechaEntrega = String(linea.fecha_entrega || '');
		var fechaProrroga = String(linea.fecha_prorroga || '');
		var fechaAprobacion = String(linea.fecha_aprobacion || '');
		var display = fechaProrroga || fechaEntrega;
		var hasProrroga = fechaProrroga !== '';
		var dias = computePedidosDiasEntregaDesdeAprobacion(display, fechaAprobacion);
		var diasLabel = formatPedidosDiasEntregaLabel(dias);
		var html = '<span class="logistica-pedidos-fecha-entrega-cell' + (hasProrroga ? ' has-prorroga' : '') + '">';

		if (hasProrroga && fechaEntrega) {
			html += '<span class="logistica-pedidos-fecha-entrega-cell__original" title="Fecha original">' + escapeHtml(fechaEntrega) + '</span>';
		}
		html += '<span class="logistica-pedidos-fecha-entrega-cell__effective">' + escapeHtml(display) + '</span>';
		if (diasLabel) {
			html += '<span class="logistica-pedidos-fecha-entrega-cell__dias" data-pedidos-entrega-dias title="Días entre aprobación y entrega">' + escapeHtml(diasLabel) + '</span>';
		} else {
			html += '<span class="logistica-pedidos-fecha-entrega-cell__dias" data-pedidos-entrega-dias hidden></span>';
		}
		if (hasProrroga) {
			html += '<span class="logistica-pedidos-fecha-entrega-cell__badge" title="Prórroga acordada con el cliente">Prórroga</span>';
		}
		html += '</span>';
		html += '<input type="hidden" data-field="fecha_entrega" value="' + escapeAttr(fechaEntrega) + '">';
		html += '<input type="hidden" data-field="fecha_prorroga" value="' + escapeAttr(fechaProrroga) + '">';
		return html;
	}

	function updateFechaEntregaCell(row, linea) {
		if (!row) {
			return;
		}
		var cell = row.querySelector('[data-pedidos-orden-fecha-entrega-cell]');
		if (cell) {
			cell.innerHTML = buildFechaEntregaCellHtml(linea);
		}
	}

	function populateOrdenLineaLockedFields(row, orden, linea) {
		if (!row) {
			return;
		}
		setLockedFieldInContainer(row, 'articulo', linea.articulo || '');
		setLockedFieldInContainer(row, 'descripcion', linea.descripcion || '');
		setLockedFieldInContainer(row, 'cantidad', linea.cantidad_fmt || formatPedidosQuantity(linea.cantidad) || '');
		setLockedFieldInContainer(row, 'cantidad_maxima_recibida', linea.cantidad_maxima_recibida_fmt || formatPedidosToleranciaPct(linea.cantidad_maxima_recibida) || '');
		setLockedFieldInContainer(row, 'precio_unit', linea.precio_unit_fmt || formatPedidosMoney(linea.precio_unit) || '');
		setLockedFieldInContainer(row, 'fecha_entrega', linea.fecha_entrega || '');
		setLockedFieldInContainer(row, 'fecha_prorroga', linea.fecha_prorroga || '');
		updateFechaEntregaCell(row, linea);
		setLockedFieldInContainer(row, 'observaciones', linea.observaciones || '');
		setLockedFieldInContainer(row, 'op', linea.op || '');
		syncOrdenOpField(row);
		setLockedFieldInContainer(row, 'fecha_aprobacion', linea.fecha_aprobacion || '');
		syncOrdenFechaAprobacionField(row);
		var estadoSelect = row.querySelector('[data-field="estado"]');
		if (estadoSelect && linea.estado) {
			estadoSelect.value = linea.estado;
		}
		if (row.querySelector('td[data-pedidos-orden-cliente]')) {
			setLockedFieldInContainer(row, 'cliente', orden.cliente || '');
			setLockedFieldInContainer(row, 'oc_numero', orden.oc_numero || '');
			setLockedFieldInContainer(row, 'fecha_oc', orden.fecha_oc || '', 'date');
		}
		row.setAttribute('data-pedidos-orden-oc', String(orden.oc_numero || ''));
		updateOrdenLineaComputedQuantities(row, linea);
	}

	function findFirstOrdenRowWithHeaders(sheetRoot, ordenId, ocNumero) {
		var rows = getOrdenRowsInGroup(sheetRoot, ordenId, ocNumero);
		for (var i = 0; i < rows.length; i++) {
			if (rows[i].querySelector('td[data-pedidos-orden-cliente]')) {
				return rows[i];
			}
		}
		return null;
	}

	function getOrdenRowsInGroup(sheetRoot, ordenId, ocNumero) {
		if (!sheetRoot) {
			return [];
		}
		var allRows = Array.from(sheetRoot.querySelectorAll('[data-pedidos-orden-row]'));
		var wantOc = normalizeReferencia(ocNumero || '');

		return allRows.filter(function (row) {
			var rowOc = normalizeReferencia(getOrdenOcNumero(row));
			if (wantOc && rowOc !== wantOc) {
				return false;
			}
			if (ordenId && ordenId !== '0') {
				return (row.getAttribute('data-orden-id') || '0') === String(ordenId);
			}
			return !!wantOc;
		});
	}

	function bumpOrdenGroupRowspan(sheetRoot, ordenId, ocNumero) {
		var first = findFirstOrdenRowWithHeaders(sheetRoot, ordenId, ocNumero);
		if (!first) {
			return;
		}
		first.querySelectorAll('td[data-pedidos-orden-fecha], td[data-pedidos-orden-numero], td[data-pedidos-orden-cliente]').forEach(function (td) {
			var span = parseInt(td.getAttribute('rowspan') || '1', 10);
			td.setAttribute('rowspan', String(span + 1));
		});
	}

	function updateOrdenGroupHeaders(sheetRoot, ordenId, orden) {
		var first = findFirstOrdenRowWithHeaders(sheetRoot, ordenId, orden ? orden.oc_numero : '');
		if (!first || !orden) {
			return;
		}
		var fechaTd = first.querySelector('td[data-pedidos-orden-fecha]');
		var ocTd = first.querySelector('td[data-pedidos-orden-numero]');
		var clienteTd = first.querySelector('td[data-pedidos-orden-cliente]');
		if (fechaTd) {
			setLockedFieldInContainer(fechaTd, 'fecha_oc', orden.fecha_oc || '', 'date');
		}
		if (ocTd) {
			setLockedFieldInContainer(ocTd, 'oc_numero', orden.oc_numero || '');
		}
		if (clienteTd) {
			setLockedFieldInContainer(clienteTd, 'cliente', orden.cliente || '');
		}
		var templates = clonePedidosOrdenHeaderTemplatesFromRow(first);
		if (templates.length) {
			savePedidosOrdenHeaderTemplateStore(sheetRoot, getOrdenGroupKey(first), templates);
		}
	}

	function buildOrdenRowHtml(sheetRoot, orden, linea, includeHeaders) {
		var cfg = getConfig();
		var estadoOptions = cfg.estadoOptions || {};
		var estadoSelect = Object.keys(estadoOptions).map(function (key) {
			var selected = (linea.estado || 'sin_confirmar') === key ? ' selected' : '';
			return '<option value="' + key + '"' + selected + '>' + estadoOptions[key] + '</option>';
		}).join('');
		var html = '';
		var cantidadFinalizada = linea.cantidad_entregada_fmt || formatPedidosQuantity(linea.cantidad_entregada) || '0';
		var cantidadPendiente = linea.cantidad_pendiente_fmt || formatPedidosQuantity(
			Math.max(0, parsePedidosQuantity(linea.cantidad) - getRowDespachadaTotal(null, linea))
		) || '0';
		if (includeHeaders) {
			html += '<td rowspan="1" data-pedidos-orden-cliente>' + lockedInputHtml('cliente', orden.cliente || '') + '</td>';
			html += '<td rowspan="1" data-pedidos-orden-numero>' + lockedInputHtml('oc_numero', orden.oc_numero || '') + '</td>';
			html += '<td rowspan="1" data-pedidos-orden-fecha>' + lockedInputHtml('fecha_oc', orden.fecha_oc || '', 'date') + '</td>';
		}
		html += '<td>' + lockedReferenciaHtml(linea.articulo || '') + '</td>';
		html += '<td data-pedidos-orden-referencia-cell>' + lockedInputHtml('descripcion', linea.descripcion || '') + '</td>';
		html += '<td data-pedidos-orden-cantidad>' + lockedInputHtml('cantidad', linea.cantidad_fmt || formatPedidosQuantity(linea.cantidad) || '') + '</td>';
		html += '<td data-pedidos-orden-cantidad-finalizada>' + cantidadFinalizadaFieldHtml(cantidadFinalizada, linea.estado || 'sin_confirmar', linea) + '</td>';
		html += '<td data-pedidos-orden-pendiente>' + lockedComputedHtml(cantidadPendiente) + '</td>';
		html += '<td>' + lockedToleranciaPctHtml('cantidad_maxima_recibida', linea.cantidad_maxima_recibida_fmt || linea.cantidad_maxima_recibida || '') + '</td>';
		html += '<td>' + lockedInputHtml('precio_unit', linea.precio_unit_fmt || formatPedidosMoney(linea.precio_unit) || '') + '</td>';
		html += '<td data-pedidos-orden-fecha-aprobacion>' + fechaAprobacionFieldHtml(linea.fecha_aprobacion || '', linea.estado || 'sin_confirmar') + '</td>';
		html += '<td data-pedidos-orden-fecha-entrega-cell>' + buildFechaEntregaCellHtml(linea) + '</td>';
		html += '<td>' + lockedInputHtml('observaciones', linea.observaciones || '') + '</td>';
		html += '<td data-pedidos-orden-op>' + opFieldHtml(linea.op || '', linea.estado || 'sin_confirmar') + '</td>';
		html += '<td><select data-field="estado">' + estadoSelect + '</select></td>';
		html += buildOrdenParcialCellsHtml(sheetRoot, linea);
		html += '<td class="logistica-pedidos-table__actions-col">' + ordenLineaEditButtonHtml() + ordenLineaDeleteButtonHtml() + '</td>';
		return html;
	}

	function insertPedidosOrdenRowInTbody(tbody, tr, groupRows, includeHeaders) {
		if (!tbody || !tr) {
			return;
		}
		if (includeHeaders || !groupRows.length) {
			tbody.insertBefore(tr, tbody.firstChild);
			return;
		}
		var anchor = groupRows[groupRows.length - 1];
		if (anchor && anchor.parentNode === tbody) {
			if (anchor.nextSibling) {
				tbody.insertBefore(tr, anchor.nextSibling);
			} else {
				tbody.appendChild(tr);
			}
			return;
		}
		tbody.insertBefore(tr, tbody.firstChild);
	}

	function insertOrdenRowFromSave(sheetRoot, orden, linea) {
		sheetRoot = getPedidosSheetRoot(sheetRoot);
		var tbody = sheetRoot ? sheetRoot.querySelector('[data-pedidos-ordenes-rows]') : null;
		if (!tbody || !orden || !linea) {
			return null;
		}
		removeEmptyRows(tbody);
		var ordenId = String(orden.id || 0);
		var groupRows = getOrdenRowsInGroup(sheetRoot, ordenId, orden.oc_numero || '');
		var includeHeaders = groupRows.length === 0;
		var tr = document.createElement('tr');
		tr.setAttribute('data-pedidos-orden-row', '');
		tr.setAttribute('data-orden-id', ordenId);
		tr.setAttribute('data-linea-id', String(linea.id || 0));
		tr.setAttribute('data-pedidos-orden-oc', String(orden.oc_numero || ''));
		syncOrdenRowParcialesDataAttr(tr, linea.entregas_parciales || []);
		tr.innerHTML = buildOrdenRowHtml(sheetRoot, orden, linea, includeHeaders);
		syncPedidosOrdenRowFilterAttrs(tr, orden, linea);
		syncOrdenRowEstadoClass(tr, linea.estado || 'sin_confirmar');
		syncOrdenOpField(tr);
		syncOrdenFechaAprobacionField(tr);
		syncRowParcialSlotButtons(tr);
		if (!includeHeaders) {
			bumpOrdenGroupRowspan(sheetRoot, ordenId, orden.oc_numero || '');
		}
		insertPedidosOrdenRowInTbody(tbody, tr, groupRows, includeHeaders);
		if (typeof sheetRoot._pedidosOrdenFilterRefresh === 'function') {
			sheetRoot._pedidosOrdenFilterRefresh();
		}
		return tr;
	}

	function applyPedidosOcSaveToDom(payload, options) {
		options = options || {};
		var sheetRoot = options.sheetRoot || pedidosOcModalSheet;
		if (!payload || !payload.data || !sheetRoot) {
			return null;
		}
		var orden = payload.data.orden || {};
		var linea = payload.data.linea || {};
		var row = options.editRow || null;

		if (row) {
			row.setAttribute('data-orden-id', String(orden.id || 0));
			row.setAttribute('data-linea-id', String(linea.id || 0));
			populateOrdenLineaLockedFields(row, orden, linea);
			syncPedidosOrdenReferenciaDisplayFromAttrs(row);
		} else {
			row = insertOrdenRowFromSave(sheetRoot, orden, linea);
		}

		if (!row) {
			return null;
		}

		propagateOrdenIdInGroup(row, orden.id);
		updateOrdenGroupHeaders(sheetRoot, String(orden.id || 0), orden);
		getOrdenRowsInGroup(sheetRoot, String(orden.id || 0), orden.oc_numero || '').forEach(function (groupRow) {
			var groupLinea = groupRow === row ? linea : collectOrdenLineaPayload(groupRow).linea;
			syncPedidosOrdenRowFilterAttrs(groupRow, orden, groupLinea);
		});
		updateOrdenLineaRowUI(row, linea);
		syncPedidosOrdenRowFilterAttrs(row, orden, linea);
		syncOrdenEntregaFields(row);
		syncOrdenOpField(row);
		syncOrdenFechaAprobacionField(row);
		ensureOrdenLineaActionButtons(row);
		ordenSavedSnapshots.set(row, ordenLineaSnapshot(row));

		if (typeof sheetRoot._pedidosOrdenFilterRefresh === 'function') {
			sheetRoot._pedidosOrdenFilterRefresh();
		}

		if (!options.quietStatus) {
			if (payload.data.sync_warning) {
				setBoardStatus(payload.data.sync_warning, true);
			} else if (payload.data.entrega_sync && payload.data.inventario_rows) {
				payload.data.inventario_rows.forEach(function (invRow) {
					var target = sheetRoot.querySelector('[data-pedidos-inventario-row][data-inventario-id="' + invRow.id + '"]');
					updateInventarioRowUI(target, invRow);
				});
				setBoardStatus('OC guardada. Entregas sincronizadas con inventario.', false);
			} else {
				setBoardStatus(options.wasEdit ? 'Orden de compra actualizada.' : 'Orden de compra guardada.', false);
			}
		}

		scheduleRefreshPedidosWeekMetrics();
		return row;
	}

	function syncOrdenRowParcialesDataAttr(row, parciales) {
		if (!row) {
			return;
		}
		try {
			row.setAttribute('data-pedidos-parciales', JSON.stringify(Array.isArray(parciales) ? parciales : []));
		} catch (error) {
			row.setAttribute('data-pedidos-parciales', '[]');
		}
	}

	function ordenRowParcialesNeedHydration(row, parciales) {
		if (!row || !Array.isArray(parciales) || !parciales.length) {
			return false;
		}
		var needsHydrate = false;
		parciales.forEach(function (parcial) {
			var slot = String(parcial.slot_index || 0);
			var qtyInput = row.querySelector('[data-field="parcial_cantidad"][data-slot="' + slot + '"]');
			var facInput = row.querySelector('[data-field="parcial_factura"][data-slot="' + slot + '"]');
			if (!qtyInput) {
				needsHydrate = true;
				return;
			}
			var parcialId = parseInt(qtyInput.getAttribute('data-parcial-id') || '0', 10);
			var qtyValue = String(qtyInput.value || '').trim();
			var facValue = facInput ? String(facInput.value || '').trim() : '';
			var savedId = parseInt(parcial.id || 0, 10);
			var savedQty = String(parcial.cantidad_fmt || parcial.cantidad || '').trim();
			var savedFac = String(parcial.factura || '').trim();
			if (savedId > 0 && parcialId !== savedId) {
				needsHydrate = true;
				return;
			}
			if (savedQty !== '' && qtyValue === '') {
				needsHydrate = true;
				return;
			}
			if (savedFac !== '' && facValue === '') {
				needsHydrate = true;
			}
		});
		return needsHydrate;
	}

	function hydrateOrdenRowParcialesFromData(row) {
		if (!row) {
			return;
		}
		var raw = row.getAttribute('data-pedidos-parciales');
		if (!raw) {
			return;
		}
		var parciales;
		try {
			parciales = JSON.parse(raw);
		} catch (error) {
			return;
		}
		if (!Array.isArray(parciales) || !parciales.length) {
			return;
		}
		if (!ordenRowParcialesNeedHydration(row, parciales)) {
			return;
		}
		updateOrdenLineaRowUI(row, {
			id: parseInt(row.getAttribute('data-linea-id') || '0', 10) || 0,
			entregas_parciales: parciales
		});
	}

	function hydrateAllOrdenRowParciales() {
		document.querySelectorAll('[data-pedidos-orden-row]').forEach(function (row) {
			hydrateOrdenRowParcialesFromData(row);
		});
	}

	function updateOrdenLineaRowUI(row, linea, options) {
		options = options || {};
		if (!row || !linea) {
			return;
		}
		row.setAttribute('data-linea-id', String(linea.id || 0));
		if (linea.orden_id) {
			propagateOrdenIdInGroup(row, linea.orden_id);
		}
		if (linea.estado) {
			setPersistedOrdenLineaEstado(row, linea.estado);
			var estadoSelect = row.querySelector('[data-field="estado"]');
			if (estadoSelect) {
				estadoSelect.value = linea.estado;
			}
		}
		syncOrdenRowEstadoClass(row, linea.estado);
		syncOrdenRowEntregadoAt(row, linea);

		if (options.skipParciales !== true) {
			ensureRowParcialSlotsForLinea(row, linea);
			var slotsSeen = {};
			(linea.entregas_parciales || []).forEach(function (parcial) {
				var slot = String(parcial.slot_index || 0);
				slotsSeen[slot] = true;
				if (parcialSlotIsProtected(row, slot)) {
					var protectedQty = row.querySelector('[data-field="parcial_cantidad"][data-slot="' + slot + '"]');
					if (protectedQty && parcial.id) {
						protectedQty.setAttribute('data-parcial-id', String(parcial.id || 0));
					}
					var protectedFac = row.querySelector('[data-field="parcial_factura"][data-slot="' + slot + '"]');
					if (protectedFac && parcial.id) {
						protectedFac.setAttribute('data-parcial-id', String(parcial.id || 0));
					}
					return;
				}
				var qtyInput = row.querySelector('[data-field="parcial_cantidad"][data-slot="' + slot + '"]');
				var facInput = row.querySelector('[data-field="parcial_factura"][data-slot="' + slot + '"]');
				if (qtyInput) {
					qtyInput.setAttribute('data-parcial-id', String(parcial.id || 0));
					qtyInput.value = parcial.cantidad_fmt || parcial.cantidad || '';
				}
				if (facInput) {
					facInput.setAttribute('data-parcial-id', String(parcial.id || 0));
					facInput.value = parcial.factura || '';
				}
			});

			row.querySelectorAll('[data-field="parcial_cantidad"]').forEach(function (input) {
				var slot = input.getAttribute('data-slot') || '0';
				if (!slotsSeen[slot]) {
					if (parcialSlotShouldPreserve(row, slot)) {
						return;
					}
					input.setAttribute('data-parcial-id', '0');
					input.value = '';
					var facInput = row.querySelector('[data-field="parcial_factura"][data-slot="' + slot + '"]');
					if (facInput) {
						facInput.setAttribute('data-parcial-id', '0');
						facInput.value = '';
					}
				}
			});
			syncRowParcialSlotButtons(row);
			if (linea.entregas_parciales) {
				syncOrdenRowParcialesDataAttr(row, linea.entregas_parciales);
			}
		}

		var totalCell = row.querySelector('[data-pedidos-orden-total-entregado]');
		if (totalCell) {
			var pedida = linea.cantidad_fmt || linea.cantidad || fieldValue(row, 'cantidad') || '0';
			totalCell.setAttribute('data-cantidad-pedida', pedida);
			var despachada = linea.cantidad_despachada_fmt || linea.cantidad_despachada || '0';
			totalCell.textContent = despachada + ' / ' + pedida;
		}

		if (linea.precio_unit_fmt || linea.precio_unit) {
			setLockedFieldInContainer(row, 'precio_unit', linea.precio_unit_fmt || linea.precio_unit);
		}
		if (linea.cantidad_fmt || linea.cantidad) {
			setLockedFieldInContainer(row, 'cantidad', linea.cantidad_fmt || formatPedidosQuantity(linea.cantidad));
		}
		if (linea.articulo) {
			setLockedFieldInContainer(row, 'articulo', linea.articulo);
		}
		if (Object.prototype.hasOwnProperty.call(linea, 'descripcion')) {
			setLockedFieldInContainer(row, 'descripcion', linea.descripcion || '');
		}
		if (linea.cantidad_maxima_recibida_fmt || linea.cantidad_maxima_recibida != null) {
			setLockedFieldInContainer(row, 'cantidad_maxima_recibida', linea.cantidad_maxima_recibida_fmt || formatPedidosToleranciaPct(linea.cantidad_maxima_recibida));
		}
		if (linea.fecha_entrega != null || linea.fecha_prorroga != null || linea.fecha_aprobacion != null) {
			setLockedFieldInContainer(row, 'fecha_entrega', linea.fecha_entrega || '');
			setLockedFieldInContainer(row, 'fecha_prorroga', linea.fecha_prorroga || '');
			updateFechaEntregaCell(row, linea);
		}
		if (linea.op != null) {
			setLockedFieldInContainer(row, 'op', linea.op || '');
		}
		syncOrdenOpField(row);
		if (linea.fecha_aprobacion != null) {
			setLockedFieldInContainer(row, 'fecha_aprobacion', linea.fecha_aprobacion || '');
		}
		syncOrdenFechaAprobacionField(row);
		if (linea.observaciones != null) {
			setLockedFieldInContainer(row, 'observaciones', linea.observaciones || '');
		}
		updateOrdenLineaComputedQuantities(row, linea);

		ensureOrdenLineaActionButtons(row);
	}

	function applyInventarioSyncResponse(payload) {
		if (payload.data.inventario_rows) {
			payload.data.inventario_rows.forEach(function (invRow) {
				var target = document.querySelector('[data-pedidos-inventario-row][data-inventario-id="' + invRow.id + '"]');
				updateInventarioRowUI(target, invRow);
			});
		}
		if (payload.data.sync_warning) {
			setBoardStatus(payload.data.sync_warning, true);
			return;
		}
		if (payload.data.entrega_sync && payload.data.inventario_rows) {
			setBoardStatus('Entrega parcial registrada e inventario actualizado.', false);
			return;
		}
		setBoardStatus('Entrega parcial guardada.', false);
	}

	function syncOrdenEntregaFields(row) {
		if (!row || !row.matches('[data-pedidos-orden-row]')) {
			return;
		}
		var allows = ordenRowAllowsEntrega(row);
		var title = allows
			? 'Editar cantidad y factura de despacho'
			: 'Solo editable con OC, tipo de producto y estado Despacho o Entregado.';
		row.querySelectorAll('[data-action="pedidos-edit-parcial-slot"]').forEach(function (button) {
			button.disabled = !allows;
			button.classList.toggle('is-disabled', !allows);
			button.setAttribute('title', title);
			button.setAttribute('aria-label', title);
		});
		syncOrdenCantidadFinalizadaField(row);
		syncOrdenOpField(row);
		syncOrdenFechaAprobacionField(row);
		updateOrdenTotalCell(row);
	}

	function syncOrdenGroupEntregaFields(ordenId, sheetRoot, ocNumero) {
		var root = getPedidosSheetRoot(sheetRoot);
		if (!root) {
			return;
		}
		getOrdenRowsInGroup(root, ordenId || '', ocNumero || '').forEach(syncOrdenEntregaFields);
	}

	function syncAllOrdenEntregaFields() {
		document.querySelectorAll('[data-pedidos-orden-row]').forEach(function (row) {
			syncOrdenEntregaFields(row);
			syncOrdenOpField(row);
			syncOrdenFechaAprobacionField(row);
			syncRowParcialSlotButtons(row);
		});
	}

	function syncAllOrdenRowEstadoClasses() {
		document.querySelectorAll('[data-pedidos-orden-row]').forEach(function (row) {
			syncOrdenRowEstadoClass(row, fieldValue(row, 'estado'));
		});
	}

	function collectOrdenLineaPayload(row) {
		var sheetRoot = getPedidosSheetRoot(row);
		var ordenId = row.getAttribute('data-orden-id') || '0';
		var lineaId = row.getAttribute('data-linea-id') || '0';
		var fechaOcCell = sheetRoot
			? sheetRoot.querySelector('[data-pedidos-orden-row][data-orden-id="' + ordenId + '"] [data-field="fecha_oc"]')
			: document.querySelector('[data-pedidos-orden-row][data-orden-id="' + ordenId + '"] [data-field="fecha_oc"]');
		var ocCell = sheetRoot
			? sheetRoot.querySelector('[data-pedidos-orden-row][data-orden-id="' + ordenId + '"] [data-field="oc_numero"]')
			: document.querySelector('[data-pedidos-orden-row][data-orden-id="' + ordenId + '"] [data-field="oc_numero"]');
		var clienteCell = sheetRoot
			? sheetRoot.querySelector('[data-pedidos-orden-row][data-orden-id="' + ordenId + '"] [data-field="cliente"]')
			: document.querySelector('[data-pedidos-orden-row][data-orden-id="' + ordenId + '"] [data-field="cliente"]');

		return {
			orden: {
				id: ordenId,
				board_slug: getBoardSlug(sheetRoot),
				fecha_oc: fechaOcCell ? fechaOcCell.value : fieldValue(row, 'fecha_oc'),
				oc_numero: ocCell ? ocCell.value : fieldValue(row, 'oc_numero'),
				cliente: clienteCell ? clienteCell.value : fieldValue(row, 'cliente')
			},
			linea: {
				id: lineaId,
				orden_id: ordenId,
				oc_numero: ocCell ? ocCell.value : fieldValue(row, 'oc_numero'),
				articulo: fieldValue(row, 'articulo'),
				descripcion: fieldValue(row, 'descripcion'),
				cantidad: fieldValue(row, 'cantidad'),
				cantidad_maxima_recibida: fieldValue(row, 'cantidad_maxima_recibida'),
				precio_unit: fieldValue(row, 'precio_unit'),
				fecha_entrega: fieldValue(row, 'fecha_entrega'),
				fecha_prorroga: fieldValue(row, 'fecha_prorroga'),
				observaciones: fieldValue(row, 'observaciones'),
				op: ordenRowAllowsOp(row) ? fieldValue(row, 'op') : undefined,
				fecha_aprobacion: ordenRowAllowsFechaAprobacion(row) ? fieldValue(row, 'fecha_aprobacion') : undefined,
				estado: fieldValue(row, 'estado') || 'sin_confirmar',
				cantidad_entregada: ordenRowAllowsCantidadFinalizadaEdit(row) ? fieldValue(row, 'cantidad_entregada') : undefined
			}
		};
	}

	function ordenParcialSnapshot(row, slot) {
		var qtyInput = row.querySelector('[data-field="parcial_cantidad"][data-slot="' + slot + '"]');
		var facInput = row.querySelector('[data-field="parcial_factura"][data-slot="' + slot + '"]');
		return {
			cantidad: qtyInput ? String(qtyInput.value || '').trim() : '',
			factura: facInput ? String(facInput.value || '').trim() : '',
			parcialId: qtyInput ? String(qtyInput.getAttribute('data-parcial-id') || '0') : '0'
		};
	}

	function isParcialField(field) {
		return !!(field && field.matches && field.matches('[data-field="parcial_cantidad"], [data-field="parcial_factura"]'));
	}

	function getParcialSlotFromField(field) {
		return field ? String(field.getAttribute('data-slot') || '0') : '0';
	}

	function syncRowParcialEditingFlag(row) {
		if (!row) {
			return;
		}
		if (row.querySelector('[data-parcial-editing="1"]')) {
			row.dataset.pedidosParcialEditing = '1';
			return;
		}
		delete row.dataset.pedidosParcialEditing;
	}

	function setParcialFieldEditing(field, editing) {
		if (!field) {
			return;
		}
		var row = field.closest('[data-pedidos-orden-row]');
		if (editing) {
			field.dataset.parcialEditing = '1';
			if (row) {
				row.dataset.pedidosParcialEditing = '1';
				if (parcialSaveTimers.has(row)) {
					clearTimeout(parcialSaveTimers.get(row));
					parcialSaveTimers.delete(row);
				}
			}
			return;
		}
		delete field.dataset.parcialEditing;
		syncRowParcialEditingFlag(row);
	}

	function parcialSlotIsProtected(row, slot) {
		if (!row) {
			return false;
		}
		var qty = row.querySelector('[data-field="parcial_cantidad"][data-slot="' + slot + '"]');
		var fac = row.querySelector('[data-field="parcial_factura"][data-slot="' + slot + '"]');
		if ((qty && qty.dataset.parcialEditing === '1') || (fac && fac.dataset.parcialEditing === '1')) {
			return true;
		}
		var active = document.activeElement;
		if (active && row.contains(active) && isParcialField(active)) {
			return getParcialSlotFromField(active) === String(slot);
		}
		return false;
	}

	function parcialSlotShouldPreserve(row, slot) {
		if (parcialSlotIsProtected(row, slot)) {
			return true;
		}
		var snap = ordenParcialSnapshot(row, slot);
		return snap.cantidad !== '' || snap.factura !== '';
	}

	function getPersistedOrdenLineaEstado(row) {
		if (!row) {
			return '';
		}
		var persisted = row.getAttribute('data-pedidos-estado-persisted');
		if (persisted) {
			return String(persisted);
		}
		return String(row.getAttribute('data-pedidos-orden-estado') || '');
	}

	function setPersistedOrdenLineaEstado(row, estado) {
		if (!row) {
			return;
		}
		var value = String(estado || '');
		row.setAttribute('data-pedidos-estado-persisted', value);
		row.setAttribute('data-pedidos-orden-estado', value);
	}

	function rowIsEntregadoPersisted(row) {
		if (!row) {
			return false;
		}
		if (getPersistedOrdenLineaEstado(row) === 'entregado') {
			return true;
		}
		if (String(row.getAttribute('data-pedidos-orden-estado') || '').toLowerCase().trim() === 'entregado') {
			return true;
		}
		if (fieldValue(row, 'estado') === 'entregado' && resolveEstadoForEntregaPersist(row) === 'entregado') {
			return true;
		}
		return false;
	}

	function syncOrdenRowEntregadoAt(row, linea) {
		if (!row) {
			return;
		}
		linea = linea || {};
		var estado = String(linea.estado || getPersistedOrdenLineaEstado(row) || '');
		var entregadoAt = String(linea.entregado_at || '').trim();
		if ('entregado' === estado) {
			row.setAttribute('data-pedidos-orden-entregado-at', entregadoAt || getTodayYmd());
			return;
		}
		row.removeAttribute('data-pedidos-orden-entregado-at');
	}

	function notifyOrdenMovedToHistorial() {
		setBoardStatus(
			'La línea quedó como entregada y se ocultó del tablero activo. Consúltala en Historial de entregados.',
			false
		);
	}

	function handleOrdenBecameEntregado(row, wasEntregado) {
		if (!row || wasEntregado || !rowIsEntregadoPersisted(row)) {
			return;
		}
		syncOrdenRowEntregadoAt(row, { estado: 'entregado', entregado_at: row.getAttribute('data-pedidos-orden-entregado-at') || getTodayYmd() });
		notifyOrdenMovedToHistorial();
		var sheetRoot = getPedidosSheetRoot(row);
		if (sheetRoot && typeof sheetRoot._pedidosOrdenFilterRefresh === 'function') {
			sheetRoot._pedidosOrdenFilterRefresh();
		}
	}

	function ordenLineaNeedsServerSync(row) {
		if (!row) {
			return false;
		}
		var targetEstado = resolveEstadoForEntregaPersist(row);
		if (getPersistedOrdenLineaEstado(row) !== targetEstado) {
			return true;
		}
		return ordenSavedSnapshots.get(row) !== ordenLineaSnapshot(row);
	}

	function getSavedOrdenLineaEstado(row) {
		return getPersistedOrdenLineaEstado(row);
	}

	function getRowParcialEntregadoTotal(row) {
		var total = 0;
		row.querySelectorAll('[data-field="parcial_cantidad"]').forEach(function (input) {
			total += parsePedidosQuantity(input.value);
		});
		return total;
	}

	function rowHasPersistedParcial(row) {
		if (!row) {
			return false;
		}
		var found = false;
		row.querySelectorAll('[data-field="parcial_cantidad"]').forEach(function (input) {
			if (parseInt(input.getAttribute('data-parcial-id') || '0', 10) > 0) {
				found = true;
			}
		});
		return found;
	}

	function resolveEstadoForEntregaPersist(row) {
		var uiEstado = fieldValue(row, 'estado') || 'sin_confirmar';
		if (uiEstado !== 'despacho' && uiEstado !== 'entregado') {
			return uiEstado;
		}
		if (uiEstado === 'entregado') {
			var pedida = parsePedidosQuantity(fieldValue(row, 'cantidad'));
			var entregada = getRowParcialEntregadoTotal(row);
			if (rowHasPersistedParcial(row) && pedida > 0 && entregada >= pedida) {
				return 'entregado';
			}
			return 'despacho';
		}
		return uiEstado;
	}

	function ensureOrdenLineaEntregaEstadoSynced(row, options) {
		options = options || {};
		if (!ordenRowAllowsEntrega(row)) {
			return Promise.resolve();
		}
		var persistedEstado = getPersistedOrdenLineaEstado(row);
		var targetEstado = resolveEstadoForEntregaPersist(row);
		if (targetEstado !== 'despacho' && targetEstado !== 'entregado') {
			return Promise.resolve();
		}
		if (persistedEstado === targetEstado) {
			return Promise.resolve();
		}
		return saveOrdenLineaRow(row, {
			quiet: options.quiet !== false,
			estadoOverride: targetEstado
		}).catch(function (error) {
			setBoardStatus(error.message, true);
			throw error;
		});
	}

	function triggerParcialSaveAfterBlur(row, field) {
		if (!row || !field) {
			return;
		}
		var slot = getParcialSlotFromField(field);
		setParcialFieldEditing(field, false);
		window.setTimeout(function () {
			var active = document.activeElement;
			if (active && row.contains(active) && isParcialField(active) && getParcialSlotFromField(active) === slot) {
				setParcialFieldEditing(active, true);
				return;
			}
			if (field.matches('[data-field="parcial_cantidad"]')) {
				formatPedidosQuantityField(field);
			}
			updateOrdenTotalCell(row);
			triggerOrdenParcialSave(row, slot);
		}, 0);
	}

	function slotNeedsParcialSave(row, slot) {
		var snap = ordenParcialSnapshot(row, slot);
		return snap.parcialId !== '0' || snap.cantidad !== '' || snap.factura !== '';
	}

	function ensureOrdenLineaPersisted(row, options) {
		options = options || {};
		if ((row.getAttribute('data-linea-id') || '0') !== '0') {
			return Promise.resolve();
		}
		if (!ordenRowAllowsEntrega(row)) {
			return Promise.reject(new Error('Las entregas parciales requieren OC, tipo de producto y estado Despacho o Entregado.'));
		}
		return saveOrdenLineaRow(row, { quiet: options.quiet !== false });
	}

	var parcialSaveFlights = Object.create(null);
	var parcialSaveTimers = new WeakMap();

	function scheduleParcialAutoSave(row, slot, saveOptions) {
		saveOptions = saveOptions || {};
		if (!row || !slotNeedsParcialSave(row, slot)) {
			return;
		}
		var timerKey = row;
		if (parcialSaveTimers.has(timerKey)) {
			clearTimeout(parcialSaveTimers.get(timerKey));
		}
		var delay = saveOptions.immediate ? 0 : 700;
		parcialSaveTimers.set(timerKey, window.setTimeout(function () {
			parcialSaveTimers.delete(timerKey);
			triggerOrdenParcialSave(row, slot, saveOptions);
		}, delay));
	}

	function flushParcialSavesOnRow(row) {
		if (!row) {
			return Promise.resolve();
		}
		if (row.dataset.pedidosParcialEditing === '1') {
			return Promise.resolve();
		}
		if (parcialSaveTimers.has(row)) {
			clearTimeout(parcialSaveTimers.get(row));
			parcialSaveTimers.delete(row);
		}
		var slots = [];
		row.querySelectorAll('[data-field="parcial_cantidad"]').forEach(function (input) {
			var slot = input.getAttribute('data-slot') || '0';
			if (slots.indexOf(slot) === -1 && slotNeedsParcialSave(row, slot)) {
				slots.push(slot);
			}
		});
		if (!slots.length) {
			return Promise.resolve();
		}
		return Promise.all(slots.map(function (slot) {
			return saveOrdenParcialFromRow(row, slot, { quiet: true, immediate: true });
		})).then(function () {
			return undefined;
		});
	}

	function saveOrdenParcialFromRow(row, slot, options) {
		options = options || {};
		var qtyInput = row.querySelector('[data-field="parcial_cantidad"][data-slot="' + slot + '"]');
		var facInput = row.querySelector('[data-field="parcial_factura"][data-slot="' + slot + '"]');
		if (!qtyInput) {
			return Promise.resolve();
		}

		var cantidad = qtyInput.value;
		var factura = facInput ? facInput.value : '';
		var flightKey = getOrdenGroupKey(row) + ':' + (row.getAttribute('data-linea-id') || '0') + ':' + slot + ':' + cantidad + ':' + factura;
		if (parcialSaveFlights[flightKey]) {
			return parcialSaveFlights[flightKey];
		}

		var persist = options.skipLineaPersist
			? Promise.resolve()
			: ensureOrdenLineaEntregaEstadoSynced(row, { quiet: true }).then(function () {
				return ensureOrdenLineaPersisted(row, options);
			});

		var flight = persist.then(function () {
			return postPedidos('logistica_save_pedidos_orden_linea_entrega', {
				orden_linea_id: row.getAttribute('data-linea-id') || '0',
				slot_index: slot,
				cantidad: cantidad,
				factura: factura,
				estado: fieldValue(row, 'estado') || ''
			});
		}).then(function (payload) {
			if (!payload || !payload.success) {
				throw new Error((payload && payload.data && payload.data.message) || 'No se pudo guardar la entrega parcial.');
			}
			var wasEntregado = rowIsEntregadoPersisted(row);
			if (payload.data.linea) {
				updateOrdenLineaRowUI(row, payload.data.linea);
				setPersistedOrdenLineaEstado(row, payload.data.linea.estado || getPersistedOrdenLineaEstado(row));
				var estadoSelect = row.querySelector('[data-field="estado"]');
				if (estadoSelect && payload.data.linea.estado) {
					estadoSelect.value = payload.data.linea.estado;
					syncOrdenRowEstadoClass(row, payload.data.linea.estado);
				}
			}
			var rowPayload = collectOrdenLineaPayload(row);
			syncPedidosOrdenRowFilterAttrs(row, rowPayload.orden, payload.data.linea || rowPayload.linea);
			syncOrdenEntregaFields(row);
			updateOrdenLineaComputedQuantities(row, payload.data.linea || null);
			ordenSavedSnapshots.set(row, ordenLineaSnapshot(row));
			if (payload.data.linea && payload.data.linea.estado === 'entregado') {
				handleOrdenBecameEntregado(row, wasEntregado);
			}
			if (!options.quiet) {
				applyInventarioSyncResponse(payload);
			} else if (payload && payload.success) {
				setBoardStatus('Entrega parcial guardada.', false);
			}
			if (parseInt(slot, 10) >= getRowVisibleParcialSlots(row) - 1 && parsePedidosQuantity(cantidad) > 0) {
				if (row.dataset.pedidosParcialEditing !== '1') {
					addOrdenParcialSlotToRow(row);
				}
			}
			syncInventarioEntregaSlotsFromOrdenRows(getPedidosSheetRoot(row));
			return ensureOrdenLineaEntregaEstadoSynced(row, { quiet: true }).then(function () {
				if (fieldValue(row, 'estado') === 'entregado' && resolveEstadoForEntregaPersist(row) === 'entregado') {
					queueOrdenLineaAutoSave(row);
				}
				if (typeof getPedidosSheetRoot(row)._pedidosOrdenFilterRefresh === 'function') {
					getPedidosSheetRoot(row)._pedidosOrdenFilterRefresh();
				}
				scheduleRefreshPedidosWeekMetrics();
				return payload;
			});
		}).catch(function (error) {
			if (!options.suppressStatusError) {
				setBoardStatus(error.message, true);
			}
			throw error;
		}).finally(function () {
			delete parcialSaveFlights[flightKey];
		});

		parcialSaveFlights[flightKey] = flight;
		return flight;
	}

	function saveAllOrdenParcialesFromRow(row, options) {
		options = options || {};
		if (!ordenRowAllowsEntrega(row)) {
			return Promise.resolve();
		}
		var slots = [];
		row.querySelectorAll('[data-field="parcial_cantidad"]').forEach(function (input) {
			var slot = input.getAttribute('data-slot') || '0';
			if (slotNeedsParcialSave(row, slot)) {
				slots.push(slot);
			}
		});
		if (!slots.length) {
			return Promise.resolve();
		}
		var persist = options.skipLineaPersist
			? Promise.resolve()
			: ensureOrdenLineaEntregaEstadoSynced(row, { quiet: true }).then(function () {
				return ensureOrdenLineaPersisted(row, options);
			});
		return persist.then(function () {
			var chain = Promise.resolve();
			slots.forEach(function (slot) {
				chain = chain.then(function () {
					return saveOrdenParcialFromRow(row, slot, { quiet: true, skipLineaPersist: true });
				});
			});
			return chain.then(function (lastPayload) {
				if (!options.quiet && lastPayload) {
					applyInventarioSyncResponse(lastPayload);
				}
				return lastPayload;
			});
		});
	}

	function triggerOrdenParcialSave(row, slot, options) {
		options = options || {};
		if (!row || !ordenRowAllowsEntrega(row)) {
			setBoardStatus('Las entregas parciales requieren OC, tipo de producto y estado Despacho o Entregado.', true);
			return Promise.resolve();
		}
		if ((row.getAttribute('data-linea-id') || '0') === '0') {
			setBoardStatus('Guarda primero la línea de OC (número de OC y producto) antes de registrar la entrega.', true);
			return ensureOrdenLineaPersisted(row, { quiet: false }).then(function () {
				return triggerOrdenParcialSave(row, slot, options);
			}).catch(function (error) {
				setBoardStatus(error.message, true);
			});
		}
		if (!slotNeedsParcialSave(row, slot)) {
			return Promise.resolve();
		}
		return saveOrdenParcialFromRow(row, slot, options).catch(function (error) {
			setBoardStatus(error.message, true);
		});
	}

	function saveInventarioRow(row, options) {
		options = options || {};
		var oldReferencia = row.getAttribute('data-referencia') || '';

		return postPedidos('logistica_save_pedidos_inventario', collectInventarioPayload(row)).then(function (payload) {
			if (!payload || !payload.success) {
				throw new Error((payload && payload.data && payload.data.message) || 'No se pudo guardar.');
			}

			var newReferencia = String(payload.data.row.referencia || '');
			if (oldReferencia && normalizeReferencia(oldReferencia) !== normalizeReferencia(newReferencia)) {
				var sheetRoot = getPedidosSheetRoot(row);
				var articuloFields = sheetRoot
					? sheetRoot.querySelectorAll('[data-pedidos-orden-row] [data-field="articulo"]')
					: document.querySelectorAll('[data-pedidos-orden-row] [data-field="articulo"]');
				articuloFields.forEach(function (field) {
					if (normalizeReferencia(field.value) !== normalizeReferencia(oldReferencia)) {
						return;
					}
					if (field.tagName === 'SELECT') {
						field.value = newReferencia;
						return;
					}
					if (field.type === 'hidden') {
						field.value = newReferencia;
						var span = field.parentElement
							? field.parentElement.querySelector('.logistica-pedidos-locked-value')
							: null;
						if (span) {
							span.textContent = newReferencia || '—';
						}
					}
				});
			}

			updateInventarioRowUI(row, payload.data.row);
			applyInventarioArticuloOptions(payload.data.articulo_options, getPedidosSheetRoot(row));
			inventarioSavedSnapshots.set(row, inventarioRowSnapshot(row));

			if (!options.quiet) {
				setBoardStatus('Inventario guardado.', false);
			}
			return payload.data.row;
		});
	}

	var inventarioSaveTimers = new WeakMap();
	var inventarioSavedSnapshots = new WeakMap();
	var ordenSaveTimers = new WeakMap();
	var ordenSavedSnapshots = new WeakMap();

	function isOrdenLineaEditableField(target) {
		return target.matches('[data-field="estado"]');
	}

	function ordenLineaCanAutoSave(row) {
		if (!row) {
			return false;
		}
		if ((row.getAttribute('data-linea-id') || '0') !== '0') {
			return true;
		}
		return ordenRowHasOc(row) && fieldValue(row, 'articulo') !== '';
	}

	function ordenLineaSnapshot(row) {
		return JSON.stringify(collectOrdenLineaPayload(row));
	}

	function initOrdenLineaSnapshots() {
		document.querySelectorAll('[data-pedidos-orden-row]').forEach(function (row) {
			setPersistedOrdenLineaEstado(row, getPersistedOrdenLineaEstado(row) || fieldValue(row, 'estado') || 'sin_confirmar');
			if (rowIsEntregadoPersisted(row)) {
				syncOrdenRowEntregadoAt(row, {
					estado: 'entregado',
					entregado_at: row.getAttribute('data-pedidos-orden-entregado-at') || getTodayYmd()
				});
			}
			if ((row.getAttribute('data-linea-id') || '0') !== '0') {
				syncPedidosOrdenReferenciaDisplayFromAttrs(row);
				ordenSavedSnapshots.set(row, ordenLineaSnapshot(row));
			}
		});
	}

	function queueOrdenLineaAutoSave(row) {
		if (!row || !ordenLineaCanAutoSave(row)) {
			return;
		}
		if (ordenRowNeedsFechaAprobacionBeforeSave(row)) {
			promptOrdenFechaAprobacionIfNeeded(row, {
				requireConfirm: true,
				previousEstado: getPersistedOrdenLineaEstado(row) || 'sin_confirmar',
				estadoSelect: row.querySelector('[data-field="estado"]')
			});
			return;
		}
		if (!ordenLineaNeedsServerSync(row)) {
			return;
		}
		if (row.dataset.ordenSaving === '1') {
			row.dataset.ordenSavePending = '1';
			return;
		}
		row.dataset.ordenSaving = '1';
		var payload = collectOrdenLineaPayload(row);
		var estado = payload.linea && payload.linea.estado ? payload.linea.estado : '';
		var chain = Promise.resolve();
		if (estado === 'despacho' || estado === 'entregado') {
			chain = ensureOrdenLineaEntregaEstadoSynced(row, { quiet: true }).then(function () {
				return flushParcialSavesOnRow(row);
			});
		}
		chain.then(function () {
			return saveOrdenLineaRow(row, { quiet: true });
		}).then(function () {
			ordenSavedSnapshots.set(row, ordenLineaSnapshot(row));
		}).catch(function (error) {
			setBoardStatus(error.message, true);
		}).finally(function () {
			row.dataset.ordenSaving = '0';
			if (row.dataset.ordenSavePending === '1') {
				row.dataset.ordenSavePending = '0';
				queueOrdenLineaAutoSave(row);
			}
		});
	}

	function scheduleOrdenLineaAutoSave(row, saveOptions) {
		saveOptions = saveOptions || {};
		if (!row) {
			return;
		}
		if (ordenSaveTimers.has(row)) {
			clearTimeout(ordenSaveTimers.get(row));
		}
		var delay = saveOptions.immediate ? 0 : 500;
		ordenSaveTimers.set(row, window.setTimeout(function () {
			ordenSaveTimers.delete(row);
			queueOrdenLineaAutoSave(row);
		}, delay));
	}

	function inventarioRowSnapshot(row) {
		return JSON.stringify(collectInventarioPayload(row));
	}

	function initInventarioRowSnapshots() {
		document.querySelectorAll('[data-pedidos-inventario-row]').forEach(function (row) {
			if ((row.getAttribute('data-inventario-id') || '0') !== '0') {
				inventarioSavedSnapshots.set(row, inventarioRowSnapshot(row));
			}
		});
	}

	function scheduleInventarioAutoSave(row, saveOptions) {
		saveOptions = saveOptions || {};
		if (!row) {
			return;
		}
		if (inventarioSaveTimers.has(row)) {
			clearTimeout(inventarioSaveTimers.get(row));
		}
		var delay = saveOptions.immediate ? 0 : 500;
		inventarioSaveTimers.set(row, window.setTimeout(function () {
			inventarioSaveTimers.delete(row);
			queueInventarioAutoSave(row);
		}, delay));
	}

	function queueInventarioAutoSave(row) {
		if (!fieldValue(row, 'referencia')) {
			return;
		}

		var snapshot = inventarioRowSnapshot(row);
		if (inventarioSavedSnapshots.get(row) === snapshot) {
			return;
		}

		if (row.dataset.inventarioSaving === '1') {
			row.dataset.inventarioSavePending = '1';
			return;
		}

		row.dataset.inventarioSaving = '1';
		saveInventarioRow(row, { quiet: true }).catch(function (error) {
			setBoardStatus(error.message, true);
		}).finally(function () {
			row.dataset.inventarioSaving = '0';
			if (row.dataset.inventarioSavePending === '1') {
				row.dataset.inventarioSavePending = '0';
				queueInventarioAutoSave(row);
			}
		});
	}

	function isInventarioEditableField(target) {
		return target.matches(
			'[data-field="item"],'
			+ '[data-field="referencia"],'
			+ '[data-field="cantidad_op"],'
			+ '[data-field="fecha_op"],'
			+ '[data-field="reporte_hornitos"],'
			+ '[data-field="valor_und"],'
			+ '[data-field="en_produccion"]'
		);
	}

	function adjustStockFromRow(row, action, promptLabel) {
		var inventarioId = row.getAttribute('data-inventario-id') || '0';
		if (inventarioId === '0') {
			setBoardStatus('Guarda la fila de inventario antes de ajustar el stock.', true);
			return Promise.resolve();
		}
		var qtyRaw = window.prompt(promptLabel);
		if (!qtyRaw) {
			return Promise.resolve();
		}
		var qty = parsePedidosQuantity(qtyRaw);
		if (!qty || qty <= 0) {
			setBoardStatus('Indica una cantidad válida mayor que cero.', true);
			return Promise.resolve();
		}
		return postPedidos(action, {
			inventario_id: inventarioId,
			cantidad: String(qty)
		}).then(function (payload) {
			if (!payload || !payload.success) {
				throw new Error((payload && payload.data && payload.data.message) || 'No se pudo actualizar el stock.');
			}
			updateInventarioRowUI(row, payload.data.row);
			setBoardStatus('Stock actualizado.', false);
		});
	}

	function saveOrdenLineaRow(row, options) {
		options = options || {};
		var wasEntregado = rowIsEntregadoPersisted(row);
		var data = collectOrdenLineaPayload(row);
		if (options.estadoOverride) {
			data.linea.estado = options.estadoOverride;
		}
		return postPedidos('logistica_save_pedidos_orden_linea', {
			orden_json: JSON.stringify(data.orden),
			linea_json: JSON.stringify(data.linea)
		}).then(function (payload) {
			if (!payload || !payload.success) {
				throw new Error((payload && payload.data && payload.data.message) || 'No se pudo guardar la OC.');
			}
			if (payload.data.linea && payload.data.linea.id) {
				row.setAttribute('data-linea-id', String(payload.data.linea.id));
			}
			if (payload.data.orden && payload.data.orden.id) {
				propagateOrdenIdInGroup(row, payload.data.orden.id);
			} else if (payload.data.linea && payload.data.linea.orden_id) {
				propagateOrdenIdInGroup(row, payload.data.linea.orden_id);
			}
			if (payload.data.linea) {
				updateOrdenLineaRowUI(row, payload.data.linea, { skipParciales: true });
			}
			if (payload.data.orden) {
				updateOrdenGroupHeaders(getPedidosSheetRoot(row), String(payload.data.orden.id || row.getAttribute('data-orden-id') || '0'), payload.data.orden);
			}
			syncPedidosOrdenRowFilterAttrs(row, payload.data.orden || collectOrdenLineaPayload(row).orden, payload.data.linea || {});
			syncOrdenEntregaFields(row);
			syncOrdenOpField(row);
			syncOrdenFechaAprobacionField(row);
			ordenSavedSnapshots.set(row, ordenLineaSnapshot(row));
			if (payload.data.linea && payload.data.linea.estado === 'entregado') {
				handleOrdenBecameEntregado(row, wasEntregado);
			}

			if (!options.quiet) {
				if (payload.data.sync_warning) {
					setBoardStatus(payload.data.sync_warning, true);
				} else if (payload.data.entrega_sync) {
					setBoardStatus('OC guardada. Entregas sincronizadas con inventario.', false);
					if (payload.data.inventario_rows) {
						payload.data.inventario_rows.forEach(function (invRow) {
							var target = document.querySelector('[data-pedidos-inventario-row][data-inventario-id="' + invRow.id + '"]');
							updateInventarioRowUI(target, invRow);
						});
					}
				} else {
					setBoardStatus('Orden de compra guardada.', false);
				}
			}
			scheduleRefreshPedidosWeekMetrics();
			return payload;
		});
	}

	function removeEmptyRows(tbody) {
		if (!tbody) {
			return;
		}
		tbody.querySelectorAll('[data-pedidos-empty-row]').forEach(function (row) {
			row.remove();
		});
	}

	var pedidosOcModalSheet = null;
	var pedidosOcModalRow = null;
	var pedidosOcModalOrdenId = 0;
	var pedidosOcModalLineasSaved = 0;
	var cantidadFinalizadaModalRow = null;
	var opModalRow = null;
	var opModalAutoOpened = false;
	var opModalDismissedRows = typeof WeakSet !== 'undefined' ? new WeakSet() : { has: function () { return false; }, add: function () {}, delete: function () {} };
	var faModalRow = null;
	var faModalAutoOpened = false;
	var faModalPendingConfirm = null;
	var faModalDismissedRows = typeof WeakSet !== 'undefined' ? new WeakSet() : { has: function () { return false; }, add: function () {}, delete: function () {} };

	function getPedidosOcModal() {
		return document.querySelector('[data-pedidos-oc-modal]');
	}

	function getPedidosOcLineaRoot(modal) {
		return modal ? modal.querySelector('[data-pedidos-oc-linea]') : null;
	}

	function modalLineaFieldValue(modal, name) {
		var lineaRoot = getPedidosOcLineaRoot(modal);
		if (!lineaRoot) {
			return modalFieldValue(modal, name);
		}
		var field = lineaRoot.querySelector('[data-field="' + name + '"]');
		return field ? String(field.value || '').trim() : '';
	}

	function setModalLineaFieldValue(modal, name, value) {
		var lineaRoot = getPedidosOcLineaRoot(modal);
		if (!lineaRoot) {
			setModalFieldValue(modal, name, value);
			return;
		}
		var field = lineaRoot.querySelector('[data-field="' + name + '"]');
		if (field) {
			field.value = value == null ? '' : String(value);
		}
	}

	function resetPedidosOcModalMultiState() {
		pedidosOcModalOrdenId = 0;
		pedidosOcModalLineasSaved = 0;
	}

	function lockPedidosOcModalHeader(modal, locked) {
		if (!modal) {
			return;
		}
		var header = modal.querySelector('[data-pedidos-oc-header]');
		if (header) {
			header.classList.toggle('is-locked', locked);
		}
		modal.querySelectorAll('[data-pedidos-oc-header] [data-field]').forEach(function (field) {
			if (field.matches('[data-field="cliente_selector"]')) {
				field.disabled = locked;
				return;
			}
			if (field.matches('[data-field="cliente"]')) {
				field.readOnly = locked;
				return;
			}
			field.readOnly = locked;
			field.disabled = locked;
		});
		if (!locked) {
			syncPedidosOcClienteFieldUi(modal);
		}
	}

	function resetPedidosOcLineaFields(modal) {
		if (!modal) {
			return;
		}
		var lineaRoot = getPedidosOcLineaRoot(modal);
		if (!lineaRoot) {
			return;
		}
		lineaRoot.querySelectorAll('[data-field]').forEach(function (field) {
			field.value = '';
		});
		var referenciaHost = lineaRoot.querySelector('[data-pedidos-oc-referencia]');
		if (referenciaHost && pedidosOcModalSheet) {
			referenciaHost.innerHTML = buildArticuloFieldHtml('', pedidosOcModalSheet);
		}
	}

	function syncPedidosOcModalMultiLineUi() {
		var modal = getPedidosOcModal();
		if (!modal) {
			return;
		}
		var isCreate = !pedidosOcModalRow;
		var toolbar = modal.querySelector('[data-pedidos-oc-linea-toolbar]');
		var countEl = modal.querySelector('[data-pedidos-oc-lineas-count]');
		if (toolbar) {
			toolbar.hidden = !isCreate;
		}
		if (countEl) {
			if (isCreate && pedidosOcModalLineasSaved > 0) {
				countEl.hidden = false;
				countEl.textContent = pedidosOcModalLineasSaved === 1
					? '1 producto agregado a esta OC.'
					: (pedidosOcModalLineasSaved + ' productos agregados a esta OC.');
			} else {
				countEl.hidden = true;
				countEl.textContent = '';
			}
		}
		lockPedidosOcModalHeader(modal, isCreate && pedidosOcModalOrdenId > 0);
	}

	function focusPedidosOcLineaArticulo(modal) {
		if (!modal) {
			return;
		}
		var articuloField = modal.querySelector('[data-pedidos-oc-linea] [data-field="articulo"]');
		if (articuloField) {
			window.setTimeout(function () {
				articuloField.focus();
			}, 0);
		}
	}

	function getTodayYmd() {
		var now = new Date();
		return now.getFullYear() + '-'
			+ String(now.getMonth() + 1).padStart(2, '0') + '-'
			+ String(now.getDate()).padStart(2, '0');
	}

	function modalFieldValue(modal, name) {
		if (!modal) {
			return '';
		}
		var field = modal.querySelector('[data-field="' + name + '"]');
		return field ? String(field.value || '').trim() : '';
	}

	function setPedidosOcModalError(message) {
		var modal = getPedidosOcModal();
		if (!modal) {
			return;
		}
		var error = modal.querySelector('[data-pedidos-oc-error]');
		if (!error) {
			return;
		}
		if (!message) {
			error.hidden = true;
			error.textContent = '';
			return;
		}
		error.hidden = false;
		error.textContent = message;
	}

	function setModalFieldValue(modal, name, value) {
		if (!modal) {
			return;
		}
		if ('cliente' === name) {
			setPedidosOcClienteField(modal, value);
			return;
		}
		var field = modal.querySelector('[data-field="' + name + '"]');
		if (field) {
			field.value = value == null ? '' : String(value);
		}
	}

	var PEDIDOS_OC_CLIENTE_NEW_VALUE = '__new__';

	function getPedidosOcClienteSelect(modal) {
		return modal ? modal.querySelector('[data-field="cliente_selector"]') : null;
	}

	function getPedidosOcClienteInput(modal) {
		return modal ? modal.querySelector('[data-field="cliente"]') : null;
	}

	function normalizePedidosClienteKey(value) {
		return String(value || '').toLowerCase().trim();
	}

	function collectPedidosOcClienteOptions() {
		var map = Object.create(null);

		function addCliente(label) {
			var trimmed = String(label || '').trim();
			var key = normalizePedidosClienteKey(trimmed);
			if (!key || map[key]) {
				return;
			}
			map[key] = trimmed;
		}

		getPedidosClientesList().forEach(function (cliente) {
			addCliente(cliente.nombre);
		});

		document.querySelectorAll('[data-pedidos-sheet-root] [data-pedidos-orden-row]').forEach(function (row) {
			addCliente(row.getAttribute('data-pedidos-orden-sort-cliente') || row.getAttribute('data-pedidos-orden-cliente'));
		});

		document.querySelectorAll('[data-pedidos-orden-filter-cliente] option').forEach(function (option) {
			addCliente(option.value);
		});

		return Object.keys(map).map(function (key) {
			return map[key];
		}).sort(function (a, b) {
			return a.localeCompare(b, undefined, { sensitivity: 'base' });
		});
	}

	function findPedidosClienteByNombre(nombre) {
		var key = normalizePedidosClienteKey(nombre);
		if (!key) {
			return null;
		}
		var match = null;
		getPedidosClientesList().some(function (cliente) {
			if (normalizePedidosClienteKey(cliente.nombre) === key) {
				match = cliente;
				return true;
			}
			return false;
		});
		return match;
	}

	function syncPedidosOcClienteEditUi(modal) {
		var select = getPedidosOcClienteSelect(modal);
		var editButton = modal ? modal.querySelector('[data-action="pedidos-oc-edit-cliente"]') : null;
		if (!select || !editButton) {
			return;
		}
		var canEdit = select.value
			&& select.value !== PEDIDOS_OC_CLIENTE_NEW_VALUE
			&& !select.disabled;
		editButton.hidden = !canEdit;
	}

	function updatePedidosClienteNameInDom(oldName, newName) {
		var oldKey = normalizePedidosClienteKey(oldName);
		var newKey = normalizePedidosClienteKey(newName);
		if (!oldKey || !newKey || oldKey === newKey) {
			return;
		}

		document.querySelectorAll('[data-pedidos-orden-row]').forEach(function (row) {
			var sortCliente = String(row.getAttribute('data-pedidos-orden-sort-cliente') || '').trim();
			if (normalizePedidosClienteKey(sortCliente) !== oldKey) {
				return;
			}
			row.setAttribute('data-pedidos-orden-sort-cliente', newName);
			row.setAttribute('data-pedidos-orden-cliente', newKey);
			var clienteField = row.querySelector('[data-field="cliente"]');
			if (clienteField) {
				clienteField.value = newName;
			}
		});

		document.querySelectorAll('[data-pedidos-orden-filter-cliente]').forEach(function (select) {
			var matched = false;
			Array.prototype.forEach.call(select.options, function (option) {
				if (normalizePedidosClienteKey(option.value) === oldKey) {
					option.value = newName;
					option.textContent = newName;
					matched = true;
				}
			});
			if (!matched && newName) {
				var option = document.createElement('option');
				option.value = newName;
				option.textContent = newName;
				select.appendChild(option);
			}
		});
	}

	function refreshPedidosOcClienteSelectors(selectedCliente) {
		var modal = getPedidosOcModal();
		if (modal && !modal.hidden) {
			setPedidosOcClienteField(modal, selectedCliente || getPedidosOcClienteValue(modal));
		}
	}

	function refreshAllPedidosClienteFilterOptions() {
		document.querySelectorAll('[data-pedidos-sheet-root]').forEach(function (sheetRoot) {
			ensurePedidosOrdenClienteFilterOptions(sheetRoot);
		});
	}

	function buildPedidosOcClienteSelectHtml(selectedCliente) {
		var clients = collectPedidosOcClienteOptions();
		var selectedNorm = normalizePedidosClienteKey(selectedCliente);
		var hasSelected = false;
		var html = '<option value="">Seleccionar cliente…</option>';

		clients.forEach(function (cliente) {
			var isSelected = selectedNorm !== '' && normalizePedidosClienteKey(cliente) === selectedNorm;
			if (isSelected) {
				hasSelected = true;
			}
			html += '<option value="' + escapeAttr(cliente) + '"' + (isSelected ? ' selected' : '') + '>' + escapeText(cliente) + '</option>';
		});

		if (selectedNorm !== '' && !hasSelected) {
			html += '<option value="' + escapeAttr(selectedCliente) + '" selected>' + escapeText(selectedCliente) + '</option>';
			hasSelected = true;
		}

		html += '<option value="' + PEDIDOS_OC_CLIENTE_NEW_VALUE + '">Crear nuevo cliente…</option>';
		return {
			html: html,
			hasSelected: hasSelected
		};
	}

	function syncPedidosOcClienteFieldUi(modal) {
		var select = getPedidosOcClienteSelect(modal);
		var input = getPedidosOcClienteInput(modal);
		if (!select || !input) {
			return;
		}
		if (select.value === PEDIDOS_OC_CLIENTE_NEW_VALUE) {
			input.hidden = false;
			input.required = true;
			select.required = false;
			syncPedidosOcClienteEditUi(modal);
			return;
		}
		input.hidden = true;
		input.required = false;
		select.required = true;
		syncPedidosOcClienteEditUi(modal);
	}

	function setPedidosOcClienteField(modal, clienteValue) {
		var select = getPedidosOcClienteSelect(modal);
		var input = getPedidosOcClienteInput(modal);
		var built;
		var value;
		if (!select || !input) {
			return;
		}
		value = String(clienteValue || '').trim();
		built = buildPedidosOcClienteSelectHtml(value);
		select.innerHTML = built.html;

		if (!value) {
			select.value = '';
			input.value = '';
			syncPedidosOcClienteFieldUi(modal);
			return;
		}

		if (built.hasSelected) {
			select.value = value;
			input.value = value;
		} else {
			select.value = PEDIDOS_OC_CLIENTE_NEW_VALUE;
			input.value = value;
		}
		syncPedidosOcClienteFieldUi(modal);
	}

	function getPedidosOcClienteValue(modal) {
		var select = getPedidosOcClienteSelect(modal);
		var input = getPedidosOcClienteInput(modal);
		if (!select || !input) {
			return '';
		}
		if (select.value === PEDIDOS_OC_CLIENTE_NEW_VALUE) {
			return String(input.value || '').trim();
		}
		if (select.value) {
			return String(select.value).trim();
		}
		return '';
	}

	function setPedidosOcModalMode(mode) {
		var modal = getPedidosOcModal();
		if (!modal) {
			return;
		}
		var title = modal.querySelector('[data-pedidos-oc-modal-title]');
		var saveButton = modal.querySelector('[data-pedidos-oc-save]');
		if ('edit' === mode) {
			if (title) {
				title.textContent = modal.getAttribute('data-pedidos-oc-title-edit') || 'Editar orden de compra';
			}
			if (saveButton) {
				saveButton.textContent = modal.getAttribute('data-pedidos-oc-save-edit') || 'Guardar cambios';
			}
			syncPedidosOcModalMultiLineUi();
			return;
		}
		if (title) {
			title.textContent = modal.getAttribute('data-pedidos-oc-title-new') || 'Nueva orden de compra';
		}
		if (saveButton) {
			saveButton.textContent = saveButton.getAttribute('data-pedidos-oc-save-label') || 'Guardar OC';
		}
		syncPedidosOcModalMultiLineUi();
	}

	function resetPedidosOcModalForm() {
		var modal = getPedidosOcModal();
		if (!modal) {
			return;
		}
		var form = modal.querySelector('[data-pedidos-oc-form]');
		if (!form) {
			return;
		}
		resetPedidosOcModalMultiState();
		form.reset();
		var fechaOc = form.querySelector('[data-field="fecha_oc"]');
		if (fechaOc) {
			fechaOc.value = getTodayYmd();
		}
		var lineaRoot = getPedidosOcLineaRoot(modal);
		var referenciaHost = lineaRoot ? lineaRoot.querySelector('[data-pedidos-oc-referencia]') : form.querySelector('[data-pedidos-oc-referencia]');
		if (referenciaHost && pedidosOcModalSheet) {
			referenciaHost.innerHTML = buildArticuloFieldHtml('', pedidosOcModalSheet);
		}
		setPedidosOcClienteField(modal, '');
		setPedidosOcModalError('');
		syncPedidosOcModalMultiLineUi();
	}

	function openPedidosOcModal(sheetRoot) {
		pedidosOcModalSheet = getPedidosSheetRoot(sheetRoot);
		pedidosOcModalRow = null;
		var modal = getPedidosOcModal();
		if (!modal || !pedidosOcModalSheet) {
			return;
		}
		setPedidosOcModalMode('create');
		resetPedidosOcModalForm();
		modal.hidden = false;
		document.body.classList.add('logistica-pedidos-oc-modal-open');
		var focusField = getPedidosOcClienteSelect(modal);
		if (focusField) {
			window.setTimeout(function () {
				focusField.focus();
			}, 0);
		}
	}

	function openPedidosOcModalForRow(row) {
		pedidosOcModalSheet = getPedidosSheetRoot(row);
		pedidosOcModalRow = row || null;
		var modal = getPedidosOcModal();
		if (!modal || !pedidosOcModalSheet || !pedidosOcModalRow) {
			return;
		}
		flushParcialSavesOnRow(pedidosOcModalRow).finally(function () {
			var data = collectOrdenLineaPayload(pedidosOcModalRow);
			setPedidosOcModalMode('edit');
			setPedidosOcModalError('');
			setModalFieldValue(modal, 'fecha_oc', data.orden.fecha_oc || '');
			setModalFieldValue(modal, 'oc_numero', data.orden.oc_numero || '');
			setModalFieldValue(modal, 'cliente', data.orden.cliente || '');
			setModalLineaFieldValue(modal, 'cantidad', data.linea.cantidad || '');
			setModalLineaFieldValue(modal, 'descripcion', data.linea.descripcion || '');
			setModalLineaFieldValue(modal, 'cantidad_maxima_recibida', formatPedidosToleranciaPct(data.linea.cantidad_maxima_recibida) || '');
			setModalLineaFieldValue(modal, 'precio_unit', data.linea.precio_unit || '');
			setModalLineaFieldValue(modal, 'fecha_entrega', data.linea.fecha_entrega || '');
			setModalLineaFieldValue(modal, 'fecha_prorroga', data.linea.fecha_prorroga || '');
			setModalLineaFieldValue(modal, 'observaciones', data.linea.observaciones || '');
			var lineaRoot = getPedidosOcLineaRoot(modal);
			var referenciaHost = lineaRoot ? lineaRoot.querySelector('[data-pedidos-oc-referencia]') : modal.querySelector('[data-pedidos-oc-referencia]');
			if (referenciaHost) {
				referenciaHost.innerHTML = buildArticuloFieldHtml(data.linea.articulo || '', pedidosOcModalSheet);
			}
			resetPedidosOcModalMultiState();
			syncPedidosOcModalMultiLineUi();
			modal.hidden = false;
			document.body.classList.add('logistica-pedidos-oc-modal-open');
			var focusField = modal.querySelector('[data-field="oc_numero"]');
			if (focusField) {
				window.setTimeout(function () {
					focusField.focus();
				}, 0);
			}
		});
	}

	function closePedidosOcModal() {
		var modal = getPedidosOcModal();
		if (!modal) {
			return;
		}
		modal.hidden = true;
		document.body.classList.remove('logistica-pedidos-oc-modal-open');
		setPedidosOcModalError('');
		pedidosOcModalSheet = null;
		pedidosOcModalRow = null;
		resetPedidosOcModalMultiState();
		setPedidosOcModalMode('create');
		lockPedidosOcModalHeader(modal, false);
	}

	function collectPedidosOcModalPayload() {
		var modal = getPedidosOcModal();
		var ordenId = 0;
		var lineaId = 0;
		var estado = 'sin_confirmar';
		if (pedidosOcModalRow) {
			var existing = collectOrdenLineaPayload(pedidosOcModalRow);
			ordenId = parseInt(existing.orden.id, 10) || 0;
			lineaId = parseInt(pedidosOcModalRow.getAttribute('data-linea-id') || existing.linea.id || '0', 10) || 0;
			estado = existing.linea.estado || 'sin_confirmar';
		} else if (pedidosOcModalOrdenId > 0) {
			ordenId = pedidosOcModalOrdenId;
			lineaId = 0;
		}
		return {
			orden: {
				id: ordenId,
				board_slug: getBoardSlug(pedidosOcModalSheet),
				fecha_oc: modalFieldValue(modal, 'fecha_oc'),
				oc_numero: modalFieldValue(modal, 'oc_numero'),
				cliente: getPedidosOcClienteValue(modal)
			},
			linea: {
				id: lineaId,
				orden_id: ordenId,
				articulo: modalLineaFieldValue(modal, 'articulo'),
				descripcion: modalLineaFieldValue(modal, 'descripcion'),
				cantidad: modalLineaFieldValue(modal, 'cantidad'),
				cantidad_maxima_recibida: formatPedidosToleranciaPct(modalLineaFieldValue(modal, 'cantidad_maxima_recibida')),
				precio_unit: modalLineaFieldValue(modal, 'precio_unit'),
				fecha_entrega: modalLineaFieldValue(modal, 'fecha_entrega'),
				fecha_prorroga: modalLineaFieldValue(modal, 'fecha_prorroga'),
				observaciones: modalLineaFieldValue(modal, 'observaciones'),
				estado: estado
			}
		};
	}

	function validatePedidosOcModalPayload(data) {
		if (!data.orden.fecha_oc) {
			return 'Indica la fecha de la OC.';
		}
		if (!data.orden.oc_numero) {
			return 'Indica el número de OC.';
		}
		if (!data.orden.cliente) {
			return 'Selecciona un cliente o escribe uno nuevo.';
		}
		if (!data.linea.articulo) {
			return 'Selecciona un tipo de producto.';
		}
		return '';
	}

	function savePedidosOcFromModal(options) {
		options = options || {};
		var keepOpen = Boolean(options.keepOpen);
		var modal = getPedidosOcModal();
		if (!modal || !pedidosOcModalSheet) {
			return Promise.resolve();
		}
		var data = collectPedidosOcModalPayload();
		var validationError = validatePedidosOcModalPayload(data);
		if (validationError) {
			setPedidosOcModalError(validationError);
			return Promise.reject(new Error(validationError));
		}

		var saveButton = modal.querySelector('[data-pedidos-oc-save]');
		var addButton = modal.querySelector('[data-action="pedidos-oc-add-linea"]');
		if (saveButton) {
			saveButton.disabled = true;
		}
		if (addButton) {
			addButton.disabled = true;
		}
		setPedidosOcModalError('');

		return postPedidos('logistica_save_pedidos_orden_linea', {
			orden_json: JSON.stringify(data.orden),
			linea_json: JSON.stringify(data.linea)
		}).then(function (payload) {
			if (!payload || !payload.success) {
				throw new Error((payload && payload.data && payload.data.message) || 'No se pudo guardar la OC.');
			}
			var wasEdit = !!pedidosOcModalRow;
			var editRow = pedidosOcModalRow;
			var sheetRoot = pedidosOcModalSheet;
			applyPedidosOcSaveToDom(payload, {
				wasEdit: wasEdit,
				editRow: editRow,
				sheetRoot: sheetRoot,
				quietStatus: keepOpen
			});
			if (data.orden && data.orden.cliente) {
				postPedidos('logistica_get_pedidos_clientes', {}).then(function (clientesPayload) {
					if (clientesPayload && clientesPayload.success) {
						applyPedidosClientesPayload(clientesPayload.data || {});
					}
				}).catch(function () {
					// ignore background refresh
				});
			}
			if (!keepOpen) {
				closePedidosOcModal();
				return payload;
			}
			pedidosOcModalOrdenId = parseInt((payload.data.orden && payload.data.orden.id) || pedidosOcModalOrdenId, 10) || pedidosOcModalOrdenId;
			pedidosOcModalLineasSaved += 1;
			resetPedidosOcLineaFields(modal);
			syncPedidosOcModalMultiLineUi();
			setPedidosOcModalError('');
			setBoardStatus('Producto guardado. Agrega otro o pulsa Guardar OC para terminar.', false);
			focusPedidosOcLineaArticulo(modal);
			return payload;
		}).catch(function (error) {
			setPedidosOcModalError(error.message || 'No se pudo guardar la OC.');
			throw error;
		}).finally(function () {
			if (saveButton) {
				saveButton.disabled = false;
			}
			if (addButton) {
				addButton.disabled = false;
			}
		});
	}

	function initPedidosOcModal() {
		var modal = getPedidosOcModal();
		if (!modal || modal.dataset.pedidosOcModalBound === '1') {
			return;
		}
		modal.dataset.pedidosOcModalBound = '1';

		var clienteSelect = getPedidosOcClienteSelect(modal);
		if (clienteSelect) {
			clienteSelect.addEventListener('change', function () {
				var input = getPedidosOcClienteInput(modal);
				syncPedidosOcClienteFieldUi(modal);
				if (clienteSelect.value === PEDIDOS_OC_CLIENTE_NEW_VALUE && input) {
					input.value = '';
					window.setTimeout(function () {
						input.focus();
					}, 0);
				}
				if (clienteSelect.value && clienteSelect.value !== PEDIDOS_OC_CLIENTE_NEW_VALUE && input) {
					input.value = clienteSelect.value;
				}
			});
		}

		modal.addEventListener('click', function (event) {
			if (event.target.closest('[data-action="pedidos-open-clientes-view"]')) {
				event.preventDefault();
				var board = document.querySelector('[data-pedidos-board]');
				closePedidosOcModal();
				if (board) {
					setPedidosBoardView(board, 'clientes');
				}
				return;
			}
			if (event.target.closest('[data-action="pedidos-oc-edit-cliente"]')) {
				event.preventDefault();
				var cliente = findPedidosClienteByNombre(getPedidosOcClienteValue(modal));
				if (cliente) {
					openPedidosClienteModal(cliente);
				}
			}
		});

		var form = modal.querySelector('[data-pedidos-oc-form]');
		if (form) {
			form.addEventListener('submit', function (event) {
				event.preventDefault();
				savePedidosOcFromModal().catch(function () {
					/* error shown in modal */
				});
			});
		}

		modal.addEventListener('click', function (event) {
			if (event.target.closest('[data-action="pedidos-close-oc-modal"]')) {
				event.preventDefault();
				closePedidosOcModal();
				return;
			}
			if (event.target.closest('[data-action="pedidos-oc-add-linea"]')) {
				event.preventDefault();
				savePedidosOcFromModal({ keepOpen: true }).catch(function () {
					/* error shown in modal */
				});
			}
		});

		modal.addEventListener('change', function (event) {
			var target = event.target;
			if (!target || !modal.contains(target)) {
				return;
			}
			if (target.matches('[data-field="cantidad"]')) {
				formatPedidosQuantityField(target);
			}
			if (target.matches('[data-field="precio_unit"]')) {
				formatPedidosMoneyField(target);
			}
		});

		document.addEventListener('keydown', function (event) {
			if (event.key === 'Escape' && modal && !modal.hidden) {
				closePedidosOcModal();
			}
		});
	}

	function setPedidosBoardView(board, view) {
		var ordenesView = board ? board.querySelector('[data-pedidos-board-ordenes-view]') : null;
		var clientesView = board ? board.querySelector('[data-pedidos-board-clientes-view]') : null;
		var tabs = board ? board.querySelectorAll('[data-pedidos-board-view]') : [];
		var isClientes = view === 'clientes';

		if (!ordenesView || !clientesView) {
			return;
		}

		ordenesView.hidden = isClientes;
		clientesView.hidden = !isClientes;

		tabs.forEach(function (tab) {
			var active = tab.getAttribute('data-pedidos-board-view') === view;
			tab.classList.toggle('is-active', active);
			tab.setAttribute('aria-pressed', active ? 'true' : 'false');
		});

		try {
			window.localStorage.setItem(PEDIDOS_BOARD_VIEW_STORAGE_KEY, view);
		} catch (error) {
			// ignore
		}

		if (isClientes) {
			renderPedidosClientesTable();
		}
	}

	function initPedidosBoardViewNav(board) {
		var nav = board ? board.querySelector('[data-pedidos-board-view-nav]') : null;
		if (!nav || nav.dataset.pedidosBoardViewBound === '1') {
			return;
		}
		nav.dataset.pedidosBoardViewBound = '1';

		var initialView = 'ordenes';
		try {
			var stored = window.localStorage.getItem(PEDIDOS_BOARD_VIEW_STORAGE_KEY);
			if (stored === 'clientes' || stored === 'ordenes') {
				initialView = stored;
			}
		} catch (error) {
			// ignore
		}
		setPedidosBoardView(board, initialView);

		nav.addEventListener('click', function (event) {
			var tab = event.target.closest('[data-pedidos-board-view]');
			if (!tab || !nav.contains(tab)) {
				return;
			}
			event.preventDefault();
			setPedidosBoardView(board, tab.getAttribute('data-pedidos-board-view') || 'ordenes');
		});
	}

	function getPedidosClienteModal() {
		return document.querySelector('[data-pedidos-cliente-modal]');
	}

	function setPedidosClienteModalError(message) {
		var modal = getPedidosClienteModal();
		var error = modal ? modal.querySelector('[data-pedidos-cliente-error]') : null;
		if (!error) {
			return;
		}
		if (!message) {
			error.hidden = true;
			error.textContent = '';
			return;
		}
		error.hidden = false;
		error.textContent = message;
	}

	function setPedidosClienteModalField(modal, name, value) {
		if (!modal) {
			return;
		}
		var field = modal.querySelector('[data-field="' + name + '"]');
		if (field) {
			field.value = value == null ? '' : String(value);
		}
	}

	function openPedidosClienteModal(cliente, options) {
		var modal = getPedidosClienteModal();
		var title = modal ? modal.querySelector('[data-pedidos-cliente-modal-title]') : null;
		var form = modal ? modal.querySelector('[data-pedidos-cliente-form]') : null;
		options = options || {};
		cliente = cliente || {};

		if (!modal || !form) {
			return;
		}

		form.reset();
		setPedidosClienteModalField(modal, 'id', cliente.id || '');
		setPedidosClienteModalField(modal, 'nombre', cliente.nombre || '');
		setPedidosClienteModalField(modal, 'codigo', cliente.codigo || '');
		setPedidosClienteModalField(modal, 'contacto', cliente.contacto || '');
		setPedidosClienteModalField(modal, 'telefono', cliente.telefono || '');
		setPedidosClienteModalField(modal, 'email', cliente.email || '');
		setPedidosClienteModalField(modal, 'notas', cliente.notas || '');

		if (title) {
			title.textContent = cliente.id
				? (modal.getAttribute('data-pedidos-cliente-title-edit') || 'Editar cliente')
				: (modal.getAttribute('data-pedidos-cliente-title-new') || 'Nuevo cliente');
		}

		setPedidosClienteModalError('');
		modal.hidden = false;
		document.body.classList.add('logistica-pedidos-cliente-modal-open');

		if (options.prefillNombre && !cliente.nombre) {
			setPedidosClienteModalField(modal, 'nombre', options.prefillNombre);
		}

		var nombreField = modal.querySelector('[data-field="nombre"]');
		if (nombreField) {
			window.setTimeout(function () {
				nombreField.focus();
			}, 0);
		}
	}

	function closePedidosClienteModal() {
		var modal = getPedidosClienteModal();
		if (modal) {
			modal.hidden = true;
		}
		document.body.classList.remove('logistica-pedidos-cliente-modal-open');
		setPedidosClienteModalError('');
	}

	function collectPedidosClienteFormData(modal) {
		if (!modal) {
			return null;
		}
		return {
			id: parseInt(modal.querySelector('[data-field="id"]').value, 10) || 0,
			nombre: String(modal.querySelector('[data-field="nombre"]').value || '').trim(),
			codigo: String(modal.querySelector('[data-field="codigo"]').value || '').trim(),
			contacto: String(modal.querySelector('[data-field="contacto"]').value || '').trim(),
			telefono: String(modal.querySelector('[data-field="telefono"]').value || '').trim(),
			email: String(modal.querySelector('[data-field="email"]').value || '').trim(),
			notas: String(modal.querySelector('[data-field="notas"]').value || '').trim()
		};
	}

	function applyPedidosClientesPayload(payload) {
		if (!payload || !Array.isArray(payload.clientes)) {
			return;
		}
		var previous = getPedidosClientesList();
		setPedidosClientesList(payload.clientes);
		if (payload.cliente && payload.cliente.nombre) {
			previous.some(function (entry) {
				if (entry.id === payload.cliente.id && entry.nombre !== payload.cliente.nombre) {
					updatePedidosClienteNameInDom(entry.nombre, payload.cliente.nombre);
					return true;
				}
				return false;
			});
		}
		renderPedidosClientesTable();
		refreshPedidosOcClienteSelectors(payload.cliente ? payload.cliente.nombre : '');
		refreshAllPedidosClienteFilterOptions();
	}

	function savePedidosClienteFromModal() {
		var modal = getPedidosClienteModal();
		var data = collectPedidosClienteFormData(modal);
		var oldCliente;
		if (!data || !data.nombre) {
			setPedidosClienteModalError('Indica el nombre del cliente.');
			return Promise.reject(new Error('Indica el nombre del cliente.'));
		}
		if (data.id > 0) {
			oldCliente = getPedidosClientesList().find(function (entry) {
				return entry.id === data.id;
			});
		}

		return postPedidos('logistica_save_pedidos_cliente', {
			cliente_json: JSON.stringify(data)
		}).then(function (payload) {
			if (!payload || !payload.success) {
				throw new Error((payload && payload.data && payload.data.message) || 'No se pudo guardar el cliente.');
			}
			if (oldCliente && oldCliente.nombre !== data.nombre) {
				updatePedidosClienteNameInDom(oldCliente.nombre, data.nombre);
			}
			applyPedidosClientesPayload(payload.data || {});
			closePedidosClienteModal();
			setBoardStatus((payload.data && payload.data.message) || 'Cliente guardado.', false);
			return payload;
		}).catch(function (error) {
			setPedidosClienteModalError(error.message || 'No se pudo guardar el cliente.');
			throw error;
		});
	}

	function deletePedidosCliente(clienteId) {
		return postPedidos('logistica_delete_pedidos_cliente', {
			id: String(clienteId || '')
		}).then(function (payload) {
			if (!payload || !payload.success) {
				throw new Error((payload && payload.data && payload.data.message) || 'No se pudo eliminar el cliente.');
			}
			applyPedidosClientesPayload(payload.data || {});
			setBoardStatus((payload.data && payload.data.message) || 'Cliente eliminado.', false);
			return payload;
		});
	}

	function renderPedidosClientesTable() {
		var tbody = document.querySelector('[data-pedidos-clientes-tbody]');
		var emptyRow = document.querySelector('[data-pedidos-clientes-empty]');
		var searchInput = document.querySelector('[data-pedidos-clientes-search]');
		var query = searchInput ? String(searchInput.value || '').toLowerCase().trim() : '';
		var clientes = getPedidosClientesList();
		var html = '';
		var visibleCount = 0;

		if (!tbody) {
			return;
		}

		clientes.forEach(function (cliente) {
			var haystack = [
				cliente.nombre,
				cliente.codigo,
				cliente.contacto,
				cliente.telefono,
				cliente.email,
				cliente.notas
			].join(' ').toLowerCase();
			if (query && haystack.indexOf(query) === -1) {
				return;
			}
			visibleCount += 1;
			html += '<tr data-pedidos-cliente-row data-pedidos-cliente-id="' + escapeAttr(String(cliente.id)) + '">'
				+ '<td>' + escapeText(cliente.nombre || '') + '</td>'
				+ '<td>' + escapeText(cliente.codigo || '') + '</td>'
				+ '<td>' + escapeText(cliente.contacto || '') + '</td>'
				+ '<td>' + escapeText(cliente.telefono || '') + '</td>'
				+ '<td>' + escapeText(cliente.email || '') + '</td>'
				+ '<td>' + escapeText(cliente.notas || '') + '</td>'
				+ '<td class="logistica-pedidos-table__actions-col">'
				+ '<button type="button" class="button button-small logistica-table-icon-btn" data-action="pedidos-edit-cliente" aria-label="Editar" title="Editar">'
				+ '<span class="dashicons dashicons-edit" aria-hidden="true"></span>'
				+ '</button>'
				+ '<button type="button" class="button button-small logistica-table-icon-btn" data-action="pedidos-delete-cliente" aria-label="Eliminar" title="Eliminar">'
				+ '<span class="dashicons dashicons-trash" aria-hidden="true"></span>'
				+ '</button>'
				+ '</td>'
				+ '</tr>';
		});

		tbody.innerHTML = html;
		if (emptyRow) {
			emptyRow.hidden = visibleCount > 0;
			if (!visibleCount) {
				tbody.appendChild(emptyRow);
				emptyRow.querySelector('td').textContent = query
					? 'No hay clientes que coincidan con la búsqueda.'
					: 'No hay clientes registrados.';
			}
		}
	}

	function initPedidosClientesView(board) {
		var view = board ? board.querySelector('[data-pedidos-board-clientes-view]') : null;
		if (!view || view.dataset.pedidosClientesBound === '1') {
			return;
		}
		view.dataset.pedidosClientesBound = '1';

		var searchInput = view.querySelector('[data-pedidos-clientes-search]');
		if (searchInput) {
			searchInput.addEventListener('input', function () {
				renderPedidosClientesTable();
			});
		}

		view.addEventListener('click', function (event) {
			var button = event.target.closest('[data-action]');
			if (!button || !view.contains(button)) {
				return;
			}
			var action = button.getAttribute('data-action');
			var row = button.closest('[data-pedidos-cliente-row]');
			var clienteId = row ? parseInt(row.getAttribute('data-pedidos-cliente-id') || '0', 10) : 0;
			var cliente;

			if (action === 'pedidos-add-cliente') {
				event.preventDefault();
				openPedidosClienteModal();
				return;
			}
			if (action === 'pedidos-edit-cliente' && clienteId > 0) {
				event.preventDefault();
				cliente = getPedidosClientesList().find(function (entry) {
					return entry.id === clienteId;
				});
				if (cliente) {
					openPedidosClienteModal(cliente);
				}
				return;
			}
			if (action === 'pedidos-delete-cliente' && clienteId > 0) {
				event.preventDefault();
				cliente = getPedidosClientesList().find(function (entry) {
					return entry.id === clienteId;
				});
				if (!cliente) {
					return;
				}
				if (!window.confirm('¿Eliminar el cliente «' + cliente.nombre + '» de la base de datos? Las órdenes existentes conservarán el nombre.')) {
					return;
				}
				deletePedidosCliente(clienteId).catch(function (error) {
					setBoardStatus(error.message || 'No se pudo eliminar el cliente.', true);
				});
			}
		});
	}

	function initPedidosClienteModal() {
		var modal = getPedidosClienteModal();
		if (!modal || modal.dataset.pedidosClienteModalBound === '1') {
			return;
		}
		modal.dataset.pedidosClienteModalBound = '1';

		var form = modal.querySelector('[data-pedidos-cliente-form]');
		if (form) {
			form.addEventListener('submit', function (event) {
				event.preventDefault();
				savePedidosClienteFromModal().catch(function () {
					/* error shown in modal */
				});
			});
		}

		modal.addEventListener('click', function (event) {
			if (event.target.closest('[data-action="pedidos-close-cliente-modal"]')) {
				event.preventDefault();
				closePedidosClienteModal();
			}
		});

		document.addEventListener('keydown', function (event) {
			if (event.key === 'Escape' && modal && !modal.hidden) {
				closePedidosClienteModal();
			}
		});
	}

	function getCantidadFinalizadaModal() {
		return document.querySelector('[data-pedidos-cantidad-finalizada-modal]');
	}

	function setCantidadFinalizadaModalError(message) {
		var modal = getCantidadFinalizadaModal();
		var error = modal ? modal.querySelector('[data-pedidos-cf-error]') : null;
		if (!error) {
			return;
		}
		if (message) {
			error.textContent = message;
			error.hidden = false;
		} else {
			error.textContent = '';
			error.hidden = true;
		}
	}

	function closeCantidadFinalizadaModal() {
		var modal = getCantidadFinalizadaModal();
		if (modal) {
			modal.hidden = true;
		}
		cantidadFinalizadaModalRow = null;
		document.body.classList.remove('logistica-pedidos-cf-modal-open');
		setCantidadFinalizadaModalError('');
	}

	function openCantidadFinalizadaModal(row) {
		if (!row) {
			return;
		}
		if (!ordenRowAllowsCantidadFinalizadaEdit(row)) {
			setBoardStatus('La cantidad finalizada solo se edita con estado Finalizado.', true);
			return;
		}
		var modal = getCantidadFinalizadaModal();
		var modalInput = modal ? modal.querySelector('[data-pedidos-cf-input]') : null;
		var hint = modal ? modal.querySelector('[data-pedidos-cf-hint]') : null;
		var cellInput = getCantidadFinalizadaInput(row);
		if (!modal || !modalInput) {
			return;
		}
		modalInput.value = cellInput ? String(cellInput.value || '').trim() : '0';
		if (hint) {
			hint.textContent = 'Cantidad solicitada: ' + (formatPedidosQuantity(fieldValue(row, 'cantidad')) || '0');
			hint.hidden = false;
		}
		setCantidadFinalizadaModalError('');
		cantidadFinalizadaModalRow = row;
		modal.hidden = false;
		document.body.classList.add('logistica-pedidos-cf-modal-open');
		window.setTimeout(function () {
			modalInput.focus();
			modalInput.select();
		}, 0);
	}

	function saveCantidadFinalizadaFromModal() {
		var row = cantidadFinalizadaModalRow;
		var modal = getCantidadFinalizadaModal();
		if (!row || !modal) {
			return Promise.resolve();
		}
		var modalInput = modal.querySelector('[data-pedidos-cf-input]');
		var cellInput = getCantidadFinalizadaInput(row);
		if (!modalInput || !cellInput) {
			closeCantidadFinalizadaModal();
			return Promise.resolve();
		}
		var raw = String(modalInput.value || '').trim();
		if (raw === '') {
			setCantidadFinalizadaModalError('Indica una cantidad finalizada.');
			modalInput.focus();
			return Promise.reject(new Error('Indica una cantidad finalizada.'));
		}
		cellInput.value = raw;
		formatPedidosQuantityField(cellInput);
		updateOrdenLineaComputedQuantities(row);
		updateOrdenTotalCell(row);
		closeCantidadFinalizadaModal();
		return saveOrdenLineaRow(row, { quiet: false }).then(function () {
			setBoardStatus('Cantidad finalizada guardada.', false);
		});
	}

	function initPedidosCantidadFinalizadaModal() {
		var modal = getCantidadFinalizadaModal();
		if (!modal || modal.dataset.pedidosCfModalBound === '1') {
			return;
		}
		modal.dataset.pedidosCfModalBound = '1';

		var form = modal.querySelector('[data-pedidos-cf-form]');
		if (form) {
			form.addEventListener('submit', function (event) {
				event.preventDefault();
				saveCantidadFinalizadaFromModal().catch(function (error) {
					if (error && error.message) {
						setBoardStatus(error.message, true);
					}
				});
			});
		}

		modal.addEventListener('click', function (event) {
			if (event.target.closest('[data-action="pedidos-close-cantidad-finalizada-modal"]')) {
				event.preventDefault();
				closeCantidadFinalizadaModal();
			}
		});

		document.addEventListener('keydown', function (event) {
			if (event.key === 'Escape' && modal && !modal.hidden) {
				closeCantidadFinalizadaModal();
			}
		});
	}

	function getOpModal() {
		return document.querySelector('[data-pedidos-op-modal]');
	}

	function isOpModalOpen() {
		var modal = getOpModal();
		return Boolean(modal && !modal.hidden);
	}

	function setOpModalError(message) {
		var modal = getOpModal();
		var error = modal ? modal.querySelector('[data-pedidos-op-error]') : null;
		if (!error) {
			return;
		}
		if (message) {
			error.textContent = message;
			error.hidden = false;
		} else {
			error.textContent = '';
			error.hidden = true;
		}
	}

	function closeOpModal(options) {
		options = options || {};
		var modal = getOpModal();
		if (modal) {
			modal.hidden = true;
		}
		if (options.dismissed && opModalAutoOpened && opModalRow) {
			opModalDismissedRows.add(opModalRow);
		}
		opModalRow = null;
		opModalAutoOpened = false;
		document.body.classList.remove('logistica-pedidos-op-modal-open');
		setOpModalError('');
	}

	function openOpModal(row, options) {
		options = options || {};
		if (!row) {
			return;
		}
		if (!ordenRowAllowsOp(row)) {
			setBoardStatus('La OP solo se registra con estado Conversión o Impresión.', true);
			return;
		}
		var modal = getOpModal();
		var modalInput = modal ? modal.querySelector('[data-pedidos-op-input]') : null;
		var hint = modal ? modal.querySelector('[data-pedidos-op-hint]') : null;
		var cellInput = getOrdenOpInput(row);
		if (!modal || !modalInput) {
			return;
		}
		modalInput.value = cellInput ? String(cellInput.value || '').trim() : '';
		if (hint) {
			hint.textContent = 'Tipo de producto: ' + (fieldValue(row, 'articulo') || '—');
			hint.hidden = false;
		}
		setOpModalError('');
		opModalRow = row;
		opModalAutoOpened = Boolean(options.auto);
		modal.hidden = false;
		document.body.classList.add('logistica-pedidos-op-modal-open');
		window.setTimeout(function () {
			modalInput.focus();
			modalInput.select();
		}, 0);
	}

	function saveOpFromModal() {
		var row = opModalRow;
		var modal = getOpModal();
		if (!row || !modal) {
			return Promise.resolve();
		}
		var modalInput = modal.querySelector('[data-pedidos-op-input]');
		var cellInput = getOrdenOpInput(row);
		if (!modalInput || !cellInput) {
			closeOpModal();
			return Promise.resolve();
		}
		var raw = String(modalInput.value || '').trim();
		if (raw === '') {
			setOpModalError('Indica el número de OP.');
			modalInput.focus();
			return Promise.reject(new Error('Indica el número de OP.'));
		}
		cellInput.value = raw;
		opModalDismissedRows.delete(row);
		closeOpModal();
		syncOrdenOpField(row);
		return saveOrdenLineaRow(row, { quiet: false }).then(function () {
			setBoardStatus('OP guardada.', false);
		});
	}

	function initPedidosOpModal() {
		var modal = getOpModal();
		if (!modal || modal.dataset.pedidosOpModalBound === '1') {
			return;
		}
		modal.dataset.pedidosOpModalBound = '1';

		var form = modal.querySelector('[data-pedidos-op-form]');
		if (form) {
			form.addEventListener('submit', function (event) {
				event.preventDefault();
				saveOpFromModal().catch(function (error) {
					if (error && error.message) {
						setBoardStatus(error.message, true);
					}
				});
			});
		}

		modal.addEventListener('click', function (event) {
			if (event.target.closest('[data-action="pedidos-close-op-modal"]')) {
				event.preventDefault();
				closeOpModal({ dismissed: true });
			}
		});

		document.addEventListener('keydown', function (event) {
			if (event.key === 'Escape' && modal && !modal.hidden) {
				closeOpModal({ dismissed: true });
			}
		});
	}

	function getFechaAprobacionModal() {
		return document.querySelector('[data-pedidos-fa-modal]');
	}

	function isFechaAprobacionModalOpen() {
		var modal = getFechaAprobacionModal();
		return Boolean(modal && !modal.hidden);
	}

	function setFechaAprobacionModalError(message) {
		var modal = getFechaAprobacionModal();
		var error = modal ? modal.querySelector('[data-pedidos-fa-error]') : null;
		if (!error) {
			return;
		}
		if (message) {
			error.textContent = message;
			error.hidden = false;
		} else {
			error.textContent = '';
			error.hidden = true;
		}
	}

	function closeFechaAprobacionModal(options) {
		options = options || {};
		var pending = faModalPendingConfirm;
		if (options.dismissed && faModalAutoOpened && faModalRow && !(pending && pending.requireConfirm)) {
			faModalDismissedRows.add(faModalRow);
		}
		if (options.dismissed && pending && pending.requireConfirm && pending.estadoSelect && pending.row) {
			pending.estadoSelect.value = pending.previousEstado || 'sin_confirmar';
			syncOrdenRowEstadoClass(pending.row, pending.estadoSelect.value);
			syncOrdenEntregaFields(pending.row);
			syncOrdenOpField(pending.row);
			syncOrdenFechaAprobacionField(pending.row);
			updateOrdenLineaComputedQuantities(pending.row);
		}
		var modal = getFechaAprobacionModal();
		if (modal) {
			modal.hidden = true;
		}
		faModalPendingConfirm = null;
		faModalRow = null;
		faModalAutoOpened = false;
		document.body.classList.remove('logistica-pedidos-op-modal-open');
		setFechaAprobacionModalError('');
	}

	function openFechaAprobacionModal(row, options) {
		options = options || {};
		if (!row) {
			return;
		}
		if (!ordenRowAllowsFechaAprobacion(row)) {
			setBoardStatus('La fecha de aprobación solo se registra con estado Aprobado.', true);
			return;
		}
		var modal = getFechaAprobacionModal();
		var modalInput = modal ? modal.querySelector('[data-pedidos-fa-input]') : null;
		var hint = modal ? modal.querySelector('[data-pedidos-fa-hint]') : null;
		var cellInput = getOrdenFechaAprobacionInput(row);
		if (!modal || !modalInput) {
			return;
		}
		var current = cellInput ? String(cellInput.value || '').trim() : '';
		modalInput.value = current || getTodayYmd();
		if (hint) {
			hint.textContent = 'Tipo de producto: ' + (fieldValue(row, 'articulo') || '—');
			hint.hidden = false;
		}
		if (options.requireConfirm) {
			faModalPendingConfirm = {
				row: row,
				estadoSelect: options.estadoSelect || null,
				previousEstado: options.previousEstado || 'sin_confirmar',
				requireConfirm: true
			};
		} else {
			faModalPendingConfirm = null;
		}
		setFechaAprobacionModalError('');
		faModalRow = row;
		faModalAutoOpened = Boolean(options.auto);
		modal.hidden = false;
		document.body.classList.add('logistica-pedidos-op-modal-open');
		window.setTimeout(function () {
			modalInput.focus();
		}, 0);
	}

	function saveFechaAprobacionFromModal() {
		var row = faModalRow;
		var modal = getFechaAprobacionModal();
		if (!row || !modal) {
			return Promise.resolve();
		}
		var modalInput = modal.querySelector('[data-pedidos-fa-input]');
		var cellInput = getOrdenFechaAprobacionInput(row);
		if (!modalInput || !cellInput) {
			closeFechaAprobacionModal();
			return Promise.resolve();
		}
		var raw = String(modalInput.value || '').trim();
		if (raw === '') {
			setFechaAprobacionModalError('Indica la fecha de aprobación.');
			modalInput.focus();
			return Promise.reject(new Error('Indica la fecha de aprobación.'));
		}
		cellInput.value = raw;
		faModalDismissedRows.delete(row);
		faModalPendingConfirm = null;
		closeFechaAprobacionModal();
		syncOrdenFechaAprobacionField(row);
		return saveOrdenLineaRow(row, { quiet: false }).then(function () {
			setBoardStatus('Fecha de aprobación guardada.', false);
		});
	}

	function initPedidosFechaAprobacionModal() {
		var modal = getFechaAprobacionModal();
		if (!modal || modal.dataset.pedidosFaModalBound === '1') {
			return;
		}
		modal.dataset.pedidosFaModalBound = '1';

		var form = modal.querySelector('[data-pedidos-fa-form]');
		if (form) {
			form.addEventListener('submit', function (event) {
				event.preventDefault();
				saveFechaAprobacionFromModal().catch(function (error) {
					if (error && error.message) {
						setBoardStatus(error.message, true);
					}
				});
			});
		}

		modal.addEventListener('click', function (event) {
			if (event.target.closest('[data-action="pedidos-close-fecha-aprobacion-modal"]')) {
				event.preventDefault();
				closeFechaAprobacionModal({ dismissed: true });
			}
		});

		document.addEventListener('keydown', function (event) {
			if (event.key === 'Escape' && modal && !modal.hidden) {
				closeFechaAprobacionModal({ dismissed: true });
			}
		});
	}

	function validateDespachoAgainstFinalizada(row, slot, cantidadRaw) {
		if (!row || !ordenRowAllowsEntrega(row)) {
			return null;
		}
		var finalizada = parsePedidosQuantity(fieldValue(row, 'cantidad_entregada'));
		if (finalizada <= 0) {
			return null;
		}
		var cantidad = parsePedidosQuantity(cantidadRaw);
		if (cantidad <= 0) {
			return null;
		}
		var other = 0;
		row.querySelectorAll('[data-field="parcial_cantidad"]').forEach(function (input) {
			if (String(input.getAttribute('data-slot') || '0') !== String(slot)) {
				other += parsePedidosQuantity(input.value);
			}
		});
		var total = other + cantidad;
		if (total > finalizada + 0.0001) {
			return 'La suma despachada (' + (formatPedidosQuantity(total) || '0')
				+ ') supera la cantidad finalizada (' + (formatPedidosQuantity(finalizada) || '0') + ').';
		}
		return null;
	}

	function getPedidosErrorModal() {
		return document.querySelector('[data-pedidos-error-modal]');
	}

	function showPedidosErrorModal(message) {
		var modal = getPedidosErrorModal();
		var body = modal ? modal.querySelector('[data-pedidos-error-message]') : null;
		if (!modal || !body) {
			setBoardStatus(message, true);
			return;
		}
		body.textContent = String(message || 'No se pudo guardar.');
		modal.hidden = false;
		document.body.classList.add('logistica-pedidos-error-modal-open');
	}

	function closePedidosErrorModal() {
		var modal = getPedidosErrorModal();
		if (modal) {
			modal.hidden = true;
		}
		document.body.classList.remove('logistica-pedidos-error-modal-open');
	}

	function initPedidosErrorModal() {
		var modal = getPedidosErrorModal();
		if (!modal || modal.dataset.pedidosErrorModalBound === '1') {
			return;
		}
		modal.dataset.pedidosErrorModalBound = '1';
		modal.addEventListener('click', function (event) {
			if (event.target.closest('[data-action="pedidos-close-error-modal"]')) {
				event.preventDefault();
				closePedidosErrorModal();
			}
		});
		document.addEventListener('keydown', function (event) {
			if (event.key === 'Escape' && modal && !modal.hidden) {
				closePedidosErrorModal();
			}
		});
	}

	var entregadoConfirmPending = null;

	function getEntregadoConfirmModal() {
		return document.querySelector('[data-pedidos-entregado-confirm-modal]');
	}

	function openEntregadoConfirmModal(row, estadoSelect, previousEstado) {
		var modal = getEntregadoConfirmModal();
		if (!modal || !row || !estadoSelect) {
			scheduleOrdenLineaAutoSave(row, { immediate: true });
			return;
		}
		entregadoConfirmPending = {
			row: row,
			select: estadoSelect,
			previousEstado: previousEstado || getPersistedOrdenLineaEstado(row) || 'despacho'
		};
		modal.hidden = false;
		document.body.classList.add('logistica-pedidos-entregado-confirm-open');
	}

	function closeEntregadoConfirmModal(revert) {
		var pending = entregadoConfirmPending;
		entregadoConfirmPending = null;
		var modal = getEntregadoConfirmModal();
		if (modal) {
			modal.hidden = true;
		}
		document.body.classList.remove('logistica-pedidos-entregado-confirm-open');
		if (revert && pending && pending.select && pending.row) {
			pending.select.value = pending.previousEstado || 'despacho';
			syncOrdenRowEstadoClass(pending.row, pending.select.value);
			syncOrdenEntregaFields(pending.row);
			syncOrdenOpField(pending.row);
			syncOrdenFechaAprobacionField(pending.row);
			updateOrdenLineaComputedQuantities(pending.row);
		}
	}

	function confirmEntregadoPending() {
		var pending = entregadoConfirmPending;
		entregadoConfirmPending = null;
		var modal = getEntregadoConfirmModal();
		if (modal) {
			modal.hidden = true;
		}
		document.body.classList.remove('logistica-pedidos-entregado-confirm-open');
		if (pending && pending.row) {
			scheduleOrdenLineaAutoSave(pending.row, { immediate: true });
		}
	}

	function initPedidosEntregadoConfirmModal() {
		var modal = getEntregadoConfirmModal();
		if (!modal || modal.dataset.pedidosEntregadoConfirmBound === '1') {
			return;
		}
		modal.dataset.pedidosEntregadoConfirmBound = '1';
		modal.addEventListener('click', function (event) {
			if (event.target.closest('[data-action="pedidos-cancel-entregado-confirm"]')) {
				event.preventDefault();
				closeEntregadoConfirmModal(true);
			}
			if (event.target.closest('[data-action="pedidos-confirm-entregado"]')) {
				event.preventDefault();
				confirmEntregadoPending();
			}
		});
		document.addEventListener('keydown', function (event) {
			if (event.key === 'Escape' && modal && !modal.hidden) {
				closeEntregadoConfirmModal(true);
			}
		});
	}

	function showParcialSaveError(message) {
		var parcialModal = getParcialModal();
		if (parcialModal && parcialModalRow && !parcialModal.hidden) {
			setParcialModalError(message);
			return;
		}
		showPedidosErrorModal(message);
	}

	var parcialModalRow = null;
	var parcialModalSlot = null;

	function getParcialModal() {
		return document.querySelector('[data-pedidos-parcial-modal]');
	}

	function setParcialModalError(message) {
		var modal = getParcialModal();
		var error = modal ? modal.querySelector('[data-pedidos-parcial-error]') : null;
		if (!error) {
			return;
		}
		if (message) {
			error.textContent = message;
			error.hidden = false;
		} else {
			error.textContent = '';
			error.hidden = true;
		}
	}

	function closeParcialModal() {
		var modal = getParcialModal();
		if (modal) {
			modal.hidden = true;
		}
		parcialModalRow = null;
		parcialModalSlot = null;
		document.body.classList.remove('logistica-pedidos-parcial-modal-open');
		setParcialModalError('');
	}

	function openParcialModal(row, slot) {
		if (!row) {
			return;
		}
		if (!ordenRowAllowsEntrega(row)) {
			setBoardStatus('Las entregas parciales requieren OC, tipo de producto y estado Despacho o Entregado.', true);
			return;
		}
		var modal = getParcialModal();
		var cantInput = modal ? modal.querySelector('[data-pedidos-parcial-cantidad-input]') : null;
		var facInput = modal ? modal.querySelector('[data-pedidos-parcial-factura-input]') : null;
		var hint = modal ? modal.querySelector('[data-pedidos-parcial-hint]') : null;
		var title = modal ? modal.querySelector('[data-pedidos-parcial-modal-title]') : null;
		var qtyCell = row.querySelector('[data-field="parcial_cantidad"][data-slot="' + slot + '"]');
		var facCell = row.querySelector('[data-field="parcial_factura"][data-slot="' + slot + '"]');
		if (!modal || !cantInput || !facInput) {
			return;
		}
		var slotLabel = parseInt(slot, 10) + 1;
		if (title) {
			title.textContent = 'Despacho ' + slotLabel + ' (Cant. / Factura ' + slotLabel + ')';
		}
		cantInput.value = qtyCell ? String(qtyCell.value || '').trim() : '';
		facInput.value = facCell ? String(facCell.value || '').trim() : '';
		if (hint) {
			var finalizada = formatPedidosQuantity(fieldValue(row, 'cantidad_entregada')) || '0';
			hint.textContent = 'Cantidad pedida: ' + (formatPedidosQuantity(fieldValue(row, 'cantidad')) || '0')
				+ ' · Cantidad finalizada (tope despacho): ' + finalizada
				+ ' · Tolerancia pedida vs finalizada: ±' + (fieldValue(row, 'cantidad_maxima_recibida') || '10') + '%';
			hint.hidden = false;
		}
		setParcialModalError('');
		parcialModalRow = row;
		parcialModalSlot = String(slot);
		modal.hidden = false;
		document.body.classList.add('logistica-pedidos-parcial-modal-open');
		window.setTimeout(function () {
			cantInput.focus();
			cantInput.select();
		}, 0);
	}

	function saveParcialFromModal() {
		var row = parcialModalRow;
		var slot = parcialModalSlot;
		var modal = getParcialModal();
		if (!row || slot == null || !modal) {
			return Promise.resolve();
		}
		var cantInput = modal.querySelector('[data-pedidos-parcial-cantidad-input]');
		var facInput = modal.querySelector('[data-pedidos-parcial-factura-input]');
		var qtyCell = row.querySelector('[data-field="parcial_cantidad"][data-slot="' + slot + '"]');
		var facCell = row.querySelector('[data-field="parcial_factura"][data-slot="' + slot + '"]');
		if (!cantInput || !facInput || !qtyCell) {
			closeParcialModal();
			return Promise.resolve();
		}
		var cantidad = String(cantInput.value || '').trim();
		var factura = String(facInput.value || '').trim();
		var originalQty = qtyCell ? String(qtyCell.value || '').trim() : '';
		var originalFac = facCell ? String(facCell.value || '').trim() : '';
		if (cantidad === '' && factura === '' && parseInt(qtyCell.getAttribute('data-parcial-id') || '0', 10) === 0) {
			setParcialModalError('Indica cantidad o factura para registrar el despacho.');
			cantInput.focus();
			return Promise.reject(new Error('Indica cantidad o factura para registrar el despacho.'));
		}
		var blockMsg = validateDespachoAgainstFinalizada(row, slot, cantidad);
		if (blockMsg) {
			setParcialModalError(blockMsg);
			cantInput.focus();
			return Promise.reject(new Error(blockMsg));
		}
		qtyCell.value = cantidad;
		if (facCell) {
			facCell.value = factura;
		}
		if (cantidad !== '') {
			formatPedidosQuantityField(qtyCell);
		}
		return saveOrdenParcialFromRow(row, slot, { quiet: false, suppressStatusError: true }).then(function () {
			closeParcialModal();
		}).catch(function (error) {
			qtyCell.value = originalQty;
			if (facCell) {
				facCell.value = originalFac;
			}
			var msg = error && error.message ? error.message : 'No se pudo guardar la entrega parcial.';
			setParcialModalError(msg);
			showPedidosErrorModal(msg);
			throw error;
		});
	}

	function initPedidosParcialModal() {
		var modal = getParcialModal();
		if (!modal || modal.dataset.pedidosParcialModalBound === '1') {
			return;
		}
		modal.dataset.pedidosParcialModalBound = '1';

		var form = modal.querySelector('[data-pedidos-parcial-form]');
		if (form) {
			form.addEventListener('submit', function (event) {
				event.preventDefault();
				saveParcialFromModal().catch(function () {
					return undefined;
				});
			});
		}

		modal.addEventListener('click', function (event) {
			if (event.target.closest('[data-action="pedidos-close-parcial-modal"]')) {
				event.preventDefault();
				closeParcialModal();
			}
		});

		document.addEventListener('keydown', function (event) {
			if (event.key === 'Escape' && modal && !modal.hidden) {
				closeParcialModal();
			}
		});
	}

	function createInventarioRowTemplate(sheetRoot) {
		sheetRoot = getPedidosSheetRoot(sheetRoot);
		var tbody = sheetRoot ? sheetRoot.querySelector('[data-pedidos-inventario-rows]') : null;
		if (!tbody) {
			return null;
		}
		removeEmptyRows(tbody);
		var tr = document.createElement('tr');
		tr.setAttribute('data-pedidos-inventario-row', '');
		tr.setAttribute('data-inventario-id', '0');
		tr.innerHTML = ''
			+ '<td><input type="text" data-field="item"></td>'
			+ '<td><input type="text" data-field="referencia"></td>'
			+ '<td><input type="text" inputmode="numeric" data-field="cantidad_op"></td>'
			+ '<td><input type="date" data-field="fecha_op"></td>'
			+ '<td><input type="text" inputmode="numeric" data-field="reporte_hornitos"></td>'
			+ '<td class="is-auto" data-pedidos-disponible>0</td>'
			+ '<td><input type="text" inputmode="decimal" data-field="valor_und"></td>'
			+ '<td><div class="logistica-pedidos-stock-cell"><input type="text" inputmode="numeric" class="is-sync-readonly" readonly tabindex="-1" data-field="stock_latingraf" title="Ajuste con los botones + y −"><div class="logistica-pedidos-stock-actions"><button type="button" class="logistica-pedidos-stock-btn logistica-pedidos-stock-btn--minus" data-action="pedidos-subtract-stock" title="Restar stock" aria-label="Restar stock"><span aria-hidden="true">−</span></button><button type="button" class="logistica-pedidos-stock-btn logistica-pedidos-stock-btn--plus" data-action="pedidos-add-stock" title="Sumar stock" aria-label="Sumar stock"><span aria-hidden="true">+</span></button></div></div><small class="logistica-pedidos-stock-disponible" data-pedidos-stock-disponible>Disp. 0</small></td>'
			+ '<td><select data-field="en_produccion"><option value="si">Sí</option><option value="no" selected>No</option></select></td>'
			+ buildInventarioEntregaCellsHtml(sheetRoot)
			+ '<td class="logistica-pedidos-table__actions-col"><button type="button" class="button button-small" data-action="pedidos-save-inventario">Guardar</button><button type="button" class="button button-small logistica-table-icon-btn" data-action="pedidos-delete-inventario" aria-label="Eliminar"><span class="dashicons dashicons-trash" aria-hidden="true"></span></button></td>';
		tbody.insertBefore(tr, tbody.firstChild);
		tr.querySelector('[data-field="referencia"]').focus();
		return tr;
	}

	function createOrdenRowTemplate(sheetRoot) {
		sheetRoot = getPedidosSheetRoot(sheetRoot);
		var tbody = sheetRoot ? sheetRoot.querySelector('[data-pedidos-ordenes-rows]') : null;
		var cfg = getConfig();
		var estadoOptions = cfg.estadoOptions || {};
		if (!tbody) {
			return null;
		}
		removeEmptyRows(tbody);

		var estadoSelect = Object.keys(estadoOptions).map(function (key) {
			return '<option value="' + key + '">' + estadoOptions[key] + '</option>';
		}).join('');

		var tr = document.createElement('tr');
		tr.setAttribute('data-pedidos-orden-row', '');
		tr.setAttribute('data-orden-id', '0');
		tr.setAttribute('data-linea-id', '0');
		tr.setAttribute('data-pedidos-parciales', '[]');
		tr.innerHTML = ''
			+ '<td data-pedidos-orden-cliente><input type="text" class="is-modal-locked" readonly tabindex="-1" data-field="cliente" title="Editar con el icono de editar"></td>'
			+ '<td data-pedidos-orden-numero><input type="text" class="is-modal-locked" readonly tabindex="-1" data-field="oc_numero" title="Editar con el icono de editar"></td>'
			+ '<td data-pedidos-orden-fecha><input type="date" class="is-modal-locked" readonly tabindex="-1" data-field="fecha_oc" title="Editar con el icono de editar"></td>'
			+ '<td><input type="hidden" data-field="articulo" value=""><span class="logistica-pedidos-locked-value">—</span></td>'
			+ '<td data-pedidos-orden-referencia-cell><input type="text" class="is-modal-locked" readonly tabindex="-1" data-field="descripcion" title="Editar con el icono de editar"></td>'
			+ '<td><input type="text" class="is-modal-locked" readonly tabindex="-1" data-field="cantidad" title="Editar con el icono de editar"></td>'
			+ '<td><input type="text" class="is-modal-locked" readonly tabindex="-1" data-field="precio_unit" title="Editar con el icono de editar"></td>'
			+ '<td><input type="date" class="is-modal-locked" readonly tabindex="-1" data-field="fecha_entrega" title="Editar con el icono de editar"></td>'
			+ '<td><input type="text" class="is-modal-locked" readonly tabindex="-1" data-field="observaciones" title="Editar con el icono de editar"></td>'
			+ '<td><select data-field="estado">' + estadoSelect + '</select></td>'
			+ buildOrdenParcialCellsHtml(sheetRoot)
			+ '<td class="logistica-pedidos-table__actions-col">' + ordenLineaEditButtonHtml() + ordenLineaDeleteButtonHtml() + '</td>';

		tbody.insertBefore(tr, tbody.firstChild);
		var focusField = tr.querySelector('[data-field="oc_numero"], [data-field="articulo"]');
		if (focusField) {
			focusField.focus();
		}
		syncOrdenEntregaFields(tr);
		return tr;
	}

	function parsePedidosDisplayDate(value) {
		var text = String(value == null ? '' : value).trim();
		var isoMatch = text.match(/^(\d{4})-(\d{2})-(\d{2})$/);
		if (isoMatch) {
			return new Date(Number(isoMatch[1]), Number(isoMatch[2]) - 1, Number(isoMatch[3])).getTime();
		}
		var dmyMatch = text.match(/^(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})$/);
		if (dmyMatch) {
			return new Date(Number(dmyMatch[3]), Number(dmyMatch[2]) - 1, Number(dmyMatch[1])).getTime();
		}
		return NaN;
	}

	function getPedidosOrdenRowSortValue(row, key) {
		if (!row || !key) {
			return '';
		}
		var attrValue = row.getAttribute('data-pedidos-orden-sort-' + key) || '';
		if ('estado' === key) {
			return row.getAttribute('data-pedidos-orden-estado') || attrValue;
		}
		if ('cliente' === key && !attrValue) {
			var clienteField = row.querySelector('[data-field="cliente"]');
			return clienteField ? String(clienteField.value || '').trim() : '';
		}
		if ('fecha-oc' !== key && 'fecha-entrega' !== key && 'fecha-aprobacion' !== key) {
			return attrValue;
		}
		if (attrValue) {
			return attrValue;
		}
		var fieldName = 'fecha-oc' === key ? 'fecha_oc' : ('fecha-aprobacion' === key ? 'fecha_aprobacion' : 'fecha_entrega');
		var field = row.querySelector('[data-field="' + fieldName + '"]');
		return field ? String(field.value || '').trim() : '';
	}

	function comparePedidosSortValues(valueA, valueB, dir) {
		valueA = String(valueA == null ? '' : valueA).trim();
		valueB = String(valueB == null ? '' : valueB).trim();

		var dateA = parsePedidosDisplayDate(valueA);
		var dateB = parsePedidosDisplayDate(valueB);
		if (!isNaN(dateA) && !isNaN(dateB)) {
			return (dateA - dateB) * dir;
		}

		var numA = parseFloat(valueA.replace(/[^\d.-]/g, ''));
		var numB = parseFloat(valueB.replace(/[^\d.-]/g, ''));

		if (!isNaN(numA) && !isNaN(numB) && (valueA.match(/\d/) || valueB.match(/\d/)) && !valueA.match(/[\/\-]/) && !valueB.match(/[\/\-]/)) {
			return (numA - numB) * dir;
		}

		valueA = valueA.toLowerCase();
		valueB = valueB.toLowerCase();

		if (valueA < valueB) {
			return -1 * dir;
		}

		if (valueA > valueB) {
			return 1 * dir;
		}

		return 0;
	}

	function setPedidosSortIndicator(indicator, dir) {
		if (!indicator) {
			return;
		}

		indicator.textContent = '';
		indicator.classList.remove('is-asc', 'is-desc');

		if (dir === 1) {
			indicator.classList.add('is-asc');
		} else if (dir === -1) {
			indicator.classList.add('is-desc');
		}
	}

	var PEDIDOS_ENTREGA_FILTER_EXCLUDED = {
		finalizado: true,
		cancelado: true,
		entregado: true
	};

	var PEDIDOS_ORDEN_HEADER_ATTRS = [
		'data-pedidos-orden-cliente',
		'data-pedidos-orden-numero',
		'data-pedidos-orden-fecha'
	];

	function parsePedidosIsoDate(value) {
		var text = String(value || '').trim();
		if (!/^\d{4}-\d{2}-\d{2}$/.test(text)) {
			return null;
		}
		var parts = text.split('-');
		return new Date(parseInt(parts[0], 10), parseInt(parts[1], 10) - 1, parseInt(parts[2], 10));
	}

	function getPedidosTodayDate() {
		var now = new Date();
		return new Date(now.getFullYear(), now.getMonth(), now.getDate());
	}

	function addPedidosDays(date, days) {
		var copy = new Date(date.getTime());
		copy.setDate(copy.getDate() + days);
		return copy;
	}

	function getRowEffectiveEntregaDate(row) {
		var prorroga = String(row.getAttribute('data-pedidos-orden-fecha-prorroga') || '').trim();
		var entrega = String(row.getAttribute('data-pedidos-orden-fecha-entrega') || '').trim();
		return prorroga || entrega;
	}

	function rowMatchesPedidosEntregaQuickFilter(row, filterKey) {
		if (!filterKey) {
			return true;
		}

		if (filterKey === 'prorroga') {
			return String(row.getAttribute('data-pedidos-orden-fecha-prorroga') || '').trim() !== '';
		}

		var effectiveDate = parsePedidosIsoDate(getRowEffectiveEntregaDate(row));
		if (!effectiveDate) {
			return false;
		}

		var today = getPedidosTodayDate();
		var estado = String(row.getAttribute('data-pedidos-orden-estado') || '').toLowerCase();

		if (filterKey === 'cercano') {
			if (PEDIDOS_ENTREGA_FILTER_EXCLUDED[estado]) {
				return false;
			}
			var maxDate = addPedidosDays(today, 3);
			return effectiveDate.getTime() >= today.getTime() && effectiveDate.getTime() <= maxDate.getTime();
		}

		if (filterKey === 'manana') {
			var manana = addPedidosDays(today, 1);
			return effectiveDate.getTime() === manana.getTime();
		}

		if (filterKey === 'atrasados') {
			if (PEDIDOS_ENTREGA_FILTER_EXCLUDED[estado]) {
				return false;
			}
			return effectiveDate.getTime() < today.getTime();
		}

		return true;
	}

	function buildPedidosOrdenHeaderTemplatesFromRow(row) {
		if (!row) {
			return [];
		}
		var cliente = String(row.getAttribute('data-pedidos-orden-sort-cliente') || '').trim();
		var oc = String(row.getAttribute('data-pedidos-orden-sort-oc') || '').trim();
		var fecha = String(row.getAttribute('data-pedidos-orden-sort-fecha-oc') || '').trim();
		var scratch = document.createElement('tbody');
		var tr = document.createElement('tr');
		tr.innerHTML = ''
			+ '<td data-pedidos-orden-cliente>' + lockedInputHtml('cliente', cliente) + '</td>'
			+ '<td data-pedidos-orden-numero>' + lockedInputHtml('oc_numero', oc) + '</td>'
			+ '<td data-pedidos-orden-fecha>' + lockedInputHtml('fecha_oc', fecha, 'date') + '</td>';
		scratch.appendChild(tr);
		return PEDIDOS_ORDEN_HEADER_ATTRS.map(function (attr) {
			var td = tr.querySelector('td[' + attr + ']');
			return td ? td.cloneNode(true) : null;
		}).filter(Boolean);
	}

	function ensurePedidosOrdenHeaderTemplates(group, sheetRoot, visibleRows) {
		var templates = group._pedidosHeaderTemplates || [];
		if (templates.length === PEDIDOS_ORDEN_HEADER_ATTRS.length) {
			return templates;
		}

		var seedRow = group._pedidosHeaderSourceRow || null;
		if (!seedRow) {
			group.rows.forEach(function (row) {
				if (row.querySelector('td[data-pedidos-orden-cliente]')) {
					seedRow = row;
				}
			});
		}
		if (seedRow) {
			templates = clonePedidosOrdenHeaderTemplatesFromRow(seedRow);
		}
		if (templates.length !== PEDIDOS_ORDEN_HEADER_ATTRS.length && visibleRows && visibleRows.length) {
			templates = buildPedidosOrdenHeaderTemplatesFromRow(visibleRows[0]);
		}
		if (templates.length === PEDIDOS_ORDEN_HEADER_ATTRS.length) {
			group._pedidosHeaderTemplates = templates;
			savePedidosOrdenHeaderTemplateStore(sheetRoot, group.groupKey, templates);
		}
		return templates;
	}

	function seedPedidosOrdenHeaderTemplateStores(sheetRoot) {
		getPedidosOrdenRowGroups(sheetRoot).groups.forEach(function (group) {
			capturePedidosOrdenGroupHeaderTemplates(group, sheetRoot);
		});
	}

	function syncOrdenGroupHeaderValuesFromRow(targetRow, sheetRoot) {
		if (!targetRow || !sheetRoot) {
			return;
		}
		var ordenId = targetRow.getAttribute('data-orden-id') || '0';
		updateOrdenGroupHeaders(sheetRoot, ordenId, {
			cliente: String(targetRow.getAttribute('data-pedidos-orden-sort-cliente') || '').trim(),
			oc_numero: String(targetRow.getAttribute('data-pedidos-orden-sort-oc') || '').trim(),
			fecha_oc: String(targetRow.getAttribute('data-pedidos-orden-sort-fecha-oc') || '').trim()
		});
	}

	function clonePedidosOrdenHeaderTemplatesFromRow(sourceRow) {
		if (!sourceRow) {
			return [];
		}
		return PEDIDOS_ORDEN_HEADER_ATTRS.map(function (attr) {
			var td = sourceRow.querySelector('td[' + attr + ']');
			return td ? td.cloneNode(true) : null;
		}).filter(Boolean);
	}

	function getPedidosOrdenHeaderTemplateStore(sheetRoot) {
		if (!sheetRoot) {
			return null;
		}
		if (!sheetRoot._pedidosOrdenHeaderTemplateStore) {
			sheetRoot._pedidosOrdenHeaderTemplateStore = Object.create(null);
		}
		return sheetRoot._pedidosOrdenHeaderTemplateStore;
	}

	function savePedidosOrdenHeaderTemplateStore(sheetRoot, groupKey, templates) {
		if (!sheetRoot || !groupKey || !templates || !templates.length) {
			return;
		}
		var store = getPedidosOrdenHeaderTemplateStore(sheetRoot);
		store[groupKey] = templates.map(function (td) {
			return td.cloneNode(true);
		});
	}

	function loadPedidosOrdenHeaderTemplateClones(sheetRoot, groupKey) {
		var store = getPedidosOrdenHeaderTemplateStore(sheetRoot);
		var saved = store && store[groupKey];
		if (!saved || !saved.length) {
			return [];
		}
		return saved.map(function (td) {
			return td.cloneNode(true);
		});
	}

	function capturePedidosOrdenGroupHeaderTemplates(group, sheetRoot) {
		var sourceRow = null;
		group.rows.forEach(function (row) {
			if (row.querySelector('td[data-pedidos-orden-cliente]')) {
				sourceRow = row;
			}
		});

		if (sourceRow) {
			var fresh = clonePedidosOrdenHeaderTemplatesFromRow(sourceRow);
			if (fresh.length) {
				savePedidosOrdenHeaderTemplateStore(sheetRoot, group.groupKey, fresh);
			}
		}

		var templates = loadPedidosOrdenHeaderTemplateClones(sheetRoot, group.groupKey);
		if (!templates.length && sourceRow) {
			templates = clonePedidosOrdenHeaderTemplatesFromRow(sourceRow);
		}

		group._pedidosHeaderSourceRow = sourceRow || null;
		group._pedidosHeaderTemplates = templates;
	}

	function stripPedidosOrdenRowHeaders(row) {
		PEDIDOS_ORDEN_HEADER_ATTRS.forEach(function (attr) {
			var td = row.querySelector('td[' + attr + ']');
			if (td) {
				td.remove();
			}
		});
	}

	function applyPedidosOrdenRowHeaders(targetRow, templates, rowspan) {
		if (!targetRow || !templates || !templates.length) {
			return;
		}

		var insertBeforeNode = targetRow.firstChild;
		templates.forEach(function (template) {
			var td = template.cloneNode(true);
			td.setAttribute('rowspan', String(Math.max(1, rowspan)));
			targetRow.insertBefore(td, insertBeforeNode);
		});
	}

	function reflowPedidosOrdenGroupHeaders(group, sheetRoot) {
		capturePedidosOrdenGroupHeaderTemplates(group, sheetRoot);
		var visibleRows = group.rows.filter(function (row) {
			return row.dataset.logisticaFilterVisible === '1';
		});
		if (!visibleRows.length) {
			return;
		}

		var templates = ensurePedidosOrdenHeaderTemplates(group, sheetRoot, visibleRows);
		if (!templates || templates.length !== PEDIDOS_ORDEN_HEADER_ATTRS.length) {
			return;
		}

		group.rows.forEach(stripPedidosOrdenRowHeaders);
		applyPedidosOrdenRowHeaders(visibleRows[0], templates, visibleRows.length);
		syncOrdenGroupHeaderValuesFromRow(visibleRows[0], sheetRoot);
		group.rows.forEach(syncPedidosOrdenReferenciaDisplayFromAttrs);
	}

	function getPedidosOrdenRowGroups(sheetRoot) {
		var tbody = sheetRoot.querySelector('[data-pedidos-ordenes-rows]');
		var rows = tbody ? Array.prototype.slice.call(tbody.querySelectorAll('[data-pedidos-orden-row]')) : [];
		var groups = [];
		var map = {};

		rows.forEach(function (row) {
			var groupKey = getOrdenGroupKey(row);
			if (!map[groupKey]) {
				map[groupKey] = {
					groupKey: groupKey,
					ordenId: row.getAttribute('data-orden-id') || '0',
					rows: []
				};
				groups.push(map[groupKey]);
			}
			map[groupKey].rows.push(row);
		});

		return {
			tbody: tbody,
			groups: groups
		};
	}

	function applyPedidosOrdenesSort(sheetRoot, key, dir, activeHeader) {
		var table = sheetRoot.querySelector('[data-pedidos-ordenes-table]');
		var headers = table ? table.querySelectorAll('thead th.logistica-pedidos-orden-sortable') : [];
		var grouped = getPedidosOrdenRowGroups(sheetRoot);
		var tbody = grouped.tbody;
		var groups = grouped.groups;
		var emptyRow = tbody ? tbody.querySelector('[data-pedidos-orden-filter-empty]') : null;
		var isGroupKey = 'fecha-oc' === key || 'oc' === key || 'cliente' === key;

		if (!tbody || !key) {
			return;
		}

		headers.forEach(function (header) {
			var indicator = header.querySelector('.logistica-pedidos-orden-sort-indicator');
			header.classList.remove('logistica-pedidos-orden-sort-active');
			setPedidosSortIndicator(indicator, null);
		});

		if (activeHeader) {
			activeHeader.classList.add('logistica-pedidos-orden-sort-active');
			setPedidosSortIndicator(activeHeader.querySelector('.logistica-pedidos-orden-sort-indicator'), dir);
		}

		if (!isGroupKey) {
			groups.forEach(function (group) {
				group.rows.sort(function (rowA, rowB) {
					return comparePedidosSortValues(
						getPedidosOrdenRowSortValue(rowA, key),
						getPedidosOrdenRowSortValue(rowB, key),
						dir
					);
				});
			});
		}

		groups.sort(function (groupA, groupB) {
			var rowA = groupA.rows[0];
			var rowB = groupB.rows[0];
			return comparePedidosSortValues(
				getPedidosOrdenRowSortValue(rowA, key),
				getPedidosOrdenRowSortValue(rowB, key),
				dir
			);
		});

		groups.forEach(function (group) {
			group.rows.forEach(function (row) {
				tbody.appendChild(row);
			});
		});

		if (emptyRow) {
			tbody.appendChild(emptyRow);
		}

		groups.forEach(function (group) {
			reflowPedidosOrdenGroupHeaders(group, sheetRoot);
		});

		sheetRoot._pedidosOrdenSortState = { key: key, dir: dir };
	}

	function initPedidosOrdenesSortBoard(board) {
		if (!board || board.dataset.pedidosOrdenSortBoardBound === '1') {
			return;
		}

		board.querySelectorAll('th.logistica-pedidos-orden-sortable').forEach(function (header) {
			header.setAttribute('role', 'button');
			header.setAttribute('tabindex', '0');
		});

		board.addEventListener('click', function (event) {
			var header = event.target.closest('th.logistica-pedidos-orden-sortable');
			var sheetRoot;
			var key;
			var sortState;
			var dir;

			if (!header || !board.contains(header)) {
				return;
			}

			sheetRoot = header.closest('[data-pedidos-sheet-root]');
			if (!sheetRoot) {
				return;
			}

			key = header.getAttribute('data-pedidos-orden-sort') || '';
			if (!key) {
				return;
			}

			event.preventDefault();
			sortState = sheetRoot._pedidosOrdenSortState || { key: null, dir: 1 };
			dir = sortState.key === key ? sortState.dir * -1 : 1;
			sortState.key = key;
			sortState.dir = dir;
			sheetRoot._pedidosOrdenSortState = sortState;
			applyPedidosOrdenesSort(sheetRoot, key, dir, header);
			if (typeof sheetRoot._pedidosOrdenFilterRefresh === 'function') {
				sheetRoot._pedidosOrdenFilterRefresh();
			}
		});

		board.addEventListener('keydown', function (event) {
			var header = event.target.closest('th.logistica-pedidos-orden-sortable');

			if (!header || !board.contains(header)) {
				return;
			}

			if (event.key === 'Enter' || event.key === ' ') {
				event.preventDefault();
				header.click();
			}
		});

		board.dataset.pedidosOrdenSortBoardBound = '1';
	}

	function ensurePedidosOrdenClienteFilterOptions(sheetRoot) {
		var select = sheetRoot ? sheetRoot.querySelector('[data-pedidos-orden-filter-cliente]') : null;
		if (!select) {
			return;
		}

		var existing = Object.create(null);
		Array.prototype.forEach.call(select.options, function (option) {
			var key = String(option.value || '').toLowerCase().trim();
			if (key) {
				existing[key] = true;
			}
		});

		var additions = [];
		sheetRoot.querySelectorAll('[data-pedidos-orden-row]').forEach(function (row) {
			var key = String(row.getAttribute('data-pedidos-orden-cliente') || '').toLowerCase().trim();
			var label = String(row.getAttribute('data-pedidos-orden-sort-cliente') || key).trim();
			if (key && !existing[key]) {
				existing[key] = true;
				additions.push({ key: key, label: label });
			}
		});

		additions.sort(function (a, b) {
			return a.label.localeCompare(b.label, undefined, { sensitivity: 'base' });
		});

		additions.forEach(function (item) {
			var option = document.createElement('option');
			option.value = item.label;
			option.textContent = item.label;
			select.appendChild(option);
		});
	}

	var PEDIDOS_ORDENES_PAGINATION_PREFIX = 'pedidos-ordenes';

	function getPedidosOrdenesPaginationState(sheetRoot) {
		var prefix = PEDIDOS_ORDENES_PAGINATION_PREFIX;
		var storageKey = 'logistica_' + prefix + '_page_size_v1';
		var savedSize;

		if (!sheetRoot._tablePaginationState) {
			sheetRoot._tablePaginationState = {};
		}

		if (!sheetRoot._tablePaginationState[prefix]) {
			savedSize = parseInt(localStorage.getItem(storageKey), 10);
			sheetRoot._tablePaginationState[prefix] = {
				page: 1,
				pageSize: Number.isFinite(savedSize) ? savedSize : 25
			};
		}

		return sheetRoot._tablePaginationState[prefix];
	}

	function isPedidosOrdenesPaginationBound(sheetRoot) {
		if (!sheetRoot._tablePaginationBound) {
			return false;
		}

		return sheetRoot._tablePaginationBound[PEDIDOS_ORDENES_PAGINATION_PREFIX] === true;
	}

	function markPedidosOrdenesPaginationBound(sheetRoot) {
		if (!sheetRoot._tablePaginationBound) {
			sheetRoot._tablePaginationBound = {};
		}

		sheetRoot._tablePaginationBound[PEDIDOS_ORDENES_PAGINATION_PREFIX] = true;
	}

	function applyPedidosOrdenesPagination(sheetRoot, options) {
		var prefix = PEDIDOS_ORDENES_PAGINATION_PREFIX;
		var state = getPedidosOrdenesPaginationState(sheetRoot);
		var pagination = sheetRoot.querySelector('[data-' + prefix + '-pagination]');
		var pageSizeSelect = sheetRoot.querySelector('[data-' + prefix + '-page-size]');
		var prevBtn = sheetRoot.querySelector('[data-action="' + prefix + '-page-prev"]');
		var nextBtn = sheetRoot.querySelector('[data-action="' + prefix + '-page-next"]');
		var label = sheetRoot.querySelector('[data-' + prefix + '-page-label]');
		var info = sheetRoot.querySelector('[data-' + prefix + '-page-info]');
		var grouped = getPedidosOrdenRowGroups(sheetRoot);
		var rows = grouped.tbody ? Array.prototype.slice.call(grouped.tbody.querySelectorAll('[data-pedidos-orden-row]')) : [];
		var visibleRows = [];
		var totalPages;
		var start;
		var end;
		var from;
		var to;

		options = options || {};

		if (options.resetPage) {
			state.page = 1;
		}

		if (pageSizeSelect) {
			if (!pageSizeSelect.dataset.paginationBound) {
				pageSizeSelect.value = String(state.pageSize);
			} else if (parseInt(pageSizeSelect.value, 10) !== state.pageSize) {
				state.pageSize = parseInt(pageSizeSelect.value, 10) || 25;
			}
		}

		rows.forEach(function (row) {
			if (row.dataset.logisticaFilterVisible === '1') {
				visibleRows.push(row);
			}
		});

		totalPages = Math.max(1, Math.ceil(visibleRows.length / state.pageSize));

		if (state.page > totalPages) {
			state.page = totalPages;
		}

		if (state.page < 1) {
			state.page = 1;
		}

		start = (state.page - 1) * state.pageSize;
		end = start + state.pageSize;

		visibleRows.forEach(function (row, index) {
			row.dataset.logisticaVisibleIndex = String(index);
		});

		rows.forEach(function (row) {
			var index;

			if (row.dataset.logisticaFilterVisible !== '1') {
				row.hidden = true;
				return;
			}

			index = parseInt(row.dataset.logisticaVisibleIndex, 10);
			row.hidden = index < start || index >= end;
		});

		grouped.groups.forEach(function (group) {
			reflowPedidosOrdenGroupHeaders(group, sheetRoot);
		});

		if (label) {
			label.textContent = visibleRows.length > 0
				? ('Página ' + state.page + ' de ' + totalPages)
				: '';
		}

		if (info) {
			if (visibleRows.length === 0) {
				info.textContent = '';
			} else {
				from = start + 1;
				to = Math.min(end, visibleRows.length);
				info.textContent = 'Mostrando ' + from + '-' + to + ' de ' + visibleRows.length + ' registros';
			}
		}

		if (prevBtn) {
			prevBtn.disabled = state.page <= 1 || visibleRows.length === 0;
		}

		if (nextBtn) {
			nextBtn.disabled = state.page >= totalPages || visibleRows.length === 0;
		}

		if (pagination) {
			pagination.hidden = rows.length === 0;
		}
	}

	function bindPedidosOrdenesPagination(sheetRoot) {
		var prefix = PEDIDOS_ORDENES_PAGINATION_PREFIX;
		var state = getPedidosOrdenesPaginationState(sheetRoot);
		var pageSizeSelect = sheetRoot.querySelector('[data-' + prefix + '-page-size]');

		if (isPedidosOrdenesPaginationBound(sheetRoot)) {
			return;
		}

		if (pageSizeSelect) {
			pageSizeSelect.value = String(state.pageSize);
			pageSizeSelect.dataset.paginationBound = '1';
			pageSizeSelect.addEventListener('change', function () {
				state.pageSize = parseInt(pageSizeSelect.value, 10) || 25;
				state.page = 1;

				try {
					localStorage.setItem('logistica_' + prefix + '_page_size_v1', String(state.pageSize));
				} catch (error) {
					// Storage may be unavailable.
				}

				applyPedidosOrdenesPagination(sheetRoot, { resetPage: true });
				updatePedidosOrdenesTotals(sheetRoot);
			});
		}

		sheetRoot.addEventListener('click', function (event) {
			if (event.target.closest('[data-action="' + prefix + '-page-prev"]')) {
				state.page -= 1;
				applyPedidosOrdenesPagination(sheetRoot);
				updatePedidosOrdenesTotals(sheetRoot);
				return;
			}

			if (event.target.closest('[data-action="' + prefix + '-page-next"]')) {
				state.page += 1;
				applyPedidosOrdenesPagination(sheetRoot);
				updatePedidosOrdenesTotals(sheetRoot);
			}
		});

		markPedidosOrdenesPaginationBound(sheetRoot);
	}

	function initPedidosOrdenesExcel(sheetRoot) {
		var searchInput;
		var clienteSelect;
		var referenciaSelect;
		var estadoSelect;
		var clearButton;
		var meta;
		var badge;
		var filtersWrap;
		var emptyMessage;
		var importInput;
		var entregaFilterButtons;
		var historialBanner;
		var historialEntry;
		var historialFields;
		var historialToggleButtons;
		var historialDesdeInput;
		var historialHastaInput;
		var filtersTitle;
		var filtersTitleDefault;
		var activeEntregaFilter = '';
		var historialMode = false;

		if (!sheetRoot || !sheetRoot.querySelector('[data-pedidos-ordenes-excel]')) {
			return;
		}

		if (sheetRoot.dataset.pedidosOrdenesExcelBound === '1') {
			return;
		}

		searchInput = sheetRoot.querySelector('[data-pedidos-orden-filter-search]');
		clienteSelect = sheetRoot.querySelector('[data-pedidos-orden-filter-cliente]');
		referenciaSelect = sheetRoot.querySelector('[data-pedidos-orden-filter-referencia]');
		estadoSelect = sheetRoot.querySelector('[data-pedidos-orden-filter-estado]');
		clearButton = sheetRoot.querySelector('[data-action="clear-pedidos-orden-filters"]');
		meta = sheetRoot.querySelector('[data-pedidos-orden-filter-meta]');
		badge = sheetRoot.querySelector('[data-pedidos-orden-filter-badge]');
		filtersWrap = sheetRoot.querySelector('[data-pedidos-orden-filters]');
		emptyMessage = sheetRoot.querySelector('[data-pedidos-orden-filter-empty]');
		importInput = sheetRoot.querySelector('[data-pedidos-orden-import-file]');
		entregaFilterButtons = sheetRoot.querySelectorAll('[data-pedidos-orden-entrega-filter]');
		historialBanner = sheetRoot.querySelector('[data-pedidos-orden-historial-banner]');
		historialEntry = sheetRoot.querySelector('[data-pedidos-orden-historial-entry]');
		historialFields = sheetRoot.querySelector('[data-pedidos-orden-historial-fields]');
		historialToggleButtons = sheetRoot.querySelectorAll('[data-action="toggle-pedidos-orden-historial"]');
		historialDesdeInput = sheetRoot.querySelector('[data-pedidos-historial-desde]');
		historialHastaInput = sheetRoot.querySelector('[data-pedidos-historial-hasta]');
		filtersTitle = sheetRoot.querySelector('[data-pedidos-orden-filters-title]');
		filtersTitleDefault = filtersTitle ? String(filtersTitle.textContent || '').trim() : '';

		function normalizeFilterValue(value) {
			return String(value || '').toLowerCase().trim();
		}

		function ensureHistorialDefaultDates() {
			// Sin fechas por defecto: mostrar todo el historial de entregados.
			// El usuario puede acotar el periodo antes de descargar.
		}

		function rowMatchesHistorialDateRange(row) {
			if (!historialMode) {
				return true;
			}
			var desde = historialDesdeInput ? String(historialDesdeInput.value || '').trim() : '';
			var hasta = historialHastaInput ? String(historialHastaInput.value || '').trim() : '';
			if (!desde && !hasta) {
				return true;
			}
			var entregadoAt = String(row.getAttribute('data-pedidos-orden-entregado-at') || '').trim();
			if (!entregadoAt) {
				return true;
			}
			if (desde && entregadoAt < desde) {
				return false;
			}
			if (hasta && entregadoAt > hasta) {
				return false;
			}
			return true;
		}

		function syncHistorialModeUi() {
			sheetRoot.classList.toggle('is-pedidos-historial-mode', historialMode);
			if (historialBanner) {
				historialBanner.hidden = !historialMode;
				historialBanner.classList.toggle('is-active', historialMode);
			}
			if (historialEntry) {
				historialEntry.hidden = historialMode;
			}
			if (filtersTitle) {
				filtersTitle.textContent = historialMode
					? 'Historial de entregados'
					: (filtersTitleDefault || 'Filtrar tabla');
			}
			if (historialToggleButtons && historialToggleButtons.length) {
				historialToggleButtons.forEach(function (button) {
					button.setAttribute('aria-pressed', historialMode ? 'true' : 'false');
				});
			}
			if (estadoSelect) {
				if (historialMode) {
					estadoSelect.value = 'entregado';
				} else {
					if (estadoSelect.value === 'entregado') {
						estadoSelect.value = '';
					}
				}
			}
		}

		function setHistorialMode(enabled) {
			historialMode = !!enabled;
			if (historialMode) {
				ensureHistorialDefaultDates();
				activeEntregaFilter = '';
				syncEntregaFilterButtons();
			}
			syncHistorialModeUi();
			updatePedidosOrdenesFilters({ resetPage: true });
		}

		function buildPedidosHistorialExportUrl(desde, hasta) {
			var base = sheetRoot.getAttribute('data-pedidos-historial-export-url') || '';
			if (!base) {
				return '';
			}
			try {
				var url = new URL(base, window.location.origin);
				if (desde) {
					url.searchParams.set('desde', desde);
				}
				if (hasta) {
					url.searchParams.set('hasta', hasta);
				}
				return url.toString();
			} catch (error) {
				return base;
			}
		}

		function syncEntregaFilterButtons() {
			entregaFilterButtons.forEach(function (button) {
				var key = button.getAttribute('data-pedidos-orden-entrega-filter') || '';
				button.classList.toggle('is-active', key !== '' && key === activeEntregaFilter);
				button.setAttribute('aria-pressed', key !== '' && key === activeEntregaFilter ? 'true' : 'false');
			});
		}

		function rowMatchesPedidosOrdenFilters(row, query, cliente, referencia, estado, entregaFilter) {
			var isEntregado = rowIsEntregadoPersisted(row);
			if (historialMode) {
				if (!isEntregado) {
					return false;
				}
				if (!rowMatchesHistorialDateRange(row)) {
					return false;
				}
			} else if (isEntregado) {
				return false;
			}
			var matchesSearch = !query || normalizeFilterValue(row.getAttribute('data-pedidos-orden-search')).indexOf(query) !== -1;
			var matchesCliente = !cliente || normalizeFilterValue(row.getAttribute('data-pedidos-orden-cliente')) === cliente;
			var matchesReferencia = !referencia || normalizeFilterValue(row.getAttribute('data-pedidos-orden-referencia')) === referencia;
			var matchesEstado = !estado || normalizeFilterValue(row.getAttribute('data-pedidos-orden-estado')) === estado;
			var matchesEntrega = historialMode ? true : rowMatchesPedidosEntregaQuickFilter(row, entregaFilter);
			return matchesSearch && matchesCliente && matchesReferencia && matchesEstado && matchesEntrega;
		}

		function updatePedidosOrdenesFilters(options) {
			options = options || {};
			var grouped = getPedidosOrdenRowGroups(sheetRoot);
			var groups = grouped.groups;
			var query = normalizeFilterValue(searchInput ? searchInput.value : '');
			var cliente = normalizeFilterValue(clienteSelect ? clienteSelect.value : '');
			var referencia = normalizeFilterValue(referenciaSelect ? referenciaSelect.value : '');
			var estado = normalizeFilterValue(estadoSelect ? estadoSelect.value : '');
			var hasFilters = Boolean(query || cliente || referencia || estado || activeEntregaFilter || historialMode);
			var totalRows = 0;
			var filterVisibleRows = 0;

			groups.forEach(function (group) {
				totalRows += group.rows.length;
				group.rows.forEach(function (row) {
					var visible = rowMatchesPedidosOrdenFilters(row, query, cliente, referencia, estado, activeEntregaFilter);
					row.dataset.logisticaFilterVisible = visible ? '1' : '0';
					if (visible) {
						filterVisibleRows += 1;
					}
				});
			});

			applyPedidosOrdenesPagination(sheetRoot, options);

			if (filtersWrap) {
				filtersWrap.classList.toggle('is-active', hasFilters);
			}

			if (badge) {
				badge.hidden = !hasFilters;
			}

			if (meta) {
				if (hasFilters) {
					var prefix = historialMode ? 'Historial: ' : '';
					meta.textContent = prefix + filterVisibleRows + ' de ' + totalRows + ' líneas visibles';
					meta.hidden = false;
				} else {
					meta.textContent = '';
					meta.hidden = true;
				}
			}

			if (emptyMessage) {
				emptyMessage.hidden = filterVisibleRows > 0 || totalRows === 0;
			}

			if (clearButton) {
				clearButton.disabled = !hasFilters;
			}

			updatePedidosOrdenesTotals(sheetRoot);
		}

		if (searchInput) {
			searchInput.addEventListener('input', function () {
				updatePedidosOrdenesFilters({ resetPage: true });
			});
		}

		if (clienteSelect) {
			clienteSelect.addEventListener('change', function () {
				updatePedidosOrdenesFilters({ resetPage: true });
			});
		}

		if (referenciaSelect) {
			referenciaSelect.addEventListener('change', function () {
				updatePedidosOrdenesFilters({ resetPage: true });
			});
		}

		if (estadoSelect) {
			estadoSelect.addEventListener('change', function () {
				if (!historialMode && normalizeFilterValue(estadoSelect.value) === 'entregado') {
					setHistorialMode(true);
					return;
				}
				updatePedidosOrdenesFilters({ resetPage: true });
			});
		}

		if (historialToggleButtons && historialToggleButtons.length) {
			historialToggleButtons.forEach(function (button) {
				button.addEventListener('click', function () {
					setHistorialMode(!historialMode);
				});
			});
		}

		if (historialDesdeInput) {
			historialDesdeInput.addEventListener('change', function () {
				updatePedidosOrdenesFilters({ resetPage: true });
			});
		}

		if (historialHastaInput) {
			historialHastaInput.addEventListener('change', function () {
				updatePedidosOrdenesFilters({ resetPage: true });
			});
		}

		sheetRoot.addEventListener('click', function (event) {
			var exportBtn = event.target.closest('[data-action="export-pedidos-orden-historial"]');
			if (!exportBtn || !sheetRoot.contains(exportBtn)) {
				return;
			}
			event.preventDefault();
			ensureHistorialDefaultDates();
			var desde = historialDesdeInput ? historialDesdeInput.value : '';
			var hasta = historialHastaInput ? historialHastaInput.value : '';
			if (desde && hasta && desde > hasta) {
				setBoardStatus('La fecha «desde» no puede ser posterior a «hasta».', true);
				return;
			}
			var exportUrl = buildPedidosHistorialExportUrl(desde, hasta);
			if (!exportUrl) {
				setBoardStatus('No se pudo preparar la descarga del historial.', true);
				return;
			}
			window.location.href = exportUrl;
		});

		entregaFilterButtons.forEach(function (button) {
			button.addEventListener('click', function () {
				var key = button.getAttribute('data-pedidos-orden-entrega-filter') || '';
				activeEntregaFilter = activeEntregaFilter === key ? '' : key;
				syncEntregaFilterButtons();
				updatePedidosOrdenesFilters({ resetPage: true });
			});
		});

		if (clearButton) {
			clearButton.addEventListener('click', function () {
				if (searchInput) {
					searchInput.value = '';
				}
				if (clienteSelect) {
					clienteSelect.value = '';
				}
				if (referenciaSelect) {
					referenciaSelect.value = '';
				}
				if (estadoSelect) {
					estadoSelect.value = '';
				}
				activeEntregaFilter = '';
				setHistorialMode(false);
				syncEntregaFilterButtons();
				updatePedidosOrdenesFilters({ resetPage: true });
			});
		}

		if (importInput) {
			importInput.addEventListener('change', function () {
				if (importInput.files && importInput.files.length && importInput.form) {
					importInput.form.submit();
				}
			});
		}

		ensurePedidosOrdenClienteFilterOptions(sheetRoot);
		seedPedidosOrdenHeaderTemplateStores(sheetRoot);
		syncHistorialModeUi();
		syncEntregaFilterButtons();
		bindPedidosOrdenesPagination(sheetRoot);
		updatePedidosOrdenesFilters({ resetPage: true });
		sheetRoot._pedidosOrdenFilterRefresh = function () {
			ensurePedidosOrdenClienteFilterOptions(sheetRoot);
			updatePedidosOrdenesFilters();
		};
		sheetRoot._pedidosToggleHistorialMode = function () {
			setHistorialMode(!historialMode);
		};
		sheetRoot.dataset.pedidosOrdenesExcelBound = '1';
	}

	function isoDateFromDate(date) {
		var year = date.getFullYear();
		var month = String(date.getMonth() + 1).padStart(2, '0');
		var day = String(date.getDate()).padStart(2, '0');
		return year + '-' + month + '-' + day;
	}

	function getCurrentWeekMondayIso() {
		var today = new Date();
		var day = today.getDay();
		var diff = day === 0 ? -6 : 1 - day;
		var monday = new Date(today.getFullYear(), today.getMonth(), today.getDate() + diff);
		return isoDateFromDate(monday);
	}

	function shiftIsoDate(isoDate, dayOffset) {
		var parts = String(isoDate || '').split('-');
		if (parts.length !== 3) {
			return '';
		}
		var date = new Date(parseInt(parts[0], 10), parseInt(parts[1], 10) - 1, parseInt(parts[2], 10));
		date.setDate(date.getDate() + dayOffset);
		return isoDateFromDate(date);
	}

	var pedidosWeekMetricsTimer = null;

	function scheduleRefreshPedidosWeekMetrics() {
		if (pedidosWeekMetricsTimer) {
			clearTimeout(pedidosWeekMetricsTimer);
		}
		pedidosWeekMetricsTimer = window.setTimeout(function () {
			pedidosWeekMetricsTimer = null;
			var board = document.querySelector('[data-pedidos-board]');
			if (board && typeof board._refreshPedidosWeekMetrics === 'function') {
				board._refreshPedidosWeekMetrics();
			}
		}, 400);
	}

	function initPedidosMetrics(board) {
		if (!board) {
			return;
		}

		var metricsRoot = board.querySelector('[data-planeacion-metrics]');
		var metricsPanel = board.querySelector('[data-planeacion-metrics-pedidos-panel]');
		if (!metricsRoot || !metricsPanel || !window.LogisticaPlaneacionMetrics) {
			return;
		}

		function loadPedidosWeekMetrics() {
			postPedidos('logistica_get_pedidos_metrics_week', {}).then(function (response) {
				if (!response || !response.success) {
					return;
				}
				LogisticaPlaneacionMetrics.renderPedidosWeekPanel(metricsPanel, response.data);
			}).catch(function () {
				// Sin bloquear el tablero si fallan las métricas.
			});
		}

		board._refreshPedidosWeekMetrics = loadPedidosWeekMetrics;

		if (board.dataset.pedidosMetricsBound === '1') {
			loadPedidosWeekMetrics();
			return;
		}

		board.dataset.pedidosMetricsBound = '1';

		function loadPedidosPeriodCharts() {
			var fromInput = metricsRoot.querySelector('[data-planeacion-pedidos-period-from]');
			var toInput = metricsRoot.querySelector('[data-planeacion-pedidos-period-to]');
			var hint = metricsRoot.querySelector('[data-planeacion-pedidos-period-hint]');
			var dateFrom = fromInput ? String(fromInput.value || '') : '';
			var dateTo = toInput ? String(toInput.value || '') : '';

			if (!dateFrom || !dateTo) {
				if (hint) {
					hint.textContent = 'Indique fecha desde y hasta.';
					hint.hidden = false;
				}
				return;
			}

			if (hint) {
				hint.textContent = 'Generando gráficos…';
				hint.hidden = false;
			}

			postPedidos('logistica_get_pedidos_metrics_period', {
				fecha_desde: dateFrom,
				fecha_hasta: dateTo
			}).then(function (response) {
				if (!response || !response.success) {
					if (hint) {
						hint.textContent = (response && response.data && response.data.message) || 'No se pudieron cargar los gráficos.';
						hint.hidden = false;
					}
					return;
				}

				LogisticaPlaneacionMetrics.renderPedidosPeriodCharts(metricsRoot, response.data, window.Chart);
			}).catch(function () {
				if (hint) {
					hint.textContent = 'Error de conexión.';
					hint.hidden = false;
				}
			});
		}

		var periodFrom = metricsRoot.querySelector('[data-planeacion-pedidos-period-from]');
		var periodTo = metricsRoot.querySelector('[data-planeacion-pedidos-period-to]');
		if (periodFrom && periodTo && !periodFrom.value && !periodTo.value) {
			var weekStart = getCurrentWeekMondayIso();
			periodFrom.value = shiftIsoDate(weekStart, -28);
			periodTo.value = shiftIsoDate(weekStart, 6);
		}

		metricsRoot.addEventListener('click', function (event) {
			var actionNode = event.target.closest('[data-action="planeacion-pedidos-period-charts"]');
			if (!actionNode || !metricsRoot.contains(actionNode)) {
				return;
			}
			event.preventDefault();
			loadPedidosPeriodCharts();
		});

		loadPedidosWeekMetrics();
	}

	function initPedidosBoardModals() {
		initPedidosOcModal();
		initPedidosClienteModal();
		initPedidosCantidadFinalizadaModal();
		initPedidosOpModal();
		initPedidosFechaAprobacionModal();
		initPedidosParcialModal();
		initPedidosErrorModal();
		initPedidosEntregadoConfirmModal();
	}

	function initPedidosBoard() {
		var board = document.querySelector('[data-pedidos-board]');
		if (!board) {
			return;
		}

		initPedidosBoardSelectNav(board);
		initPedidosBoardViewNav(board);
		initPedidosClientesView(board);
		initPedidosOrdenesSortBoard(board);
		initPedidosMetrics(board);
		initPedidosBoardModals();

		document.querySelectorAll('[data-pedidos-sheet-root]').forEach(function (sheetRoot) {
			initPedidosOrdenesExcel(sheetRoot);
			initPedidosEntregaSlots(sheetRoot);
		});

		if (board.dataset.pedidosBoardBound === '1') {
			document.querySelectorAll('[data-pedidos-sheet-root]').forEach(function (sheetRoot) {
				refreshOrdenArticuloSelects(sheetRoot);
			});
			initInventarioRowSnapshots();
			initOrdenLineaSnapshots();
			ensureAllOrdenLineaDeleteButtons();
			hydrateAllOrdenRowParciales();
			syncAllOrdenEntregaFields();
			syncAllOrdenRowEstadoClasses();
			return;
		}

		board.dataset.pedidosBoardBound = '1';
		document.querySelectorAll('[data-pedidos-sheet-root]').forEach(function (sheetRoot) {
			refreshOrdenArticuloSelects(sheetRoot);
		});
		initInventarioRowSnapshots();
		initOrdenLineaSnapshots();
		ensureAllOrdenLineaDeleteButtons();
		hydrateAllOrdenRowParciales();
		syncAllOrdenEntregaFields();
		syncAllOrdenRowEstadoClasses();

		board.addEventListener('click', function (event) {
			var opCell = event.target.closest('[data-pedidos-orden-op]');
			if (opCell && board.contains(opCell) && !event.target.closest('[data-action="pedidos-edit-op"]')) {
				var opRow = opCell.closest('[data-pedidos-orden-row]');
				if (opRow && ordenRowAllowsOp(opRow) && !ordenRowHasOp(opRow)) {
					event.preventDefault();
					openOpModal(opRow, { auto: true });
					return;
				}
			}

			var faCell = event.target.closest('[data-pedidos-orden-fecha-aprobacion]');
			if (faCell && board.contains(faCell) && !event.target.closest('[data-action="pedidos-edit-fecha-aprobacion"]')) {
				var faRow = faCell.closest('[data-pedidos-orden-row]');
				if (faRow && ordenRowAllowsFechaAprobacion(faRow) && !ordenRowHasFechaAprobacion(faRow)) {
					event.preventDefault();
					openFechaAprobacionModal(faRow, { auto: true });
					return;
				}
			}

			var button = event.target.closest('[data-action]');
			if (!button || !board.contains(button)) {
				return;
			}
			var action = button.getAttribute('data-action');
			var row;

			if (action === 'pedidos-add-board') {
				event.preventDefault();
				openPedidosBoardStyleModal(board, '');
					return;
				}

			if (action === 'import-pedidos-ordenes-excel') {
				event.preventDefault();
				var importSheetRoot = getPedidosSheetRoot(button);
				var pedidosImportInput = importSheetRoot ? importSheetRoot.querySelector('[data-pedidos-orden-import-file]') : null;
				if (pedidosImportInput) {
					pedidosImportInput.click();
				}
				return;
			}

			if (action === 'pedidos-add-orden-parcial-slot') {
				event.preventDefault();
				row = button.closest('[data-pedidos-orden-row]');
				if (row && addOrdenParcialSlotToRow(row)) {
					setBoardStatus('Par Cantidad / Factura agregado.', false);
				}
				return;
			}

			if (action === 'pedidos-remove-orden-parcial-slot') {
				event.preventDefault();
				row = button.closest('[data-pedidos-orden-row]');
				if (row && removeOrdenParcialSlotFromRow(row)) {
					setBoardStatus('Par Cantidad / Factura quitado.', false);
				}
				return;
			}

			if (action === 'pedidos-edit-cantidad-finalizada') {
				event.preventDefault();
				openCantidadFinalizadaModal(button.closest('[data-pedidos-orden-row]'));
				return;
			}

			if (action === 'pedidos-edit-op') {
				event.preventDefault();
				openOpModal(button.closest('[data-pedidos-orden-row]'));
				return;
			}

			if (action === 'pedidos-edit-fecha-aprobacion') {
				event.preventDefault();
				openFechaAprobacionModal(button.closest('[data-pedidos-orden-row]'));
				return;
			}

			if (action === 'pedidos-edit-parcial-slot') {
				event.preventDefault();
				row = button.closest('[data-pedidos-orden-row]');
				if (row) {
					openParcialModal(row, button.getAttribute('data-slot') || '0');
				}
				return;
			}

			row = button.closest('[data-pedidos-inventario-row]');
			if (row && action === 'pedidos-save-inventario') {
				event.preventDefault();
				saveInventarioRow(row).catch(function (error) {
					setBoardStatus(error.message, true);
				});
				return;
			}
			if (row && action === 'pedidos-delete-inventario') {
				event.preventDefault();
				if (!window.confirm('¿Eliminar esta fila de inventario?')) {
					return;
				}
				postPedidos('logistica_delete_pedidos_inventario', { id: row.getAttribute('data-inventario-id') }).then(function (payload) {
					if (!payload || !payload.success) {
						throw new Error((payload && payload.data && payload.data.message) || 'No se pudo eliminar.');
					}
					row.remove();
					applyInventarioArticuloOptions(payload.data.articulo_options, getPedidosSheetRoot(row));
					setBoardStatus('Fila eliminada.', false);
				}).catch(function (error) {
					setBoardStatus(error.message, true);
				});
				return;
			}
			if (row && action === 'pedidos-add-stock') {
				event.preventDefault();
				adjustStockFromRow(row, 'logistica_add_pedidos_stock', 'Cantidad a sumar al stock Latingraf:').catch(function (error) {
					setBoardStatus(error.message, true);
				});
				return;
			}
			if (row && action === 'pedidos-subtract-stock') {
				event.preventDefault();
				adjustStockFromRow(row, 'logistica_subtract_pedidos_stock', 'Cantidad a restar del stock Latingraf:').catch(function (error) {
					setBoardStatus(error.message, true);
				});
				return;
			}

			row = button.closest('[data-pedidos-orden-row]');
			if (row && action === 'pedidos-edit-orden-linea') {
				event.preventDefault();
				openPedidosOcModalForRow(row);
				return;
			}
			if (row && action === 'pedidos-delete-orden-linea') {
				event.preventDefault();
				if (!window.confirm('¿Eliminar esta línea de la OC?')) {
					return;
				}
				var lineaId = row.getAttribute('data-linea-id') || '0';
				if (lineaId === '0') {
					row.remove();
					updatePedidosOrdenesTotals(getPedidosSheetRoot(row));
					setBoardStatus('Línea eliminada.', false);
					scheduleRefreshPedidosWeekMetrics();
					return;
				}
				postPedidos('logistica_delete_pedidos_orden_linea', { id: lineaId }).then(function (payload) {
					if (!payload || !payload.success) {
						throw new Error((payload && payload.data && payload.data.message) || 'No se pudo eliminar.');
					}
					var sheetRoot = getPedidosSheetRoot(row);
					row.remove();
					updatePedidosOrdenesTotals(sheetRoot);
					if (sheetRoot && typeof sheetRoot._pedidosOrdenFilterRefresh === 'function') {
						sheetRoot._pedidosOrdenFilterRefresh();
					}
					setBoardStatus('Línea eliminada.', false);
					scheduleRefreshPedidosWeekMetrics();
				}).catch(function (error) {
					setBoardStatus(error.message, true);
				});
				return;
			}

			if (action === 'pedidos-add-inventario') {
				event.preventDefault();
				createInventarioRowTemplate(getPedidosSheetRoot(button));
				return;
			}
			if (action === 'pedidos-add-orden') {
				event.preventDefault();
				openPedidosOcModal(getPedidosSheetRoot(button));
			}
		});

		board.addEventListener('change', function (event) {
			var target = event.target;
			if (!target || !board.contains(target)) {
				return;
			}

			if (target.matches('[data-field="parcial_cantidad"], [data-field="cantidad"], [data-field="cantidad_op"], [data-field="reporte_hornitos"]')) {
				formatPedidosQuantityField(target);
			}
			if (target.matches('[data-field="valor_und"], [data-field="precio_unit"]')) {
				formatPedidosMoneyField(target);
			}

			var inventarioRow = target.closest('[data-pedidos-inventario-row]');
			if (inventarioRow && isInventarioEditableField(target)) {
				scheduleInventarioAutoSave(inventarioRow);
			}

			var ordenRow = target.closest('[data-pedidos-orden-row]');
			if (ordenRow && target.matches('[data-field="estado"]')) {
				var previousEstado = getPersistedOrdenLineaEstado(ordenRow);
				var newEstado = target.value;
				syncOrdenRowEstadoClass(ordenRow, newEstado);
				syncOrdenEntregaFields(ordenRow);
				syncOrdenOpField(ordenRow, { promptIfMissing: true });
				syncOrdenFechaAprobacionField(ordenRow);
				updateOrdenLineaComputedQuantities(ordenRow);
				if (newEstado === 'aprobado' && ordenRowNeedsFechaAprobacionBeforeSave(ordenRow)) {
					window.setTimeout(function () {
						if (!ordenRow || fieldValue(ordenRow, 'estado') !== 'aprobado') {
							return;
						}
						if (promptOrdenFechaAprobacionIfNeeded(ordenRow, {
							requireConfirm: true,
							previousEstado: previousEstado,
							estadoSelect: target
						})) {
							if (ordenSaveTimers.has(ordenRow)) {
								clearTimeout(ordenSaveTimers.get(ordenRow));
								ordenSaveTimers.delete(ordenRow);
							}
						}
					}, 0);
					return;
				}
				if (newEstado === 'entregado' && previousEstado !== 'entregado') {
					if (resolveEstadoForEntregaPersist(ordenRow) === 'entregado') {
						openEntregadoConfirmModal(ordenRow, target, previousEstado);
						return;
					}
					setBoardStatus('Registra cantidad y factura de despacho con el icono de editar en cada par.', false);
				}
				scheduleOrdenLineaAutoSave(ordenRow, { immediate: true });
			}
			if (target.matches('[data-field="oc_numero"]')) {
				var ordenRow = target.closest('[data-pedidos-orden-row]');
				syncOrdenGroupEntregaFields(
					ordenRow ? ordenRow.getAttribute('data-orden-id') || '0' : '0',
					getPedidosSheetRoot(target),
					ordenRow ? getOrdenOcNumero(ordenRow) : ''
				);
			}
			if (ordenRow && target.matches('[data-field="cantidad"]')) {
				updateOrdenTotalCell(ordenRow);
			}
		});

		board.addEventListener('blur', function (event) {
			var target = event.target;
			if (!target || !board.contains(target)) {
				return;
			}
			var inventarioRow = target.closest('[data-pedidos-inventario-row]');
			if (inventarioRow && isInventarioEditableField(target)) {
				scheduleInventarioAutoSave(inventarioRow, { immediate: true });
			}
			var ordenRow = target.closest('[data-pedidos-orden-row]');
			if (ordenRow && target.matches('[data-field="estado"]')) {
				if (!ordenRowNeedsFechaAprobacionBeforeSave(ordenRow)) {
					scheduleOrdenLineaAutoSave(ordenRow, { immediate: true });
				}
			}
		}, true);

		board.addEventListener('input', function (event) {
			var target = event.target;
			if (!target || !board.contains(target)) {
				return;
			}
			var ordenRow = target.closest('[data-pedidos-orden-row]');
			if (!target.matches('[data-field="oc_numero"]')) {
				return;
			}
			if (ordenRow) {
				syncOrdenGroupEntregaFields(
					ordenRow.getAttribute('data-orden-id') || '0',
					getPedidosSheetRoot(target),
					getOrdenOcNumero(ordenRow)
				);
			}
		});
	}

	document.addEventListener('DOMContentLoaded', initPedidosBoard);
	document.addEventListener('logistica:tab-loaded', initPedidosBoard);
	window.initLogisticaPedidosBoard = initPedidosBoard;
})();
