| @@ -517,8 +517,8 @@ def generate_zpl_dataflex( | |||
| ) -> str: | |||
| """ | |||
| Row 1 (from zero): QR code, then item name (rotated 90°). | |||
| Row 2: smaller Lot, then expiry at the next X, then item code. | |||
| Text is ^A@R (90° CW); the next line under Lot is +X, not +Y. | |||
| Row 2: expiry, then Lot at the next X, then item code. | |||
| Text is ^A@R (90° CW); the next line under expiry is +X, not +Y. | |||
| Label and QR use lotNo from API when present, else batch_no (Bxxxxx). | |||
| Light preprint (~JA/~RO) is sent before labels; full ~JR recovery is only for「打袋重設」. | |||
| """ | |||
| @@ -539,9 +539,9 @@ def generate_zpl_dataflex( | |||
| host_id = _dataflex_host_identification_sgd_prefix(job_order_id) | |||
| if exp_esc: | |||
| row2 = f"""^FO0,200 | |||
| ^A@R,40,40,{font_regular}^FD{label_esc}^FS | |||
| ^FO42,200 | |||
| ^A@R,40,40,{font_regular}^FD{exp_esc}^FS | |||
| ^FO42,200 | |||
| ^A@R,40,40,{font_regular}^FD{label_esc}^FS | |||
| ^FO88,200 | |||
| ^A@R,88,88,{font_bold}^FD{code}^FS""" | |||
| else: | |||
| @@ -700,8 +700,8 @@ def generate_zpl_label_small( | |||
| else: | |||
| qr_data = f"QA,{batch_no}" | |||
| exp_zpl = f""" | |||
| ^FO150,230 | |||
| ^A@N,36,36,{font}^FD{exp_esc}^FS""" if exp_esc else "" | |||
| ^FO150,194 | |||
| ^A@N,25,25,{font}^FD{exp_esc}^FS""" if exp_esc else "" | |||
| return f"""^XA | |||
| ^CI28 | |||
| ^PW500 | |||
| @@ -712,9 +712,9 @@ def generate_zpl_label_small( | |||
| ^FO10,110 | |||
| ^BQN,2,6^FD{qr_data}^FS | |||
| ^FO150,110 | |||
| ^A@N,48,48,{font}^FD{code}^FS | |||
| ^FO150,175 | |||
| ^A@N,40,40,{font}^FD{label_line2_esc}^FS{exp_zpl} | |||
| ^A@N,34,34,{font}^FD{code}^FS | |||
| ^FO150,156 | |||
| ^A@N,28,28,{font}^FD{label_line2_esc}^FS{exp_zpl} | |||
| ^XZ""" | |||
| @@ -724,9 +724,10 @@ LABEL_IMAGE_W = 720 | |||
| LABEL_IMAGE_H = 530 | |||
| LABEL_PADDING = 23 | |||
| LABEL_FONT_NAME_SIZE = 42 | |||
| LABEL_FONT_CODE_SIZE = 49 | |||
| LABEL_FONT_BATCH_SIZE = 34 | |||
| LABEL_FONT_EXPIRY_SIZE = 34 | |||
| # Item code / lot / expiry ~70% of original size so all three fit under the name. | |||
| LABEL_FONT_CODE_SIZE = 34 | |||
| LABEL_FONT_BATCH_SIZE = 24 | |||
| LABEL_FONT_EXPIRY_SIZE = 24 | |||
| LABEL_QR_SIZE = 210 | |||
| @@ -1229,8 +1230,8 @@ def save_laser_last_count(date_str: str, count: int) -> None: | |||
| LASER_PUSH_INTERVAL = 2 # seconds between pushes (like sample script) | |||
| # Click row with 激光機 selected: send this many times, delay between sends (not after last). | |||
| LASER_ROW_SEND_COUNT = 3 | |||
| # Click row with 激光機 selected: one payload. Sending 3 queued 2–3 old bags after a job change. | |||
| LASER_ROW_SEND_COUNT = 1 | |||
| LASER_ROW_SEND_DELAY_SEC = 3 | |||
| @@ -2272,6 +2273,17 @@ def open_dataflex_stop_window( | |||
| def stop() -> None: | |||
| stop_event.set() | |||
| # Cancel labels already sitting in the DataFlex buffer so the next job | |||
| # does not print 2–3 leftover bags of the previous job. | |||
| ip, port = session.printer_ip, session.printer_port | |||
| def _cancel_buffer() -> None: | |||
| try: | |||
| send_dataflex_preprint_reset(ip, port, force=True) | |||
| except Exception: | |||
| pass | |||
| threading.Thread(target=_cancel_buffer, daemon=True).start() | |||
| stop_win_ref[0] = None | |||
| clear_topmost() | |||
| try: | |||