From 7b1de24dfb0df336b881bf97f0255f2a563f1014 Mon Sep 17 00:00:00 2001 From: M_Kececi Date: Tue, 31 Mar 2026 14:54:19 +0300 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- svc/queries/order_write.go | 52 ++++++++++++++++++++++++++----- svc/queries/productsecondcolor.go | 2 +- ui/src/pages/OrderEntry.vue | 18 +++++++++++ ui/src/stores/orderentryStore.js | 41 +++++++++++++++++++----- 4 files changed, 97 insertions(+), 16 deletions(-) diff --git a/svc/queries/order_write.go b/svc/queries/order_write.go index 6b7f218..2c22eab 100644 --- a/svc/queries/order_write.go +++ b/svc/queries/order_write.go @@ -512,10 +512,28 @@ func ValidateItemVariant(tx *sql.Tx, ln models.OrderDetail) error { SELECT 1 FROM BAGGI_V3.dbo.prItemVariant V WITH (NOLOCK) WHERE ISNULL(LTRIM(RTRIM(V.ItemCode)),'') = @p1 - AND ISNULL(LTRIM(RTRIM(V.ColorCode)),'') = @p2 - AND UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(V.ItemDim1Code)),'') ,' ', ''), 'YAS', ''), 'Y', '')) - = UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(@p3)),'') ,' ', ''), 'YAS', ''), 'Y', '')) - AND ISNULL(LTRIM(RTRIM(V.ItemDim2Code)),'') = @p4 + AND ( + ( + ISNULL(LTRIM(RTRIM(V.ColorCode)),'') = @p2 + AND ( + ISNULL(LTRIM(RTRIM(@p4)),'') = '' + OR ISNULL(LTRIM(RTRIM(V.ItemDim2Code)),'') = @p4 + ) + ) + OR ( + ISNULL(LTRIM(RTRIM(@p4)),'') = '' + AND ISNULL(LTRIM(RTRIM(V.ItemDim2Code)),'') = @p2 + ) + ) + AND ( + UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(V.ItemDim1Code)),'') ,' ', ''), 'YAS', ''), 'Y', '')) + = UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(@p3)),'') ,' ', ''), 'YAS', ''), 'Y', '')) + OR ( + TRY_CONVERT(INT, NULLIF(UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(V.ItemDim1Code)),'') ,' ', ''), 'YAS', ''), 'Y', '')), '')) + = TRY_CONVERT(INT, NULLIF(UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(@p3)),'') ,' ', ''), 'YAS', ''), 'Y', '')), '')) + AND TRY_CONVERT(INT, NULLIF(UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(@p3)),'') ,' ', ''), 'YAS', ''), 'Y', '')), '')) IS NOT NULL + ) + ) ) THEN 1 ELSE 0 END `, item, color, dim1, dim2).Scan(&exists) @@ -555,10 +573,28 @@ func ValidateOrderVariants(db *sql.DB, lines []models.OrderDetail) ([]models.Inv SELECT 1 FROM BAGGI_V3.dbo.prItemVariant V WITH (NOLOCK) WHERE ISNULL(LTRIM(RTRIM(V.ItemCode)),'') = @p1 - AND ISNULL(LTRIM(RTRIM(V.ColorCode)),'') = @p2 - AND UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(V.ItemDim1Code)),'') ,' ', ''), 'YAS', ''), 'Y', '')) - = UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(@p3)),'') ,' ', ''), 'YAS', ''), 'Y', '')) - AND ISNULL(LTRIM(RTRIM(V.ItemDim2Code)),'') = @p4 + AND ( + ( + ISNULL(LTRIM(RTRIM(V.ColorCode)),'') = @p2 + AND ( + ISNULL(LTRIM(RTRIM(@p4)),'') = '' + OR ISNULL(LTRIM(RTRIM(V.ItemDim2Code)),'') = @p4 + ) + ) + OR ( + ISNULL(LTRIM(RTRIM(@p4)),'') = '' + AND ISNULL(LTRIM(RTRIM(V.ItemDim2Code)),'') = @p2 + ) + ) + AND ( + UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(V.ItemDim1Code)),'') ,' ', ''), 'YAS', ''), 'Y', '')) + = UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(@p3)),'') ,' ', ''), 'YAS', ''), 'Y', '')) + OR ( + TRY_CONVERT(INT, NULLIF(UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(V.ItemDim1Code)),'') ,' ', ''), 'YAS', ''), 'Y', '')), '')) + = TRY_CONVERT(INT, NULLIF(UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(@p3)),'') ,' ', ''), 'YAS', ''), 'Y', '')), '')) + AND TRY_CONVERT(INT, NULLIF(UPPER(REPLACE(REPLACE(REPLACE(ISNULL(LTRIM(RTRIM(@p3)),'') ,' ', ''), 'YAS', ''), 'Y', '')), '')) IS NOT NULL + ) + ) ) THEN 1 ELSE 0 END `) if err != nil { diff --git a/svc/queries/productsecondcolor.go b/svc/queries/productsecondcolor.go index 9491208..8be5a41 100644 --- a/svc/queries/productsecondcolor.go +++ b/svc/queries/productsecondcolor.go @@ -20,5 +20,5 @@ GROUP BY prItemVariant.ItemDim2Code, prItemVariant.ColorCode, ColorDesc.ColorDescription -ORDER BY ItemDim2Code +ORDER BY prItemVariant.ItemDim2Code ` diff --git a/ui/src/pages/OrderEntry.vue b/ui/src/pages/OrderEntry.vue index 4f3efcb..bfdbda9 100644 --- a/ui/src/pages/OrderEntry.vue +++ b/ui/src/pages/OrderEntry.vue @@ -2970,6 +2970,20 @@ async function onColor2Change(colorCode2) { =========================================================== */ const bedenStock = ref([]) // Görsel tablo için stok listesi const stockMap = ref({}) // { "48": 12, "50": 7, ... } şeklinde key-value map + +function warnIfSecondColorMissing() { + const hasSecondColorOptions = Array.isArray(renkOptions2.value) && renkOptions2.value.length > 0 + const secondColorEmpty = !String(form.renk2 || '').trim() + + if (hasSecondColorOptions && secondColorEmpty) { + $q.notify({ + type: 'warning', + message: 'Bu model/renk için 2. renk seçimi önerilir.', + position: 'top-right' + }) + } +} + const onSaveOrUpdateRow = async () => { if (!hasRowMutationPermission()) { notifyNoPermission( @@ -2980,6 +2994,8 @@ const onSaveOrUpdateRow = async () => { return } + warnIfSecondColorMissing() + await orderStore.saveOrUpdateRowUnified({ form, @@ -3033,6 +3049,8 @@ const onSaveAndNextColor = async () => { return } + warnIfSecondColorMissing() + const ok = await orderStore.saveOrUpdateRowUnified({ form, recalcVat: typeof recalcVat === 'function' ? recalcVat : null, diff --git a/ui/src/stores/orderentryStore.js b/ui/src/stores/orderentryStore.js index 51db494..dcc34d3 100644 --- a/ui/src/stores/orderentryStore.js +++ b/ui/src/stores/orderentryStore.js @@ -3069,20 +3069,22 @@ export const useOrderEntryStore = defineStore('orderentry', { } // ======================================================= - // 🧪 PRE-VALIDATE — prItemVariant ön kontrol - // - invalid varsa CREATE/UPDATE ÇALIŞMAZ + // 🧪 PRE-VALIDATE — prItemVariant ön kontrol (NEW + EDIT) + // - invalid varsa CREATE/UPDATE çalışmaz // ======================================================= - if (!isNew) { - const linesToValidate = lines.filter( - l => l._deleteSignal === true || l._dirty === true || !l.OrderLineID - ) + const linesToValidate = lines.filter(l => + Number(l?.Qty1 || 0) > 0 && + l?._deleteSignal !== true && + String(l?.ItemCode || '').trim() !== '' + ) + if (linesToValidate.length > 0) { const v = await api.post('/order/validate', { header, lines: linesToValidate }) const invalid = v?.data?.invalid || [] if (invalid.length > 0) { await this.showInvalidVariantDialog?.($q, invalid) - return // ❌ update ÇALIŞMAZ + return // ❌ create/update ÇALIŞMAZ } } @@ -3245,6 +3247,31 @@ export const useOrderEntryStore = defineStore('orderentry', { } catch (err) { console.error('❌ submitAllReal:', err) + const data = err?.response?.data || {} + const status = Number(err?.response?.status || 0) + if (err?.response?.status === 400 && data?.code === 'INVALID_ITEM_VARIANT') { + const oneInvalid = [{ + clientKey: data?.clientKey || '', + itemCode: data?.itemCode || '', + colorCode: data?.colorCode || '', + dim1: data?.dim1 || '', + dim2: data?.dim2 || '', + qty1: 0, + reason: data?.message || 'Tanımsız ürün kombinasyonu' + }] + await this.showInvalidVariantDialog?.($q, oneInvalid) + return + } + + if (status === 524) { + $q.notify({ + type: 'warning', + timeout: 36000, + message: 'Sunucu zaman aşımına uğradı (524). Sipariş kısmen kaydedilmiş olabilir; önce listeden kontrol edin, sonra tekrar deneyin.' + }) + return + } + $q.notify({ type: 'negative', message: