Skip to content

Changes

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

Summary

  1. Return label: tighten header band, put doc number next to title (details)
  2. Return label: shrink header band further, lift doc number 1mm (details)
  3. Mobile return: fix qty locked at 0 when scanning an Amazon-imported RMA (details)
  4. Customer Returns: link doc number to detail view, add label reprint button (details)
  5. Dev: pre-bundle AG Grid + vue-pdf deps to fix grid never rendering (details)
  6. Requests: push tickets to mobile workers as priority tasks (details)
  7. Fix return-label reprint printing wrong DocumentNo (details)
  8. Reverse caller-ID lookup: replace Elasticsearch with a direct iDempiere-backed in-memory directory — server/utils/telephony/cidDirectory.ts fetches the small active ad_user set with phone/phone2 (SERVICE token, same pattern as phoneActivity.ts/extensions.ts) into a 60s TTL stale-while-revalidate cache so cid-lookup/[number].get.ts has zero network calls on the hot path (was querying a Postgres-trigger-fed ES index that could lag/stall behind iDempiere edits); server/plugins/warm-cid-lookup.ts pre-warms the cache at server boot so the first call after a deploy/restart is instant too; recipe note in reference/recipes.md (details)
  9. Fix attachment-lookup N+1: skip the live ad_table query for known table names (details)
  10. Tickets: show staff replies to limited merchant roles (service-token reads) (details)
  11. Ticket detail: wrap toolbar instead of overlapping in the split view (details)
  12. Fix unbounded open-shipments query: replace child-table $expand with direct-Postgres list + batched line fetch (details)
  13. Mobile app: bump version to 1.0.49 (versionCode 50) (details)
  14. Change log modal (admin only) for orders, shipments, products and partners (details)
  15. Shipments list: link document numbers directly to the shipment edit page (details)
  16. Order edit: restructure the action toolbar, rename reactivation to 'Auftrag wiederöffnen' (details)
  17. Order tab: fix column overlap (30% / auto / 22%); change log table: truncate line labels, hide technical fields by default (details)
  18. Order tab: make the 'General' column really 22% wide, stack its paired fields (details)
  19. Order tab: move the partner link into the shipping-address header as a right-aligned 'Kunde' link (details)
  20. Order tab 'General' column: Organization first, compact German-formatted date row, Tenant as tooltip (details)
  21. Order edit toolbar: ticket button in the app-wide yellow (same as .button.is-ticket) (details)
  22. Order edit: no stale 'Abort' button when opening an order (details)
  23. Pushed tasks: instruction note, worker actions, take-back and deep-link fix (details)
  24. Ticket detail toolbar: chips + two workflow buttons + 'Weitere Aktionen' dropdown (details)
  25. Lead questionnaire: initial-call form (DE/EN) with blank print, draft and PDF attachment (details)
  26. Android app 1.0.50 (versionCode 51): Mobile Push Tasks release (details)
  27. Pushed tasks: refresh the mobile dashboard live on a foreground push (details)
  28. Pushed tasks: neutral dashboard banner with urgency tags, native refresh poll (details)
  29. Pushed tasks: task modal — back to dashboard, return fix, linked record cards (details)
  30. Pushed tasks: colour rows by priority tier (high red, default orange, low blue) (details)
Commit 1901094c902d6779b7ae601e4ea8109aea054959 by info
Return label: tighten header band, put doc number next to title

Shrinks the top black header-band height and moves the document number
onto the same row as the RETOURE/KUNDENRÜCKSENDUNG title (top-aligned,
right of it) instead of stacking them, freeing vertical space for more
article rows before a continuation label is needed. Title is now bold
and slightly larger; company/date text in the band keeps its prior size.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G7aDXCyYUwGgTG81QTP8E
The file was modifiedserver/api/print/return-label.post.ts (diff)
Commit 7944e52f1d3f243da24bcdbd08afc40629fccd44 by info
Return label: shrink header band further, lift doc number 1mm

Continues the earlier band/title tightening: band height reduced
again (10/7mm -> 9/6mm) and the document number nudged 1mm above the
title's baseline for a slightly better visual balance on the row.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G7aDXCyYUwGgTG81QTP8E
The file was modifiedserver/api/print/return-label.post.ts (diff)
Commit 0ded69844c268c0bbcfe1ac463f1f1fa7a7bb3e1 by info
Mobile return: fix qty locked at 0 when scanning an Amazon-imported RMA

