diff --git a/ui/quasar.config.js.temporary.compiled.1771579736454.mjs b/ui/quasar.config.js.temporary.compiled.1771597158912.mjs
similarity index 100%
rename from ui/quasar.config.js.temporary.compiled.1771579736454.mjs
rename to ui/quasar.config.js.temporary.compiled.1771597158912.mjs
diff --git a/ui/src/pages/OrderProductionUpdate.vue b/ui/src/pages/OrderProductionUpdate.vue
index 71d5058..86e2299 100644
--- a/ui/src/pages/OrderProductionUpdate.vue
+++ b/ui/src/pages/OrderProductionUpdate.vue
@@ -26,6 +26,15 @@
readonly
/>
+
+
+
Satiri Guncelle
@@ -200,6 +209,7 @@ const cariLabel = computed(() => {
})
const rows = ref([])
+const descFilter = ref('')
const productOptions = ref([])
const productSearch = ref('')
const rowSavingId = ref('')
@@ -209,6 +219,7 @@ const columns = [
{ name: 'OldColor', label: 'Eski Urun Rengi', field: 'OldColor', align: 'left', sortable: true, style: 'min-width:120px;white-space:nowrap', headerStyle: 'min-width:120px;white-space:nowrap' },
{ name: 'OldDim2', label: 'Eski 2. Renk', field: 'OldDim2', align: 'left', sortable: true, style: 'min-width:110px;white-space:nowrap', headerStyle: 'min-width:110px;white-space:nowrap' },
{ name: 'OldDesc', label: 'Eski Aciklama', field: 'OldDesc', align: 'left', sortable: false, style: 'min-width:180px;white-space:nowrap', headerStyle: 'min-width:180px;white-space:nowrap' },
+ { name: 'OldSizes', label: 'Bedenler', field: 'OldSizesLabel', align: 'left', sortable: false, style: 'min-width:160px;white-space:nowrap', headerStyle: 'min-width:160px;white-space:nowrap' },
{ name: 'NewItemCode', label: 'Yeni Urun Kodu', field: 'NewItemCode', align: 'left', sortable: false, style: 'min-width:190px;', headerStyle: 'min-width:190px;' },
{ name: 'NewColor', label: 'Yeni Urun Rengi', field: 'NewColor', align: 'left', sortable: false, style: 'min-width:160px;', headerStyle: 'min-width:160px;' },
{ name: 'NewDim2', label: 'Yeni 2. Renk', field: 'NewDim2', align: 'left', sortable: false, style: 'min-width:160px;', headerStyle: 'min-width:160px;' },
@@ -227,13 +238,7 @@ watch(orderHeaderID, async (id) => {
watch(
() => store.items,
(items) => {
- rows.value = (items || []).map(item => ({
- ...item,
- NewItemCode: '',
- NewColor: '',
- NewDim2: '',
- NewDesc: ''
- }))
+ rows.value = groupItems(items || [])
},
{ immediate: true }
)
@@ -260,6 +265,14 @@ const filteredProducts = computed(() => {
).slice(0, 50)
})
+const filteredRows = computed(() => {
+ const needle = String(descFilter.value || '').toLowerCase().trim()
+ if (!needle) return rows.value
+ return rows.value.filter(r =>
+ String(r?.OldDesc || '').toLowerCase().includes(needle)
+ )
+})
+
function onSelectProduct (row, code) {
productSearch.value = ''
onNewItemChange(row, code)
@@ -310,14 +323,83 @@ function isValidModelCode (value) {
return /^[A-Z][0-9]{3}-[A-Z]{3}[0-9]{5}$/.test(text)
}
+function buildGroupKey (item) {
+ const parts = [
+ String(item?.OldItemCode || '').trim(),
+ String(item?.OldColor || '').trim(),
+ String(item?.OldDim2 || '').trim(),
+ String(item?.OldDesc || '').trim(),
+ String(item?.OldDim3 || '').trim()
+ ]
+ return parts.join('||')
+}
+
+function formatSizes (sizeMap) {
+ const entries = Object.entries(sizeMap || {})
+ if (!entries.length) return { list: [], label: '-' }
+ entries.sort((a, b) => String(a[0]).localeCompare(String(b[0])))
+ const label = entries.map(([k, v]) => (v > 1 ? `${k}(${v})` : k)).join(', ')
+ return { list: entries.map(([k]) => k), label }
+}
+
+function groupItems (items) {
+ const map = new Map()
+
+ for (const it of items) {
+ const key = buildGroupKey(it)
+ if (!map.has(key)) {
+ map.set(key, {
+ RowKey: key,
+ OrderHeaderID: it.OrderHeaderID,
+ OldItemCode: it.OldItemCode,
+ OldColor: it.OldColor,
+ OldDim2: it.OldDim2,
+ OldDim3: it.OldDim3,
+ OldDesc: it.OldDesc,
+ OrderLineIDs: [],
+ OldSizes: [],
+ OldSizesLabel: '',
+ NewItemCode: '',
+ NewColor: '',
+ NewDim2: '',
+ NewDesc: '',
+ IsVariantMissing: !!it.IsVariantMissing
+ })
+ }
+
+ const g = map.get(key)
+ if (it?.OrderLineID) g.OrderLineIDs.push(it.OrderLineID)
+
+ const size = String(it?.OldDim1 || '').trim()
+ if (size !== '') {
+ g.__sizeMap = g.__sizeMap || {}
+ g.__sizeMap[size] = (g.__sizeMap[size] || 0) + 1
+ }
+ if (it?.IsVariantMissing) g.IsVariantMissing = true
+ }
+
+ const out = []
+ for (const g of map.values()) {
+ const sizes = formatSizes(g.__sizeMap || {})
+ g.OldSizes = sizes.list
+ g.OldSizesLabel = sizes.label
+ delete g.__sizeMap
+ out.push(g)
+ }
+
+ return out
+}
+
function buildPayloadLines () {
- return rows.value.map(r => ({
- OrderLineID: r.OrderLineID,
- NewItemCode: String(r.NewItemCode || '').trim(),
- NewColor: String(r.NewColor || '').trim(),
- NewDim2: String(r.NewDim2 || '').trim(),
- NewDesc: String(r.NewDesc || '').trim()
- }))
+ return rows.value.flatMap(r =>
+ (r.OrderLineIDs || []).map(id => ({
+ OrderLineID: id,
+ NewItemCode: String(r.NewItemCode || '').trim(),
+ NewColor: String(r.NewColor || '').trim(),
+ NewDim2: String(r.NewDim2 || '').trim(),
+ NewDesc: String(r.NewDesc || '').trim()
+ }))
+ )
}
async function refreshAll () {
@@ -327,22 +409,31 @@ async function refreshAll () {
}
async function onRowSubmit (row) {
- const line = {
- OrderLineID: row.OrderLineID,
+ const baseLine = {
NewItemCode: String(row.NewItemCode || '').trim(),
NewColor: String(row.NewColor || '').trim(),
NewDim2: String(row.NewDim2 || '').trim(),
NewDesc: String(row.NewDesc || '').trim()
}
- if (!line.NewItemCode || !line.NewColor) {
+ if (!baseLine.NewItemCode || !baseLine.NewColor) {
$q.notify({ type: 'negative', message: 'Yeni urun ve renk zorunludur.' })
return
}
- rowSavingId.value = row.OrderLineID
+ const lines = (row.OrderLineIDs || []).map(id => ({
+ OrderLineID: id,
+ ...baseLine
+ }))
+
+ if (!lines.length) {
+ $q.notify({ type: 'negative', message: 'Satir bulunamadi.' })
+ return
+ }
+
+ rowSavingId.value = row.RowKey
try {
- const validate = await store.validateUpdates(orderHeaderID.value, [line])
+ const validate = await store.validateUpdates(orderHeaderID.value, lines)
const missingCount = validate?.missingCount || 0
if (missingCount > 0) {
const missingList = (validate?.missing || []).map(v => (
@@ -355,13 +446,13 @@ async function onRowSubmit (row) {
ok: { label: 'Ekle ve Guncelle', color: 'primary' },
cancel: { label: 'Vazgec', flat: true }
}).onOk(async () => {
- await store.applyUpdates(orderHeaderID.value, [line], true)
+ await store.applyUpdates(orderHeaderID.value, lines, true)
await store.fetchItems(orderHeaderID.value)
})
return
}
- await store.applyUpdates(orderHeaderID.value, [line], false)
+ await store.applyUpdates(orderHeaderID.value, lines, false)
await store.fetchItems(orderHeaderID.value)
} catch (err) {
$q.notify({ type: 'negative', message: 'Islem basarisiz.' })
diff --git a/ui/src/stores/orderentryStore.js b/ui/src/stores/orderentryStore.js
index 7963a5e..cbd033a 100644
--- a/ui/src/stores/orderentryStore.js
+++ b/ui/src/stores/orderentryStore.js
@@ -2684,17 +2684,18 @@ export const useOrderEntryStore = defineStore('orderentry', {
// 🧪 PRE-VALIDATE — prItemVariant ön kontrol
// - invalid varsa CREATE/UPDATE ÇALIŞMAZ
// =======================================================
- const linesToValidate =
- isNew
- ? lines
- : lines.filter(l => l._deleteSignal === true || l._dirty === true || !l.OrderLineID)
+ if (!isNew) {
+ const linesToValidate = lines.filter(
+ l => l._deleteSignal === true || l._dirty === true || !l.OrderLineID
+ )
- const v = await api.post('/order/validate', { header, lines: linesToValidate })
- const invalid = v?.data?.invalid || []
+ 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 // ❌ create / update ÇALIŞMAZ
+ if (invalid.length > 0) {
+ await this.showInvalidVariantDialog?.($q, invalid)
+ return // ❌ update ÇALIŞMAZ
+ }
}
console.log('📤 submitAllReal payload', {