From f6eb31b70dda6204b78bc73164366d68ccbc7464 Mon Sep 17 00:00:00 2001 From: seb Date: Sat, 31 Oct 2026 21:19:13 +0100 Subject: [PATCH] u --- src/api/index.js | 1 + src/api/printerjob.js | 100 ++++++++++++++++++ src/automats/companyAutomat.js | 9 ++ .../settings/PrinterAgentSettingsPanel.jsx | 80 ++++++++++---- 4 files changed, 169 insertions(+), 21 deletions(-) create mode 100644 src/api/printerjob.js diff --git a/src/api/index.js b/src/api/index.js index 15fca75..2a39d9c 100644 --- a/src/api/index.js +++ b/src/api/index.js @@ -17,6 +17,7 @@ export { posterminal } from './posterminal.js'; export { printer } from './printer.js'; export { printeragent } from './printeragent.js'; export { agentprinter } from './agentprinter.js'; +export { printerjob } from './printerjob.js'; export { propertyname } from './propertyname.js'; export { quote } from './quote.js'; export { retoure } from './retoure.js'; diff --git a/src/api/printerjob.js b/src/api/printerjob.js new file mode 100644 index 0000000..44d25a7 --- /dev/null +++ b/src/api/printerjob.js @@ -0,0 +1,100 @@ +import { http } from './http.js'; + +export const printerjob = { + /** + * POST /api/zpljob + * @param {{ agentprinterId: number, data: string, copiescount?: number }} payload + * → { printerjob: PrinterJob } + */ + createZplJob({ agentprinterId, data, copiescount = 1 }) { + return http('/api/zpljob', { + method: 'POST', + body: { + agentprinterId: Number(agentprinterId), + data: String(data), + copiescount: Number(copiescount) || 1, + }, + }); + }, + + /** + * Sends a minimal ZPL test label to a specific agent printer. + * @param {number} agentprinterId + * @param {{ model?: string }} [options] + * → { printerjob: PrinterJob } + */ + sendTestZpl(agentprinterId, { model = 'Zebra' } = {}) { + const timeStr = new Date().toLocaleTimeString('de-DE'); + const safeModel = String(model || 'Drucker').replace(/[\^~]/g, ''); + const zpl = [ + '^XA', + '^FO40,40^ADN,36,20^FDTestdruck OK^FS', + `^FO40,85^ADN,18,10^FD${safeModel}^FS`, + `^FO40,115^ADN,18,10^FDID: ${agentprinterId} - ${timeStr}^FS`, + '^XZ', + ].join('\n'); + return this.createZplJob({ + agentprinterId, + data: zpl, + copiescount: 1, + }); + }, + + /** + * GET /api/printerjob + * @param {{ agentprinterId?: number, state?: string }} [query] + * → { printerjobs: PrinterJob[] } + */ + list(query = {}) { + const params = new URLSearchParams(); + if (query.agentprinterId != null) params.set('agentprinterId', String(query.agentprinterId)); + if (query.state != null) params.set('state', String(query.state)); + const qs = params.toString(); + return http(qs ? `/api/printerjob?${qs}` : '/api/printerjob'); + }, + + /** + * GET /api/printerjob/:id + * → { printerjob: PrinterJob } + */ + get(id) { + return http(`/api/printerjob/${id}`); + }, + + /** + * POST /api/printerjob + * @param {{ agentprinterId: number, type?: 'zpl'|'pdf'|'epos', data: string }} payload + * → { printerjob: PrinterJob } + */ + create({ agentprinterId, type = 'zpl', data }) { + return http('/api/printerjob', { + method: 'POST', + body: { + agentprinterId: Number(agentprinterId), + type, + data, + }, + }); + }, + + /** + * POST /api/printerjob/:id/cancel + * → { success: true, printerjob: PrinterJob } + */ + cancel(id) { + return http(`/api/printerjob/${id}/cancel`, { + method: 'POST', + }); + }, + + /** + * DELETE /api/printerjob/:id + * → { success: true, deletedJob: PrinterJob } + */ + delete(id) { + return http(`/api/printerjob/${id}`, { + method: 'DELETE', + }); + }, +}; + diff --git a/src/automats/companyAutomat.js b/src/automats/companyAutomat.js index 8ce2aca..bfdb529 100644 --- a/src/automats/companyAutomat.js +++ b/src/automats/companyAutomat.js @@ -28,6 +28,7 @@ import { printer as printerApi, printeragent as printeragentApi, agentprinter as agentprinterApi, + printerjob as printerjobApi, supplier as supplierApi, unit as unitApi, warehouse as warehouseApi, @@ -876,6 +877,14 @@ const actions = { }); }, + async sendTestPrint(agentprinterId, options = {}) { + return printerjobApi.sendTestZpl(agentprinterId, options); + }, + + async createZplJob(payload) { + return printerjobApi.createZplJob(payload); + }, + async loadLivePrinters() { const companyId = authAutomat.state.user?.selectedCompanyId ?? companyAutomat.state.current?.id; diff --git a/src/components/settings/PrinterAgentSettingsPanel.jsx b/src/components/settings/PrinterAgentSettingsPanel.jsx index ca1afba..df5b64b 100644 --- a/src/components/settings/PrinterAgentSettingsPanel.jsx +++ b/src/components/settings/PrinterAgentSettingsPanel.jsx @@ -120,7 +120,14 @@ class AgentQrCode extends PureComponent { } function renderPrinterDiagnostics(printer, live) { - if (!live) { + const isOnline = printer?.online ?? (live ? !live.unreachable && live.status !== 'offline' : false); + const isOpen = printer?.open ?? (live?.errors?.headOpen || live?.headOpen || false); + const isPaused = printer?.pause ?? (live?.errors?.pause || live?.pause || false); + const isError = printer?.error ?? (live?.errors?.other || live?.error || false); + const isUnreachable = !isOnline || (live?.errors?.unreachable || false); + const labelLength = printer?.labelLength ?? live?.labelLength; + + if (!isOnline) { return ( , ); } - if (errors.pause) { + if (isPaused) { errorChips.push( , ); } - if (errors.unreachable) { + if (isUnreachable) { errorChips.push( , ); } - if (errors.other) { + if (isError) { errorChips.push( - {live.labelLength != null ? ( + {labelLength != null ? ( )} - {/* Live connection state */} - {clientState ? ( - - ) : null} - {/* Agent version */} {agent.agentversion ? ( @@ -931,6 +945,30 @@ export default class PrinterAgentSettingsPanel extends PureComponent { + {/* Test print button */} + + + + + + {/* Enabled toggle switch */}