Skip to content

Changes

Started by timer
Started 9 hr 38 min ago
Took 1 min 10 sec on built-in

Summary

  1. Amazon invoices: book seller fee invoices (Tax Document Library PDFs) next to Ads invoices (details)
  2. Offers: custom forecast modal (scenarios, editable positions, PDF/send) + editable quote validity (details)
  3. Amazon invoices: document details, paid vs created status, Lexoffice reset, pinned actions (details)
  4. Amazon invoices: recognise fee credit notes and book them as AP CreditMemo (details)
  5. Leads list: dial icon aligned to the right edge, copy button on the e-mail column (details)
  6. Recent calls card: blacklist control moved into the number popover, with live status and unblock (details)
  7. Amazon invoices: recognise the 2025 fee-invoice template, label the charge boxes as import settings (details)
  8. Amazon invoices: quick filters, optional date range, collapsed import settings, square upload box (details)
  9. Amazon invoices: show voided documents properly, match them by POReference (details)
  10. Amazon invoices: iDempiere is the source of truth for booked invoices, PDFs from the document attachment (details)
  11. Amazon invoices: store uploads in the iDempiere table CUST_AmazonInvoiceInbox (PDF in Strapi) (details)
  12. Amazon invoices: keep inbox rows consistent with iDempiere's documents (self-heal) (details)
  13. Bank reconciliation: suggestions need at least 2 matching criteria, fuzzy names, date signal, score ranking (details)
  14. Amazon invoices: report the PDF as available when it sits on the iDempiere document (details)
  15. Amazon invoices: confirm every import with the cost type shown, no remembered cost types (details)
  16. Amazon invoices: match documents by the full number in the description (POReference is 20 chars) (details)
  17. Amazon invoices: book the exact VAT from the PDF when a line-level purchase tax exists (details)
Commit 9e5d44b9cb79373965ffd173001cf1268e6d3889 by info
Amazon invoices: book seller fee invoices (Tax Document Library PDFs) next to Ads invoices

Amazon offers no API for the seller fee invoices in Europe (the SP-API Invoices
API is Brazil-only, no report type covers them), so the PDFs downloaded from
Seller Central are dropped on the existing Amazon invoices page.

- parseSellerFeeInvoicePdf.ts: text-layer parser (kind 'fee'), one line per fee
  type with its own VAT rate; runs before the Ads parser in the upload route
- vendor resolved by the issuer's VAT id, created under org * on first import
- own charge (AMAZON_FEE_CHARGE_ID, default 1000009 "Amazon Gebühren"), tax per
  line rate; credit notes are listed but not importable yet
- list route checks bookings across the Ads vendor and all fee vendors
- page: Type / Aussteller / Empfänger columns, second charge selector
The file was modifiedserver/api/accounting/amazon-ads/status.get.ts (diff)
The file was modifiedserver/utils/amazonAds/types.ts (diff)
The file was modifiedserver/api/accounting/amazon-ads/import.post.ts (diff)
The file was addedserver/utils/amazonAds/parseSellerFeeInvoicePdf.ts
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedserver/api/accounting/amazon-ads/invoices.get.ts (diff)
The file was modifiedserver/utils/amazonAds/parseInvoicePdf.ts (diff)
The file was modifiedserver/api/accounting/amazon-ads/upload.post.ts (diff)
The file was modifiedserver/utils/amazonAds/adsApi.ts (diff)
The file was modifiednuxt.config.ts (diff)
The file was modifiedapp/pages/accounting/amazon-ads-invoices/index.vue (diff)
The file was modifiedserver/utils/amazonAds/importInvoice.ts (diff)
The file was addedreference/test-scripts/amazon-fee-parse.mjs
Commit 08ca7d5f074a1d4399860ffe4859350839a41e06 by info
Offers: custom forecast modal (scenarios, editable positions, PDF/send) + editable quote validity

Custom forecast ("Individuelle Prognose"): standalone cost forecast for leads and
partners, opened from a new "Prognose" button on both pages and from the quote
modal's forecast card (seeded from the live quote form). Seeds from the saved
custom forecast, else the saved quote conditions, else list prices. Every
position can be switched off, relabelled and re-priced (per order with factor or
% share, or per month), own positions added, up to 4 volume scenarios side by
side (3+ print landscape), display toggles for calculation column, unit prices,
subtotals, cost per order, yearly total and disclaimer. Save as draft
(offer_conditions.forecast), download, or e-mail with record attachment and
activity. Client computes, server only renders.