Scanning a return parcel's external RMA number (M_RMA.externalRmaNumber)
finds the matching pre-imported Amazon RMA and loads its linked shipment,
but that RMA is already DocStatus=CO with the expected qty on its line —
getReturnedQtyMap counted it as "already returned" against its own
shipment, zeroing maxQty and locking the qty stepper at 0 for every line.
Confirmed against a live prod record (RMA 1000688 / externalRmaNumber
"DydTw8rHRRMA": CO, one M_RMALine Qty=1 on the exact line whose remaining
qty then computed to 0).

Fix: exclude the matched RMA's own id from the already-returned tally —
it's the incoming authorization being fulfilled right now, not a separate
prior return. Searching by bpartner and selecting the shipment manually
was unaffected since it doesn't go through this RMA-number match at all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G7aDXCyYUwGgTG81QTP8E
The file was modifiedapp/pages/mobile/return.vue (diff)
Commit 130a2dfe89a8ab37acd85c775b105a96667f9bca by info
Customer Returns: link doc number to detail view, add label reprint button

The list grid's Doc Number column was plain text — no way to open a
return's detail view from it. Add AgCustomLink (mirrors the
MaterialReceipt/Shippers pattern) linking to /sales/returns/[id]/view.

On that detail view, add a "Etikett erneut drucken" button that re-fetches
the return's lines (GET /api/inouts/[id]/return-detail) and reprints the
return label via POST /api/print/return-label (kind: 'customer-return',
using the printer queue from useReturnLabelPrinter) — for when the label
didn't come out at intake for any reason.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G7aDXCyYUwGgTG81QTP8E
The file was addedapp/components/AgGrid/Shipments/AgCustomLink.vue
The file was modifiedapp/pages/sales/returns/[id]/view.vue (diff)
The file was modifiedapp/pages/sales/returns/index.vue (diff)
Commit 954812a8077115a4364b65372e92980e3ea4685b by info
Dev: pre-bundle AG Grid + vue-pdf deps to fix grid never rendering

Every AG Grid page (any of them — confirmed on both Customer Returns and
Shippers) rendered a completely empty <div class="ag-theme-balham">: no
rows, no "No Rows" overlay, no console error. Root cause was the same
class of issue the surrounding optimizeDeps.include comment already
documents for other packages, just not yet applied to these: ag-grid-community,
ag-grid-enterprise, ag-grid-vue3, and @tato30/vue-pdf were never in the
list, so Vite only discovered them when the first page using <AgGrid>/
<PrintViewer> actually rendered — triggering a disruptive re-optimize +
forced reload mid-render. That reload left AgGridVue's internal grid
creation desynced from AgGrid.vue's provideGlobalGridOptions({theme:
"legacy"}) call, surfacing as AG Grid's own "error #239" (Theming API vs
CSS File Theme conflict) — and, on the very first hit of a session, as a
totally blank grid with no error at all.

Also adds @capacitor/preferences (pulled in by plugins/00.capacitor-api.client.ts
for the dual web/Capacitor build, which stays in the dev module graph even
though it early-returns on web) — same failure mode, same fix.

Confirmed fixed: clean nuxt dev restart + rm -rf .nuxt node_modules/.cache,
Customer Returns list and detail view both rendered fully on first load,
no "Vite discovered new dependencies at runtime" warning, no AG Grid error.
Dev-only change (vite.optimizeDeps has no effect on the production build).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G7aDXCyYUwGgTG81QTP8E
The file was modifiednuxt.config.ts (diff)
Commit 39a918fde9d11a993c8aa2aad04a6d94d3171136 by info
Requests: push tickets to mobile workers as priority tasks

Lets dispatchers push a ticket to a specific mobile worker's device (native
FCM + web push) so it pops up and stays pinned as a priority-task banner on
the mobile dashboard until the worker starts the timer on it. Opening it
reuses the existing ticket instructions/chat/timer flow in tasks.vue; a new
global running-timer banner keeps the timer visible while navigating other
mobile pages.

