1999 Padel Shop
1999 Padel Shop
PANEL ADMIN
USD blue:  ·  EUR/USD:
Dashboard
Ventas del mes
0
pedidos recibidos
Compras del mes
0
pedidos realizados
Ingresos del mes
$0
USD 0
Ganancia est.
USD 0
sobre ventas
Ventas tot. ARS
$0
USD 0
Gastos de pase
USD 0
sobre ventas del mes
Logística internac.
USD 0
fletes del mes
Catálogo
0
productos

Últimas ventas

Sin pedidos aún.

Por estado

Sin datos.

Cotizaciones y márgenes (editables)

Dólar blue (USD→ARS)
EUR/USD
Márgenes mayorista
Paletas %
Zapatillas %
Indumentaria %
Pelotas %
Equipo/Instalac. %
Paleteros/Neceser %
Accesorios %
Márgenes minorista
Paletas %
Zapatillas %
Indumentaria %
Pelotas %
Equipo/Instalac. %
Paleteros/Neceser %
Accesorios %
Costo importación (USD/kg)
Tarifa USD por kg
Paletas (kg)
Zapatillas (kg)
Indumentaria (kg)
Pelotas (kg)
Equipo/Instalac. (kg)
Paleteros/Neceser (kg)
Accesorios (kg)
Los cambios se aplican al instante a todo el catálogo y recalculan precios.

Alertas

💾
Persistencia activada — Tus datos se guardan automáticamente en este navegador. Hacé backup periódico con el botón "Backup".
Google Sheets — Configurá la URL en Ajustes para sincronizar todo con una hoja en la nube.
✈️
Logística internacional — Registrá fletes y se prorratean automáticamente entre las compras incluidas.
🔍
#
Cliente
Productos
Pago
USD
ARS
Estado
Fecha
Acc.
Fletes activos
0
envíos
Costo total USD
USD 0
acumulado
Mes actual
USD 0
fletes del mes
🔍
#
Carrier
Descripción
Costo USD
Compras
Estado
Fecha
Acc.

Prorrateo por compra

Sin fletes aún.

Resumen

Cada flete distribuye su costo entre las compras asociadas según el método elegido:
Igual: costo ÷ cantidad total de unidades
Por valor: proporcional al valor € de cada compra

El prorrateo se suma al costo real de cada producto para calcular el margen neto.
Ingresos totales
$0
USD 0
Gastos
$0
registrados
Ganancia neta
$0
Cobrados
0
de 0 pedidos

Ingresos por marca

Sin pedidos.

Gastos

Últimos movimientos
Sin gastos.

Logística internacional (fletes)

Sin fletes registrados.

Compras recientes

Sin compras.
📋
Módulo de stock
Listo para activarse cuando Nico empiece a manejar stock físico.
Incluirá cantidad por talle/color, alertas de stock bajo y movimientos de entrada/salida.
PRÓXIMAMENTE

☁ Google Sheets sync

Pegá acá la URL del Web App de Google Apps Script. Te permite respaldar y sincronizar tus datos con una hoja en la nube.
Sin sincronizaciones aún.
📋 Ver código de Google Apps Script (copiar/pegar)
// Code.gs — Pegá esto en script.google.com
// 1) Crear una Google Sheet nueva
// 2) Extensiones → Apps Script
// 3) Pegar este código, reemplazar SHEET_ID
// 4) Implementar → Web app → Ejecutar como: yo, Acceso: cualquiera
// 5) Copiar la URL y pegarla arriba

const SHEET_ID = 'TU_SHEET_ID_ACÁ';

function doPost(e) {
  const data = JSON.parse(e.postData.contents);
  const ss = SpreadsheetApp.openById(SHEET_ID);

  if (data.mode === 'prods_chunk') {
    // Modo paginado: primer chunk limpia, los demás agregan
    const sh = ss.getSheetByName('Productos') || ss.insertSheet('Productos');
    if (data.chunk === 0) {
      sh.clear();
      if (data.prods.length > 0) {
        const keys = Object.keys(data.prods[0]);
        sh.appendRow(keys);
      }
    }
    const keys = sh.getRange(1, 1, 1, sh.getLastColumn()).getValues()[0];
    const rows = data.prods.map(r => keys.map(k => JSON.stringify(r[k] ?? '')));
    if (rows.length) sh.getRange(sh.getLastRow() + 1, 1, rows.length, keys.length).setValues(rows);
    return ContentService.createTextOutput(JSON.stringify({ok:true,chunk:data.chunk}))
      .setMimeType(ContentService.MimeType.JSON);
  }

  // Modo base: escribe todo menos productos
  if (data.pedidos) writeSheet(ss, 'Ventas', flatten(data.pedidos, 'items'));
  if (data.compras) writeSheet(ss, 'Compras', flatten(data.compras, 'items'));
  if (data.gastos) writeSheet(ss, 'Gastos', data.gastos);
  if (data.fletes) writeSheet(ss, 'Fletes', data.fletes);
  if (data.rates) writeSheet(ss, 'Config', [data.rates, data.marginsMay, data.marginsMin]);
  return ContentService.createTextOutput(JSON.stringify({ok:true,ts:Date.now()}))
    .setMimeType(ContentService.MimeType.JSON);
}

function doGet(e) {
  const ss = SpreadsheetApp.openById(SHEET_ID);
  const out = {
    prods: readSheet(ss, 'Productos'),
    pedidos: readSheet(ss, 'Ventas'),
    compras: readSheet(ss, 'Compras'),
    gastos: readSheet(ss, 'Gastos'),
    fletes: readSheet(ss, 'Fletes')
  };
  return ContentService.createTextOutput(JSON.stringify(out))
    .setMimeType(ContentService.MimeType.JSON);
}

function writeSheet(ss, name, rows) {
  let sh = ss.getSheetByName(name) || ss.insertSheet(name);
  sh.clear();
  if (!rows || !rows.length) return;
  const keys = [...new Set(rows.flatMap(r => Object.keys(r || {})))];
  sh.appendRow(keys);
  const data = rows.map(r => keys.map(k => JSON.stringify(r[k] ?? '')));
  sh.getRange(2, 1, data.length, keys.length).setValues(data);
}

function readSheet(ss, name) {
  const sh = ss.getSheetByName(name); if (!sh) return [];
  const data = sh.getDataRange().getValues();
  if (data.length < 2) return [];
  const keys = data[0];
  return data.slice(1).map(row => {
    const o = {};
    keys.forEach((k, i) => { try { o[k] = JSON.parse(row[i]); } catch(e) { o[k] = row[i]; } });
    return o;
  });
}

function flatten(rows, key) {
  return (rows || []).map(r => ({...r, [key]: JSON.stringify(r[key] || [])}));
}

💾 Backup local

Descargá un archivo JSON con todos tus datos (productos, ventas, compras, gastos, fletes, configuración).
Snapshots automáticos (últimos 5)
Se guarda automáticamente antes de cada sincronización.

ℹ Información

Versión: v4
Almacenamiento: localStorage del navegador
Dependencias externas: Google Fonts, dolarapi.com
Última modificación: