From 8a7d0167fddacbccd77fdc28027beae84ceac9a2 Mon Sep 17 00:00:00 2001 From: Fai Luk Date: Sat, 3 Oct 2026 00:52:15 +0800 Subject: [PATCH] fixing the schedule_sync_log.query too long error added version 4 of PO item label --- .../com/ffii/fpsms/m18/model/SyncResult.kt | 16 +- .../m18/service/M18DeliveryOrderService.kt | 6 +- .../m18/service/M18PurchaseOrderService.kt | 6 +- .../fpsms/modules/common/SettingNames.java | 2 +- .../scheduler/service/SchedulerService.kt | 13 +- .../service/PurchaseOrderService.kt | 2 +- .../stock/service/PoItemLabelTemplate.kt | 3 + .../stock/service/StockInLineService.kt | 14 +- .../03_allow_version_4.sql | 7 + .../01_widen_query_and_error_message.sql | 8 + .../resources/qrCodeLabel/poItemPDF_v4.jrxml | 172 ++++++++++++++++++ 11 files changed, 226 insertions(+), 23 deletions(-) create mode 100644 src/main/resources/db/changelog/changes/20261001_po_item_label_version/03_allow_version_4.sql create mode 100644 src/main/resources/db/changelog/changes/20261002_scheduler_sync_log_text/01_widen_query_and_error_message.sql create mode 100644 src/main/resources/qrCodeLabel/poItemPDF_v4.jrxml diff --git a/src/main/java/com/ffii/fpsms/m18/model/SyncResult.kt b/src/main/java/com/ffii/fpsms/m18/model/SyncResult.kt index 4c4d3340..d0df7074 100644 --- a/src/main/java/com/ffii/fpsms/m18/model/SyncResult.kt +++ b/src/main/java/com/ffii/fpsms/m18/model/SyncResult.kt @@ -1,10 +1,20 @@ package com.ffii.fpsms.m18.model -import java.time.LocalDateTime - data class SyncResult( val totalProcessed: Int, val totalSuccess: Int, val totalFail: Int, val query: String? = null -) \ No newline at end of file +) + +/** + * Bounded suffix for [scheduler_sync_log.query]. Listing every skipped document + * overflows VARCHAR(2000) on a multi-day PO window. + */ +fun skippedNotPendingQuerySuffix(entries: List, previewLimit: Int = 20): String { + if (entries.isEmpty()) return "" + val shown = entries.take(previewLimit) + val hidden = entries.size - shown.size + val more = if (hidden > 0) "; ... +$hidden more" else "" + return " | skipped (not pending, only pending may be overwritten) count=${entries.size}: ${shown.joinToString("; ")}$more" +} \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/m18/service/M18DeliveryOrderService.kt b/src/main/java/com/ffii/fpsms/m18/service/M18DeliveryOrderService.kt index 6bd1d094..34c7f81f 100644 --- a/src/main/java/com/ffii/fpsms/m18/service/M18DeliveryOrderService.kt +++ b/src/main/java/com/ffii/fpsms/m18/service/M18DeliveryOrderService.kt @@ -649,11 +649,7 @@ open class M18DeliveryOrderService( logger.info("--------------------------------------------End - Saving M18 Delivery Order--------------------------------------------") val skippedExistingSuffix = if (skippedList.isNotEmpty()) " | skipped=${skippedList.size}" else "" - val skippedNotPendingSuffix = if (skippedNotPendingList.isNotEmpty()) { - " | skipped (not pending, only pending may be overwritten): ${skippedNotPendingList.joinToString("; ")}" - } else { - "" - } + val skippedNotPendingSuffix = skippedNotPendingQuerySuffix(skippedNotPendingList) return SyncResult( totalProcessed = successList.size + failList.size + skippedList.size + skippedNotPendingList.size, totalSuccess = successList.size, diff --git a/src/main/java/com/ffii/fpsms/m18/service/M18PurchaseOrderService.kt b/src/main/java/com/ffii/fpsms/m18/service/M18PurchaseOrderService.kt index 8dffa5ab..e93bbcd4 100644 --- a/src/main/java/com/ffii/fpsms/m18/service/M18PurchaseOrderService.kt +++ b/src/main/java/com/ffii/fpsms/m18/service/M18PurchaseOrderService.kt @@ -745,11 +745,7 @@ open class M18PurchaseOrderService( logger.info("--------------------------------------------End - Saving M18 Purchase Order--------------------------------------------") val baseQuery = purchaseOrdersWithType?.query ?: "" - val skippedSuffix = if (skippedNotPendingList.isNotEmpty()) { - " | skipped (not pending, only pending may be overwritten): ${skippedNotPendingList.joinToString("; ")}" - } else { - "" - } + val skippedSuffix = skippedNotPendingQuerySuffix(skippedNotPendingList) return SyncResult( totalProcessed = successList.size + failList.size + skippedNotPendingList.size, diff --git a/src/main/java/com/ffii/fpsms/modules/common/SettingNames.java b/src/main/java/com/ffii/fpsms/modules/common/SettingNames.java index 7aad93fc..88b8dfee 100644 --- a/src/main/java/com/ffii/fpsms/modules/common/SettingNames.java +++ b/src/main/java/com/ffii/fpsms/modules/common/SettingNames.java @@ -135,7 +135,7 @@ public abstract class SettingNames { /** JSON: last laser TCP send where printer returned receive (job order no., lot, itemId/stockInLineId, etc.) */ public static final String LASER_PRINT_LAST_RECEIVE_SUCCESS = "LASER_PRINT.lastReceiveSuccess"; - /** PO / stock-in item label: 1 = original, 2 = enlarged, 3 = smaller QR with a larger item name. */ + /** PO / stock-in item label: 1 = original, 2 = enlarged, 3 = smaller QR, 4 = version 3 with the version 1 QR size. */ public static final String LABEL_PO_ITEM_VERSION = "LABEL.poItem.version"; } diff --git a/src/main/java/com/ffii/fpsms/modules/common/scheduler/service/SchedulerService.kt b/src/main/java/com/ffii/fpsms/modules/common/scheduler/service/SchedulerService.kt index de198a67..7322508c 100644 --- a/src/main/java/com/ffii/fpsms/modules/common/scheduler/service/SchedulerService.kt +++ b/src/main/java/com/ffii/fpsms/modules/common/scheduler/service/SchedulerService.kt @@ -87,6 +87,8 @@ open class SchedulerService( const val M18_BOM_SHOP_DEFAULT_CRON: String = "0 0 23 * * *" /** Daily 00:00:15 — process job orders whose planStart was yesterday. */ const val JO_PLAN_START_DEFAULT_CRON: String = "15 0 0 * * *" + /** MySQL TEXT is 65535 bytes; 16000 chars stays under that for utf8mb4. */ + const val SYNC_LOG_TEXT_MAX_CHARS: Int = 16_000 } /** Class logger (was incorrectly wired to JwtTokenUtil, so all scheduler lines showed under that category). */ @@ -730,14 +732,21 @@ open class SchedulerService( recordsProcessed = result?.totalProcessed ?: 0, recordsSaved = result?.totalSuccess ?: 0, recordsFailed = result?.totalFail ?: 0, - errorMessage = error, - query = result?.query ?: "", + errorMessage = fitSyncLogText(error), + query = fitSyncLogText(result?.query ?: ""), startTime = start, endTime = LocalDateTime.now() ) schedulerSyncLogRepository.save(log) } + private fun fitSyncLogText(value: String?): String? { + if (value == null || value.length <= SYNC_LOG_TEXT_MAX_CHARS) return value + val marker = "...(truncated, length=${value.length})" + logger.warn("scheduler_sync_log text truncated from {} to {} characters", value.length, SYNC_LOG_TEXT_MAX_CHARS) + return value.take((SYNC_LOG_TEXT_MAX_CHARS - marker.length).coerceAtLeast(0)) + marker + } + open fun getM18Dos2() { logger.info("DO Scheduler 2 - DO") val currentTime = LocalDateTime.now() diff --git a/src/main/java/com/ffii/fpsms/modules/purchaseOrder/service/PurchaseOrderService.kt b/src/main/java/com/ffii/fpsms/modules/purchaseOrder/service/PurchaseOrderService.kt index d90a7daa..039f0228 100644 --- a/src/main/java/com/ffii/fpsms/modules/purchaseOrder/service/PurchaseOrderService.kt +++ b/src/main/java/com/ffii/fpsms/modules/purchaseOrder/service/PurchaseOrderService.kt @@ -103,7 +103,7 @@ open fun getPoSummariesByIds(ids: List): List { orderDate = it["orderDate"] as LocalDateTime?, estimatedArrivalDate = it["estimatedArrivalDate"] as LocalDateTime?, supplierName = it["supplierName"] as String?, - escalated = (it["escalated"] as Boolean?) ?: false, + escalated = it["escalated"] == 1L, ) } } diff --git a/src/main/java/com/ffii/fpsms/modules/stock/service/PoItemLabelTemplate.kt b/src/main/java/com/ffii/fpsms/modules/stock/service/PoItemLabelTemplate.kt index d0228bf0..f4dcf00e 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/service/PoItemLabelTemplate.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/service/PoItemLabelTemplate.kt @@ -9,6 +9,7 @@ object PoItemLabelTemplate { const val V1 = "qrCodeLabel/poItemPDF.jrxml" const val V2 = "qrCodeLabel/poItemPDF_v2.jrxml" const val V3 = "qrCodeLabel/poItemPDF_v3.jrxml" + const val V4 = "qrCodeLabel/poItemPDF_v4.jrxml" fun version(settingsService: SettingsService): Int { val raw = settingsService.findByName(SettingNames.LABEL_PO_ITEM_VERSION) @@ -18,6 +19,7 @@ object PoItemLabelTemplate { return when (raw) { "2" -> 2 "3" -> 3 + "4" -> 4 else -> 1 } } @@ -25,6 +27,7 @@ object PoItemLabelTemplate { fun path(version: Int): String = when (version) { 2 -> V2 3 -> V3 + 4 -> V4 else -> V1 } diff --git a/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt b/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt index 800dacfd..446fa208 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/service/StockInLineService.kt @@ -650,13 +650,15 @@ open class StockInLineService( open fun updatePurchaseOrderStatus(po : PurchaseOrder) : PurchaseOrder { val pols = polRepository.findAllByPurchaseOrderIdAndDeletedIsFalse(po.id!!) - var newStatus = PurchaseOrderStatus.PENDING - if (pols.isNotEmpty()) { - newStatus = if (pols.any { pol-> pol.status != PurchaseOrderLineStatus.COMPLETED }) { - PurchaseOrderStatus.RECEIVING - } else { + // A line that was never received, or whose stock-in rows were all removed before putaway, is pending. + // Receiving only while some line is still receiving or already completed. + val newStatus = when { + pols.isEmpty() || pols.all { it.status == null || it.status == PurchaseOrderLineStatus.PENDING } -> + PurchaseOrderStatus.PENDING + pols.all { it.status == PurchaseOrderLineStatus.COMPLETED } -> PurchaseOrderStatus.COMPLETED - } + else -> + PurchaseOrderStatus.RECEIVING } po.apply { status = newStatus diff --git a/src/main/resources/db/changelog/changes/20261001_po_item_label_version/03_allow_version_4.sql b/src/main/resources/db/changelog/changes/20261001_po_item_label_version/03_allow_version_4.sql new file mode 100644 index 00000000..30cafc5c --- /dev/null +++ b/src/main/resources/db/changelog/changes/20261001_po_item_label_version/03_allow_version_4.sql @@ -0,0 +1,7 @@ +--liquibase formatted sql +--changeset fpsms:20261002_po_item_label_version_allow_4 + +UPDATE `settings` +SET `type` = '1/2/3/4' +WHERE `name` = 'LABEL.poItem.version' + AND `type` IN ('1/2', '1/2/3'); diff --git a/src/main/resources/db/changelog/changes/20261002_scheduler_sync_log_text/01_widen_query_and_error_message.sql b/src/main/resources/db/changelog/changes/20261002_scheduler_sync_log_text/01_widen_query_and_error_message.sql new file mode 100644 index 00000000..6b682cf6 --- /dev/null +++ b/src/main/resources/db/changelog/changes/20261002_scheduler_sync_log_text/01_widen_query_and_error_message.sql @@ -0,0 +1,8 @@ +-- liquibase formatted sql +-- changeset fpsms:20261002-scheduler-sync-log-text + +-- PO sync stores the M18 conds plus skipped PO codes. VARCHAR(2000) / VARCHAR(1024) +-- reject that insert (MySQL 1406) and the scheduled task fails after the sync. +ALTER TABLE `fpsmsdb`.`scheduler_sync_log` + MODIFY COLUMN `query` TEXT NULL, + MODIFY COLUMN `errorMessage` TEXT NULL; diff --git a/src/main/resources/qrCodeLabel/poItemPDF_v4.jrxml b/src/main/resources/qrCodeLabel/poItemPDF_v4.jrxml new file mode 100644 index 00000000..7125b95a --- /dev/null +++ b/src/main/resources/qrCodeLabel/poItemPDF_v4.jrxml @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +