ui: add B2B olmayan stok (orphans) page
This commit is contained in:
@@ -70,6 +70,31 @@
|
||||
</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-fixed kategori">
|
||||
<div class="filter-head">
|
||||
<span>KATEGORI</span>
|
||||
<q-btn dense flat round size="sm" icon="filter_list" :color="activeFilterCount('kategori') ? 'primary' : 'grey-8'">
|
||||
<q-badge v-if="activeFilterCount('kategori')" floating color="primary">{{ activeFilterCount('kategori') }}</q-badge>
|
||||
<q-menu class="column-filter-menu" anchor="bottom left" self="top left">
|
||||
<div class="q-pa-sm">
|
||||
<q-input v-model="filterSearch.kategori" dense outlined clearable placeholder="Ara" autofocus />
|
||||
<div class="row q-gutter-xs q-mt-sm">
|
||||
<q-btn dense flat size="sm" label="Tumu" @click="selectAllFilter('kategori')" />
|
||||
<q-btn dense flat size="sm" label="Temizle" @click="clearFilter('kategori')" />
|
||||
</div>
|
||||
<q-separator class="q-my-sm" />
|
||||
<q-option-group
|
||||
v-model="columnFilters.kategori"
|
||||
:options="filteredFilterOptions('kategori')"
|
||||
type="checkbox"
|
||||
dense
|
||||
class="column-filter-options"
|
||||
/>
|
||||
</div>
|
||||
</q-menu>
|
||||
</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-fixed renk">
|
||||
<div class="filter-head">
|
||||
<span>RENK</span>
|
||||
@@ -212,6 +237,7 @@
|
||||
>
|
||||
<div class="sub-col model">{{ row.product_code || '-' }}</div>
|
||||
<div class="sub-col desc">{{ row.product_description || '-' }}</div>
|
||||
<div class="sub-col kategori">{{ row.kategori || '-' }}</div>
|
||||
<div class="sub-col renk">
|
||||
<div class="renk-kodu">{{ variantCode(row) }}</div>
|
||||
<div class="renk-aciklama">{{ row.color_title || '-' }}</div>
|
||||
@@ -273,6 +299,7 @@ const errorMessage = ref('')
|
||||
const columnFilters = ref({
|
||||
model: [],
|
||||
desc: [],
|
||||
kategori: [],
|
||||
renk: [],
|
||||
ana: [],
|
||||
alt: [],
|
||||
@@ -281,6 +308,7 @@ const columnFilters = ref({
|
||||
const filterSearch = ref({
|
||||
model: '',
|
||||
desc: '',
|
||||
kategori: '',
|
||||
renk: '',
|
||||
ana: '',
|
||||
alt: '',
|
||||
@@ -325,6 +353,7 @@ const productGroups = computed(() => displayRows.value)
|
||||
const filterOptions = computed(() => ({
|
||||
model: uniqueOptions(rows.value.map(row => row.product_code)),
|
||||
desc: uniqueOptions(rows.value.map(row => row.product_description)),
|
||||
kategori: uniqueOptions(rows.value.map(row => row.kategori)),
|
||||
renk: uniqueOptions(rows.value.map(row => variantCode(row))),
|
||||
ana: uniqueOptions(rows.value.map(row => row.urun_ana_grubu)),
|
||||
alt: uniqueOptions(rows.value.map(row => row.urun_alt_grubu)),
|
||||
@@ -370,6 +399,7 @@ function clearFilter (key) {
|
||||
function rowPassesFilters (row) {
|
||||
return filterMatch('model', row.product_code) &&
|
||||
filterMatch('desc', row.product_description) &&
|
||||
filterMatch('kategori', row.kategori) &&
|
||||
filterMatch('renk', variantCode(row)) &&
|
||||
filterMatch('ana', row.urun_ana_grubu) &&
|
||||
filterMatch('alt', row.urun_alt_grubu) &&
|
||||
@@ -492,7 +522,7 @@ function mapRowSizesToSchema (row) {
|
||||
const rawSizeLabels = sizeEntries.map(([rawSize]) => normalizeBedenLabel(rawSize))
|
||||
const schemaMap = getSchemaMap()
|
||||
const grpKey = detectRowGroupKey(row, rawSizeLabels)
|
||||
const schema = grpKey && schemaMap?.[grpKey] ? schemaMap[grpKey] : null
|
||||
const schema = pickSchemaForRow(schemaMap, grpKey, rawSizeLabels)
|
||||
const schemaLabelMap = normalizedSchemaLabelMap(schema)
|
||||
const mapped = {}
|
||||
|
||||
@@ -513,6 +543,26 @@ function mapRowSizesToSchema (row) {
|
||||
return { grpKey, schema, mapped }
|
||||
}
|
||||
|
||||
function pickSchemaForRow (schemaMap, grpKey, rawSizeLabels) {
|
||||
const primary = grpKey && schemaMap?.[grpKey] ? schemaMap[grpKey] : null
|
||||
const rawSet = new Set((rawSizeLabels || []).map(v => normalizeBedenLabel(v)).filter(Boolean))
|
||||
if (!rawSet.size) return primary
|
||||
const primarySet = new Set((primary?.values || []).map(v => normalizeBedenLabel(v)))
|
||||
if ([...rawSet].some(v => primarySet.has(v))) return primary
|
||||
|
||||
let best = primary
|
||||
let bestScore = 0
|
||||
for (const schema of Object.values(schemaMap || {})) {
|
||||
const schemaSet = new Set((schema?.values || []).map(v => normalizeBedenLabel(v)))
|
||||
const score = [...rawSet].reduce((sum, v) => sum + (schemaSet.has(v) ? 1 : 0), 0)
|
||||
if (score > bestScore) {
|
||||
best = schema
|
||||
bestScore = score
|
||||
}
|
||||
}
|
||||
return best
|
||||
}
|
||||
|
||||
function formatQty (value) {
|
||||
const n = Number(value || 0)
|
||||
if (!Number.isFinite(n) || n === 0) return ''
|
||||
@@ -544,7 +594,7 @@ function csvEscape (v) {
|
||||
}
|
||||
|
||||
function exportVisibleExcel () {
|
||||
const cols = ['MODEL', 'DESC', 'RENK', 'URUN ANA GRUBU', 'URUN ALT GRUBU', 'MARKA']
|
||||
const cols = ['MODEL', 'DESC', 'KATEGORI', 'RENK', 'URUN ANA GRUBU', 'URUN ALT GRUBU', 'MARKA']
|
||||
const sizeCols = schemaRows.value.flatMap(grp => paddedSchemaValues(grp).map(v => (v.ghost ? '' : v.value))).filter(Boolean)
|
||||
cols.push(...sizeCols)
|
||||
cols.push('TOPLAM', 'SERI', 'UYARI')
|
||||
@@ -559,6 +609,7 @@ function exportVisibleExcel () {
|
||||
lines.push([
|
||||
row.product_code || '',
|
||||
row.product_description || '',
|
||||
row.kategori || '',
|
||||
variantCode(row),
|
||||
row.urun_ana_grubu || '',
|
||||
row.urun_alt_grubu || '',
|
||||
@@ -590,6 +641,7 @@ onMounted(() => reload())
|
||||
--psq-sticky-offset: 12px;
|
||||
--grp-title-w: 90px;
|
||||
--col-desc: var(--col-aciklama);
|
||||
--col-kategori-series: 86px;
|
||||
--col-marka-series: var(--col-marka, 90px);
|
||||
--psq-header-h: var(--grid-header-h);
|
||||
--series-total-w: 76px;
|
||||
@@ -606,6 +658,7 @@ onMounted(() => reload())
|
||||
grid-template-columns:
|
||||
var(--col-model)
|
||||
var(--col-desc)
|
||||
var(--col-kategori-series)
|
||||
var(--col-renk)
|
||||
var(--col-ana)
|
||||
var(--col-alt)
|
||||
@@ -699,11 +752,11 @@ onMounted(() => reload())
|
||||
}
|
||||
|
||||
.total-header-cell {
|
||||
grid-column: 8 / 9;
|
||||
grid-column: 9 / 10;
|
||||
}
|
||||
|
||||
.series-header-cell {
|
||||
grid-column: 9 / 10;
|
||||
grid-column: 10 / 11;
|
||||
}
|
||||
|
||||
.series-flat-row {
|
||||
@@ -741,12 +794,14 @@ onMounted(() => reload())
|
||||
|
||||
.series-flat-row .sub-col.model { grid-column: 1; }
|
||||
.series-flat-row .sub-col.desc { grid-column: 2; }
|
||||
.series-flat-row .sub-col.renk { grid-column: 3; }
|
||||
.series-flat-row .sub-col.ana { grid-column: 4; }
|
||||
.series-flat-row .sub-col.alt { grid-column: 5; }
|
||||
.series-flat-row .sub-col.marka { grid-column: 6; }
|
||||
.series-flat-row .sub-col.kategori { grid-column: 3; }
|
||||
.series-flat-row .sub-col.renk { grid-column: 4; }
|
||||
.series-flat-row .sub-col.ana { grid-column: 5; }
|
||||
.series-flat-row .sub-col.alt { grid-column: 6; }
|
||||
.series-flat-row .sub-col.marka { grid-column: 7; }
|
||||
|
||||
.series-flat-row .sub-col.model,
|
||||
.series-flat-row .sub-col.kategori,
|
||||
.series-flat-row .sub-col.renk,
|
||||
.series-flat-row .sub-col.ana,
|
||||
.series-flat-row .sub-col.alt,
|
||||
@@ -776,7 +831,7 @@ onMounted(() => reload())
|
||||
}
|
||||
|
||||
.flat-size-cells {
|
||||
grid-column: 7;
|
||||
grid-column: 8;
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
grid-auto-columns: var(--beden-w);
|
||||
@@ -818,7 +873,7 @@ onMounted(() => reload())
|
||||
}
|
||||
|
||||
.total-cell {
|
||||
grid-column: 8;
|
||||
grid-column: 9;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
@@ -831,7 +886,7 @@ onMounted(() => reload())
|
||||
}
|
||||
|
||||
.series-select-cell {
|
||||
grid-column: 9 / 10;
|
||||
grid-column: 10 / 11;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
Reference in New Issue
Block a user