


































(function () {
  var CR = window.CR, R = window.React, h = R.createElement;
  var useState = R.useState, useEffect = R.useEffect;
  var CICLOS = ['AM', 'PM'];


  var VIGENCIA_INICIAL = '2026-08-01';





  var INICIO_RED = { HEAVY_AND_BULKY: '2026-10-01' };

  var NOVEDAD_RED = { HEAVY_AND_BULKY: { 'data-novedad': 'lm-tarifas-heavy-and-bulky' } };


  var FACTOR_PM = 0.85;
  var LEYENDA_SOLO_LECTURA = 'Sólo administradores de Last Mile cargan y modifican tarifas';
  var SIN_GRILLA = 'El servidor no mandó la grilla de Mercado Libre por red (tipos de unidad y rangos de km). Sin ella no se muestran ni se cargan estas tarifas: recargá la página y, si sigue igual, avisá por CRÁNEO.';
  function fechaCorta(iso) { return String(iso).split('-').reverse().join('/'); }
  var MOTIVOS = { monto_invalido: 'importe inválido', ciclo_invalido: 'falta el ciclo AM o PM', clave_invalida: 'casillero inválido',
    patente_invalida: 'patente inválida', repetida: 'repetida', sin_tarifa_vigente: 'no tiene tarifa: se carga en la tabla, no como modificación' };
  function today() { return new Intl.DateTimeFormat('en-CA', { timeZone: 'America/Argentina/Buenos_Aires', year: 'numeric', month: '2-digit', day: '2-digit' }).format(new Date()); }
  // Pesos con separador de miles y dos decimales: el mismo formato que Primera Milla → Tarifas Mercado
  // Libre. Dos decimales siempre, porque el PM = AM − 15 % deja centavos y redondearlos en pantalla sería
  // mostrar un importe que no es el guardado.
  function money(n) {
    if (typeof n !== 'number' || !isFinite(n)) return '—';
    return '$' + n.toLocaleString('es-AR', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  }
  function pmDesde(am) { var n = Number(am); return am === '' || am === null || !isFinite(n) ? '' : String(Math.round(n * FACTOR_PM * 100) / 100); }
  // `redes`: el nombre de cada red según la grilla del servidor. Un casillero de MELI se nombra con su red:
  // «CHASIS MEDIANO 0_50 AM» solo no dice cuál de las dos grillas se rechazó.
  function etiqueta(x, redes) {
    if (x.patente !== undefined) return x.patente + ' ' + x.ciclo;
    return (x.red ? ((redes && redes[x.red]) || x.red) + ' · ' : '') + x.tipoUnidad + ' ' + x.rangoKm + (x.ciclo ? ' ' + x.ciclo : '');
  }
  function resumen(r, modo, vigenteDesde, redes) {
    var rechazadas = r.rechazadas || [], bloqueadas = r.bloqueadas || [], texto;
    if (modo === 'modificacion') {
      texto = 'Modificación guardada desde ' + vigenteDesde + ': ' + r.nuevas + ' importe(s) cambiado(s)'
        + (r.cerradas ? ' (' + r.cerradas + ' tarifa(s) anterior(es) cerrada(s) el día previo)' : '')
        + ' · ' + r.sinCambio + ' sin cambio · ' + rechazadas.length + ' rechazada(s).';
    } else {
      texto = 'Guardado: ' + r.nuevas + ' nuevas · ' + r.sinCambio + ' sin cambio · ' + rechazadas.length + ' rechazadas.';
    }
    if (rechazadas.length) texto += ' Rechazadas: ' + rechazadas.map(function (x) { return etiqueta(x, redes) + ' (' + (MOTIVOS[x.motivo] || x.motivo) + ')'; }).join(', ') + '.';
    // La carga no cambia una tarifa guardada: si alguna ya tenía importe (otra pestaña, otra persona), se dice cuál y cuánto vale.
    if (bloqueadas.length) texto += ' No se cambiaron ' + bloqueadas.length + ' que ya tenían tarifa (' + bloqueadas.map(function (x) {
      var v = x.vigente || {}; return etiqueta(x, redes) + ': ' + money(v.monto) + ' desde ' + v.desde; }).join(', ') + '): para cambiarlas usá «Cargar modificación».';
    return texto;
  }
  function explicar(err) {
    var texto = (err && err.message) || 'No se pudo guardar.';
    // 422 vigencia_retroactiva (v1.0.15): el mensaje del servidor ya dice qué hacer (fechar desde hoy, o pedir
    // el recálculo por CRÁNEO), así que se muestra tal cual. Agregarle lo del 409 sería explicar otro error.
    // 409 vigencia_posterior_existente: el servidor ya dice para qué clave; acá va qué hacer.
    if (err && err.clave === 'vigencia_posterior_existente') texto += ' Ya hay una tarifa que empieza después de esa fecha, así que no se puede cargar un período más viejo. Elegí un «Vigente desde» posterior a la fecha desde la que rige hoy cada valor (figura debajo de cada importe).';
    return texto;
  }
  /* Lo que se tipeó en la modificación y cambió de verdad. Lo inválido se cuenta aparte: si no, el
     operador ve «guardado» y no se entera de que un importe mal escrito se descartó. Si el servidor no
     mandó el importe de hoy (usuario sin costos), cualquier número tipeado cuenta como cambio. */
  function cambios(claves, vigentes, valores, fila) {
    var filas = [], invalidas = 0;
    claves.forEach(function (k) {
      var t = vigentes[k.clave]; if (!t) return;
      var v = valores[k.clave]; if (v === undefined || v === '') return;
      var n = Number(v);
      if (!isFinite(n) || n < 0) { invalidas++; return; }
      if (typeof t.monto !== 'number' || Math.abs(n - t.monto) >= 0.005) filas.push(fila(k, n));
    });
    return { filas: filas, invalidas: invalidas };
  }
  /* «Vigente desde» de la carga de MELI: sin ninguna tarifa, la vigencia del negocio; si alguna red con fecha
     de inicio conocida (INICIO_RED) todavía no tiene NINGUNA tarifa —ni vigente ni programada—, esa fecha;
     si no, hoy. */
  function vigenciaMeli(j) {
    var cargadas = j.cargadas || {};
    if (!cargadas.meli) return VIGENCIA_INICIAL;
    var conTarifa = {};
    (j.meli || []).concat((j.proximas || {}).meli || []).forEach(function (t) { conTarifa[t.red] = true; });
    var red = Object.keys(j.grillaMeli || {}).filter(function (k) { return INICIO_RED[k] && !conTarifa[k]; })[0];
    return red ? INICIO_RED[red] : today();
  }
  function LastMileTarifas(props) {
    var admin = !!(props.permissions && props.permissions.administrar);
    // MELI es un dato de gerencia: el panel sólo existe para el administrador del módulo. El servidor
    // tampoco se lo manda a los demás (la otra mitad de la regla, en local/last-mile.cjs).
    var verMeli = admin;
    var d = useState(null), datos = d[0], setDatos = d[1];
    var l = useState(true), loading = l[0], setLoading = l[1];
    var e = useState(''), error = e[0], setError = e[1];
    var rv = useState(0), revision = rv[0], setRevision = rv[1];
    var b = useState(''), busy = b[0], setBusy = b[1];
    var ms = useState({}), mensajes = ms[0], setMensajes = ms[1];
    var m = useState({ valores: {}, vigenteDesde: '', nota: '' }), meli = m[0], setMeli = m[1];
    var p = useState({ valores: {}, vigenteDesde: '', nota: '', pmDesdeAm: true }), prov = p[0], setProv = p[1];
    // «Cargar modificación»: null = tarifas cerradas; un objeto = el formulario de la modificación abierto.
    var mm = useState(null), modMeli = mm[0], setModMeli = mm[1];
    var mp = useState(null), modProv = mp[0], setModProv = mp[1];
    var rt = useState(null), retro = rt[0], setRetro = rt[1];
    var rs = R.useRef(0), retroSeq = rs;
    useEffect(function(){setRetro(null);setBusy('');setMensajes({});retroSeq.current++;return function(){retroSeq.current++;};},[admin]);
    useEffect(function () {
      var active = true; setLoading(true); setError('');
      CR.backend.lastMileGet('tarifas', today()).then(function (j) {
        if (!active) return;
        setDatos(j);
        var cargadas = j.cargadas || {};
        // Lo guardado ya no vive en los campos: se muestra cerrado. Los campos de la carga quedan para lo que falta.
        setMeli(function (prev) { return { valores: {}, vigenteDesde: prev.vigenteDesde || vigenciaMeli(j), nota: prev.nota }; });
        setProv(function (prev) { return { valores: {}, vigenteDesde: prev.vigenteDesde || (cargadas.proveedor ? today() : VIGENCIA_INICIAL), nota: prev.nota, pmDesdeAm: prev.pmDesdeAm }; });
      }).catch(function (err) { if (active) setError(err.message); }).finally(function () { if (active) setLoading(false); });
      return function () { active = false; };
    }, [revision, admin]);
    function mensaje(panel, tipo, texto) { setMensajes(function (prev) { var next = Object.assign({}, prev); next[panel] = { tipo: tipo, texto: texto }; return next; }); }
    function enviar(panel, ruta, data, modo, alGuardar) {
      if (busy || !admin) return; setBusy(panel); mensaje(panel, '', '');
      var turno = ++retroSeq.current;
      if (modo === 'modificacion' && data.vigenteDesde < today() && !data.confirmacionRetroactiva) {
        CR.backend.lastMilePost(ruta+'/propuesta',data).then(function(r){
          if(retroSeq.current !== turno) return;
          setRetro({panel:panel,ruta:ruta,data:data,impacto:r,alGuardar:alGuardar});
        }).catch(function(err){if(retroSeq.current===turno) mensaje(panel,'error',explicar(err));})
          .finally(function(){if(retroSeq.current===turno) setBusy('');});
        return;
      }
      CR.backend.lastMilePost(ruta, data).then(function (r) {
        if (retroSeq.current !== turno) return;
        setRetro(null); mensaje(panel, 'ok', resumen(r, modo, data.vigenteDesde, nombresRed)); if (alGuardar) alGuardar(); setRevision(function (v) { return v + 1; });
      }).catch(function (err) { if (retroSeq.current === turno) { setRetro(null); mensaje(panel, 'error', explicar(err)); } }).finally(function () { if (retroSeq.current === turno) setBusy(''); });
    }
    var proximas = (datos && datos.proximas) || {};


    var grilla = datos && datos.grillaMeli;
    var redesMeli = grilla ? Object.keys(grilla).map(function (k) { return Object.assign({ clave: k }, grilla[k]); }) : [];
    var nombresRed = {};
    redesMeli.forEach(function (red) { nombresRed[red.clave] = red.nombre || red.clave; });
    function claveMeli(t) { return t.red + '|' + t.tipoUnidad + '|' + t.rangoKm + '|' + t.ciclo; }
    var vigM = {}, proxM = {}, vigP = {}, proxP = {};
    (datos && datos.meli || []).forEach(function (t) { vigM[claveMeli(t)] = t; });
    (proximas.meli || []).forEach(function (t) { proxM[claveMeli(t)] = t; });
    (datos && datos.proveedor || []).forEach(function (t) { vigP[t.patente + '|' + t.ciclo] = t; });
    (proximas.proveedor || []).forEach(function (t) { proxP[t.patente + '|' + t.ciclo] = t; });
    var patentes = datos && datos.patentes || [];
    var clavesMeli = [];
    redesMeli.forEach(function (red) { (red.tipos || []).forEach(function (t) { (red.rangos || []).forEach(function (r) { CICLOS.forEach(function (c) {
      clavesMeli.push({ clave: claveMeli({ red: red.clave, tipoUnidad: t, rangoKm: r[0], ciclo: c }), red: red.clave, tipoUnidad: t, rangoKm: r[0], ciclo: c }); }); }); }); });
    var clavesProv = [];
    patentes.forEach(function (pt) { CICLOS.forEach(function (c) { clavesProv.push({ clave: pt.patente + '|' + c, patente: pt.patente, ciclo: c }); }); });
    // Una clave se CARGA en la tabla sólo si no tiene tarifa hoy ni una programada: lo que ya tiene
    // tarifa está cerrado, y cargar hoy algo que empieza más adelante daría el 409 del período viejo.
    function libre(vig, prox, clave) { return !vig[clave] && !prox[clave]; }
    var faltanMeli = clavesMeli.some(function (k) { return libre(vigM, proxM, k.clave); });
    var faltanProv = clavesProv.some(function (k) { return libre(vigP, proxP, k.clave); });
    var hayMeli = clavesMeli.some(function (k) { return !!vigM[k.clave]; });
    var hayProv = clavesProv.some(function (k) { return !!vigP[k.clave]; });

    function guardarMeli(ev) {
      ev.preventDefault();
      var filas = [];
      clavesMeli.forEach(function (k) { var v = meli.valores[k.clave];
        if (libre(vigM, proxM, k.clave) && v !== undefined && v !== '') filas.push({ red: k.red, tipoUnidad: k.tipoUnidad, rangoKm: k.rangoKm, ciclo: k.ciclo, monto: Number(v) }); });
      if (!filas.length) { mensaje('meli', 'error', 'Cargá al menos un importe de los que faltan.'); return; }
      enviar('meli', 'tarifas-meli', { vigenteDesde: meli.vigenteDesde, filas: filas, nota: meli.nota || null }, 'carga');
    }
    function provChange(patente, ciclo, value) {
      setProv(function (prev) {
        var fila = Object.assign({ AM: '', PM: '' }, prev.valores[patente] || {});
        fila[ciclo] = value;
        // El PM derivado sólo va donde el PM también se está cargando: uno guardado está cerrado.
        if (ciclo === 'AM' && prev.pmDesdeAm && libre(vigP, proxP, patente + '|PM')) fila.PM = pmDesde(value);
        var valores = Object.assign({}, prev.valores); valores[patente] = fila;
        return Object.assign({}, prev, { valores: valores });
      });
    }
    function guardarProv(ev) {
      ev.preventDefault();
      var filas = [];
      clavesProv.forEach(function (k) { var fila = prov.valores[k.patente] || {}, v = fila[k.ciclo];
        if (libre(vigP, proxP, k.clave) && v !== undefined && v !== '') filas.push({ patente: k.patente, ciclo: k.ciclo, monto: Number(v) }); });
      if (!filas.length) { mensaje('proveedor', 'error', 'Cargá al menos un importe de los que faltan.'); return; }
      enviar('proveedor', 'tarifas-proveedor', { vigenteDesde: prov.vigenteDesde, filas: filas, nota: prov.nota || null, pmDesdeAm: prov.pmDesdeAm }, 'carga');
    }
    // «Cargar modificación»: el formulario arranca con los importes vigentes y la fecha de hoy.
    function prellenar(claves, vigentes) {
      var valores = {};
      claves.forEach(function (k) { var t = vigentes[k.clave]; if (t) valores[k.clave] = typeof t.monto === 'number' ? String(t.monto) : ''; });
      return valores;
    }
    function abrirModMeli() { mensaje('meli', '', ''); setModMeli({ valores: prellenar(clavesMeli, vigM), vigenteDesde: today(), nota: '' }); }
    function abrirModProv() { mensaje('proveedor', '', ''); setModProv({ valores: prellenar(clavesProv, vigP), vigenteDesde: today(), nota: '', pmDesdeAm: true }); }
    function modMeliChange(clave, value) { setModMeli(function (prev) { var valores = Object.assign({}, prev.valores); valores[clave] = value; return Object.assign({}, prev, { valores: valores }); }); }
    function modProvChange(patente, ciclo, value) {
      setModProv(function (prev) {
        var valores = Object.assign({}, prev.valores); valores[patente + '|' + ciclo] = value;
        // En la modificación el PM se completa acá, a la vista: lo que se ve es lo que se guarda.
        if (ciclo === 'AM' && prev.pmDesdeAm && vigP[patente + '|PM']) valores[patente + '|PM'] = pmDesde(value);
        return Object.assign({}, prev, { valores: valores });
      });
    }
    function guardarModMeli(ev) {
      ev.preventDefault();
      var c = cambios(clavesMeli, vigM, modMeli.valores, function (k, n) { return { red: k.red, tipoUnidad: k.tipoUnidad, rangoKm: k.rangoKm, ciclo: k.ciclo, monto: n }; });
      if (c.invalidas) { mensaje('meli', 'error', 'Hay ' + c.invalidas + ' importe(s) que no son un número válido. Corregilos antes de guardar.'); return; }
      if (!c.filas.length) { mensaje('meli', 'error', 'No cambiaste ningún importe.'); return; }
      enviar('meli', 'tarifas-meli/modificacion', { vigenteDesde: modMeli.vigenteDesde, filas: c.filas, nota: modMeli.nota || null }, 'modificacion', function () { setModMeli(null); });
    }
    function guardarModProv(ev) {
      ev.preventDefault();
      var c = cambios(clavesProv, vigP, modProv.valores, function (k, n) { return { patente: k.patente, ciclo: k.ciclo, monto: n }; });
      if (c.invalidas) { mensaje('proveedor', 'error', 'Hay ' + c.invalidas + ' importe(s) que no son un número válido. Corregilos antes de guardar.'); return; }
      if (!c.filas.length) { mensaje('proveedor', 'error', 'No cambiaste ningún importe.'); return; }
      enviar('proveedor', 'tarifas-proveedor/modificacion', { vigenteDesde: modProv.vigenteDesde, filas: c.filas, nota: modProv.nota || null }, 'modificacion', function () { setModProv(null); });
    }
    function aviso(panel) {
      var x = mensajes[panel]; if (!x || !x.texto) return null;
      return x.tipo === 'error' ? h('p', { className: 'alerta alerta--alta', role: 'alert' }, x.texto) : h('p', { className: 'lm-success', role: 'status' }, x.texto);
    }
    function importe(label, value, onChange) {
      return h('span', { className: 'lm-importe' }, h('span', { className: 'lm-importe-signo', 'aria-hidden': 'true' }, '$'),
        h('input', { className: 'input', type: 'number', min: 0, step: '0.01', inputMode: 'decimal', 'aria-label': label, value: value === undefined ? '' : value,
          disabled: !!busy || !!retro, onChange: function (ev) { onChange(ev.target.value); } }));
    }
    function proxima(px) { return px ? h('small', { className: 'lm-tarifa-proxima' }, 'Desde ' + px.desde + ': ' + money(px.monto)) : null; }
    /* Una celda de tarifa. Con tarifa vigente: el importe CERRADO, en pesos, y desde cuándo rige (o, en la
       modificación, el campo con el importe nuevo y lo que vale hoy). Sin tarifa: el campo de la carga,
       sólo para el administrador. Con una vigencia futura cargada: se muestra, así una modificación
       fechada más adelante no parece perdida. Si el servidor no manda el importe (una cuenta sin
       permiso de costos), se dice eso en vez de un campo vacío. */
    function celda(label, clave, vig, prox, mod, onCarga, onMod, valorCarga) {
      var t = vig[clave], px = prox[clave];
      if (mod) {
        if (!t) return h('div', { className: 'lm-tarifa-celda' }, h('small', { className: 'muted' }, 'sin tarifa'), proxima(px));
        return h('div', { className: 'lm-tarifa-celda' }, importe('Modificación ' + label, mod.valores[clave], onMod),
          h('small', { className: 'muted' }, 'hoy ' + money(t.monto) + ' desde ' + t.desde), proxima(px));
      }
      if (t) return h('div', { className: 'lm-tarifa-celda' },
        h('strong', { className: 'lm-tarifa-cerrada', 'aria-label': label + ' (cerrada)' }, money(t.monto)),
        typeof t.monto !== 'number' ? h('small', { className: 'muted' }, 'importe no visible para tu usuario') : null,
        h('small', { className: 'muted' }, 'desde ' + t.desde + (t.hasta ? ' · hasta ' + t.hasta : '')), proxima(px));
      if (px) return h('div', { className: 'lm-tarifa-celda' }, h('small', { className: 'muted' }, 'sin tarifa hoy'), proxima(px));
      if (!admin) return h('div', { className: 'lm-tarifa-celda' }, h('small', { className: 'muted' }, 'sin tarifa'));
      return h('div', { className: 'lm-tarifa-celda' }, importe(label, valorCarga, onCarga), h('small', { className: 'muted' }, 'sin tarifa'));
    }
    // Una fecha pasada lleva a la revisión explícita del recálculo antes de escribir.
    function vigencia(label, value, onChange, min) {
      return h('label', { className: 'lm-field' }, h('span', null, 'Vigente desde'),
        h('input', Object.assign({ className: 'input', type: 'date', required: true, 'aria-label': label, value: value, disabled: !!busy || !!retro, onChange: function (ev) { onChange(ev.target.value); } },
          min ? { min: min } : {})));
    }
    function nota(label, value, onChange) {
      return h('label', { className: 'lm-field' }, h('span', null, 'Nota (opcional)'),
        h('input', { className: 'input', maxLength: 300, 'aria-label': label, value: value, disabled: !!busy || !!retro, onChange: function (ev) { onChange(ev.target.value); } }));
    }
    var AYUDA_MODIFICACION = 'Cambiá sólo los importes que se modifican. La tarifa de hoy se cierra el día previo a «Vigente desde» y la nueva rige desde esa fecha; la anterior no se borra. Si elegís la misma fecha desde la que rige un importe, se corrige ese importe (queda en Auditoría). Si elegís una vigencia pasada, revisarás las quincenas afectadas y confirmarás el recálculo de las abiertas. Las cerradas conservan su foto. No se modifica antes de una tarifa ya programada.';
    function acciones(panel, mod, faltan, hay, abrir, cerrar, textoGuardar, extra) {
      if (!admin) return null;
      if (mod) return h('div', { className: 'lm-actions lm-tarifas-acciones' },
        h('button', { type: 'button', className: 'btn', disabled: !!busy || !!retro, onClick: cerrar }, 'Cancelar'),
        h('button', { className: 'btn btn--primary', disabled: !!busy || !!retro || loading }, busy === panel ? 'Guardando…' : 'Guardar modificación'));
      return h('div', { className: 'lm-actions lm-tarifas-acciones' },
        faltan ? h('button', { className: 'btn btn--primary', disabled: !!busy || !!retro || loading }, busy === panel ? 'Guardando…' : textoGuardar) : null,
        h('button', Object.assign({ type: 'button', className: 'btn', disabled: !!busy || !!retro || loading || !hay, onClick: abrir,
          title: hay ? 'Cambiar una tarifa guardada, con la fecha desde la que rige' : 'Todavía no hay tarifas guardadas para modificar' }, extra || {}), 'Cargar modificación'));
    }




    function grillaDeRed(red) {
      var tipos = red.tipos || [], rangos = red.rangos || [], ayudantes = red.ayudantes || {}, nombre = red.nombre || red.clave;
      var vacia = !clavesMeli.some(function (k) { return k.red === red.clave && (vigM[k.clave] || proxM[k.clave]); });
      var inicio = INICIO_RED[red.clave];
      return h('div', Object.assign({ key: red.clave, className: 'lm-tarifas-red', role: 'group', 'aria-labelledby': 'lm-tarifas-red-' + red.clave }, NOVEDAD_RED[red.clave] || {}),
        h('h3', { id: 'lm-tarifas-red-' + red.clave }, nombre),
        admin && !modMeli && vacia && inicio ? h('p', { className: 'muted lm-tarifas-red-nota' },
          'Esta red todavía no tiene tarifas. Opera desde el ' + fechaCorta(inicio) + ': «Vigente desde» propone esa fecha para su carga inicial.') : null,
        h('div', { className: 'lm-table-wrap' }, h('table', { className: 'lm-table' },
          h('thead', null, h('tr', null, ['Tipo de unidad', 'Rango de km', 'Tarifa AM', 'Tarifa PM'].map(function (x) { return h('th', { key: x }, x); }))),
          h('tbody', null, tipos.map(function (t) { return rangos.map(function (r, i) {
            return h('tr', { key: t + r[0] }, i === 0 ? h('th', { scope: 'rowgroup', rowSpan: rangos.length }, t,
                ayudantes[t] ? h('small', { className: 'lm-tarifas-ayudantes' }, ayudantes[t] === 1 ? '1 ayudante' : ayudantes[t] + ' ayudantes') : null) : null,
              h('td', null, r[1]),
              CICLOS.map(function (c) { var clave = claveMeli({ red: red.clave, tipoUnidad: t, rangoKm: r[0], ciclo: c }), label = 'Tarifa MELI ' + nombre + ' · ' + t + ' ' + r[1] + ' ' + c;
                return h('td', { key: c }, celda(label, clave, vigM, proxM, modMeli,
                  function (v) { setMeli(function (prev) { var valores = Object.assign({}, prev.valores); valores[clave] = v; return Object.assign({}, prev, { valores: valores }); }); },
                  function (v) { modMeliChange(clave, v); }, meli.valores[clave])); })); }); })))));
    }
    return h('div', { className: 'lm-tarifas' },
      retro && admin ? h('section',{className:'card lm-section lm-retro-confirmacion',role:'region','aria-label':'Confirmar tarifa retroactiva','data-novedad':'lm-tarifa-retroactiva'},
        h('h2',null,'Revisá el recálculo antes de guardar'),
        h('p',null,'Vigencia desde '+retro.impacto.vigenteDesde+'. '+retro.impacto.nota),
        retro.impacto.periodos.length ? h('ul',null,retro.impacto.periodos.map(function(p){return h('li',{key:p.desde},p.desde+' al '+p.hasta+' · '+p.servicios+' servicio(s) · '+(p.cerrada?'Cerrada: conserva su foto':'Abierta: se recalcula'));})) : h('p',null,'No hay servicios afectados por estas claves y esta vigencia.'),
        h('div',{className:'lm-actions'},h('button',{type:'button',className:'btn btn--primary',disabled:!!busy,onClick:function(){enviar(retro.panel,retro.ruta,Object.assign({},retro.data,{confirmacionRetroactiva:retro.impacto.huella}),'modificacion',retro.alGuardar);}},busy?'Guardando…':'Guardar y recalcular abiertas'),
          h('button',{type:'button',className:'btn',disabled:!!busy,onClick:function(){setRetro(null);}},'Cancelar sin cambios'))) : null,
      !admin ? h('p', { className: 'lm-empty', role: 'note' }, LEYENDA_SOLO_LECTURA) : null,
      error ? h('p', { className: 'alerta alerta--alta', role: 'alert' }, error) : null,
      loading && !datos ? h('p', { role: 'status' }, 'Cargando tarifas…') : null,

      verMeli ? h('section', { className: 'card lm-section', 'aria-labelledby': 'lm-tarifas-meli-titulo', 'data-novedad': 'lm-tarifas-meli' },
        h('h2', { id: 'lm-tarifas-meli-titulo' }, 'Tarifas Mercado Libre'),
        h('p', { className: 'muted' }, 'Lo que paga Mercado Libre por ruta según la red, el tipo de unidad, los km finales de la ruta y el ciclo: el AM y el PM se pagan distinto. Hay una grilla por red; la red sale del centro (SVC) donde se hace el servicio. Sólo lo ven los administradores de Last Mile.'),
        datos && !grilla ? h('p', { className: 'alerta alerta--alta', role: 'alert', 'data-sin-grilla': '' }, SIN_GRILLA) : null,
        grilla ? h('form', { className: 'lm-form lm-tarifas-form', onSubmit: modMeli ? guardarModMeli : guardarMeli },
          modMeli ? h('p', { className: 'lm-flota-note lm-tarifas-ayuda', role: 'note' }, h('b', null, 'Modificación de tarifas Mercado Libre. '), AYUDA_MODIFICACION) : null,
          redesMeli.map(grillaDeRed),
          modMeli ? vigencia('Vigente desde (modificación Mercado Libre)', modMeli.vigenteDesde, function (v) { setModMeli(Object.assign({}, modMeli, { vigenteDesde: v })); }) : null,
          modMeli ? nota('Nota (modificación Mercado Libre)', modMeli.nota, function (v) { setModMeli(Object.assign({}, modMeli, { nota: v })); }) : null,
          !modMeli && faltanMeli ? vigencia('Vigente desde (Mercado Libre)', meli.vigenteDesde, function (v) { setMeli(Object.assign({}, meli, { vigenteDesde: v })); }) : null,
          !modMeli && faltanMeli ? nota('Nota (Mercado Libre)', meli.nota, function (v) { setMeli(Object.assign({}, meli, { nota: v })); }) : null,
          acciones('meli', modMeli, faltanMeli, hayMeli, abrirModMeli, function () { setModMeli(null); mensaje('meli', '', ''); }, 'Guardar tarifas MELI')) : null,
        aviso('meli')) : null,
      h('section', { className: 'card lm-section', 'aria-labelledby': 'lm-tarifas-prov-titulo' },
        h('h2', { id: 'lm-tarifas-prov-titulo' }, 'Tarifas de proveedores'),
        h('p', { className: 'muted' }, 'Lo que cobra cada patente de Última Milla por ciclo. Se listan las unidades con estado ÚLTIMA MILLA en Flota (MELI) y las que ya tienen tarifa.'),
        h('form', { className: 'lm-form lm-tarifas-form', onSubmit: modProv ? guardarModProv : guardarProv },
          modProv ? h('p', { className: 'lm-flota-note lm-tarifas-ayuda', role: 'note' }, h('b', null, 'Modificación de tarifas de proveedores. '), AYUDA_MODIFICACION) : null,
          admin && modProv ? h('label', { className: 'lm-check' },
            h('input', { type: 'checkbox', 'aria-label': 'PM = AM − 15 % (modificación)', checked: modProv.pmDesdeAm, disabled: !!busy || !!retro, onChange: function (ev) { var on = ev.target.checked; setModProv(Object.assign({}, modProv, { pmDesdeAm: on })); } }),
            h('span', null, 'PM = AM − 15 % (al cambiar el AM se completa el PM nuevo; lo podés pisar)')) : null,
          admin && !modProv && faltanProv ? h('label', { className: 'lm-check' },
            h('input', { type: 'checkbox', 'aria-label': 'PM = AM − 15 %', checked: prov.pmDesdeAm, disabled: !!busy || !!retro, onChange: function (ev) { var on = ev.target.checked; setProv(Object.assign({}, prov, { pmDesdeAm: on })); } }),
            h('span', null, 'PM = AM − 15 % (al escribir el AM se completa el PM que falta; las filas sin PM lo reciben al guardar)')) : null,
          h('div', { className: 'lm-table-wrap' }, h('table', { className: 'lm-table' },
            h('thead', null, h('tr', null, ['Patente', 'Tipo', 'Tarifa AM', 'Tarifa PM'].map(function (x) { return h('th', { key: x }, x); }))),
            h('tbody', null, !patentes.length ? h('tr', null, h('td', { colSpan: 4, className: 'lm-empty' }, loading ? 'Cargando…' : 'No hay patentes habilitadas para Última Milla. En Flota (MELI), editá o creá la unidad con estado ÚLTIMA MILLA.')) :
              patentes.map(function (pt) { var fila = prov.valores[pt.patente] || { AM: '', PM: '' };
                return h('tr', { key: pt.patente }, h('th', { scope: 'row' }, pt.patente, !pt.enFlota ? h('small', null, 'fuera del padrón') : null),
                  h('td', null, pt.tipoUnidad || '—'),
                  CICLOS.map(function (c) { return h('td', { key: c }, celda('Tarifa ' + c + ' de ' + pt.patente, pt.patente + '|' + c, vigP, proxP, modProv,
                    function (v) { provChange(pt.patente, c, v); }, function (v) { modProvChange(pt.patente, c, v); }, fila[c])); })); })))),
          modProv ? vigencia('Vigente desde (modificación proveedores)', modProv.vigenteDesde, function (v) { setModProv(Object.assign({}, modProv, { vigenteDesde: v })); }) : null,
          modProv ? nota('Nota (modificación proveedores)', modProv.nota, function (v) { setModProv(Object.assign({}, modProv, { nota: v })); }) : null,
          !modProv && admin && faltanProv ? vigencia('Vigente desde (proveedores)', prov.vigenteDesde, function (v) { setProv(Object.assign({}, prov, { vigenteDesde: v })); }) : null,
          !modProv && admin && faltanProv ? nota('Nota (proveedores)', prov.nota, function (v) { setProv(Object.assign({}, prov, { nota: v })); }) : null,

          acciones('proveedor', modProv, faltanProv, hayProv, abrirModProv, function () { setModProv(null); mensaje('proveedor', '', ''); }, 'Guardar tarifas de proveedores',
            { 'data-novedad': 'lm-tarifas-modificacion' })),
        aviso('proveedor')),
      h('p', { className: 'muted' }, 'Las vigencias funcionan como en Primera Milla: una tarifa guardada queda cerrada y «Cargar modificación» abre una vigencia nueva que cierra la anterior el día previo (no la borra). Una modificación retroactiva requiere revisar y confirmar el recálculo, porque cambiaría lo que ya se liquidó. Si hace falta corregir un período ya liquidado, Gerencia o Administración debe reabrirlo con motivo antes de corregirlo. Tampoco se puede cargar un período viejo sobre uno más nuevo. Liquidación y Estado de Negocio usan estas tarifas en las quincenas abiertas y las fotos conservadas en las cerradas.'));
  }
  CR.screens.LastMileTarifas = LastMileTarifas;
})();