Needs two new custom columns on R_Request in iDempiere (IsPushedTask Yes-No,
PushedTaskAt Date+Time) — stays inert until those exist.
The file was modifiedapp/layouts/mobile.vue (diff)
The file was addedapp/composables/usePushedTasks.ts
The file was modifiedserver/api/requests/requests/update.put.ts (diff)
The file was modifiedapp/components/requests/MyTicketDetail.vue (diff)
The file was modifiedserver/utils/fcmNotifier.ts (diff)
The file was modifiedapp/composables/states.ts (diff)
The file was modifiedapp/pages/mobile/tasks.vue (diff)
The file was addedserver/api/mobile/pushed-tasks.get.ts
The file was modifiedapp/plugins/20.native-push.client.ts (diff)
The file was addedserver/api/requests/requests/[id]/push-task.post.ts
The file was modifiedapp/pages/mobile/index.vue (diff)
Commit f2540ba61045ce40c991525ed3931844b57bc0ef by info
Fix return-label reprint printing wrong DocumentNo

The "Etikett erneut drucken" button on the return detail page always
printed the customer-return's own DocumentNo, but /mobile/reconditioning
only scans the linked RMA's DocumentNo (571/572 live returns have one).
Now prints the RMA's number when present, matching what intake already
prints, and falls back to the return's own number only when there's no
linked RMA.
The file was modifiedapp/pages/sales/returns/[id]/view.vue (diff)
Commit 3534d36393ce6175fe9b2f1c21ed9741129048c8 by info
Reverse caller-ID lookup: replace Elasticsearch with a direct iDempiere-backed in-memory directory — server/utils/telephony/cidDirectory.ts fetches the small active ad_user set with phone/phone2 (SERVICE token, same pattern as phoneActivity.ts/extensions.ts) into a 60s TTL stale-while-revalidate cache so cid-lookup/[number].get.ts has zero network calls on the hot path (was querying a Postgres-trigger-fed ES index that could lag/stall behind iDempiere edits); server/plugins/warm-cid-lookup.ts pre-warms the cache at server boot so the first call after a deploy/restart is instant too; recipe note in reference/recipes.md
The file was modifiedreference/recipes.md (diff)
The file was addedserver/utils/telephony/cidDirectory.ts
The file was modifiedserver/api/telephony/cid-lookup/[number].get.ts (diff)
The file was addedserver/plugins/warm-cid-lookup.ts
Commit 4fc7a95b074a29eacb5e9ff0da45ea06db028255 by info
Fix attachment-lookup N+1: skip the live ad_table query for known table names

server/api/attachments/[table]/[id]/index.get.ts hit iDempiere's ad_table
model on every call to resolve a table name to its numeric id, even though
the very same route already had a complete hardcoded fallback map for the
common tables. Every AgGrid row with an attachment cell (AgCustomAttachment.vue)
fires this once, so a large order/shipment grid render turned into hundreds
of redundant REST calls, each going through the synchronized
DefaultQueryConverter singleton (see the "iDempiere REST load rules" recipe /
2026-09-10 incident) — a live capture on prod showed 287 of these in one
grid render. Now the static map is checked first and iDempiere is only
queried for a genuinely unmapped table name. Behavior-preserving: also drops
a dead duplicate M_Product branch that was unreachable (208 always won).
The file was modifiedserver/api/attachments/[table]/[id]/index.get.ts (diff)
Commit 26a325c9da0087ee13a1ed7a95bba6080578f643 by info
Tickets: show staff replies to limited merchant roles (service-token reads)

Staff replies on merchant tickets were stamped with the staff member's
active org (LogYou) instead of the ticket's org, so iDempiere's org
row-level security hid them from the merchant's limited role — customers
saw only their own messages (85 such rows across 5 merchants on prod,
e.g. Wonderhome ticket 1000439 with both LogYou replies missing).
AD_Org_ID is not updateable on R_Request/R_RequestUpdate/R_RequestAction,
so the rows cannot be re-stamped.

- server/utils/ticketViewer.ts: role FrontendMenu resolved server-side
  (service token, cached), caller-token ticket access check, server-side
  twin of the client's internal-entry filter ('I' / [Zeitabrechnung]).
- request-update / request-history GET: a proven-limited viewer reads the
  ticket's rows with the service token AFTER the caller-token access check;
  internal entries are dropped server-side. Both lists now ordered + capped.
- request-update POST: AD_Org_ID derived from the ticket server-side
  (body.organizationId ignored) so every caller stamps the right org;
  limited roles can never post an 'I' entry. Write stays on the caller's
  token so CreatedBy is correct.