Quote validity: "Gültig (Tage)" and "Gültig bis" pair in the quote modal, default
7 days from now. One server resolver (resolveQuoteValidity) drives the PDF, the
e-mail text, the activity, the saved conditions and the confirmation link expiry.
The file was modifiedserver/api/offers/conditions/index.post.ts (diff)
The file was addedserver/api/offers/forecast/send.post.ts
The file was addedapp/components/offers/ForecastModal.vue
The file was addedserver/api/offers/forecast/preview.post.ts
The file was modifiedapp/composables/useOfferQuote.ts (diff)
The file was modifiedapp/pages/partners/partners/[id]/edit.vue (diff)
The file was modifiedserver/utils/offers/offerConditions.ts (diff)
The file was modifiedserver/utils/offers/quotePdf.ts (diff)
The file was modifiedapp/assets/langs/shared.js (diff)
The file was addedapp/composables/useOfferForecast.ts
The file was modifiedserver/api/offers/quote/send.post.ts (diff)
The file was modifiedapp/components/offers/QuoteModal.vue (diff)
The file was addedserver/utils/offers/forecastPdf.ts
The file was modifiedapp/pages/users/leads/[id]/edit.vue (diff)
The file was modifiedserver/utils/offers/quoteConfirmation.ts (diff)
Commit 7c40ce743ed6563a2b58c00f358be5d811025e38 by info
Amazon invoices: document details, paid vs created status, Lexoffice reset, pinned actions

- "Beleg in" column (org · vendor) + details dialog per created AP invoice
  (new booking.get.ts: header, payment/Lexoffice state, lines with charge + tax)
- status no longer says "Verbucht" for a merely created document: "Beleg erstellt
  · Zahlung offen" until iDempiere has the invoice allocated to a payment
  (IsPaid) → "Bezahlt"; separate counters
- Lexoffice reset for selected rows and from the details dialog (shared
  /api/invoices/lexoffice-reset), with a confirm that the voucher in Lexoffice
  is not deleted
- actions column pinned right, status/document columns moved left, API notice
  collapsed by default, PDF icon fixed (ti-pdf)
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedserver/utils/amazonAds/importInvoice.ts (diff)
The file was modifiedapp/pages/accounting/amazon-ads-invoices/index.vue (diff)
The file was modifiedserver/api/accounting/amazon-ads/invoices.get.ts (diff)
The file was addedserver/api/accounting/amazon-ads/booking.get.ts
Commit 8aac736389fbef7e2d88535f9f39bc7b296c4eb9 by info
Amazon invoices: recognise fee credit notes and book them as AP CreditMemo

- parser: "STEUERGUTSCHRIFT" template (Gutschriftennummer, Ausstellungsdatum /
  Zeitraum der Gutschrift), amounts with the sign before the currency
  ("-EUR 2.61"), "Ursprüngliche Rechnungsnummer" → originalInvoiceNo
- import: credit notes become a vendor credit memo — doctype DocBaseType APC
  (AP CreditMemo) with positive amounts, reference to the original invoice in
  the description; no longer refused
- OPOS + /sales/invoices: doctype 1000006 counts as customer-side only when the
  partner is flagged IsCustomer, so genuine vendor credit memos stay on the
  payables side (existing customer credit notes unchanged)
The file was modifiedserver/api/invoices/so.get.ts (diff)
The file was modifiedserver/utils/amazonAds/parseSellerFeeInvoicePdf.ts (diff)
The file was modifiedapp/pages/accounting/amazon-ads-invoices/index.vue (diff)
The file was modifiedserver/utils/amazonAds/importInvoice.ts (diff)
The file was modifiedserver/api/accounting/amazon-ads/invoices.get.ts (diff)
The file was modifiedserver/api/accounting/opos/index.get.ts (diff)
The file was modifiedserver/utils/amazonAds/types.ts (diff)
The file was modifiedapp/pages/sales/invoices/index.vue (diff)
Commit 9779bba8ea83bac8745a1d1a8386e89c2a9a1135 by info
Leads list: dial icon aligned to the right edge, copy button on the e-mail column

