Organización de materiales de reembolso empresarial
Organiza el lote de materiales de reembolso originales que te da el usuario en un conjunto de entregables estructurados, con nombres estandarizados y listos para entregar a finanzas: materiales archivados en cubos + tabla de gastos rellena + nota explicativa para finanzas + cuadro de mando de trazabilidad.
Tres líneas rojas infranqueables
- Los materiales originales y la plantilla original nunca se modifican. Todos los cambios se realizan en copias de seguridad y copias de la plantilla.
- Nunca inventes información. Si algo no se ve claro, no coincide o faltan elementos, inclúyelo en una lista de dudas y pídelo al usuario; mejor preguntar que inventar.
- Un gasto solo va en una fila de la tabla, nunca se duplica. La factura y su captura de pago son el mismo gasto; antes y después de un cambio de billete es el mismo trayecto; las partes ya pagadas por la empresa no se reembolsan. Ver secciones 3.1–3.3 y sexta sección de
references/clasificación_y_normas_de_nombrado.md.
Todos los comandos usan
python3(muchos entornos no tienen el aliaspython); las rutas de los scripts son relativas a este directorio skill:scripts/....
Datos de entrada que obtener antes de empezar
- Ruta de la carpeta de materiales originales (puede contener archivos jpg/png/pdf/ofd/excel, varios formatos mezclados, puede tener subdirectorios).
- Ruta de la plantilla de reembolso .xlsx.
- Información de identidad (nombre, departamento, fecha de presentación, moneda, departamento por defecto, código de proyecto por defecto, efectivo adelantado).
- Primero comprueba si existe
archivos_de_proceso/información_de_identidad.json(guardado de la ejecución anterior); si existe, léelo y confirma con el usuario si quiere usarlo. - Si no existe o está incompleto, pide al usuario los campos que falten y luego escríbelos en
archivos_de_proceso/información_de_identidad.jsonpara su reutilización futura.
- Primero comprueba si existe
Consulta references/plantilla_y_mapeo_de_campos.md para conocer los campos de la plantilla, el significado de las columnas y los elementos obligatorios del motivo; léelo antes de empezar.
Tres comportamientos predeterminados ajustables (el usuario puede cambiarlos con una frase)
- Grado de autonomía (predeterminado: preguntar solo si no estoy seguro). Los elementos de alta confianza se clasifican y archivan automáticamente; los que no se distingan entre viaje de negocios vs. transporte urbano, importes no claros, posible consumo personal o elementos faltantes del motivo, se acumulan en una lista de dudas y se preguntan al usuario de una vez. El usuario también puede solicitar totalmente automático o confirmación uno por uno.
- Información de identidad (predeterminado: preguntar la primera vez, guardar para reutilizar). Ver arriba.
- Multimoneda (predeterminado: convertir a RMB e incluir en la tabla). Los comprobantes en moneda extranjera (USD/KRW, etc., como recibos de Uber en el extranjero) se convierten al tipo de cambio especificado por el usuario. Si no se da el tipo de cambio, no lo inventes – primero inclúyelo en la lista de dudas (o usa el tipo de cambio del Banco de China de la fecha del comprobante e indica la fuente); la moneda original, el importe, el tipo de cambio y el resultado se escriben en
nota_adicional/, y en el cuadro de mando se rellena la columna "Importe original/Tipo de cambio". También se puede cambiar a rellenar en la moneda original y que el usuario gestione el tipo de cambio.
Flujo de trabajo
Paso 0: Crear espacio de trabajo + copia de seguridad (script)
python3 scripts/crear_espacio_de_trabajo.py --source <carpeta_materiales_originales> [--out <directorio_raíz_espacio_de_trabajo>] [--template <plantilla_reembolso.xlsx>]
--outopcional: si no se proporciona, se crea un nuevo espacio de trabajo con nombre significativo (<nombre_carpeta_original>_reembolso_<YYYYMMDD>) junto a la carpeta de materiales originales (su directorio padre = ubicación predeterminada); también se puede usar--outpara especificar un directorio deseado por el usuario.--templateopcional: la plantilla puede variar entre usuarios o incluso no existir. Si no hay plantilla, se sigue la rama "sin plantilla" (ver paso 6), y finalmente se usacrear_tabla_predeterminada.pypara generar una tabla de gastos genérica. Crea: diez subcarpetas (con_factura/sin_factura/material_auxiliar/por_verificar/sustituto/nota_adicional/archivos_de_proceso/copia_de_seguridad/material_complementario/no_relacionados), copia todos los materiales originales encopia_de_seguridad/(la plantilla misma y*.skillno se consideran materiales y se omiten automáticamente), si hay plantilla, guarda el original encopia_de_seguridad/_plantilla_original/y genera una copia editable<nombre_original>_rellenado.xlsx, generaarchivos_de_proceso/manifest.json. El espacio de trabajo se crea fuera de la carpeta de materiales originales. stdout devuelve las rutas clave (workspace/writable_template, si no hay plantillawritable_templatees null). Todos los scripts son puramentepython3, multiplataforma (mac/linux/windows), sin dependencias de comandos específicos del sistema.
Paso 1: Leer y comprender los materiales uno por uno
Lee secuencialmente según el orden de manifest.json, eligiendo el método según el tipo:
- Imágenes (jpg/png/webp, etc.): leer directamente con comprensión visual (este modelo puede leer imágenes), no es necesario OCR primero. Extraer: fecha de consumo, comercio/proyecto, importe, si es factura oficial, lugares de inicio/fin, número de personas, etc.
- PDF: primero
extract-texto skill de lectura de PDF para obtener texto; si es escaneado/formato de factura sin texto, convertir a imagen y luego leer visualmente (consultar el método de rasterización del skill de lectura de PDF). - OFD (factura electrónica nacional estándar):
Si no se obtiene texto (OFD de solo capas), recurrir: convertir a imagen y reconocer visualmente.python3 scripts/extraer_ofd.py <archivo.ofd> --json- Billete electrónico de ferrocarril: leer "precio del billete" (importe a reembolsar por viaje normal) o "tasa de cancelación/reembolso diferencial" (cancelación, importe muy pequeño), prestar atención a la marca "cambio de billete de salida".
- Factura de IVA: el importe a incluir en la tabla es el total con impuestos (incluido IVA), no el importe sin impuestos (consultar
references/plantilla_y_mapeo_de_campos.md).
- Excel/CSV:
extract-text archivo.xlsxo pandas para leer, común en facturas de teléfono, extractos bancarios, resúmenes detallados. - Otros formatos desconocidos: primero
file <ruta>para identificar el tipo, luego elegir el método adecuado; si realmente no se puede leer, incluir en la lista de dudas.
Cada material escribe los elementos extraídos en archivos_de_proceso/extraido/<nombre_original>.json.
Paso 2: Clasificar en cubos + categorizar + asociar eventos
Según references/clasificación_y_normas_de_nombrado.md:
- Determinar si pertenece al cubo con_factura / sin_factura / material_auxiliar (criterios en la primera sección del archivo de referencia). Clave: los gastos reales que solo tienen captura de pantalla, sin factura oficial, van a "sin_factura" (es la prueba principal), no a "material_auxiliar" (sección 1.1); el material auxiliar debe tener una prueba principal al lado. Una vez que aparezcan partidas sin factura, recuerda recordar al cliente que coloque facturas sustitutas en
sustituto/(ver 'Directorio especial · sustituto/'). - Determinar a cuál de las 12 categorías de gasto pertenece → qué columna de la plantilla (mapeo de columnas en
references/plantilla_y_mapeo_de_campos.md). Prestar atención a la diferencia entre J Viaje de negocios vs Q Transporte urbano. - Asignar el mismo número de evento a varios materiales del mismo gasto (factura + captura de pago + comprobante de viaje + captura de reembolso se vinculan al mismo evento). También vincular antes y después de un cambio de billete, pago corporativo/pago personal al mismo evento (secciones 3.1–3.3).
- Posible consumo personal/sin relación con este viaje (suscripciones personales, visados de países no relacionados, comprobantes sin factura de alto importe, etc.) van a la lista de dudas, por defecto no se incluyen (sección 5); si el usuario confirma que no están relacionados/no se reembolsan/pertenecen a otro período, se mueven a
no_relacionados/(no se contabilizan en este período). - Si no estás seguro, no lo fuerces: los materiales cuyo cubo/categoría/elegibilidad no esté clara, colócalos primero en
por_verificar/, no los pongas directamente encon_factura/osin_factura/; acumúlalos en una lista de dudas y pregunta al usuario, y una vez confirmado, muévelos depor_verificar/al cubo correcto.
Paso 3: Crear cuadro de mando (archivos de proceso)
En archivos_de_proceso/cuadro_de_mando_materiales.csv (UTF-8-SIG), una fila por material original, estructura de columnas según la cuarta sección de references/clasificación_y_normas_de_nombrado.md. El cuadro de mando es la única fuente de datos para el posterior rellenado y el informe de auditoría: primero haz bien el cuadro de mando.
Paso 4: Copiar + renombrar + archivar en cubos
Siguiendo la norma de nomenclatura fecha_tipo_gasto_info_clave_importe, copia los materiales desde copia_de_seguridad/ al cubo correspondiente y renómbralos. Los mismos eventos que cruzan cubos tienen el mismo nombre; en el mismo cubo se añaden sufijos semánticos (reglas en el archivo de referencia). Rellena los nuevos nombres de archivo en el cuadro de mando.
Paso 5: Escribir nota adicional (según sea necesario)
Para cualquier combinación, reembolso parcial, conversión de moneda extranjera, división/AA, o cuando el importe del material ≠ importe en tabla, escribe un .txt en nota_adicional/ siguiendo references/formato_de_nota_adicional.md, y en la columna "Observaciones" del cuadro de mando haz referencia a él.
Paso 6: Cuadro de mando → deduplicación y conciliación → generar ledger → rellenar copia de plantilla (script)
Primero haz la deduplicación y conciliación (sección 6 de references/clasificación_y_normas_de_nombrado.md): por número de evento, pliega el cuadro de mando en "una fila por evento" – la factura/la prueba principal sin factura da el importe; el material auxiliar y la captura de reembolso no forman fila independiente; la cancelación solo cuenta la tasa de cancelación; el pago corporativo solo cuenta la parte pagada por el empleado; la moneda extranjera se convierte a RMB. Anota Σ(importe del ledger) como base de conciliación.
Ordenar por fecha: el encabezado de la plantilla requiere "rellenar en orden cronológico". Los ítems del ledger deben ordenarse en orden ascendente por fecha de consumo (varios gastos el mismo día pueden ordenarse como "factura normal primero, cancelación/complemento después"). rellenar_plantilla.py también ordena de forma estable por defecto por mes/día (si quieres conservar tu orden, usa --no-sort).
Luego organiza en archivos_de_proceso/ledger.json (estructura en el comentario superior de scripts/rellenar_plantilla.py: identity + items, cada uno da "columna" o "categoría" + importe + motivo + inicio/fin/departamento/código de proyecto). El motivo debe completar los elementos requeridos para la anotación de finanzas según references/plantilla_y_mapeo_de_campos.md. Luego:
python3 scripts/rellenar_plantilla.py --xlsx <plantilla_editable> --ledger archivos_de_proceso/ledger.json
rellenar_plantilla.py maneja automáticamente la inserción de filas más allá de 31 y la extensión de SUM, y en el computed de salida da directamente los valores esperados de los subtotales/totales de cada columna – primero verifica que coincidan con tu base de conciliación.
Luego recalcula las fórmulas (elegir una):
# Opción preferida: skill xlsx (requiere LibreOffice)
python3 /mnt/skills/public/xlsx/scripts/recalcular.py <plantilla_editable>
# Sin LibreOffice / sin esa ruta, usa el recurso de seguridad de esta skill (--write escribe los valores devuelta, los entregables muestran números directamente):
python3 scripts/recalcular_recurso.py <plantilla_editable> --write
Debes confirmar que total_errors es 0, y que el resultado del recálculo coincide con el computed de rellenar_plantilla y con la suma del cuadro de mando, los tres consistentes.
Rama sin plantilla: cuando el usuario no tiene plantilla, salta rellenar_plantilla.py/recalcular y usa el script para generar una tabla de gastos genérica (escribe directamente valores y totales, y adjunta una vista previa en .md):
python3 scripts/crear_tabla_predeterminada.py --ledger archivos_de_proceso/ledger.json --out <espacio_de_trabajo>/<nombre_significativo>.xlsx
En este caso, ledger.json usa la estructura "versión sin plantilla" (ver comentario superior de crear_tabla_predeterminada.py: identity puede incluir título/persona que reclama/departamento, etc., cada ítem da fecha/categoría/motivo/comercio/moneda/importe original/tipo de cambio/importe (RMB)/observaciones). El total del xlsx generado debe coincidir con la suma del cuadro de mando.
Paso 7: Informe de auditoría + entrega
Escribe informe_de_auditoría.md en la raíz del espacio de trabajo:
- Resumen de importes por categoría de gasto, importe total del reembolso;
- Verificación de conciliación: suma del cuadro de mando = total de la plantilla = suma de los importes de los materiales en cada cubo (enumerar elemento por elemento; si no coinciden, marcarlo en rojo y explicar);
- Lista de dudas: elementos que el usuario debe completar (número de invitados, días de viaje, tipo de cambio, importes ilegibles, posible consumo personal, etc.);
- Conteo de archivos por cubo, lista de notas adicionales.
Presenta
<plantilla_editable>primero (si hay herramientas comopresent_files, úsalas; si no, da la ruta del espacio de trabajo y la lista de archivos), junto con el informe de auditoría al usuario, y pregunta la lista de dudas en persona.
Directorios especiales (según sea necesario, ninguno contamina la conciliación del flujo principal)
Además del flujo principal 0–7, hay cuatro directorios que se activan según sea necesario; son independientes y no afectan el cuadro de mando ni la conciliación de con_factura/sin_factura/material_auxiliar.
por_verificar/—— lo que no esté claro, guárdalo aquí primero
Los materiales cuya clasificación (cubo, categoría, elegibilidad) no esté clara, colócalos primero en por_verificar/, nunca los metas directamente en con_factura/ o sin_factura/. Acumúlalos en una lista de dudas y pregunta al usuario de una vez; una vez que el usuario decida, muévelos de por_verificar/ al cubo correcto e inclúyelos en la cuenta. Al entregar, por_verificar/ debería estar vacío; si aún quedan elementos pendientes, menciónalos en el informe de auditoría.
no_relacionados/—— sin relación con este viaje / no se reembolsa en este período / cruce de período
Materiales que el usuario confirma que no están relacionados con este reembolso, no se reembolsan en este período o corresponden al siguiente período (billetes de avión de otro período, visados no relacionados con este viaje, etc.), copia una copia desde copia_de_seguridad/ a no_relacionados/ para almacenarlos por separado, no los incluyas en el cuadro de mando ni en la plantilla de este período; en el informe de auditoría, indica "movido a no_relacionados". No contaminan la conciliación ni se pierden materiales.
sustituto/—— pool opcional de facturas sustitutas (no se convierten a con_factura, no cuentan importes)
Algunas partidas "sin_factura" son gastos reales pero no tienen factura oficial (alquiler y gastos de empresa, pagos personales esporádicos, etc.). El cliente puede optar por proporcionar facturas oficiales de otros consumos habituales y colocarlas en sustituto/, para que aproximadamente sumen el importe de estas partidas sin factura y se adjunten a finanzas – también puede no proporcionarlas.
Lo más importante: las facturas sustitutas no son facturas reales uno a una con las partidas sin factura, solo se acercan en importe. Por lo tanto:
- Las facturas sustitutas nunca se transfieren a
con_factura/, y las partidas sin factura nunca se reclasifican como "con_factura" – las partidas sin factura siempre se gestionan como sin factura (son el registro de este gasto real). - Las facturas sustitutas permanecen en
sustituto/y se adjuntan por separado a finanzas, no entran en las filas de gastos del cuadro de mando ni en el importe del reembolso (de lo contrario se duplicaría el importe con las partidas sin factura). - Solo se registra la lista de facturas sustitutas y el total del pool en
archivos_de_proceso/pool_sustitutos.csv, y se hace una comparación aproximada de cobertura con el total de partidas sin factura; no se hace mapeo 1:1, no se cambian cubos, no se altera el ledger. - Siempre que aparezcan partidas sin factura, recuerda al cliente en la conversación que puede opcionalmente colocar facturas sustitutas (enumera las partidas sin factura y el importe total, explicando "puede darlas o no"). No fuerces al cliente a completarlas, no supongas que siempre se proporcionarán.
material_complementario/—— materiales que el cliente proporciona después (se vacían tras procesarlos)
Los materiales que el cliente proporciona posteriormente (facturas que faltaban, comprobantes olvidados) se colocan en material_complementario/. Al volver a ejecutar, se procesan de la siguiente manera, y una vez hecho, material_complementario/ debe quedar vacío:
- Copia de seguridad: cada uno se copia en
copia_de_seguridad/_complemento_<fecha>/(los originales no se pierden). - Lectura + asociación de eventos: usa el método del paso 1 para identificar, vincular a un número de evento existente o crear uno nuevo.
- Acción de complemento de factura: si una partida era "sin_factura (pendiente de factura)" y llega una factura oficial – la factura va a
con_factura/, la captura original se reclasifica amaterial_auxiliar/, el cubo/confianza/importe (usando total con impuestos) de ese evento en el cuadro de mando se actualiza junto con la eliminación de la duda correspondiente. - Rehacer deduplicación y conciliación + relleno: según el paso 6, recalcular y confirmar que el total se ha actualizado y sigue siendo consistente entre los tres.
- Vaciar
material_complementario/: después de procesar, eliminar los archivos (ya hay copias en la copia de seguridad y en los cubos), mantenerlo vacío para la próxima vez.
Así queda el directorio al finalizar
<espacio_de_trabajo>/
├── <nombre_original>_rellenado.xlsx ← tabla de gastos rellena (entregable)
├── informe_de_auditoría.md
├── con_factura/ comprobantes oficiales que pueden servir como prueba independiente (solo se colocan aquí tras confirmación)
├── sin_factura/ prueba principal de gastos reales sin factura oficial (solo se colocan aquí tras confirmación)
├── material_auxiliar/ pruebas secundarias (capturas de pedido/pago/viaje)
├── por_verificar/ lo que no esté claro (cubo/categoría/elegibilidad) se guarda aquí primero, no lo metas directamente en con_factura/sin_factura; muévelo después de verificar
├── sustituto/ pool opcional de facturas sustitutas: cubren aproximadamente el importe de las sin_factura para finanzas, no se convierten a con_factura, no cuentan importes (ver 'Directorios especiales')
├── nota_adicional/ archivos .txt para finanzas (combinación/reembolso/divisa/división)
├── archivos_de_proceso/ información_de_identidad.json, manifest.json, extraído/, cuadro_de_mando_materiales.csv, ledger.json, (pool_sustitutos.csv)
├── copia_de_seguridad/ copia 1:1 de los materiales originales + _plantilla_original/ (la plantilla y *.skill no se incluyen en la copia de seguridad de materiales)
├── material_complementario/ materiales que el cliente proporciona después; se vacía tras el procesamiento (ver 'Directorios especiales')
└── no_relacionados/ materiales confirmados como sin relación con este reembolso / no reembolsables en este período / de otro período, almacenados por separado, no incluidos en este período
Autocomprobación final
- Los materiales originales y la plantilla original no han sido modificados (solo se han modificado las copias de seguridad/copias)
- Cada material ha ido a algún directorio y tiene una fila en el cuadro de mando
- Sin duplicación de cargos: cada número de evento tiene solo una fila en el ledger; factura + captura de pago, antes y después de cambio de billete, reembolsos no se han contado como múltiples partidas
- Las facturas de IVA se incluyen por el total con impuestos (incluido IVA); las cancelaciones solo cuentan la tasa de cancelación; los pagos corporativos solo cuentan la parte pagada por el empleado
- La moneda extranjera ya se ha convertido y el tipo de cambio tiene fuente (o se ha incluido en la lista de dudas)
- La plantilla se ha rellenado en orden cronológico; después del recálculo, cero errores de fórmula, y total de la plantilla = suma del ledger =
computedderellenar_plantilla - Los motivos cumplen con los requisitos de anotación correspondientes (número de personas/tiempo/inicio-fin/días, etc.)
-
por_verificar/ya está vacío (todo decidido),material_complementario/ya está vacío;sustituto/(si existe) no cuenta importes - Los elementos sospechosos de ser personales/sin relación y otras dudas se han confirmado en persona con el usuario