- author-orgs: collect update/action authors with the service token for
  limited viewers so the newly visible staff rows get their LogYou label.
- latest-updates: limited viewers get updates of their visible tickets via
  chunked `R_Request_ID in (...)` with the service token, filtered.
The file was addedserver/utils/ticketViewer.ts
The file was modifiedapp/components/requests/MyTicketDetail.vue (diff)
The file was modifiedserver/api/requests/requests/latest-updates.get.ts (diff)
The file was modifiedserver/api/requests/requests/[id]/request-update/index.get.ts (diff)
The file was modifiedserver/api/requests/requests/[id]/request-update/index.post.ts (diff)
The file was modifiedserver/api/requests/requests/[id]/request-history/index.get.ts (diff)
The file was modifiedserver/api/requests/requests/[id]/author-orgs.get.ts (diff)
Commit 4e94b7513ae63f4e85e54ccfdc83f8ceaaa7169b by info
Ticket detail: wrap toolbar instead of overlapping in the split view

The ticket header bar was a single non-wrapping row with hidden horizontal
scroll; in the my-tickets split view (and small windows) the action group
painted over the metadata chips (ticket no., date, type, category,
assignee). The bar now wraps into a metadata row and an action row when
space runs out, chips wrap inside each group, and in narrow bars the
secondary actions (push to mobile, accounting flag) collapse to icon
buttons with tooltips via a container query.
The file was modifiedapp/components/requests/MyTicketDetail.vue (diff)
Commit 40b7c61af8d06bd8bc95b02f3393b1f37fd504c5 by info
Fix unbounded open-shipments query: replace child-table $expand with direct-Postgres list + batched line fetch

useOpenShipments.ts (backing components/integrations/OpenShipments.vue, polled every
2 minutes per open tab on the commissioning page) queried m_inout with a 5-way $expand
including the CHILD table m_inoutline($expand=m_product_id) and no $top — same shape as
the 2026-09-10 incident's m_product $expand=M_Storage, hitting the synchronized
DefaultQueryConverter singleton once per shipment per line. A live capture returned 2MB
in one response; only 67 rows today but it only gets heavier as open-shipment volume grows.

