Skip to content

Añadir actualización opcional de stock y datos de compra al importar facturas#46

Merged
erseco merged 27 commits into
mainfrom
copilot/add-option-add-items-to-inventory
May 31, 2026
Merged

Añadir actualización opcional de stock y datos de compra al importar facturas#46
erseco merged 27 commits into
mainfrom
copilot/add-option-add-items-to-inventory

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 20, 2026

Implementa la propuesta del #37: poder volcar al inventario las líneas de las facturas importadas con AiScan.

Qué hace

Añade una opción opcional (desactivada por defecto) en el paso de importación que, al activarse, hace dos cosas por cada línea de la factura de proveedor:

  1. Actualiza el stock del almacén: si la línea está vinculada a un producto que controla stock, suma la cantidad importada al almacén de la factura.
  2. Actualiza los datos de compra del producto-proveedor (ProductoProveedor): precio de compra, descuentos, divisa, fecha de actualización y, si viene en la extracción, la referencia del proveedor.

La opción se controla con una casilla en la pantalla de importación (individual y por lote), y la decisión se propaga al backend (update_stock_purchase_data).

Cómo funciona

En lugar de mover el stock manualmente, se apoya en el mecanismo nativo de FacturaScripts: cada línea se crea con actualizastock = 0 y, cuando la opción está activa, el PurchaseLineInventoryUpdater marca actualizastock = 1 y guarda la línea, dejando que el core calcule el movimiento de stock (con su lógica de delta: revierte la contribución anterior y aplica la nueva). Si la opción está desactivada, se garantiza que ninguna línea mueva stock.

Comportamiento por línea (con avisos claros, sin abortar la importación)

  • Sin producto vinculado → no se toca stock (aviso informativo).
  • Producto que no controla stock (nostock) → no se genera movimiento, pero sí se actualizan los datos de compra (aviso).
  • Cantidad no válida (≤ 0) → no se mueve stock; se actualizan los datos de compra.
  • Precio neto no válido (≤ 0) → no se actualizan los datos de compra.
  • Modo de importación "total" (líneas agregadas por impuesto, sin productos) → la actualización se omite por completo, ya que no hay productos que actualizar.

Los avisos generados se devuelven al frontend y se muestran con un badge por documento y un modal de detalle.

Cobertura

Tests de integración contra modelos reales de FacturaScripts que cubren: stock sumado al activar, sin cambios al desactivar, producto nostock, producto sin coincidencia, precio inválido, cantidad inválida y varias líneas de forma independiente.

Notas

  • Traducciones añadidas en ES y EN.
  • Verificado en CI (lint + suite PHPUnit completa) en PHP 8.1–8.5.

Closes #37

Copilot AI linked an issue May 20, 2026 that may be closed by this pull request
@github-actions
Copy link
Copy Markdown

FacturaScripts Playground Preview

Open this PR in FacturaScripts Playground
Try this PR in your browser

This preview is generated automatically for the copilot/add-option-add-items-to-inventory branch and loads the plugin directly from the PR branch ZIP in FacturaScripts Playground.

Copilot AI changed the title [WIP] Add option to add invoice line items to inventory Add optional stock and purchase-data updates to AiScan invoice imports May 20, 2026
Copilot finished work on behalf of erseco May 20, 2026 18:20
Copilot AI requested a review from erseco May 20, 2026 18:20
Copilot finished work on behalf of erseco May 21, 2026 06:07
erseco added 7 commits May 24, 2026 16:06
Resolve conflicts in workflow.js and InvoiceMapper to combine the
payment-method selector from #48 with the stock/purchase-data update
flow. Force actualizastock=0 on built lines so the inventory updater
is the single source of truth for stock changes, fixing the failing
InvoiceMapperStockUpdateTest cases (disabled flag + invalid quantity)
where setReceivedStatus was auto-incrementing stock.
…k on invalid quantity

- Only call setReceivedStatus when updateStockPurchaseData is enabled so
  the FS core state-change loop does not auto-bump stock for invoices
  the user imported with the toggle off (test 1).
- When the inventory updater skips a line for invalid quantity, force
  actualizastock back to 0 and save to reverse any stock added by the
  state transition before the updater ran (test 2).
- Ensure the invalid-payment-method error always contains the offending
  codpago string, even when the plugin translation file is not loaded
  in the test environment (test 3).
…abled

Reverting the earlier 'skip setReceivedStatus when disabled' shortcut
broke success=true in the PHP-matrix CI (something in the slim test env
needs the invoice advanced to a real state). Restore the original
unconditional call to setReceivedStatus, and undo its stock side effects
in the inventory updater by resetting actualizastock=0 on every line
when updateStockPurchaseData is false.
The PHP-matrix CI is asserting false=true with no clue why. Attach the
errors array to the assertion message so the next run tells us what's
actually being returned.
CI's PHP-matrix environment installs a bare FacturaScripts where new
Proveedor instances do not get default codpago/codserie, causing the
downstream FacturaProveedor save to fail with NOT NULL constraint
errors. Look up the first available FormaPago / Serie and assign them
before saving the supplier so the invoice mapper has the values it
needs to persist the invoice.
The PHP-matrix CI's bare FacturaScripts install does not seed any
Serie, so even after we set codpago the FacturaProveedor save still
fails on codserie. Create a minimal 'A' serie when none exist and
assign it to the supplier so the downstream invoice save can proceed.
PHPUnit 9 uses an int-based getStatus() (0 = PASSED), while PHPUnit 13
exposes a status() object with isSuccess(). The CI matrix uses 9.6 and
Docker uses 13.1, so check method_exists for each.
@erseco erseco marked this pull request as ready for review May 24, 2026 15:46
- InvoiceMapper: skip the stock/purchase-data updater when import mode is
  'total'. Total mode aggregates lines by tax with no linked products, so
  running the updater only produced misleading 'no product' warnings.
- PurchaseLineInventoryUpdater: load the Variante once per line instead of
  twice (the old hasLinkedProduct() re-queried it) and drop the unused helper.
  Behavior is covered by the existing matched/unmatched-product tests.
@erseco erseco force-pushed the copilot/add-option-add-items-to-inventory branch from 060d922 to 79357f2 Compare May 31, 2026 19:14
@erseco erseco changed the title Add optional stock and purchase-data updates to AiScan invoice imports Añadir actualización opcional de stock y datos de compra al importar facturas May 31, 2026
@erseco erseco merged commit 743f090 into main May 31, 2026
7 checks passed
@erseco erseco deleted the copilot/add-option-add-items-to-inventory branch May 31, 2026 19:24
erseco added a commit that referenced this pull request May 31, 2026
…S.md (#54)

- Document the live upload -> AI extraction -> review -> import flow (make up,
  port, login, provider selection, fixtures) so the merged features can be
  exercised against a real provider, mirroring the ScheduledMail recipe.
- Add Test/e2e-smoke.php: a non-interactive helper that runs the extraction +
  map + import path over the fixtures and reports invoice/attachment/warnings.
- Fix outdated CI matrix references (8.1-8.4 -> 8.1-8.5 after the 8.5 addition).
- Exclude the dev-only smoke helper from PHPCS, like the other Test/ scripts.

No functional defects were found end-to-end testing today's merged PRs
(#27 keyboard nav, #29 image attachments, #46 stock/purchase data, #48 payment
method, #41 localized warnings, #31 tax-inclusive receipts); this PR only adds
the validation guide, the smoke helper and the doc fixes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

añadir opción de añadir artículos al almacen

2 participants