diff --git a/server/src/printer/format-utils.ts b/server/src/printer/format-utils.ts index a24d2ad..c57c590 100644 --- a/server/src/printer/format-utils.ts +++ b/server/src/printer/format-utils.ts @@ -60,11 +60,15 @@ export const formatUtils = { * @param bannerChar Character to use for the banner * @returns Array of formatted lines */ - formatSection(header: string, content: string, bannerChar: string = '='): string[] { - return [ + formatSection(header: string, content: string, bannerChar: string = '=', trailingNewline: boolean = false): string[] { + const parts = [ this.formatCheckbox(header), this.createBanner(bannerChar), content, ]; + if (trailingNewline) { + parts.push(''); + } + return parts; } }; \ No newline at end of file diff --git a/server/src/printer/printer-constants.ts b/server/src/printer/printer-constants.ts new file mode 100644 index 0000000..e3a5cce --- /dev/null +++ b/server/src/printer/printer-constants.ts @@ -0,0 +1,33 @@ +export const PRINTER_CONFIG = { + ENCODING: 'CP437', + DEFAULT_USER_ID: 1, +} as const; + +export const FONT_SIZES = { + NORMAL: { width: 1, height: 1 }, // 0.08 x 2.13 mm + SMALL: { width: 1, height: 1 }, // Same as normal for now, but can be adjusted if needed + LARGE: { width: 2, height: 2 }, // Double size +} as const; + +export const BARCODE_CONFIG = { + TYPE: 'CODE128', + DIMENSIONS: { width: 2, height: 50 }, +} as const; + +export const PAPER_CONFIG = { + BANNER_LENGTH: 32, + CUT_LINES: 2, +} as const; + +export const ALIGNMENT = { + CENTER: 'ct', + LEFT: 'lt', +} as const; + +export const FONT = { + DEFAULT: 'a', +} as const; + +export const STYLE = { + BOLD: 'b', +} as const; \ No newline at end of file diff --git a/server/src/printer/serial-printer.ts b/server/src/printer/serial-printer.ts index 7df2e59..8c8269e 100644 --- a/server/src/printer/serial-printer.ts +++ b/server/src/printer/serial-printer.ts @@ -5,6 +5,15 @@ import { StepRepository, PrintHistoryRepository } from '../db/repositories'; import { Knex } from 'knex'; import logger from '../logger'; import { formatUtils } from './format-utils'; +import { + PRINTER_CONFIG, + FONT_SIZES, + BARCODE_CONFIG, + PAPER_CONFIG, + ALIGNMENT, + FONT, + STYLE, +} from './printer-constants'; export class SerialPrinter implements PrinterInterface { private device: USB | null = null; @@ -32,7 +41,7 @@ export class SerialPrinter implements PrinterInterface { }); }); - const options = { encoding: 'CP437' }; + const options = { encoding: PRINTER_CONFIG.ENCODING }; this.printer = new Printer(this.device, options); logger.info('Printer initialized successfully'); } catch (error) { @@ -54,18 +63,18 @@ export class SerialPrinter implements PrinterInterface { try { // Print header with task ID as barcode await this.printer - .font('a') - .align('ct') - .style('b') - .size(1, 1) // Normal size (0.08 x 2.13 mm) + .font(FONT.DEFAULT) + .align(ALIGNMENT.CENTER) + .style(STYLE.BOLD) + .size(FONT_SIZES.LARGE.width, FONT_SIZES.LARGE.height) .text(formatUtils.formatCheckbox(`Task: ${task.name}`)) - .text(formatUtils.createBanner('=', 32)) + .text(formatUtils.createBanner('=', PAPER_CONFIG.BANNER_LENGTH)) .text('') - .align('lt'); + .align(ALIGNMENT.LEFT); // Print task ID as barcode await this.printer - .barcode(task.id.toString(), 'CODE128', { width: 2, height: 50 }) + .barcode(task.id.toString(), BARCODE_CONFIG.TYPE, BARCODE_CONFIG.DIMENSIONS) .text('') .text(''); @@ -79,27 +88,27 @@ export class SerialPrinter implements PrinterInterface { ); await this.printer - .size(1, 1) // Normal size for step header - .text(stepSection[0]) // Header with checkbox - .text(stepSection[1]) // Banner - .size(0, 0) // Smaller size for instructions - .text(stepSection[3]) // Instructions + .size(FONT_SIZES.NORMAL.width, FONT_SIZES.NORMAL.height) + .text(stepSection[0]) + .text(stepSection[1]) + .size(FONT_SIZES.SMALL.width, FONT_SIZES.SMALL.height) + .text(stepSection[3]) .text(''); // Print step ID as barcode await this.printer - .barcode(step.id.toString(), 'CODE128', { width: 2, height: 50 }) + .barcode(step.id.toString(), BARCODE_CONFIG.TYPE, BARCODE_CONFIG.DIMENSIONS) .text(''); } await this.printer - .cut(true, 2) + .cut(true, PAPER_CONFIG.CUT_LINES) .close(); logger.info(`Printed task ${task.id}`); await this.printHistoryRepo.create({ - user_id: 1, // Replace with actual user ID if available + user_id: PRINTER_CONFIG.DEFAULT_USER_ID, task_id: task.id, printed_at: new Date(), }); @@ -125,29 +134,29 @@ export class SerialPrinter implements PrinterInterface { ); await this.printer - .font('a') - .align('ct') - .style('b') - .size(1, 1) // Normal size (0.08 x 2.13 mm) - .text(stepSection[0]) // Header with checkbox - .text(stepSection[1]) // Banner + .font(FONT.DEFAULT) + .align(ALIGNMENT.CENTER) + .style(STYLE.BOLD) + .size(FONT_SIZES.LARGE.width, FONT_SIZES.LARGE.height) + .text(stepSection[0]) + .text(stepSection[1]) .text('') - .align('lt') - .size(0, 0) // Smaller size for instructions - .text(stepSection[3]) // Instructions + .align(ALIGNMENT.LEFT) + .size(FONT_SIZES.NORMAL.width, FONT_SIZES.NORMAL.height) + .text(stepSection[3]) .text('') .text(''); // Print step ID as barcode await this.printer - .barcode(step.id.toString(), 'CODE128', { width: 2, height: 50 }) - .cut(true, 2) + .barcode(step.id.toString(), BARCODE_CONFIG.TYPE, BARCODE_CONFIG.DIMENSIONS) + .cut(true, PAPER_CONFIG.CUT_LINES) .close(); logger.info(`Printed step ${step.id}`); await this.printHistoryRepo.create({ - user_id: 1, // Replace with actual user ID if available + user_id: PRINTER_CONFIG.DEFAULT_USER_ID, step_id: step.id, printed_at: new Date(), }); diff --git a/server/src/printer/test-printer.ts b/server/src/printer/test-printer.ts index 1f87a36..118b358 100644 --- a/server/src/printer/test-printer.ts +++ b/server/src/printer/test-printer.ts @@ -41,7 +41,8 @@ export class TestPrinter implements Printer { formatUtils.formatSection( formatUtils.formatStepHeader(step.name, index + 1, task.name, true), step.instructions, - '-' + '-', + true, ) ).flat(), ].join('\n');