Fix, following the same pattern already used for products+storage (productStorageHelper.ts):
- Shipment list now comes from the existing direct-Postgres endpoint
  server/api/inouts/open-to-commission-list.get.ts (already used by the dashboard "Offene
  Aufträge" card and the commissioning modal), extended with the fields the widget needs
  (location/shipper name, PO reference, line-qty sum) so it's purely additive for its
  existing consumers.
- Line items (needed for the barcode-scan-to-shipment search in commission.vue) are fetched
  in one bounded REST call: m_inoutline top-level list with $filter=M_InOut_ID in (...)
  and $expand=M_Product_ID as a to-one FK expand, not a child expand under m_inout, so it
  takes the cheap code path per the "iDempiere REST load rules" recipe. Verified directly
  against prod (SQL query + REST filter) before committing.
The file was modifiedserver/api/inouts/open-to-commission-list.get.ts (diff)
The file was modifiedapp/composables/useOpenShipments.ts (diff)
Commit 9ab77d566a46409c11846c82a81629cb020bfd70 by info
Mobile app: bump version to 1.0.49 (versionCode 50)
The file was modifiedandroid/update-files/version.json (diff)
The file was modifiedandroid/app/build.gradle (diff)
Commit 6ef4fadbda7e9d755b39ea38b02904770c07e887 by info
Change log modal (admin only) for orders, shipments, products and partners

Adds an iDempiere AD_ChangeLog viewer like the ZK 'Change Log' / 'Time Line' tab:
- server/utils/changeLogHelper.ts + GET /api/changelog/detail/{table}/{id}:
  paged changelog read with column metadata, list values resolved via
  AD_Ref_List, foreign keys resolved to record labels (bounded, cached),
  child lines included (order/shipment lines, partner locations + contacts),
  record creation event; role must be IsClientAdministrator (checked server-side)
- components/ChangeLogModal.vue: timeline (grouped per transaction, day
  separators) + table view, search, line/technical-field toggles, DE/EN/ES
- components/ChangeLogButton.vue: admin-gated toolbar button, wired into the
  order, shipment, product and business-partner edit pages
The file was modifiedapp/pages/sales/orders/[id]/edit.vue (diff)
The file was modifiedapp/pages/materials/products/[id]/edit.vue (diff)
The file was modifiedapp/pages/partners/partners/[id]/edit.vue (diff)
The file was addedserver/utils/changeLogHelper.ts
The file was addedapp/components/ChangeLogButton.vue
The file was addedapp/components/ChangeLogModal.vue
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedapp/pages/sales/shipments/[id]/edit.vue (diff)
The file was addedserver/api/changelog/detail/[table]/[recid].get.ts
Commit 4068470597d78282ca601129755254f00bd0a7c5 by info
Shipments list: link document numbers directly to the shipment edit page
The file was modifiedapp/pages/sales/shipments/index.vue (diff)
The file was addedapp/components/AgGrid/Shipments/AgShipmentEditLink.vue
Commit 679f81dc67cf8b18be03cdd88c38f3e00bf257c1 by info
Order edit: restructure the action toolbar, rename reactivation to 'Auftrag wiederöffnen'

The order edit bar had grown to ~20 coloured icon-only buttons. It is now a
neutral, text-labelled toolbar: Save, Files (with badge), Complete / Reopen
order, Create shipment, Create invoice, Void, and a grouped 'More actions'
dropdown (print / labels / duplicate / video / reminders / compare / change
log). All visibility rules live in one data-driven action list; on phones
(<= 768px) only Save, Files and the status action stay outside the dropdown.
Right side: Abort, share, Back, Ticket as labelled buttons.

- 'Reaktivieren' is now 'Auftrag wiederöffnen' (Reopen order); the orders list
  batch action 'Auf Entwurf' uses the same wording
- new translation keys (en/de/es): reopen_order, more_actions,
  create_shipment_action, create_invoice_action, shipment_created,
  invoice_created, void_not_possible_shipped, force_void_short,
  manual_commission_short, reprint_label, order_reminders, show_video
The file was modifiedapp/pages/sales/orders/index.vue (diff)
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedapp/pages/sales/orders/[id]/edit.vue (diff)
Commit f158c2abbbf73217d0b95096455df4882b77d43d by info
Order tab: fix column overlap (30% / auto / 22%); change log table: truncate line labels, hide technical fields by default

- OrderForm: explicit flex bases + min-width:0 on the three order-tab columns
  (numbers/refs wider, shipping address flexible, 'General' column narrower) so
  the row can no longer overflow under the side cards; long e-mails wrap
- ChangeLogModal: fixed table layout with column widths, line badges truncated
  with full text as tooltip, 'Hide technical fields' on by default
The file was modifiedapp/components/sales/OrderForm.vue (diff)
The file was modifiedapp/components/ChangeLogModal.vue (diff)
Commit 7eb042353e2b5a3fbc37ccee28f6b5b2ace61a6c by info
Order tab: make the 'General' column really 22% wide, stack its paired fields

The earlier width rule lost to Bulma's .column.is-one-third (higher specificity),
so the column was still a third of the row. The selector now outranks it and
the Date Ordered/Promised and Organization/Tenant pairs stack vertically so
nothing truncates in the narrow column.
The file was modifiedapp/components/sales/OrderForm.vue (diff)
Commit 6e5caf40f53fed39d1a293b80f62304060008fb8 by info
Order tab: move the partner link into the shipping-address header as a right-aligned 'Kunde' link

The partner row above the recipient name is replaced by a compact 'Kunde' link
(with open-link icon) on the right of the 'Lieferanschrift' header; the partner
name is shown as tooltip only. Limited roles get a static label.
The file was modifiedapp/components/sales/OrderForm.vue (diff)
Commit cce23cadaf525474a569212d8c883efbd265512a by info
Order tab 'General' column: Organization first, compact German-formatted date row, Tenant as tooltip

- Organization is the first field; Tenant is no longer a field, it shows as a
  tooltip on hover over Organization
- Date Ordered / Date Promised sit side by side in one compact row (smaller
  label + input, short labels 'Ordered' / 'Promised' with full title); on
  completed/voided orders the read-only values display as dd.mm.yyyy
The file was modifiedapp/components/sales/OrderForm.vue (diff)
Commit 67b55a0e93a3b98c8d50c634e6c42f29d52c436d by info
Order edit toolbar: ticket button in the app-wide yellow (same as .button.is-ticket)
The file was modifiedapp/pages/sales/orders/[id]/edit.vue (diff)
Commit b23e90b7728a7cee87ddf690a385dde8403b453d by info
Order edit: no stale 'Abort' button when opening an order

- loadOrderData() resets the global useActiveSave flag before loading — a
  fresh record has nothing unsaved; the flag is shared by every edit page and
  modal, so a leftover true (e.g. from a dismissed quick-add) showed 'Abort'
  and blocked navigation on the next order opened from the grid
- the Abort button additionally requires the form to be really dirty
  (activeSave && !noEdit)
- OrderQuickAddModal clears the flag when it is closed without saving
The file was modifiedapp/pages/sales/orders/[id]/edit.vue (diff)
The file was modifiedapp/components/OrderQuickAddModal.vue (diff)
Commit f81ead42e45699211b185cc66502b6580111e91b by info
Pushed tasks: instruction note, worker actions, take-back and deep-link fix

Rounds out the push-to-mobile-worker flow into one coherent workflow:

- Desktop push modal: the note becomes an instruction for the worker (up to
  1000 chars) and is stored as an INTERNAL chat note "[Anweisung] …" — never
  visible to the merchant and no merchant notification. The modal shows which
  order/product is linked (rendered on the device with the instruction).
- Desktop ticket: a prominent banner while the ticket lives on a device
  ("An Mobilgerät gepusht · wartet" / "In Arbeit auf dem Mobilgerät · X"),
  a state pill in the toolbar and a "Zurückholen" button (optional take-back).
- New route [id]/push-task-status.post.ts: start → TaskStatus 20 %, return →
  IsPushedTask cleared (+ internal note, staff toast when from mobile),
  complete → IsComplete + TaskStatus 100 % + IsPushedTask cleared. push-task
  sets TaskStatus 0 %; the pending list now includes started tasks
  (TaskStatus ≠ 0 → "In Arbeit") plus linked order/product.
- Mobile ticket modal for a pushed task: instruction card, order/product
  cards, "Timer starten" (keeps the task in the list as "In Arbeit"),
  "Arbeit abschließen" (stops the timer, books the time, completes and hands
  the ticket back to the desktop) and "Zurück an Desktop" (optional reason).
  Full history collapsed behind "Verlauf anzeigen".
- Dashboard banner separates new vs. "in Arbeit" pushed tasks.
- Fix: opening a pushed task from the dashboard again after leaving the
  keep-alive'd tasks page re-showed the state it was left in (wizard step,
  open list). Deep links are now handled on every activation/query change
  and reset the page first (a running timer is never discarded).