- AgDialPhone: number stays left, only the dial button is pushed to the right
  (shared renderer — also applies to the users / external users lists)
- new AgCopyEmail cell renderer: copy-to-clipboard button with check-mark
  feedback, does not start the inline editor
The file was addedapp/components/AgGrid/AgCopyEmail.vue
The file was modifiedapp/pages/users/leads/index.vue (diff)
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedapp/components/AgGrid/AgDialPhone.vue (diff)
Commit c8fb1add4aec93b10d32265652cff746fddd349b by info
Recent calls card: blacklist control moved into the number popover, with live status and unblock

- no per-row block button any more (it cost a column of width); clicking the
  number opens the popover, which now shows the FreePBX blacklist status and
  either "Nummer sperren" (two-step confirm) or "gesperrt · Entsperren"
- new TelephonyBlacklistControl, used inside the dial popover (DialButton
  show-blacklist) and in the card's own popover for sessions that cannot dial
- server: blacklist status read via AMI DBGet (one session for the ≤ 10 numbers
  of a page), unblock via DBDel; GET + DELETE /api/telephony/blacklist. An
  unexpected AMI error is "status unknown", never a false "not blocked"
- blocked numbers are marked red with a ban icon in the list
The file was modifiedapp/components/DialButton.vue (diff)
The file was addedapp/components/telephony/BlacklistControl.vue
The file was modifiedserver/api/telephony/blacklist.post.ts (diff)
The file was addedserver/api/telephony/blacklist.delete.ts
The file was addedserver/api/telephony/blacklist.get.ts
The file was modifiedserver/utils/telephony/blacklist.ts (diff)
The file was modifiedapp/components/dashboard/RecentCallsCard.vue (diff)
Commit b2d24d604b14700496f0d0ebc1f53dd8a3358015 by info
Amazon invoices: recognise the 2025 fee-invoice template, label the charge boxes as import settings

- parser: 2025 labels (Rechnungsnr, Name des Anbieters / Verkaeufers, Adresse /
  UStID des Anbieters) plus a label-independent fallback for supplier name and
  VAT id, so the next rename by Amazon does not break recognition
- page: the two charge selectors are grouped as "Import-Einstellung · Kostenart
  für neue Belege (kein Filter)" with an explanatory tooltip
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedapp/pages/accounting/amazon-ads-invoices/index.vue (diff)
The file was modifiedserver/utils/amazonAds/parseSellerFeeInvoicePdf.ts (diff)
Commit 7b3ffcb02f1a492cae8e96636728f270a769594e by info
Amazon invoices: quick filters, optional date range, collapsed import settings, square upload box

- quick-filter chips with counts: Typ (Ads / Gebühren / Gutschriften), Beleg
  (ohne / erstellt / bezahlt), Lexoffice (noch nicht hochgeladen / hochgeladen);
  totals follow the filter ("1 von 3")
- no date filter by default; the optional invoice-date range sits behind a quiet
  "Zeitraum" button, reloads on change, and an upload widens it so new invoices
  are never hidden. The Ads API call keeps a bounded 12-month window server-side
- the two cost-type selectors are collapsed behind "Import-Einstellungen" with a
  one-line summary and an info box (what they do, why two, not a filter, when to
  change); the panel opens by itself when a cost type is missing
- upload area is a square drop box on the right with drag feedback and keyboard
  support
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedapp/pages/accounting/amazon-ads-invoices/index.vue (diff)
The file was modifiedserver/api/accounting/amazon-ads/invoices.get.ts (diff)
Commit 786df63b6cc3a86132f1f9a056fec00574c6943a by info
Amazon invoices: show voided documents properly, match them by POReference

- a voided invoice row names its Storno document ("Storniert #<id> · erneut
  importierbar"), opens its details (banner + link to iDempiere's reversal
  document, no Lexoffice reset), has its own row tint, a "Storno-Beleg" action,
  a "Storniert" quick-filter chip and a counter; it no longer counts as
  "Ohne Beleg (neu)"
- list route: documents are matched to the Amazon invoice by POReference (full
  number) instead of DocumentNo — the void rename '<no>-VOID-<id>' is truncated
  to the 30-char column ('DE-AEU-2025-2978769' → 'DE-AEU-2025-29787-VOID-…'),
  so a voided document was not recognised; reversal documents are flagged and
  listed after the original
