Skip to content

Changes

Started by timer
Started 4 days 13 hr ago
Took 1 min 11 sec on built-in

Summary

  1. Dial popover: show the PBX extension name instead of the state text — server/utils/telephony/extensions.ts reads each extension's FreePBX display name from the astdb (AMI DBGet AMPUSER/<ext>/cidname, covered by the reporting class already granted to the logship manager user; cached 10 min per extension, fetched on the same socket as DeviceStateList, ERP user name stays the fallback), DialButton rows now read '401 Younes' with the state carried by the coloured dot + hover tooltip only, DirectoryExtension type gains pbxName (details)
  2. Bank fetch page: /accounting/bank-transactions becomes the dedicated "Bankabruf" page (fetch from the bank), replacing the duplicate staged-statements/import tables — coverage table per connection (data from/to, counts, last fetch, 12-month strip green = staged / red = never fetched, click = preselect), backfill runner for past periods (months from a coverage-aware grid with "Select missing", everything since a date, free range, single day; chunks of max 31 days so PayPal's 30-day window and the proxy timeout are respected; sequential per connection + chunk, progress bar, per-chunk log, abort, retry failed, details via the fetch-result modal, dry-run toggle, hand-off to Banking → import), connection cards kept in a collapsible section; new proxy route bank-transactions/coverage.get.ts (Laravel banking/statements/coverage, fail-soft notice when not deployed); shared bk-* styles moved from the Banking page into app/assets/css/banking.css (loaded by both pages); Banking fetch modal links to the backfill page; menu labels "Bankabruf"/"Bank Fetch"; bankfetch_* translations en/de/es (details)
  3. Dashboard calls card: '+' on unmatched numbers → quick-create contact modal — new components/dashboard/QuickContactModal.vue (teleported; name required + autofocused, phone preset from the call row incl. PBX caller-id name, optional e-mail and 'als Lead anlegen' flag; creates a plain ad_user via /api/admin/users/store, not a system user, current org); RecentCallsCard remembers checked-but-unmatched numbers (null entries) so the '+' only shows after the ES match finished, and stores the created user as the number's contact locally so the row flips to the contact menu without waiting for the ad_user index sync; rcc_add_contact/qcm_* translations en/de/es (details)
  4. DPD labels: carry address2 (Adresszusatz) like DHL — dpd/index + dpd/multi now map body.address2 into the recipient: name2 when no company/c/o is set, otherwise the company keeps name2 and address2 goes to contact (the only other printed DPD line, 35 chars), plus a data-only comment mirror (70); <contact> emitted after <city> and <comment> after <email> per the DPD XSD order. DHL index/multi cap consignee name2/name3 at 50 chars so over-long values are truncated instead of rejected. Frontend unchanged (commission.vue already sends both fields to both carriers). (details)
  5. Call recordings: async whisper transcription — transcribe.post.ts starts the job, waits max 20 s and answers 202 pending for anything longer (the edge nginx cuts requests at 60 s, long calls used to 504 while whisper kept running); new transcribe-status.get.ts polls the disk state (pending marker <file>.pending.json shared across PM2 instances, cache file = done, marker error = failed); shared statusResponse() in transcriptionResponse.ts; CallRecordingsModal polls every 3 s up to 25 min and shows the elapsed time (details)
  6. Roadsurfer price sheet: update workbook, drop stray Excel lock file (details)
  7. Amazon Ads invoices → Eingangsrechnungen: new page /accounting/amazon-ads-invoices lists Sponsored-Ads invoices (Amazon Ads API when connected — LWA consent flow, profile picker, GET /invoices + /invoices/{id} + /billing/documents PDF — or console PDFs dropped on the page and parsed server-side), lets the user tick which ones to import and books each as a completed AP invoice on the fixed vendor 1043801 (org *): one charge line per campaign (default charge Werbekosten), tax by rate so GrandTotal = Amazon gross, DocumentNo/POReference = Amazon invoice no., duplicate guard, original Amazon PDF attached under PO_Invoice; Storno action voids + renames the number (<no>-VOID-<id>) so the same invoice can be re-imported; booked/Lexoffice status comes from iDempiere (vendor AP invoices matched by number). Lexoffice upload: purchase invoices now upload the attached vendor original instead of the Jasper print (no ZUGFeRD on foreign documents) and requireOriginal:true skips invoices without one (used by the Ads page). Store data/amazon-ads.db + PDF cache data/amazon-ads/ (git-ignored); AMAZON_ADS_* env keys (empty = PDF-upload mode until the Ads API approval exists); AgGrid wrapper registers RowGroupingPanelModule (error #200 on every grid page); menu + en/de/es labels; parser dev script reference/test-scripts/amazon-ads-parse.mjs + sample invoice (details)
  8. Sales order ship-to name + dashboard calls card improvements (details)
  9. Sales invoices: merge in purchase (AP) invoices, incl. Amazon Ads imports (details)
  10. Lead page: move Aufnahmen button out of the offer/contract CTA group (details)
  11. DialButton: opt-in Recordings toggle (play-only) in the dial popover (details)
  12. Recent calls card: stack date above number, give the name its own full line (details)
  13. Locator priorities: exclude locators not allowed for shipping (details)
  14. DialButton: fix recordings that appeared to play but stayed silent (details)
  15. AgInvoiceKind: fix AP/AR tags never actually getting their colors (details)
  16. Lexoffice upload: default AP invoices into Ausgaben, not the general inbox (details)
  17. Bank fetch coverage: show import progress per month, not just staged (details)
  18. Add asterisk lookup endpoint (details)
  19. Quote: configurable grading pricing (time/fixed + description) and save-draft button (details)
  20. Quote: customer-requirements checklist; dashboard: leads card quick actions (details)
  21. Amazon: switch central OAuth app to Published, fix test-connection + credential UI (details)
  22. SIS: new Amazon pricing control page — compare internal vs Amazon price/qty, Buy Box, fees, push corrected prices (details)
Commit 630fc88a6a26eba7608728a395bb5fc80a4964ef by info
Dial popover: show the PBX extension name instead of the state text — server/utils/telephony/extensions.ts reads each extension's FreePBX display name from the astdb (AMI DBGet AMPUSER/<ext>/cidname, covered by the reporting class already granted to the logship manager user; cached 10 min per extension, fetched on the same socket as DeviceStateList, ERP user name stays the fallback), DialButton rows now read '401 Younes' with the state carried by the coloured dot + hover tooltip only, DirectoryExtension type gains pbxName
The file was modifiedapp/components/DialButton.vue (diff)
The file was modifiedserver/utils/telephony/extensions.ts (diff)
The file was modifiedapp/composables/useClickToDial.ts (diff)
Commit 53342fb748940c080a9c541b0d4c1a87499d5339 by info
Bank fetch page: /accounting/bank-transactions becomes the dedicated "Bankabruf" page (fetch from the bank), replacing the duplicate staged-statements/import tables — coverage table per connection (data from/to, counts, last fetch, 12-month strip green = staged / red = never fetched, click = preselect), backfill runner for past periods (months from a coverage-aware grid with "Select missing", everything since a date, free range, single day; chunks of max 31 days so PayPal's 30-day window and the proxy timeout are respected; sequential per connection + chunk, progress bar, per-chunk log, abort, retry failed, details via the fetch-result modal, dry-run toggle, hand-off to Banking → import), connection cards kept in a collapsible section; new proxy route bank-transactions/coverage.get.ts (Laravel banking/statements/coverage, fail-soft notice when not deployed); shared bk-* styles moved from the Banking page into app/assets/css/banking.css (loaded by both pages); Banking fetch modal links to the backfill page; menu labels "Bankabruf"/"Bank Fetch"; bankfetch_* translations en/de/es
The file was modifiedapp/components/MainNavigationMenu.vue (diff)
The file was addedserver/api/accounting/bank-transactions/coverage.get.ts
The file was addedapp/assets/css/banking.css
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedapp/pages/accounting/banking/index.vue (diff)
The file was addedapp/components/accounting/banking/BankBackfillPanel.vue
The file was modifiedapp/pages/accounting/bank-transactions/index.vue (diff)
The file was modifiedapp/composables/menu/admin/accounting.ts (diff)
Commit f810d698d77298b9a9a8e0a18b8ea93623b496bc by info
Dashboard calls card: '+' on unmatched numbers → quick-create contact modal — new components/dashboard/QuickContactModal.vue (teleported; name required + autofocused, phone preset from the call row incl. PBX caller-id name, optional e-mail and 'als Lead anlegen' flag; creates a plain ad_user via /api/admin/users/store, not a system user, current org); RecentCallsCard remembers checked-but-unmatched numbers (null entries) so the '+' only shows after the ES match finished, and stores the created user as the number's contact locally so the row flips to the contact menu without waiting for the ad_user index sync; rcc_add_contact/qcm_* translations en/de/es
The file was addedapp/components/dashboard/QuickContactModal.vue
The file was modifiedapp/components/dashboard/RecentCallsCard.vue (diff)
The file was modifiedapp/assets/langs/shared.js (diff)
Commit e644ded9fd4885ca7e5be18f1d3c638d0b687e12 by info
DPD labels: carry address2 (Adresszusatz) like DHL — dpd/index + dpd/multi now map body.address2 into the recipient: name2 when no company/c/o is set, otherwise the company keeps name2 and address2 goes to contact (the only other printed DPD line, 35 chars), plus a data-only comment mirror (70); <contact> emitted after <city> and <comment> after <email> per the DPD XSD order. DHL index/multi cap consignee name2/name3 at 50 chars so over-long values are truncated instead of rejected. Frontend unchanged (commission.vue already sends both fields to both carriers).
The file was modifiedserver/api/commission/parcels/dhl/index.post.ts (diff)
The file was modifiedserver/api/commission/parcels/dhl/multi.post.ts (diff)
The file was modifiedserver/api/commission/parcels/dpd/index.post.ts (diff)
The file was modifiedserver/api/commission/parcels/dpd/multi.post.ts (diff)
Commit 72610850d43102cc0e14ac7cf6ef1b5db716ace6 by info
Call recordings: async whisper transcription — transcribe.post.ts starts the job, waits max 20 s and answers 202 pending for anything longer (the edge nginx cuts requests at 60 s, long calls used to 504 while whisper kept running); new transcribe-status.get.ts polls the disk state (pending marker <file>.pending.json shared across PM2 instances, cache file = done, marker error = failed); shared statusResponse() in transcriptionResponse.ts; CallRecordingsModal polls every 3 s up to 25 min and shows the elapsed time
The file was addedserver/utils/telephony/transcriptionResponse.ts
The file was modifiedserver/utils/telephony/recordings.ts (diff)
The file was addedserver/api/telephony/recordings/transcribe-status.get.ts
The file was modifiedapp/components/telephony/CallRecordingsModal.vue (diff)
The file was modifiedserver/api/telephony/recordings/transcribe.post.ts (diff)
Commit 14d0e08b8c0a28cd535aeb98b9273a2ce1dfb557 by info
Roadsurfer price sheet: update workbook, drop stray Excel lock file
The file was modifiedreference/roadsurfer_Fulfillment_Anfrage_Preisblatt_LogYou.xlsx (diff)
The file was removedreference/~$roadsurfer_Fulfillment_Anfrage_Preisblatt_LogYou.xlsx
Commit 0f630bc593490f322597f096f15bc84851b5a3c0 by info
Amazon Ads invoices → Eingangsrechnungen: new page /accounting/amazon-ads-invoices lists Sponsored-Ads invoices (Amazon Ads API when connected — LWA consent flow, profile picker, GET /invoices + /invoices/{id} + /billing/documents PDF — or console PDFs dropped on the page and parsed server-side), lets the user tick which ones to import and books each as a completed AP invoice on the fixed vendor 1043801 (org *): one charge line per campaign (default charge Werbekosten), tax by rate so GrandTotal = Amazon gross, DocumentNo/POReference = Amazon invoice no., duplicate guard, original Amazon PDF attached under PO_Invoice; Storno action voids + renames the number (<no>-VOID-<id>) so the same invoice can be re-imported; booked/Lexoffice status comes from iDempiere (vendor AP invoices matched by number). Lexoffice upload: purchase invoices now upload the attached vendor original instead of the Jasper print (no ZUGFeRD on foreign documents) and requireOriginal:true skips invoices without one (used by the Ads page). Store data/amazon-ads.db + PDF cache data/amazon-ads/ (git-ignored); AMAZON_ADS_* env keys (empty = PDF-upload mode until the Ads API approval exists); AgGrid wrapper registers RowGroupingPanelModule (error #200 on every grid page); menu + en/de/es labels; parser dev script reference/test-scripts/amazon-ads-parse.mjs + sample invoice
The file was modified.env-prod (diff)
The file was addedserver/utils/amazonAds/types.ts
The file was modified.env (diff)
The file was addedserver/api/accounting/amazon-ads/connect.get.ts
The file was addedserver/api/accounting/amazon-ads/document.get.ts
The file was modifiednuxt.config.ts (diff)
The file was addedserver/api/accounting/amazon-ads/status.get.ts
The file was addedserver/utils/amazonAds/parseInvoicePdf.ts
The file was modifiedserver/api/invoices/lexoffice-upload.post.ts (diff)
The file was addedserver/utils/amazonAds/adsStore.ts
The file was addedreference/INVOICE-503111M5PA26.pdf
The file was addedapp/pages/accounting/amazon-ads-invoices/index.vue
The file was addedserver/api/accounting/amazon-ads/upload.post.ts
The file was addedserver/api/accounting/amazon-ads/import.post.ts
The file was addedserver/utils/invoiceOriginalPdf.ts
The file was addedserver/api/accounting/amazon-ads/void.post.ts
The file was modified.gitignore (diff)
The file was modifiedapp/components/AgGrid.vue (diff)
The file was modifiedapp/components/MainNavigationMenu.vue (diff)
The file was addedserver/api/accounting/amazon-ads/profile.put.ts
The file was modifiedapp/assets/langs/shared.js (diff)
The file was addedreference/test-scripts/amazon-ads-parse.mjs
The file was addedserver/utils/amazonAds/adsApi.ts
The file was addedserver/utils/amazonAds/importInvoice.ts
The file was addedserver/api/accounting/amazon-ads/invoices.get.ts
The file was addedserver/utils/amazonAds/routeShared.ts
The file was modifiedapp/composables/menu/admin/accounting.ts (diff)
The file was addedserver/api/oauth/amazon-ads/callback.get.ts
The file was modified.env-dev (diff)
The file was addedserver/api/accounting/amazon-ads/profiles.get.ts
The file was addedserver/api/accounting/amazon-ads/disconnect.post.ts
Commit b99b7ac21f59acb46845cd37905cf64ad2f389e4 by info
Sales order ship-to name + dashboard calls card improvements

Sales orders: edit.vue only fetched order data in onMounted, so switching
between order tabs via the in-app tab bar (router.push into the same
keep-alive'd component, only :id changes) kept showing the previously loaded
order's data — including its business partner — until a hard reload. Added a
route.params.id watcher (loadOrderData()) mirroring the existing fix on
sales/invoices and sales/customer-rma edit pages. Also added the ship-to
recipient name (C_BPartner_Location_ID.Name — the same field the orders grid
shows as "Name", which can legitimately differ from the business partner's
own Name) to the read-only order view.vue page, which was missing it
entirely; edit.vue's OrderForm.vue already displayed it correctly.

Dashboard "Letzte Anrufe" card: the extension badge and duration/missed
label were side-by-side in a fixed-width column that could overflow into
neighboring text. Stacked them vertically instead and gave rows a bit more
height. Added server-side search (number/name) and pagination — cdr.ts's
recentCalls() now takes offset/search/direction and returns total +
missedTotal (so the missed-count badge stays accurate regardless of the
active direction tab or page).

Quick-contact modal (dashboard "+" on unmatched calls): added a "search
existing contact" panel above the create-new form, so a call can be linked
to an existing ad_user/lead instead of always creating a duplicate. Scoped
to the caller's own organization by default ("search all organizations" to
widen), with a type filter (All/Lead/External/Internal) mirroring the
site's existing Users/Leads/External Users split. New
GET /api/admin/users/search endpoint backs it; picking a result only PUTs
the call's phone number onto the existing contact when it isn't already on
file, to avoid clobbering an existing different number.
The file was modifiedapp/components/dashboard/QuickContactModal.vue (diff)
The file was modifiedapp/components/dashboard/RecentCallsCard.vue (diff)
The file was addedserver/api/admin/users/search.get.ts
The file was modifiedserver/api/telephony/recent-calls.get.ts (diff)
The file was modifiedserver/utils/telephony/cdr.ts (diff)
The file was modifiedapp/pages/sales/orders/[id]/edit.vue (diff)
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedapp/pages/sales/orders/[id]/view.vue (diff)
Commit 852e5a139e7dc3c8d4e43fa24f46d603c71b710d by info
Sales invoices: merge in purchase (AP) invoices, incl. Amazon Ads imports

server/api/invoices/so.get.ts dropped its IsSOTrx-only filter (kept the
existing DocStatus CO/CL/DR restriction) so /sales/invoices now returns both
sales and purchase invoices — including the Amazon Ads AP invoices booked via
/accounting/amazon-ads-invoices, which land in c_invoice like any other
vendor invoice. Route name/URL kept as-is to avoid touching every caller.

New "Type" grid column (AgInvoiceKind.vue) tags each row AR/AR-CM/AP/AP-CM
from C_Invoice.DocBaseType (the same field lexoffice-upload.post.ts already
keys its AR/AP branching on), right after the document-number column.

InvoiceListFilters.vue gained two segmented filters: Receivables/Payables
(side, derived from IsSOTrx / the C_DocTypeTarget_ID 1000006 "AP CreditMemo
used as a customer credit note" exception — same convention as
accounting/opos) and Lexoffice upload status (uploaded/not uploaded), both
applied client-side alongside the existing fulfillment/payment/amount
filters so the grand-total row and counts stay consistent.

The existing bulk Lexoffice upload button needed no changes — the shared
lexoffice-upload.post.ts route already branches on DocBaseType per invoice
(original vendor PDF for AP, Jasper print for AR) and processes mixed AR/AP
id batches correctly; it just never had AP rows to select from before.

Fixed InvoiceAction.vue's row-menu edit/duplicate handlers, which always
navigated to the sales-invoice pages — now they branch on isSOTrx to
/procurements/invoices/{id}/{edit,duplicate} for AP rows, matching the
branching AgLink.vue's document-number link already had.

Note: this route has no $top cap (pre-existing), so removing the AR-only
restriction roughly doubles the worst-case row count for orgs with a long
purchase-invoice history — worth watching if the page gets sluggish.
The file was modifiedapp/components/sales/InvoiceAction.vue (diff)
The file was modifiedapp/components/sales/InvoiceListFilters.vue (diff)
The file was modifiedapp/assets/langs/shared.js (diff)
The file was addedapp/components/AgGrid/Invoices/AgInvoiceKind.vue
The file was modifiedserver/api/invoices/so.get.ts (diff)
The file was modifiedapp/pages/sales/invoices/index.vue (diff)
Commit 9b08ac127dfe1f98967ced8227f64c07868a1db3 by info
Lead page: move Aufnahmen button out of the offer/contract CTA group

The "Aufnahmen" (call recordings) button sat in the top-right CTA cluster
alongside Angebot/Vertrag/SEPA/Onboarding, but it isn't part of that
offer/contract workflow — it's phone-call history. Moved it next to the
phone number / DialButton in the contact-chips row instead, gated on the
lead having a phone number (nothing to match recordings against otherwise).
The compact top-toolbar icon button (MobileActionsMenu) already had its own
"Aufnahmen" entry and is unchanged.
The file was modifiedapp/pages/users/leads/[id]/edit.vue (diff)
Commit 39f1dfd5739eef2e6173ff543b20fba47bca5fa3 by info
DialButton: opt-in Recordings toggle (play-only) in the dial popover

Adds a showRecordings prop that puts a headset icon in the popover header
next to Close. Toggling it switches the popover body to a compact list of
FreePBX recordings matched to `number` (GET /api/telephony/recordings, same
endpoint CallRecordingsModal.vue uses on contact pages, called here with
just `numbers` — no source/recordId, so it works for numbers with no known
contact too) — date, direction, duration and a play button only, no
transcription/download clutter. Off by default everywhere; enabled on both
DialButton usages in the dashboard's "Letzte Anrufe" card, so clicking a
call's number now offers a quick way to listen to past recordings for that
number right from the dial popover.
The file was modifiedapp/components/DialButton.vue (diff)
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedapp/components/dashboard/RecentCallsCard.vue (diff)
Commit 3a2aa7e776b1ecd670ff8e1f0abb8a4de7311b04 by info
Recent calls card: stack date above number, give the name its own full line

The date used to be its own fixed 62px grid column, squeezing how much
width the number/name column got. Moved it to sit above the number instead
(inside the same column), so the name — which can run considerably longer
than the number — gets the full row width on its own line rather than
sharing it with a separate date column.
The file was modifiedapp/components/dashboard/RecentCallsCard.vue (diff)
Commit d9627b7266e6432d9febb322babb26fcc4f62970 by info
Locator priorities: exclude locators not allowed for shipping

M_LocatorType.IsAvailableForShipping=false locators (return bins,
quarantine, reconditioning input, ...) are dropped before building
pick-order conflicts/proposals, since shipment generation never picks
from them anyway.
The file was modifiedserver/api/materials/locators/priority-recommendations.get.ts (diff)
Commit c1fb76e4b48ea72b198182db778fce1fb2a4892b by info
DialButton: fix recordings that appeared to play but stayed silent

Chrome's <audio> element does not behave like a normal failed request when
the recordings route errors out (e.g. the PBX recordings service returns a
JSON error body instead of audio): no 'error' event ever fires and
.play()'s promise never settles either — it just sits at
networkState=LOADING/readyState=HAVE_NOTHING with paused=false forever.
Since the row's play/stop icon was driven only by a manually-toggled ref,
a failed load looked exactly like "still playing" with no sound and no
way to tell it failed. Add a stall-timeout guard (6s) that aborts the
hung request, resets the button and shows an inline error message when
playable data never arrives; canplay/playing clear the timer on success.
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedapp/components/DialButton.vue (diff)
Commit 182290a4e2c2f6c96174f4a55e9d7c30acf5855c by info
AgInvoiceKind: fix AP/AR tags never actually getting their colors

The tag colors never rendered: this component is used as an AG Grid
cellRenderer, and its <style scoped> block never reached the rendered
elements (they carried no data-v-* attribute at all), so every tag
silently fell back to Bulma's plain grey .tag look regardless of AR/AP/
credit-memo type — the same gap already documented for AG Grid image
cell renderers. Move the styling to a non-scoped block keyed off a
dedicated .ag-ikind-tag marker class (so it can't leak onto the many
other Bulma .tag elements elsewhere in the app), and switch from thin
outlined tags to solid-filled ones so AP vs AR reads at a glance while
scanning a long invoice grid.
The file was modifiedapp/components/AgGrid/Invoices/AgInvoiceKind.vue (diff)
Commit 3648fbba0e22b85d8209ea8ec5b961f204aff7e9 by info
Lexoffice upload: default AP invoices into Ausgaben, not the general inbox

Without an explicit category, uploads went through Lexoffice's plain
Files-drop, which auto-creates its own uncategorized draft voucher — it
never lands as a filed Einnahmen/Ausgaben entry, just a general/pending
item in Lexoffice's own inbox. AR invoices only looked correctly filed
under Einnahmen because someone picked a category for them every time,
which goes through the Vouchers API instead.

Add a third modal option, "Mit Standardkategorie hochladen": books a
real voucher via the same Vouchers API as an explicit category, using a
generic catch-all per direction (Einnahmen for AR/AR-CM, Sonstige
Ausgaben for AP/AP-CM) resolved per invoice so a mixed bulk upload still
files each one correctly. The true "Ohne Kategorie hochladen" (plain,
uncategorized Files-drop) option is unchanged and still available.

Also fixes APC (AP credit memo) incorrectly booking as voucher type
purchaseinvoice instead of purchasecreditnote.
The file was modifiedapp/components/sales/LexofficeCategoryModal.vue (diff)
The file was modifiedserver/api/invoices/lexoffice-upload.post.ts (diff)
Commit d7464e740863297d158a64b96ec8573d0e755371 by info
Bank fetch coverage: show import progress per month, not just staged

Coverage cells only reflected whether any statement was staged for a
month; add the imported/open counts the coverage endpoint already
returns so a month reads green only once fully imported, amber while
partially imported, with the count shown. Also surface the imported
count as a pill on the connection row, next to the existing pending one.
The file was modifiedapp/pages/accounting/bank-transactions/index.vue (diff)
The file was modifiedapp/assets/langs/shared.js (diff)
Commit 3c67c7ed036f479cad2a91044c687bb5dbfbe6a4 by info
Add asterisk lookup endpoint

Squashed to drop an accidentally committed 134MB HAR capture file
that was blocking the push (GitHub's 100MB file size limit); also
gitignore *.har so this can't recur.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G7aDXCyYUwGgTG81QTP8E
The file was modified.env-prod (diff)
The file was modified.gitignore (diff)
The file was modified.env-dev (diff)
The file was modifiedserver/utils/elasticHelper.ts (diff)
The file was modifiednuxt.config.ts (diff)
The file was modified.env (diff)
The file was addedserver/api/telephony/cid-lookup/[number].get.ts
Commit 0d5c36c95d22b6066ed5d0718459bb0e6e13c578 by info
Quote: configurable grading pricing (time/fixed + description) and save-draft button

Grading is now priced by time/effort or a fixed price with a freetext
description printed as a subtext, instead of a flat by-effort checkbox.
Also adds a Save button on the quote modal to persist offer_conditions
without sending the quote.
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedapp/composables/useOfferQuote.ts (diff)
The file was addedserver/api/offers/conditions/index.post.ts
The file was modifiedapp/components/offers/QuoteModal.vue (diff)
The file was modifiedserver/utils/offers/quotePdf.ts (diff)
Commit 26efb3a1498df891c0853f9e44aae23876a7713c by info
Quote: customer-requirements checklist; dashboard: leads card quick actions

Add a "Kundenanforderungen" section to the quote modal — freetext bullet
points each answered possible/not possible (green check / red X) or with
a freetext answer, printed as a checklist in the PDF.

Also add "create lead" and "open all leads" icon buttons to the dashboard's
latest-leads card header.
The file was modifiedserver/utils/offers/offerConditions.ts (diff)
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedapp/components/offers/QuoteModal.vue (diff)
The file was modifiedserver/utils/offers/quotePdf.ts (diff)
The file was modifiedapp/pages/index.vue (diff)
The file was modifiedapp/composables/useOfferQuote.ts (diff)
Commit 82e20b0c80024eabe37fea705ff9d11134cfbf58 by info
Amazon: switch central OAuth app to Published, fix test-connection + credential UI

Order source 1000026 stopped importing because the previous central Amazon app
("logship", Draft) hit its mandatory 180-day LWA Client Secret rotation deadline
(2026-09-12) — LWA still authenticated fine, but every SP-API call was denied.
Reconnecting the seller's own authorization doesn't rotate the app's secret, so
that never fixed it. Standardized the central app on "LogShip App" (Published)
instead, matching what order source 1000000 already used successfully.

Also:
- test-connection.post.ts: report failure (with Amazon's real error text) when
  every SP-API endpoint is denied, instead of always defaulting to a misleading
  "missing Tax Invoicing role" message.
- OrderSourceForm.vue: hide the raw Client ID / Client Secret / Refresh Token
  fields for Amazon by default (Connect/Reconnect manages them automatically);
  only reveal them behind an explicit "uses its own separate Amazon Developer
  app" toggle.
The file was modifiedapp/components/settings/OrderSourceForm.vue (diff)
The file was modified.env-prod (diff)
The file was modifiedserver/api/oauth/amazon/test-connection.post.ts (diff)
Commit 7ccda3abf09f752e54f2ad7299b242330511d169 by info
SIS: new Amazon pricing control page — compare internal vs Amazon price/qty, Buy Box, fees, push corrected prices

Admin-only page under Sales comparing internal price/stock against what's
live on Amazon for each Amazon order source, with a one-click price push
back to Amazon. New Amazon SP-API surface in amazonSpApi.ts: bulk merchant
listings report (Reports API, the source of truth for "what's on Amazon"),
Listings Items API read/patch, Product Pricing API (Buy Box), Fees Estimate
API. Product matching is SKU-first (Value/SKU) with ASIN as fallback, via
sisMatching.ts. Verified end-to-end against live production data, including
a real price push (Amazon's Listings Items PATCH turned out to be async
despite returning immediately, so pushes poll briefly then trust the
accepted submission, with a short-lived overlay so a subsequent bulk report
refresh can't revert a just-pushed price before Amazon's own report catches
up).
The file was addedapp/pages/sales/sis/index.vue
The file was addedserver/utils/sisMatching.ts
The file was addedserver/api/sales/sis/price-update.post.ts
The file was modifiedapp/assets/langs/shared.js (diff)
The file was addedserver/api/sales/sis/order-sources.get.ts
The file was modifiedapp/composables/menu/admin/sales.ts (diff)
The file was modifiedserver/utils/amazonSpApi.ts (diff)
The file was modifiedapp/components/MainNavigationMenu.vue (diff)
The file was addedserver/api/sales/sis/offers.post.ts
The file was addedserver/api/sales/sis/listings.get.ts