The file was modifiedapp/pages/mobile/tasks.vue (diff)
The file was modifiedapp/pages/mobile/index.vue (diff)
The file was modifiedserver/api/mobile/pushed-tasks.get.ts (diff)
The file was modifiedapp/composables/usePushedTasks.ts (diff)
The file was addedserver/api/requests/requests/[id]/push-task-status.post.ts
The file was modifiedserver/api/requests/requests/[id]/push-task.post.ts (diff)
The file was modifiedapp/components/requests/MyTicketDetail.vue (diff)
Commit a05516e158e1274739e9bf16292acf5114274e7f by info
Ticket detail toolbar: chips + two workflow buttons + 'Weitere Aktionen' dropdown

Same pattern as the order edit toolbar: state chips (open/completed, owner,
pushed, accounted) on the left of the action group, the two workflow actions
(hand over / take back, close / reopen) as text buttons, and everything else
(push to mobile, take back from mobile, accounting flag, PDF report, open
full page) grouped in a data-driven "Weitere Aktionen" dropdown — so the bar
fits one row in the split view instead of a wall of buttons.
The file was modifiedapp/components/requests/MyTicketDetail.vue (diff)
Commit 6556f77238142892a52f9c9b0e26663c42a909e6 by info
Lead questionnaire: initial-call form (DE/EN) with blank print, draft and PDF attachment

New "Fragebogen" on the lead page (hero CTA + toolbar icon): a catalog-driven
questionnaire staff fill in while talking to a prospect — current situation,
order volume, articles (barcode, MHD, serials), additional services
(customisation, kitting, Amazon Prime/FBA/Pre-FBA), inbound & storage,
organisational. German by default, EN toggle switches labels and PDF.