The file was modifiedapp/pages/accounting/amazon-ads-invoices/index.vue (diff)
The file was modifiedserver/api/accounting/amazon-ads/invoices.get.ts (diff)
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedserver/api/accounting/amazon-ads/booking.get.ts (diff)
Commit bcd4de9387b784591e675d94d2d83cd354b63cb6 by info
Amazon invoices: iDempiere is the source of truth for booked invoices, PDFs from the document attachment

The page's list lived only in data/amazon-ads.db, which was missing from the
deploy script's preserve list — every deploy wiped it, so booked invoices
vanished from the page (the documents themselves were never affected).

- list route: every Amazon invoice that HAS a document is rebuilt from iDempiere
  (AP documents of the Amazon vendors, found by vendor flag + name; key =
  POReference; kind from the vendor, credit note from the doctype, period from
  the description). The local store only adds uploads that are not imported yet
  plus parsed details / PDF cache
- document route: without a local copy the ORIGINAL PDF attached to the
  iDempiere document is served (&cInvoiceId=); the page passes the document id
- rows rebuilt from iDempiere are labelled (Quelle "iDempiere", PDF "Anhang");
  a voided one asks for the PDF to be uploaded again before re-import
- deploy script: amazon-ads.db + data/amazon-ads/ added to the preserve lists
  (must be pasted into the Jenkins job to take effect)
The file was modifiedreference/ci/deploy-production.sh (diff)
The file was modifiedserver/api/accounting/amazon-ads/document.get.ts (diff)
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedapp/pages/accounting/amazon-ads-invoices/index.vue (diff)
The file was modifiedserver/api/accounting/amazon-ads/invoices.get.ts (diff)
Commit bcd159169e2557be05d88bbad7d54b88e7c038cf by info
Amazon invoices: store uploads in the iDempiere table CUST_AmazonInvoiceInbox (PDF in Strapi)

- new invoiceStore.ts: one async storage API with two backends — the iDempiere
  table (row via REST, PDF attached in Strapi) and, only as a fallback when the
  table is not reachable, the old SQLite file
- upload / list / import / void / document routes use it; the upload route reads
  the multipart body once and retries with a refreshed token
- rows still in the SQLite file are moved over when the page loads (bounded,
  idempotent, fail-soft; imported rows keep their PDF on the c_invoice document,
  pending rows get their PDF uploaded to Strapi). A run where nothing can be
  written pauses for 10 minutes instead of retrying on every load, and rows that
  are not in the table yet stay visible and importable from the local file
- status/list responses report the active backend
The file was modifiedserver/api/accounting/amazon-ads/import.post.ts (diff)
The file was modifiedserver/api/accounting/amazon-ads/document.get.ts (diff)
The file was modifiedserver/api/accounting/amazon-ads/invoices.get.ts (diff)
The file was modifiedserver/api/accounting/amazon-ads/void.post.ts (diff)
The file was modifiedserver/api/accounting/amazon-ads/upload.post.ts (diff)
The file was addedserver/utils/amazonAds/invoiceStore.ts
The file was modifiedserver/api/accounting/amazon-ads/status.get.ts (diff)
Commit f5a4b95955cba38382c3ac8c7cc1ffae1e2654e7 by info
Amazon invoices: keep inbox rows consistent with iDempiere's documents (self-heal)

On each list load an inbox row whose document exists but is not linked (imported
on another host / before the table existed) gets status 'imported' + the link;
a row that still points to a voided or missing document is released. Bounded,
fail-soft, idempotent — the page itself reads the documents and never depends on it.
The file was modifiedserver/api/accounting/amazon-ads/invoices.get.ts (diff)
Commit d6003a7b7ccaba8faa27e1d466fff5d221e8dd67 by info
Bank reconciliation: suggestions need at least 2 matching criteria, fuzzy names, date signal, score ranking

- a candidate is only suggested when at least 2 of 4 criteria match: document
  number, amount, partner (IBAN or name count as one) and date. On the current
  33 open statements all 47 old invoice suggestions rested on a single signal
