Merge remote-tracking branch 'origin/master'

This commit is contained in:
M_Kececi
2026-02-20 17:47:10 +03:00
parent 66df9b0f10
commit ac55f5a96c
3 changed files with 125 additions and 33 deletions

View File

@@ -26,6 +26,15 @@
readonly readonly
/> />
</div> </div>
<div class="col-3">
<q-input
v-model="descFilter"
label="Aciklama Ara"
filled
dense
clearable
/>
</div>
<div class="col-2"> <div class="col-2">
<q-input <q-input
:model-value="header?.OrderNumber || ''" :model-value="header?.OrderNumber || ''"
@@ -61,8 +70,8 @@
bordered bordered
dense dense
separator="cell" separator="cell"
row-key="OrderLineID" row-key="RowKey"
:rows="rows" :rows="filteredRows"
:columns="columns" :columns="columns"
:loading="store.loading" :loading="store.loading"
no-data-label="Uretime verilecek urun bulunamadi" no-data-label="Uretime verilecek urun bulunamadi"
@@ -77,7 +86,7 @@
flat flat
round round
dense dense
:loading="rowSavingId === props.row.OrderLineID" :loading="rowSavingId === props.row.RowKey"
@click="onRowSubmit(props.row)" @click="onRowSubmit(props.row)"
> >
<q-tooltip>Satiri Guncelle</q-tooltip> <q-tooltip>Satiri Guncelle</q-tooltip>
@@ -200,6 +209,7 @@ const cariLabel = computed(() => {
}) })
const rows = ref([]) const rows = ref([])
const descFilter = ref('')
const productOptions = ref([]) const productOptions = ref([])
const productSearch = ref('') const productSearch = ref('')
const rowSavingId = 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: '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: '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: '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: '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: '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;' }, { 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( watch(
() => store.items, () => store.items,
(items) => { (items) => {
rows.value = (items || []).map(item => ({ rows.value = groupItems(items || [])
...item,
NewItemCode: '',
NewColor: '',
NewDim2: '',
NewDesc: ''
}))
}, },
{ immediate: true } { immediate: true }
) )
@@ -260,6 +265,14 @@ const filteredProducts = computed(() => {
).slice(0, 50) ).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) { function onSelectProduct (row, code) {
productSearch.value = '' productSearch.value = ''
onNewItemChange(row, code) onNewItemChange(row, code)
@@ -310,14 +323,83 @@ function isValidModelCode (value) {
return /^[A-Z][0-9]{3}-[A-Z]{3}[0-9]{5}$/.test(text) 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 () { function buildPayloadLines () {
return rows.value.map(r => ({ return rows.value.flatMap(r =>
OrderLineID: r.OrderLineID, (r.OrderLineIDs || []).map(id => ({
OrderLineID: id,
NewItemCode: String(r.NewItemCode || '').trim(), NewItemCode: String(r.NewItemCode || '').trim(),
NewColor: String(r.NewColor || '').trim(), NewColor: String(r.NewColor || '').trim(),
NewDim2: String(r.NewDim2 || '').trim(), NewDim2: String(r.NewDim2 || '').trim(),
NewDesc: String(r.NewDesc || '').trim() NewDesc: String(r.NewDesc || '').trim()
})) }))
)
} }
async function refreshAll () { async function refreshAll () {
@@ -327,22 +409,31 @@ async function refreshAll () {
} }
async function onRowSubmit (row) { async function onRowSubmit (row) {
const line = { const baseLine = {
OrderLineID: row.OrderLineID,
NewItemCode: String(row.NewItemCode || '').trim(), NewItemCode: String(row.NewItemCode || '').trim(),
NewColor: String(row.NewColor || '').trim(), NewColor: String(row.NewColor || '').trim(),
NewDim2: String(row.NewDim2 || '').trim(), NewDim2: String(row.NewDim2 || '').trim(),
NewDesc: String(row.NewDesc || '').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.' }) $q.notify({ type: 'negative', message: 'Yeni urun ve renk zorunludur.' })
return 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 { try {
const validate = await store.validateUpdates(orderHeaderID.value, [line]) const validate = await store.validateUpdates(orderHeaderID.value, lines)
const missingCount = validate?.missingCount || 0 const missingCount = validate?.missingCount || 0
if (missingCount > 0) { if (missingCount > 0) {
const missingList = (validate?.missing || []).map(v => ( const missingList = (validate?.missing || []).map(v => (
@@ -355,13 +446,13 @@ async function onRowSubmit (row) {
ok: { label: 'Ekle ve Guncelle', color: 'primary' }, ok: { label: 'Ekle ve Guncelle', color: 'primary' },
cancel: { label: 'Vazgec', flat: true } cancel: { label: 'Vazgec', flat: true }
}).onOk(async () => { }).onOk(async () => {
await store.applyUpdates(orderHeaderID.value, [line], true) await store.applyUpdates(orderHeaderID.value, lines, true)
await store.fetchItems(orderHeaderID.value) await store.fetchItems(orderHeaderID.value)
}) })
return return
} }
await store.applyUpdates(orderHeaderID.value, [line], false) await store.applyUpdates(orderHeaderID.value, lines, false)
await store.fetchItems(orderHeaderID.value) await store.fetchItems(orderHeaderID.value)
} catch (err) { } catch (err) {
$q.notify({ type: 'negative', message: 'Islem basarisiz.' }) $q.notify({ type: 'negative', message: 'Islem basarisiz.' })

View File

@@ -2684,17 +2684,18 @@ export const useOrderEntryStore = defineStore('orderentry', {
// 🧪 PRE-VALIDATE — prItemVariant ön kontrol // 🧪 PRE-VALIDATE — prItemVariant ön kontrol
// - invalid varsa CREATE/UPDATE ÇALIŞMAZ // - invalid varsa CREATE/UPDATE ÇALIŞMAZ
// ======================================================= // =======================================================
const linesToValidate = if (!isNew) {
isNew const linesToValidate = lines.filter(
? lines l => l._deleteSignal === true || l._dirty === true || !l.OrderLineID
: lines.filter(l => l._deleteSignal === true || l._dirty === true || !l.OrderLineID) )
const v = await api.post('/order/validate', { header, lines: linesToValidate }) const v = await api.post('/order/validate', { header, lines: linesToValidate })
const invalid = v?.data?.invalid || [] const invalid = v?.data?.invalid || []
if (invalid.length > 0) { if (invalid.length > 0) {
await this.showInvalidVariantDialog?.($q, invalid) await this.showInvalidVariantDialog?.($q, invalid)
return // ❌ create / update ÇALIŞMAZ return // ❌ update ÇALIŞMAZ
}
} }
console.log('📤 submitAllReal payload', { console.log('📤 submitAllReal payload', {