- Question catalog in app/utils/leadQuestionnaire.ts, shared by the modal and
  the server renderer; adding a question is one entry.
- server/utils/offers/questionnairePdf.ts (pdf-lib): blank mode = fillable
  AcroForm (text fields + check boxes) for hand-written answers, filled mode =
  drawn values; the free-notes box grows to the rest of its page.
- Routes: offers/questionnaire/pdf (render) and offers/questionnaire/save
  (answers on offer_conditions.questionnaire; with attach: filled PDF attached
  to Lead_User via Strapi + C_ContactActivity with the answer summary).
- Draft save / reopen prefilled, progress chip, conversation meta (date,
  channel, interviewer).
- Leads list: "Leerer Fragebogen" (+ EN) prints the blank form without any
  lead prefill.
- offerConditions section type widened to string (new 'questionnaire' section).
The file was modifiedapp/assets/langs/shared.js (diff)
The file was modifiedapp/pages/users/leads/[id]/edit.vue (diff)
The file was addedapp/utils/leadQuestionnaire.ts
The file was addedserver/utils/offers/questionnairePdf.ts
The file was modifiedapp/pages/users/leads/index.vue (diff)
The file was addedserver/api/offers/questionnaire/pdf.post.ts
The file was modifiedserver/utils/offers/offerConditions.ts (diff)
The file was addedserver/api/offers/questionnaire/save.post.ts
The file was addedapp/components/offers/LeadQuestionnaireModal.vue
Commit 84f6e38b0d2d238419af49bc604a98c97074e6f0 by info
Android app 1.0.50 (versionCode 51): Mobile Push Tasks release
The file was modifiedandroid/update-files/version.json (diff)
The file was modifiedandroid/app/build.gradle (diff)
Commit ed5155594b06a3de2a0b937148dc0a67bc965024 by info
Pushed tasks: refresh the mobile dashboard live on a foreground push

Android hands a foreground FCM message to the app without a tray
notification, so a worker sitting on the dashboard saw nothing until they
left and came back. The native plugin now refetches the pushed-task list on
a 'pushed_task' receipt, plays the warning feedback and shows a toast.
The file was modifiedapp/plugins/20.native-push.client.ts (diff)
Commit 4931f7663993c142be7e4ed09071c1b04489782c by info
Pushed tasks: neutral dashboard banner with urgency tags, native refresh poll

The banner stays sticky at the top but drops the red block: rows are neutral
and only priority 1 (Dringend) / 3 (Hoch) carry a tag. The native app adds a
60 s refetch while the dashboard is visible as a safety net for missed pushes.
The desktop "Gepusht · wartet" pill uses the blue working-state colours.
The file was modifiedapp/components/requests/MyTicketDetail.vue (diff)
The file was modifiedapp/pages/mobile/index.vue (diff)
Commit 82990a75948958eacd02ef68561ba8961b52ef9d by info
Pushed tasks: task modal — back to dashboard, return fix, linked record cards

- Closing a task opened from the dashboard/notification deep link returns to
  the dashboard (history entry replaced) instead of the new-task wizard.
- "Zurück an Desktop" confirmation replaces the action row in place (it used
  to render below the fold), books a running timer instead of refusing, and
  hands back to the dashboard afterwards.
- Linked product (thumbnail, codes, stock per locator, open shortcut), order
  (customer, ship-to, lines, shipments) and shipment (status, tracking, lines)
  are rendered as cards; the pushed-task list now carries M_InOut_ID.
- Pinned list uses neutral colours with Dringend/Hoch tags.
The file was modifiedapp/composables/usePushedTasks.ts (diff)
The file was modifiedserver/api/mobile/pushed-tasks.get.ts (diff)
The file was modifiedapp/pages/mobile/tasks.vue (diff)
Commit 1e77ee19cf43852966794881cd3f1642880f624d by info
Pushed tasks: colour rows by priority tier (high red, default orange, low blue)

Dashboard banner rows and the pinned list now carry the ticket's priority
tier on border/background plus a solid tag: 1/3 (Urgent/High) red, 5 (the
default) orange, 7/9 (Low/Minor) light blue. Theme tokens only, so dark mode
follows automatically.
The file was modifiedapp/pages/mobile/tasks.vue (diff)
The file was modifiedapp/pages/mobile/index.vue (diff)