744 lines
22 KiB
Vue
744 lines
22 KiB
Vue
<template>
|
|
<q-page class="q-pa-md full-width order-prod-page">
|
|
<div class="row items-center justify-between page-header">
|
|
<div>
|
|
<div class="text-h6 text-weight-bold">Uretime Verilen Urunleri Guncelle</div>
|
|
</div>
|
|
<q-btn
|
|
color="primary"
|
|
icon="refresh"
|
|
label="Yenile"
|
|
:loading="store.loading"
|
|
@click="refreshAll"
|
|
/>
|
|
<q-btn
|
|
class="q-ml-sm"
|
|
color="secondary"
|
|
icon="save"
|
|
label="Secili Degisiklikleri Kaydet"
|
|
:loading="store.saving"
|
|
@click="onBulkSubmit"
|
|
/>
|
|
</div>
|
|
|
|
<div class="filter-bar row q-col-gutter-md">
|
|
<div class="col-5">
|
|
<q-input
|
|
:model-value="cariLabel"
|
|
label="Cari Secimi"
|
|
filled
|
|
dense
|
|
readonly
|
|
/>
|
|
</div>
|
|
<div class="col-3">
|
|
<q-input
|
|
v-model="descFilter"
|
|
label="Aciklama Ara"
|
|
filled
|
|
dense
|
|
clearable
|
|
/>
|
|
</div>
|
|
<div class="col-2">
|
|
<q-input
|
|
:model-value="header?.OrderNumber || ''"
|
|
label="Siparis No"
|
|
filled
|
|
dense
|
|
readonly
|
|
/>
|
|
</div>
|
|
<div class="col-2">
|
|
<q-input
|
|
:model-value="formatDate(header?.OrderDate)"
|
|
label="Olusturulma Tarihi"
|
|
filled
|
|
dense
|
|
readonly
|
|
/>
|
|
</div>
|
|
<div class="col-2">
|
|
<q-input
|
|
:model-value="formatDate(header?.AverageDueDate)"
|
|
label="Tahmini Termin Tarihi"
|
|
filled
|
|
dense
|
|
readonly
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-wrap">
|
|
<q-table
|
|
class="q-mt-md prod-table"
|
|
flat
|
|
bordered
|
|
dense
|
|
separator="cell"
|
|
row-key="RowKey"
|
|
:rows="filteredRows"
|
|
:columns="columns"
|
|
:loading="store.loading"
|
|
no-data-label="Uretime verilecek urun bulunamadi"
|
|
:rows-per-page-options="[0]"
|
|
hide-bottom
|
|
>
|
|
<template #header-cell-select="props">
|
|
<q-th :props="props" class="text-center" style="width: 44px">
|
|
<q-checkbox
|
|
size="sm"
|
|
:model-value="allSelectedVisible"
|
|
:indeterminate="someSelectedVisible && !allSelectedVisible"
|
|
@update:model-value="toggleSelectAllVisible"
|
|
/>
|
|
</q-th>
|
|
</template>
|
|
|
|
<template #body-cell-select="props">
|
|
<q-td :props="props" class="text-center" style="width: 44px">
|
|
<q-checkbox
|
|
size="sm"
|
|
:model-value="!!selectedMap[props.row.RowKey]"
|
|
@update:model-value="(val) => toggleRowSelection(props.row.RowKey, val)"
|
|
/>
|
|
</q-td>
|
|
</template>
|
|
|
|
<template #body-cell-actions="props">
|
|
<q-td :props="props" class="text-center">
|
|
<q-btn
|
|
color="primary"
|
|
icon="save"
|
|
flat
|
|
round
|
|
dense
|
|
:loading="rowSavingId === props.row.RowKey"
|
|
@click="onRowSubmit(props.row)"
|
|
>
|
|
<q-tooltip>Satiri Guncelle</q-tooltip>
|
|
</q-btn>
|
|
</q-td>
|
|
</template>
|
|
|
|
<template #body-cell-NewItemCode="props">
|
|
<q-td :props="props">
|
|
<q-input
|
|
v-model="props.row.NewItemCode"
|
|
dense
|
|
filled
|
|
maxlength="13"
|
|
label="Yeni Urun"
|
|
@update:model-value="val => onNewItemChange(props.row, val)"
|
|
>
|
|
<template #append>
|
|
<q-icon name="arrow_drop_down" class="cursor-pointer" />
|
|
</template>
|
|
<q-menu
|
|
anchor="bottom left"
|
|
self="top left"
|
|
fit
|
|
>
|
|
<div class="q-pa-sm" style="min-width:260px">
|
|
<q-input
|
|
v-model="productSearch"
|
|
dense
|
|
filled
|
|
debounce="200"
|
|
placeholder="Urun ara..."
|
|
/>
|
|
<q-list class="q-mt-xs" bordered separator>
|
|
<q-item
|
|
v-for="opt in filteredProducts"
|
|
:key="opt.ProductCode"
|
|
clickable
|
|
@click="onSelectProduct(props.row, opt.ProductCode)"
|
|
>
|
|
<q-item-section>{{ opt.ProductCode }}</q-item-section>
|
|
</q-item>
|
|
</q-list>
|
|
</div>
|
|
</q-menu>
|
|
</q-input>
|
|
</q-td>
|
|
</template>
|
|
|
|
<template #body-cell-NewColor="props">
|
|
<q-td :props="props">
|
|
<q-select
|
|
v-model="props.row.NewColor"
|
|
:options="getColorOptions(props.row)"
|
|
option-label="colorLabel"
|
|
option-value="color_code"
|
|
emit-value
|
|
map-options
|
|
use-input
|
|
new-value-mode="add-unique"
|
|
dense
|
|
filled
|
|
label="Yeni Renk"
|
|
@update:model-value="() => onNewColorChange(props.row)"
|
|
@new-value="(val, done) => onCreateColorValue(props.row, val, done)"
|
|
/>
|
|
</q-td>
|
|
</template>
|
|
|
|
<template #body-cell-NewDim2="props">
|
|
<q-td :props="props">
|
|
<q-select
|
|
v-model="props.row.NewDim2"
|
|
:options="getSecondColorOptions(props.row)"
|
|
option-label="item_dim2_code"
|
|
option-value="item_dim2_code"
|
|
emit-value
|
|
map-options
|
|
use-input
|
|
new-value-mode="add-unique"
|
|
dense
|
|
filled
|
|
label="Yeni 2. Renk"
|
|
@new-value="(val, done) => onCreateSecondColorValue(props.row, val, done)"
|
|
/>
|
|
</q-td>
|
|
</template>
|
|
|
|
<template #body-cell-NewDesc="props">
|
|
<q-td :props="props" class="cell-new">
|
|
<q-input
|
|
v-model="props.row.NewDesc"
|
|
dense
|
|
filled
|
|
type="textarea"
|
|
autogrow
|
|
label="Yeni Aciklama"
|
|
/>
|
|
</q-td>
|
|
</template>
|
|
</q-table>
|
|
</div>
|
|
|
|
<q-banner v-if="store.error" class="bg-red text-white q-mt-sm">
|
|
Hata: {{ store.error }}
|
|
</q-banner>
|
|
</q-page>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed, onMounted, ref, watch } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
import { useQuasar } from 'quasar'
|
|
import { useOrderProductionItemStore } from 'src/stores/OrderProductionItemStore'
|
|
|
|
const route = useRoute()
|
|
const $q = useQuasar()
|
|
const store = useOrderProductionItemStore()
|
|
|
|
const orderHeaderID = computed(() => String(route.params.orderHeaderID || '').trim())
|
|
const header = computed(() => store.header || {})
|
|
const cariLabel = computed(() => {
|
|
const code = header.value?.CurrAccCode || ''
|
|
const name = header.value?.CurrAccDescription || ''
|
|
if (!code && !name) return ''
|
|
if (!name) return code
|
|
return `${code} - ${name}`
|
|
})
|
|
|
|
const rows = ref([])
|
|
const descFilter = ref('')
|
|
const productOptions = ref([])
|
|
const productSearch = ref('')
|
|
const rowSavingId = ref('')
|
|
const selectedMap = ref({})
|
|
|
|
const columns = [
|
|
{ name: 'select', label: '', field: 'select', align: 'center', sortable: false, style: 'width:44px;', headerStyle: 'width:44px;' },
|
|
{ name: 'OldItemCode', label: 'Eski Urun Kodu', field: 'OldItemCode', align: 'left', sortable: true, style: 'min-width:120px;white-space:nowrap', headerStyle: 'min-width:120px;white-space:nowrap', headerClasses: 'col-old', classes: 'col-old' },
|
|
{ name: 'OldColor', label: 'Eski Urun Rengi', field: 'OldColor', align: 'left', sortable: true, style: 'min-width:100px;white-space:nowrap', headerStyle: 'min-width:100px;white-space:nowrap', headerClasses: 'col-old', classes: 'col-old' },
|
|
{ name: 'OldDim2', label: 'Eski 2. Renk', field: 'OldDim2', align: 'left', sortable: true, style: 'min-width:90px;white-space:nowrap', headerStyle: 'min-width:90px;white-space:nowrap', headerClasses: 'col-old', classes: 'col-old' },
|
|
{ name: 'OldDesc', label: 'Eski Aciklama', field: 'OldDesc', align: 'left', sortable: false, style: 'min-width:160px;', headerStyle: 'min-width:160px;', headerClasses: 'col-old col-desc', classes: 'col-old col-desc' },
|
|
{ name: 'OldSizes', label: 'Bedenler', field: 'OldSizesLabel', align: 'left', sortable: false, style: 'min-width:130px;', headerStyle: 'min-width:130px;', headerClasses: 'col-old col-wrap', classes: 'col-old col-wrap' },
|
|
{ name: 'NewItemCode', label: 'Yeni Urun Kodu', field: 'NewItemCode', align: 'left', sortable: false, style: 'min-width:160px;', headerStyle: 'min-width:160px;', headerClasses: 'col-new col-new-first', classes: 'col-new col-new-first' },
|
|
{ name: 'NewColor', label: 'Yeni Urun Rengi', field: 'NewColor', align: 'left', sortable: false, style: 'min-width:120px;', headerStyle: 'min-width:120px;', headerClasses: 'col-new', classes: 'col-new' },
|
|
{ name: 'NewDim2', label: 'Yeni 2. Renk', field: 'NewDim2', align: 'left', sortable: false, style: 'min-width:120px;', headerStyle: 'min-width:120px;', headerClasses: 'col-new', classes: 'col-new' },
|
|
{ name: 'NewDesc', label: 'Yeni Aciklama', field: 'NewDesc', align: 'left', sortable: false, style: 'min-width:200px;', headerStyle: 'min-width:200px;', headerClasses: 'col-new col-desc', classes: 'col-new col-desc' },
|
|
{ name: 'actions', label: '', field: 'actions', align: 'center', sortable: false, style: 'width:50px;', headerStyle: 'width:50px;' }
|
|
]
|
|
|
|
onMounted(async () => {
|
|
await refreshAll()
|
|
})
|
|
|
|
watch(orderHeaderID, async (id) => {
|
|
await refreshAll()
|
|
})
|
|
|
|
watch(
|
|
() => store.items,
|
|
(items) => {
|
|
rows.value = groupItems(items || [], rows.value)
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
watch(
|
|
() => store.products,
|
|
(products) => {
|
|
productOptions.value = products || []
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
function formatDate (val) {
|
|
if (!val) return ''
|
|
const text = String(val)
|
|
return text.length >= 10 ? text.slice(0, 10) : text
|
|
}
|
|
|
|
const filteredProducts = computed(() => {
|
|
const needle = String(productSearch.value || '').toLowerCase()
|
|
if (!needle) return productOptions.value.slice(0, 50)
|
|
return productOptions.value.filter(p =>
|
|
String(p?.ProductCode || '').toLowerCase().includes(needle)
|
|
).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)
|
|
)
|
|
})
|
|
|
|
const visibleRowKeys = computed(() => filteredRows.value.map(r => r.RowKey))
|
|
const selectedVisibleCount = computed(() => visibleRowKeys.value.filter(k => !!selectedMap.value[k]).length)
|
|
const allSelectedVisible = computed(() => visibleRowKeys.value.length > 0 && selectedVisibleCount.value === visibleRowKeys.value.length)
|
|
const someSelectedVisible = computed(() => selectedVisibleCount.value > 0)
|
|
|
|
function onSelectProduct (row, code) {
|
|
productSearch.value = ''
|
|
onNewItemChange(row, code)
|
|
}
|
|
|
|
function onNewItemChange (row, val) {
|
|
const next = String(val || '').trim().toUpperCase()
|
|
if (next.length > 13) {
|
|
$q.notify({ type: 'negative', message: 'Model kodu en fazla 13 karakter olabilir.' })
|
|
row.NewItemCode = next.slice(0, 13)
|
|
return
|
|
}
|
|
row.NewItemCode = next ? next.toUpperCase() : ''
|
|
row.NewColor = ''
|
|
row.NewDim2 = ''
|
|
if (row.NewItemCode) {
|
|
store.fetchColors(row.NewItemCode)
|
|
}
|
|
}
|
|
|
|
function onNewColorChange (row) {
|
|
row.NewColor = normalizeShortCode(row.NewColor, 3)
|
|
row.NewDim2 = ''
|
|
if (row.NewItemCode && row.NewColor) {
|
|
store.fetchSecondColors(row.NewItemCode, row.NewColor)
|
|
}
|
|
}
|
|
|
|
function getColorOptions (row) {
|
|
const code = row?.NewItemCode || ''
|
|
const list = store.colorOptionsByCode[code] || []
|
|
return list.map(c => ({
|
|
...c,
|
|
colorLabel: `${c.color_code} - ${c.color_description || ''}`.trim()
|
|
}))
|
|
}
|
|
|
|
function getSecondColorOptions (row) {
|
|
const code = row?.NewItemCode || ''
|
|
const color = row?.NewColor || ''
|
|
const key = `${code}::${color}`
|
|
return store.secondColorOptionsByKey[key] || []
|
|
}
|
|
|
|
function toggleRowSelection (rowKey, checked) {
|
|
const next = { ...selectedMap.value }
|
|
if (checked) next[rowKey] = true
|
|
else delete next[rowKey]
|
|
selectedMap.value = next
|
|
}
|
|
|
|
function toggleSelectAllVisible (checked) {
|
|
const next = { ...selectedMap.value }
|
|
for (const key of visibleRowKeys.value) {
|
|
if (checked) next[key] = true
|
|
else delete next[key]
|
|
}
|
|
selectedMap.value = next
|
|
}
|
|
|
|
function onCreateColorValue (row, val, done) {
|
|
const code = normalizeShortCode(val, 3)
|
|
if (!code) {
|
|
done(null)
|
|
return
|
|
}
|
|
row.NewColor = code
|
|
onNewColorChange(row)
|
|
done(code, 'add-unique')
|
|
}
|
|
|
|
function onCreateSecondColorValue (row, val, done) {
|
|
const code = normalizeShortCode(val, 3)
|
|
if (!code) {
|
|
done(null)
|
|
return
|
|
}
|
|
row.NewDim2 = code
|
|
done(code, 'add-unique')
|
|
}
|
|
|
|
function normalizeShortCode (value, maxLen) {
|
|
return String(value || '').trim().toUpperCase().slice(0, maxLen)
|
|
}
|
|
|
|
function validateRowInput (row) {
|
|
const newItemCode = String(row.NewItemCode || '').trim().toUpperCase()
|
|
const newColor = normalizeShortCode(row.NewColor, 3)
|
|
const newDim2 = normalizeShortCode(row.NewDim2, 3)
|
|
const oldColor = String(row.OldColor || '').trim()
|
|
const oldDim2 = String(row.OldDim2 || '').trim()
|
|
|
|
if (!newItemCode) return 'Yeni model kodu zorunludur.'
|
|
if (newItemCode.length !== 13) return 'Yeni model kodu 13 karakter olmalidir.'
|
|
if (oldColor && !newColor) return 'Eski kayitta 1. renk oldugu icin yeni 1. renk zorunludur.'
|
|
if (newColor && newColor.length !== 3) return 'Yeni 1. renk kodu 3 karakter olmalidir.'
|
|
if (oldDim2 && !newDim2) return 'Eski kayitta 2. renk oldugu icin yeni 2. renk zorunludur.'
|
|
if (newDim2 && newDim2.length !== 3) return 'Yeni 2. renk kodu 3 karakter olmalidir.'
|
|
if (newDim2 && !newColor) return '2. renk girmek icin 1. renk zorunludur.'
|
|
|
|
row.NewItemCode = newItemCode
|
|
row.NewColor = newColor
|
|
row.NewDim2 = newDim2
|
|
return ''
|
|
}
|
|
|
|
function collectLinesFromRows (selectedRows) {
|
|
const lines = []
|
|
for (const row of selectedRows) {
|
|
const errMsg = validateRowInput(row)
|
|
if (errMsg) {
|
|
return { errMsg, lines: [] }
|
|
}
|
|
|
|
const baseLine = {
|
|
NewItemCode: String(row.NewItemCode || '').trim().toUpperCase(),
|
|
NewColor: normalizeShortCode(row.NewColor, 3),
|
|
NewDim2: normalizeShortCode(row.NewDim2, 3),
|
|
NewDesc: String((row.NewDesc || row.OldDesc) || '').trim()
|
|
}
|
|
|
|
for (const id of (row.OrderLineIDs || [])) {
|
|
lines.push({
|
|
OrderLineID: id,
|
|
...baseLine
|
|
})
|
|
}
|
|
}
|
|
return { errMsg: '', lines }
|
|
}
|
|
|
|
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, prevRows = []) {
|
|
const prevMap = new Map()
|
|
for (const r of prevRows || []) {
|
|
if (r?.RowKey) prevMap.set(r.RowKey, String(r.NewDesc || '').trim())
|
|
}
|
|
const map = new Map()
|
|
|
|
for (const it of items) {
|
|
const key = buildGroupKey(it)
|
|
if (!map.has(key)) {
|
|
const prevDesc = prevMap.get(key) || ''
|
|
const fallbackDesc = String((it?.NewDesc || it?.OldDesc) || '').trim()
|
|
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: prevDesc || fallbackDesc,
|
|
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.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 || r.OldDesc) || '').trim()
|
|
}))
|
|
)
|
|
}
|
|
|
|
async function refreshAll () {
|
|
await store.fetchHeader(orderHeaderID.value)
|
|
await store.fetchItems(orderHeaderID.value)
|
|
await store.fetchProducts()
|
|
}
|
|
|
|
async function onRowSubmit (row) {
|
|
const { errMsg, lines } = collectLinesFromRows([row])
|
|
if (errMsg) {
|
|
$q.notify({ type: 'negative', message: errMsg })
|
|
return
|
|
}
|
|
|
|
if (!lines.length) {
|
|
$q.notify({ type: 'negative', message: 'Satir bulunamadi.' })
|
|
return
|
|
}
|
|
|
|
rowSavingId.value = row.RowKey
|
|
try {
|
|
const validate = await store.validateUpdates(orderHeaderID.value, lines)
|
|
const missingCount = validate?.missingCount || 0
|
|
if (missingCount > 0) {
|
|
const missingList = (validate?.missing || []).map(v => (
|
|
`${v.ItemCode} / ${v.ColorCode} / ${v.ItemDim1Code} / ${v.ItemDim2Code}`
|
|
))
|
|
$q.dialog({
|
|
title: 'Eksik Varyantlar',
|
|
message: `Eksik varyant bulundu: ${missingCount}<br><br>${missingList.join('<br>')}`,
|
|
html: true,
|
|
ok: { label: 'Ekle ve Guncelle', color: 'primary' },
|
|
cancel: { label: 'Vazgec', flat: true }
|
|
}).onOk(async () => {
|
|
await store.applyUpdates(orderHeaderID.value, lines, true)
|
|
await store.fetchItems(orderHeaderID.value)
|
|
})
|
|
return
|
|
}
|
|
|
|
await store.applyUpdates(orderHeaderID.value, lines, false)
|
|
await store.fetchItems(orderHeaderID.value)
|
|
} catch (err) {
|
|
$q.notify({ type: 'negative', message: 'Islem basarisiz.' })
|
|
} finally {
|
|
rowSavingId.value = ''
|
|
}
|
|
}
|
|
|
|
async function onBulkSubmit () {
|
|
const selectedRows = rows.value.filter(r => !!selectedMap.value[r.RowKey])
|
|
if (!selectedRows.length) {
|
|
$q.notify({ type: 'warning', message: 'Lutfen en az bir satir seciniz.' })
|
|
return
|
|
}
|
|
|
|
const { errMsg, lines } = collectLinesFromRows(selectedRows)
|
|
if (errMsg) {
|
|
$q.notify({ type: 'negative', message: errMsg })
|
|
return
|
|
}
|
|
if (!lines.length) {
|
|
$q.notify({ type: 'negative', message: 'Secili satirlarda guncellenecek kayit bulunamadi.' })
|
|
return
|
|
}
|
|
|
|
try {
|
|
const validate = await store.validateUpdates(orderHeaderID.value, lines)
|
|
const missingCount = validate?.missingCount || 0
|
|
if (missingCount > 0) {
|
|
const missingList = (validate?.missing || []).map(v => (
|
|
`${v.ItemCode} / ${v.ColorCode} / ${v.ItemDim1Code} / ${v.ItemDim2Code}`
|
|
))
|
|
$q.dialog({
|
|
title: 'Eksik Varyantlar',
|
|
message: `Eksik varyant bulundu: ${missingCount}<br><br>${missingList.join('<br>')}`,
|
|
html: true,
|
|
ok: { label: 'Ekle ve Guncelle', color: 'primary' },
|
|
cancel: { label: 'Vazgec', flat: true }
|
|
}).onOk(async () => {
|
|
await store.applyUpdates(orderHeaderID.value, lines, true)
|
|
await store.fetchItems(orderHeaderID.value)
|
|
selectedMap.value = {}
|
|
})
|
|
return
|
|
}
|
|
|
|
await store.applyUpdates(orderHeaderID.value, lines, false)
|
|
await store.fetchItems(orderHeaderID.value)
|
|
selectedMap.value = {}
|
|
} catch (err) {
|
|
$q.notify({ type: 'negative', message: 'Toplu kayit islemi basarisiz.' })
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.prod-table :deep(th) {
|
|
font-weight: 700;
|
|
letter-spacing: 0.2px;
|
|
}
|
|
|
|
.prod-table :deep(td) {
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.prod-table :deep(.q-table__container) {
|
|
width: 100%;
|
|
}
|
|
|
|
.prod-table :deep(.q-table) {
|
|
font-size: 11px;
|
|
}
|
|
|
|
.order-prod-page {
|
|
--header-height: 56px;
|
|
--filter-bar-height: 72px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100vh;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.page-header {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 8;
|
|
background: #fff;
|
|
margin-top: -8px;
|
|
margin-bottom: 8px;
|
|
padding-top: 4px;
|
|
padding-bottom: 6px;
|
|
}
|
|
|
|
.filter-bar {
|
|
position: sticky;
|
|
top: var(--header-height);
|
|
z-index: 7;
|
|
background: #fff;
|
|
padding-top: 4px;
|
|
padding-bottom: 8px;
|
|
}
|
|
|
|
.table-wrap {
|
|
flex: 1;
|
|
min-height: 0;
|
|
display: flex;
|
|
}
|
|
|
|
.prod-table :deep(.q-table__middle) {
|
|
max-height: calc(100vh - var(--header-height) - var(--filter-bar-height) - 140px);
|
|
overflow: auto;
|
|
}
|
|
|
|
.prod-table :deep(.q-table__container) {
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.prod-table :deep(.q-table thead tr th) {
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 6;
|
|
background: #fff;
|
|
}
|
|
|
|
.prod-table :deep(th.col-old),
|
|
.prod-table :deep(td.col-old) {
|
|
background: #fff0d9;
|
|
}
|
|
|
|
.prod-table :deep(th.col-new),
|
|
.prod-table :deep(td.col-new) {
|
|
background: #e3f3ff;
|
|
}
|
|
|
|
.prod-table :deep(th.col-old) {
|
|
color: #8a5a00;
|
|
}
|
|
|
|
.prod-table :deep(th.col-new) {
|
|
color: #0d4f7a;
|
|
}
|
|
|
|
.prod-table :deep(td.col-old) {
|
|
border-left: 4px solid #f0a500;
|
|
}
|
|
|
|
.prod-table :deep(td.col-new) {
|
|
border-left: 4px solid #2d9cdb;
|
|
}
|
|
|
|
.prod-table :deep(th.col-new-first),
|
|
.prod-table :deep(td.col-new-first) {
|
|
border-left: 6px solid #1b7cc8;
|
|
}
|
|
|
|
.prod-table :deep(td.cell-new) {
|
|
background: #e3f3ff;
|
|
}
|
|
|
|
.prod-table :deep(td.col-desc),
|
|
.prod-table :deep(th.col-desc),
|
|
.prod-table :deep(td.col-wrap),
|
|
.prod-table :deep(th.col-wrap) {
|
|
white-space: normal;
|
|
word-break: break-word;
|
|
line-height: 1.2;
|
|
}
|
|
</style>
|