- new date signal: statement line date −5 … +60 days around the invoice date
- fuzzy partner names: umlauts spelled out, accents stripped, legal forms and
  filler words ignored, prefix matches, brand word, brand inside run-together
  text or the remittance text ("AMAZON PAYMENTS EUROPE S.C.A." matches "Amazon EU
  S.à r.l., Niederlassung Deutschland"; "Deutsche Bank" does not match
  "Deutsche Post")
- ranking by score, best first (doc no. 50 · amount 30 · IBAN 25 / name 10–25 ·
  date closeness 0–15); up to 8 candidates per line
- match dialog: top 3 + "weitere anzeigen", date chip, n/4 criteria, best-match
  marker, top candidate preselected; list pill shows "+n" and a criteria tooltip
The file was modifiedapp/components/accounting/BankLineMatchModal.vue (diff)
The file was modifiedapp/components/accounting/banking/BankReconcilePanel.vue (diff)
The file was modifiedserver/utils/bankReconciliationSuggestions.ts (diff)
The file was modifiedapp/assets/langs/shared.js (diff)
Commit 6e71fb22714beae7d74a7a44353b11faad234015 by info
Amazon invoices: report the PDF as available when it sits on the iDempiere document

Rows migrated from the local file (and rows rebuilt from documents) carry no file
of their own — their original PDF is the document's attachment. The list flagged
them as "no PDF" although the link works; they now show "Anhang".
The file was modifiedserver/api/accounting/amazon-ads/invoices.get.ts (diff)
The file was modifiedapp/pages/accounting/amazon-ads-invoices/index.vue (diff)
Commit 87678796cc3032e2763f178f8e4731c10c6ed9b2 by info
Amazon invoices: confirm every import with the cost type shown, no remembered cost types

12 fee invoices were booked to "Werbekosten": the page remembered the last
selection of each cost-type box in the browser and a stale value silently
overrode the correct default.

- cost types are no longer stored in the browser (old keys are removed); every
  page load starts from the server defaults (Ads → Werbekosten, fees/credit notes
  → Amazon Gebühren); a deviation is flagged (amber summary, reset to default)
- every import goes through a confirmation dialog that groups the invoices by
  type, shows the cost type each group will be booked to (changeable there, the
  default is marked, a deviation is highlighted) and lists already booked ones as
  skipped. It opens on "Ausgewählte importieren" and right after an upload
  ("jetzt importieren" / "Später")
- the import result names the cost type that was used per invoice
The file was modifiedserver/api/accounting/amazon-ads/import.post.ts (diff)
The file was modifiedapp/pages/accounting/amazon-ads-invoices/index.vue (diff)
The file was modifiedapp/assets/langs/shared.js (diff)
Commit 267e7becbfac41d14dbd209d510b958cf7628124 by info
Amazon invoices: match documents by the full number in the description (POReference is 20 chars)

The first credit-memo import showed that POReference cannot carry the key: the
column is 20 chars, so 'DE-CN-AEU-2026-134720' (21) is stored as
'DE-CN-AEU-2026-13472' — the new AP CreditMemo was not recognised as the credit
note's document and the self-heal released its inbox row ('voided').

The importer's description starts with the FULL Amazon number on every document
(active, voided rename, iDempiere's reversal), so that is the primary match key
now; DocumentNo / POReference remain the fallback for documents not created by
the importer. No double booking was possible — the importer's duplicate guard
checks the full DocumentNo.
The file was modifiedserver/api/accounting/amazon-ads/invoices.get.ts (diff)
Commit cc0ff592b5ae3cc181da2058102242fd926336b5 by info
Amazon invoices: book the exact VAT from the PDF when a line-level purchase tax exists

Amazon rounds the VAT down (74,66 × 19 % → 14,18), iDempiere half-up (14,19); with
the document-level "19% Mwst." the VAT is recomputed at completion, so 3 of 15
documents ended up one cent above the Amazon total.

iDempiere keeps a manually entered line TaxAmt on purchase documents whose tax
rate is NOT document level. The importer now prefers such a rate (purchase,
IsDocumentLevel = N) and writes the VAT from the PDF on each line (per-line VAT
for fee invoices, proportional for Ads campaigns, remainder on the largest line).
Without such a rate nothing changes — except that a difference between the booked
total and the Amazon document is now reported as a warning instead of going unnoticed.
The file was modifiedserver/utils/amazonAds/importInvoice.ts (diff)