Files
bssapp/ui/src/pages/ProductStockByAttributes.vue
2026-03-04 13:21:13 +03:00

1128 lines
30 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<q-page
v-if="canReadOrder"
class="order-page q-pa-md"
:style="{ '--grid-header-h': gridHeaderHeight }"
>
<div class="sticky-stack">
<div class="filter-bar row q-col-gutter-md q-mb-sm">
<div
v-for="def in attrDefs"
:key="def.key"
class="col-12 col-md-3"
>
<q-select
v-model="filters[def.key]"
:options="filteredAttrOptions[def.key] || []"
:label="def.label"
filled
dense
clearable
use-input
input-debounce="250"
:loading="loadingAttributeOptions"
@filter="(val, update) => filterAttributeOptions(def.key, val, update)"
@keyup.enter="fetchStockByAttributes"
/>
</div>
<div class="col-auto">
<q-btn
color="primary"
icon="search"
label="Sorgula"
:loading="loadingStock"
:disable="!hasAnyFilter"
@click="fetchStockByAttributes"
/>
</div>
<div class="col-auto">
<q-btn
flat
color="grey-8"
icon="restart_alt"
label="Sıfırla"
@click="resetForm"
/>
</div>
<div class="col-auto">
<q-btn
flat
color="primary"
icon="unfold_more"
:label="allDetailsExpanded ? 'Tüm Depoları Kapat' : 'Tüm Depoları Göster'"
:disable="!level1Groups.length"
@click="toggleAllDetails"
/>
</div>
</div>
<div class="save-toolbar">
<div class="text-subtitle2 text-weight-bold">Ürün Özelliklerinden Stok Bul</div>
</div>
<div
v-if="showGridHeader"
class="order-grid-header"
>
<div class="col-fixed model">MODEL</div>
<div class="col-fixed renk">RENK</div>
<div class="col-fixed ana">ÜRÜN ANA GRUBU</div>
<div class="col-fixed alt">ÜRÜN ALT GRUBU</div>
<div class="col-fixed aciklama-col">AÇIKLAMA</div>
<div class="beden-block">
<div class="grp-row">
<div class="grp-title">{{ activeSchema?.title || 'BEDEN' }}</div>
<div class="grp-body">
<div
v-for="v in sizeLabels"
:key="'hdr-' + activeGrpKey + '-' + v"
class="grp-cell hdr"
>
{{ v }}
</div>
</div>
</div>
</div>
<div class="total-row">
<div class="total-cell">ADET</div>
</div>
</div>
</div>
<q-banner
v-if="errorMessage"
class="bg-red-1 text-negative q-my-sm rounded-borders"
dense
>
{{ errorMessage }}
</q-banner>
<q-banner
v-else-if="!loadingStock && !level1Groups.length"
class="bg-blue-1 text-primary q-my-sm rounded-borders"
dense
>
Ürün özelliği seçip sorgulayın.
</q-banner>
<div class="order-scroll-y">
<div v-if="level1Groups.length" class="order-grid-body">
<template v-for="grp1 in level1Groups" :key="grp1.key">
<div class="summary-group open">
<div class="order-sub-header level-1" @click="toggleOpen(grp1.key)">
<div class="sub-col level1-merged">
<div class="text-weight-bold">{{ grp1.productCode }}</div>
<div class="text-caption">{{ grp1.productDesc || '-' }}</div>
</div>
<div class="sub-center level1-center">
<div class="beden-row values-top">
<div v-for="sz in sizeLabels" :key="`v1-${grp1.key}-${sz}`" class="beden-cell">
{{ Number(grp1.sizeTotals[sz] || 0) > 0 ? formatNumber(grp1.sizeTotals[sz]) : '' }}
</div>
</div>
<div class="beden-row headers">
<div v-for="sz in sizeLabels" :key="`h1-${grp1.key}-${sz}`" class="beden-cell">
{{ sz }}
</div>
</div>
</div>
<div class="sub-right level1-right">
<div class="top-total">{{ formatNumber(grp1.totalQty) }}</div>
<div class="bottom-row">
<div class="bottom-label">ADET</div>
</div>
<div class="icon-row">
<q-icon :name="isOpen(grp1.key) ? 'expand_less' : 'expand_more'" size="18px" />
</div>
</div>
</div>
<template v-if="isOpen(grp1.key)">
<template v-for="grp2 in grp1.children" :key="grp2.key">
<div class="order-sub-header level-2" @click="onLevel2Click(grp1.productCode, grp2)">
<div class="sub-col model">{{ grp1.productCode || '-' }}</div>
<div class="sub-col renk">
<div class="renk-kodu">{{ grp2.colorCode || '-' }}{{ grp2.secondColor ? '-' + grp2.secondColor : '' }}</div>
<div class="renk-aciklama">{{ grp2.colorDesc || '-' }}</div>
</div>
<div class="sub-col ana">{{ grp2.urunAnaGrubu || '-' }}</div>
<div class="sub-col alt">{{ grp2.urunAltGrubu || '-' }}</div>
<div class="sub-col aciklama">{{ grp2.aciklama || '-' }}</div>
<div class="sub-center level2-center">
<div class="beden-row values-top">
<div v-for="sz in sizeLabels" :key="`top2-${grp2.key}-${sz}`" class="beden-cell">
{{ Number(grp2.sizeTotals[sz] || 0) > 0 ? formatNumber(grp2.sizeTotals[sz]) : '' }}
</div>
</div>
<div class="beden-row headers">
<div v-for="sz in sizeLabels" :key="`h2-${grp2.key}-${sz}`" class="beden-cell">
{{ sz }}
</div>
</div>
</div>
<div class="sub-right level2-right">
<div class="top-total">{{ formatNumber(grp2.totalQty) }}</div>
<div class="bottom-row">
<div class="bottom-label">ADET</div>
<q-icon :name="isOpen(grp2.key) ? 'expand_less' : 'expand_more'" size="18px" />
</div>
</div>
</div>
<template v-if="isOpen(grp2.key)">
<div class="detail-table-wrap">
<div
v-for="row in buildLevel2Rows(grp2)"
:key="row.rowKey"
class="summary-row"
>
<div class="cell depo-merged">{{ row.depoAdi || '-' }}</div>
<div class="grp-area">
<div class="grp-row">
<div
v-for="v in sizeLabels"
:key="row.rowKey + '-sz-' + v"
class="cell beden"
>
{{ resolveBedenValue(row.bedenMap, row.grpKey, v) }}
</div>
</div>
</div>
<div class="cell adet">{{ formatNumber(row.adet) }}</div>
</div>
</div>
</template>
</template>
</template>
</div>
</template>
</div>
</div>
</q-page>
<q-page v-else class="q-pa-md flex flex-center">
<div class="text-negative text-subtitle1">Bu modüle erişim yetkiniz yok.</div>
</q-page>
</template>
<script setup>
import { computed, onMounted, ref } from 'vue'
import { useQuasar } from 'quasar'
import api from 'src/services/api'
import { usePermission } from 'src/composables/usePermission'
import {
detectBedenGroup,
normalizeBedenLabel,
schemaByKey as storeSchemaByKey,
useOrderEntryStore
} from 'src/stores/orderentryStore'
const $q = useQuasar()
const { canRead } = usePermission()
const canReadOrder = canRead('order')
const orderStore = useOrderEntryStore()
const attrDefs = [
{ key: 'att01', label: 'Urun Ana Grubu' },
{ key: 'att02', label: 'Urun Alt Grubu' },
{ key: 'att10', label: 'Marka' },
{ key: 'att11', label: 'DR' },
{ key: 'att21', label: 'Kalip' },
{ key: 'att35', label: 'Sezon Yili' },
{ key: 'att36', label: 'Mevsim' },
{ key: 'att44', label: 'Yetiskin/Garson' }
]
const loadingAttributeOptions = ref(false)
const loadingStock = ref(false)
const errorMessage = ref('')
const filters = ref({
att01: '',
att02: '',
att10: '',
att11: '',
att21: '',
att35: '',
att36: '',
att44: ''
})
const attributeOptions = ref({})
const filteredAttrOptions = ref({})
const rawRows = ref([])
const activeSchema = ref(storeSchemaByKey.tak)
const activeGrpKey = ref('tak')
const openState = ref({})
const hasAnyFilter = computed(() =>
attrDefs.some((def) => String(filters.value?.[def.key] || '').trim() !== '')
)
const sizeLabels = computed(() => activeSchema.value?.values || [])
const showGridHeader = computed(() =>
!loadingStock.value && level1Groups.value.length > 0
)
const allDetailsExpanded = computed(() => {
const groups = level1Groups.value || []
if (!groups.length) return false
const detailKeys = []
for (const g1 of groups) {
for (const g2 of g1.children || []) {
detailKeys.push(g2.key)
for (const g3 of g2.children || []) detailKeys.push(g3.key)
}
}
if (!detailKeys.length) return false
return detailKeys.every((k) => openState.value[k] === true)
})
const gridHeaderHeight = computed(() =>
showGridHeader.value ? '56px' : '0px'
)
function emptySizeTotals() {
const map = {}
for (const s of sizeLabels.value) map[s] = 0
return map
}
function parseNumber(value) {
if (typeof value === 'number') return Number.isFinite(value) ? value : 0
const text = String(value ?? '').trim()
if (!text) return 0
const normalized = text.replace(/\./g, '').replace(',', '.')
const n = Number.parseFloat(normalized)
return Number.isFinite(n) ? n : 0
}
function formatNumber(v) {
return parseNumber(v).toLocaleString('tr-TR', { minimumFractionDigits: 0, maximumFractionDigits: 2 })
}
function normalizeSize(v) {
return normalizeBedenLabel(v)
}
function resolveBedenValue(bedenMap, grpKey, bedenLabel) {
const map = bedenMap?.[grpKey]
if (!map || typeof map !== 'object') return 0
return Number(map[bedenLabel] || 0)
}
function isOpen(key) {
return openState.value[key] !== false
}
function toggleOpen(key) {
openState.value[key] = !isOpen(key)
}
function initOpenState(groups, expandDetails = false) {
const next = {}
for (const g1 of groups) {
next[g1.key] = true
for (const g2 of g1.children) {
next[g2.key] = expandDetails
for (const g3 of g2.children) {
next[g3.key] = expandDetails
}
}
}
openState.value = next
}
function expandAllDetails() {
initOpenState(level1Groups.value || [], true)
}
function collapseAllDetails() {
initOpenState(level1Groups.value || [], false)
}
function toggleAllDetails() {
if (allDetailsExpanded.value) {
collapseAllDetails()
return
}
expandAllDetails()
}
function buildLevel3Rows(grp3) {
const byKey = new Map()
const gk = activeGrpKey.value || 'tak'
for (const item of grp3.items || []) {
const model = String(item.Urun_Kodu || '').trim()
const renk = String(item.Renk_Kodu || '').trim()
const renk2 = String(item.Yaka || '').trim()
const urunAnaGrubu = String(item.URUN_ANA_GRUBU || '').trim()
const urunAltGrubu = String(item.URUN_ALT_GRUBU || '').trim()
const aciklama = String(item.Madde_Aciklamasi || '').trim()
const beden = normalizeSize(item.Beden || '')
const qty = parseNumber(item.Kullanilabilir_Envanter)
const rowKey = [model, renk, renk2, grp3.depoKodu || '', grp3.depoAdi || ''].join('|')
if (!byKey.has(rowKey)) {
byKey.set(rowKey, {
rowKey,
model,
renk,
renk2,
urunAnaGrubu,
urunAltGrubu,
aciklama,
grpKey: gk,
bedenMap: { [gk]: {} },
adet: 0,
depoAdi: grp3.depoAdi || '-'
})
}
const row = byKey.get(rowKey)
row.bedenMap[gk][beden] = Number(row.bedenMap[gk][beden] || 0) + qty
row.adet += qty
}
return Array.from(byKey.values())
}
function buildLevel2Rows(grp2) {
const merged = []
for (const grp3 of grp2.children || []) {
merged.push(...buildLevel3Rows(grp3))
}
return merged
}
const level1Groups = computed(() => {
const l1Map = new Map()
for (const item of rawRows.value) {
const productCode = String(item.Urun_Kodu || '').trim()
const productDesc = String(item.Madde_Aciklamasi || '').trim()
const colorCode = String(item.Renk_Kodu || '').trim()
const colorDesc = String(item.Renk_Aciklamasi || '').trim()
const secondColor = String(item.Yaka || '').trim()
const depoKodu = String(item.Depo_Kodu || '').trim()
const depoAdi = String(item.Depo_Adi || '').trim()
const urunAnaGrubu = String(item.URUN_ANA_GRUBU || '').trim()
const urunAltGrubu = String(item.URUN_ALT_GRUBU || '').trim()
const aciklama = String(item.Madde_Aciklamasi || '').trim()
const beden = normalizeSize(item.Beden || '')
const qty = parseNumber(item.Kullanilabilir_Envanter)
if (!l1Map.has(productCode)) {
l1Map.set(productCode, {
key: `L1|${productCode}`,
productCode,
productDesc,
sizeTotals: emptySizeTotals(),
totalQty: 0,
childrenMap: new Map()
})
}
const l1 = l1Map.get(productCode)
if (Object.prototype.hasOwnProperty.call(l1.sizeTotals, beden)) {
l1.sizeTotals[beden] += qty
}
l1.totalQty += qty
const l2Key = `${colorCode}|${secondColor}`
if (!l1.childrenMap.has(l2Key)) {
l1.childrenMap.set(l2Key, {
key: `L2|${productCode}|${l2Key}`,
colorCode,
colorDesc,
secondColor,
urunAnaGrubu,
urunAltGrubu,
aciklama,
sizeTotals: emptySizeTotals(),
totalQty: 0,
childrenMap: new Map()
})
}
const l2 = l1.childrenMap.get(l2Key)
if (Object.prototype.hasOwnProperty.call(l2.sizeTotals, beden)) {
l2.sizeTotals[beden] += qty
}
l2.totalQty += qty
const l3Key = `${depoKodu}|${depoAdi}`
if (!l2.childrenMap.has(l3Key)) {
l2.childrenMap.set(l3Key, {
key: `L3|${productCode}|${l2Key}|${l3Key}`,
depoKodu,
depoAdi,
sizeTotals: emptySizeTotals(),
totalQty: 0,
items: []
})
}
const l3 = l2.childrenMap.get(l3Key)
if (Object.prototype.hasOwnProperty.call(l3.sizeTotals, beden)) {
l3.sizeTotals[beden] += qty
}
l3.totalQty += qty
l3.items.push({
...item,
_rowKey: `${productCode}|${colorCode}|${secondColor}|${depoKodu}|${beden}`
})
}
return Array.from(l1Map.values()).map((l1) => ({
...l1,
children: Array.from(l1.childrenMap.values()).map((l2) => ({
...l2,
children: Array.from(l2.childrenMap.values())
}))
}))
})
function filterAttributeOptions(field, val, update) {
const source = Array.isArray(attributeOptions.value?.[field])
? attributeOptions.value[field]
: []
if (!val) {
update(() => {
filteredAttrOptions.value[field] = [...source]
})
return
}
const needle = String(val || '').toLocaleLowerCase('tr-TR')
update(() => {
filteredAttrOptions.value[field] = source.filter((opt) =>
String(opt || '').toLocaleLowerCase('tr-TR').includes(needle)
)
})
}
async function loadAttributeOptions() {
loadingAttributeOptions.value = true
try {
const res = await api.get('/product-stock-attribute-options')
const payload = res?.data && typeof res.data === 'object' ? res.data : {}
const next = {}
const nextFiltered = {}
for (const def of attrDefs) {
const arr = Array.isArray(payload?.[def.key]) ? payload[def.key] : []
const list = arr
.map((x) => String(x || '').trim())
.filter((x) => x.length > 0)
.sort((a, b) => a.localeCompare(b, 'tr'))
next[def.key] = list
nextFiltered[def.key] = [...list]
}
attributeOptions.value = next
filteredAttrOptions.value = nextFiltered
} catch (err) {
errorMessage.value = 'Urun ozellik secenekleri alinamadi.'
console.error('loadAttributeOptions error:', err)
} finally {
loadingAttributeOptions.value = false
}
}
async function fetchStockByAttributes() {
if (!hasAnyFilter.value) return
const params = {}
for (const def of attrDefs) {
const val = String(filters.value?.[def.key] || '').trim()
if (val) params[def.key] = val
}
loadingStock.value = true
errorMessage.value = ''
try {
if (!orderStore.schemaMap || !Object.keys(orderStore.schemaMap).length) {
orderStore.initSchemaMap()
}
const res = await api.get('/product-stock-query-by-attributes', { params })
const list = Array.isArray(res?.data) ? res.data : []
if (!list.length) {
rawRows.value = []
openState.value = {}
return
}
const first = list[0] || {}
const grpKey = detectBedenGroup(
list.map((x) => x?.Beden || ''),
first?.URUN_ANA_GRUBU || '',
first?.YETISKIN_GARSON || ''
)
const schemaMap = Object.keys(orderStore.schemaMap || {}).length
? orderStore.schemaMap
: storeSchemaByKey
activeGrpKey.value = grpKey || 'tak'
activeSchema.value = schemaMap?.[grpKey] || storeSchemaByKey.tak
rawRows.value = list
initOpenState(level1Groups.value)
} catch (err) {
console.error('fetchStockByAttributes error:', err)
rawRows.value = []
openState.value = {}
errorMessage.value = 'Stok sorgulama sirasinda hata olustu.'
$q.notify({
type: 'negative',
position: 'top-right',
message: 'Stok sorgusu basarisiz.'
})
} finally {
loadingStock.value = false
}
}
function onLevel2Click(_productCode, grp2) {
toggleOpen(grp2.key)
}
function resetForm() {
filters.value = {
att01: '',
att02: '',
att10: '',
att11: '',
att21: '',
att35: '',
att36: '',
att44: ''
}
rawRows.value = []
errorMessage.value = ''
openState.value = {}
activeSchema.value = storeSchemaByKey.tak
}
onMounted(() => {
loadAttributeOptions()
})
</script>
<style scoped>
.order-page {
--psq-sticky-offset: 12px;
--grp-title-w: 44px;
--psq-header-h: 56px;
--psq-col-adet: calc(var(--col-adet) + var(--beden-w));
--psq-l1-lift: 42px;
}
.order-grid-header {
top: calc(var(--header-h) + var(--filter-h) + var(--save-h) + var(--psq-sticky-offset)) !important;
grid-template-columns:
var(--col-model)
var(--col-renk)
var(--col-ana)
var(--col-alt)
var(--col-aciklama)
calc(var(--grp-title-w) + var(--grp-title-gap) + (var(--beden-w)*var(--beden-count)))
var(--psq-col-adet) !important;
}
.order-grid-header .col-fixed,
.order-grid-header .total-cell {
writing-mode: horizontal-tb !important;
transform: none !important;
height: var(--psq-header-h) !important;
font-size: 10px !important;
line-height: 1 !important;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0 4px !important;
}
.order-grid-header .beden-block {
height: var(--psq-header-h) !important;
}
.order-grid-header .grp-row {
height: var(--psq-header-h) !important;
align-items: center;
}
.order-grid-header .grp-title {
width: var(--grp-title-w) !important;
text-align: center !important;
padding-right: 0 !important;
font-size: 10px !important;
}
.order-grid-header .grp-cell.hdr {
height: var(--psq-header-h) !important;
font-size: 10px !important;
}
.order-grid-header .total-row {
grid-column: 7 / -1 !important;
}
.order-grid-header .total-cell {
width: var(--psq-col-adet) !important;
}
.order-grid-header .total-cell:last-child {
width: var(--psq-col-adet) !important;
}
.order-sub-header {
grid-template-columns:
var(--col-model)
var(--col-renk)
var(--col-ana)
var(--col-alt)
var(--col-aciklama)
calc(var(--grp-title-w) + var(--grp-title-gap) + (var(--beden-w)*var(--beden-count)))
var(--psq-col-adet) !important;
top: calc(
var(--header-h)
+ var(--filter-h)
+ var(--save-h)
+ var(--grid-header-h)
+ var(--psq-sticky-offset)
) !important;
}
.order-sub-header.level-2 {
min-height: 82px !important;
height: 82px !important;
background: #fff9c4 !important;
border-top: 1px solid #d4c79f !important;
border-bottom: 1px solid #d4c79f !important;
}
.order-sub-header.level-1 {
min-height: 84px !important;
height: 84px !important;
top: calc(
var(--header-h)
+ var(--filter-h)
+ var(--save-h)
+ var(--grid-header-h)
+ var(--psq-sticky-offset)
- var(--psq-l1-lift)
) !important;
background: var(--q-primary, #1976d2) !important;
border-top: 1px solid #145ea8 !important;
border-bottom: 1px solid #145ea8 !important;
color: #fff !important;
}
.order-sub-header.level-1 .sub-col.level1-merged {
grid-column: 1 / 6;
display: flex;
flex-direction: column;
justify-content: center;
gap: 2px;
padding: 0 10px;
border-right: 1px solid rgba(255, 255, 255, 0.45);
min-width: 0;
}
.order-sub-header.level-1 .sub-col.level1-merged .text-caption {
color: #fff !important;
opacity: 0.95;
}
.order-sub-header.level-1 .sub-center.level1-center {
grid-column: 6;
display: grid;
grid-template-rows: 42px 42px;
align-items: stretch;
height: 100%;
overflow: hidden;
padding-left: calc(var(--grp-title-w) + var(--grp-title-gap));
margin-left: 0;
}
.order-sub-header.level-1 .beden-row {
display: grid;
grid-auto-flow: column;
grid-auto-columns: var(--beden-w);
height: 42px;
min-height: 42px;
}
.order-sub-header.level-1 .beden-row .beden-cell {
display: flex;
align-items: center;
justify-content: center;
height: 42px;
min-height: 42px;
background: var(--q-primary, #1976d2) !important;
color: #fff !important;
border-right: 1px solid rgba(255, 255, 255, 0.45);
border-bottom: 1px solid rgba(255, 255, 255, 0.45);
border-top: none;
border-left: none;
font-size: 12px;
font-weight: 600;
line-height: 1;
white-space: nowrap;
overflow: hidden;
}
.order-sub-header.level-1 .beden-row.values-top .beden-cell {
background: #fff9c4 !important;
color: var(--q-primary, #1976d2) !important;
font-weight: 700;
}
.order-sub-header.level-1 .beden-row.headers .beden-cell {
font-weight: 500;
color: #fff !important;
}
.order-sub-header.level-1 .sub-right.level1-right {
grid-column: 7 / 8;
display: grid;
grid-template-columns: var(--psq-col-adet);
grid-template-rows: 30px 30px 24px;
align-items: stretch;
justify-items: stretch;
height: 100%;
overflow: hidden;
padding: 0 8px 0 6px;
border-left: 1px solid rgba(255, 255, 255, 0.45);
color: #fff;
}
.order-sub-header.level-1 .sub-right .top-total {
grid-column: 1;
grid-row: 1;
display: flex;
align-items: center;
justify-content: flex-end;
font-size: 14px;
font-weight: 700;
line-height: 1;
white-space: nowrap;
background: #fff9c4 !important;
color: var(--q-primary, #1976d2) !important;
padding: 0 6px;
border-radius: 4px;
}
.order-sub-header.level-1 .sub-right .bottom-label {
font-size: 12px;
font-weight: 700;
}
.order-sub-header.level-1 .sub-right .bottom-row {
grid-column: 1;
grid-row: 2;
width: 100%;
display: flex;
align-items: center;
justify-content: flex-end;
gap: 4px;
white-space: nowrap;
overflow: hidden;
}
.order-sub-header.level-1 .sub-right .icon-row {
grid-column: 1;
grid-row: 3;
display: flex;
align-items: center;
justify-content: flex-end;
}
.order-sub-header.level-2 .sub-col {
display: flex;
align-items: center;
padding: 0 8px;
font-size: 12px;
font-weight: 500;
color: #111;
min-width: 0;
border-right: 1px solid #d4c79f;
white-space: normal;
overflow: visible;
text-overflow: clip;
line-height: 1.2;
word-break: break-word;
overflow-wrap: anywhere;
}
.order-sub-header.level-2 .sub-col.model { grid-column: 1; }
.order-sub-header.level-2 .sub-col.renk { grid-column: 2; }
.order-sub-header.level-2 .sub-col.ana { grid-column: 3; }
.order-sub-header.level-2 .sub-col.alt { grid-column: 4; }
.order-sub-header.level-2 .sub-col.aciklama { grid-column: 5; }
.order-sub-header.level-2 .sub-col.model,
.order-sub-header.level-2 .sub-col.renk,
.order-sub-header.level-2 .sub-col.ana,
.order-sub-header.level-2 .sub-col.alt {
justify-content: center;
text-align: center;
}
.order-sub-header.level-2 .sub-col.renk {
flex-direction: column;
gap: 2px;
line-height: 1.1;
}
.order-sub-header.level-2 .sub-col.renk .renk-kodu {
font-weight: 700;
}
.order-sub-header.level-2 .sub-col.renk .renk-aciklama {
font-size: 11px;
opacity: 0.9;
}
.order-sub-header.level-2 .sub-col.aciklama {
justify-content: flex-start;
text-align: left;
}
.order-sub-header.level-2 .sub-center.level2-center {
grid-column: 6;
display: grid;
grid-template-rows: 1fr 1fr;
align-items: stretch;
height: 100%;
padding-left: var(--grp-title-w);
margin-left: var(--grp-title-gap);
}
.order-sub-header.level-2 .beden-row {
display: grid;
grid-auto-flow: column;
grid-auto-columns: var(--beden-w);
}
.order-sub-header.level-2 .beden-row.values-top .beden-cell {
border-right: 1px solid #d4c79f;
background: transparent;
font-size: 13px;
font-weight: 600;
color: #1f1f1f;
line-height: 1;
}
.order-sub-header.level-2 .beden-row.headers .beden-cell {
border-top: 1px solid #d4c79f;
border-right: 1px solid #d4c79f;
border-bottom: none;
background: var(--q-primary, #1976d2);
font-size: 12px;
font-weight: 700;
color: #fff;
line-height: 1;
}
.order-sub-header.level-2 .sub-right.level2-right {
grid-column: 7 / 8;
display: grid;
grid-template-columns: var(--psq-col-adet);
grid-template-rows: 1fr 1fr;
align-items: center;
justify-items: start;
padding-left: 8px;
padding-right: 0;
transform: none !important;
border-left: 1px solid #d4c79f;
}
.order-sub-header.level-2 .sub-right .top-total {
grid-column: 1 / 2;
grid-row: 1;
font-size: 14px;
font-weight: 700;
line-height: 1;
justify-self: start;
text-align: left;
}
.order-sub-header.level-2 .sub-right .bottom-label {
font-size: 12px;
font-weight: 700;
}
.order-sub-header.level-2 .sub-right .bottom-row {
grid-column: 1;
grid-row: 2;
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
gap: 4px;
}
.order-grid-body .summary-row {
display: grid !important;
grid-template-columns:
var(--col-model)
var(--col-renk)
var(--col-ana)
var(--col-alt)
var(--col-aciklama)
calc(var(--grp-title-w) + var(--grp-title-gap) + (var(--beden-w) * var(--beden-count)))
var(--psq-col-adet) !important;
min-height: 56px;
height: 56px;
background: #fff;
border-top: 1px solid #d4c79f;
border-bottom: 1px solid #d4c79f;
align-items: stretch;
}
.order-grid-body .summary-row .cell {
min-height: 56px;
height: 56px;
display: flex;
align-items: center;
justify-content: center;
border-right: 1px solid #d4c79f;
font-size: 12px;
overflow: hidden !important;
}
.order-grid-body .summary-row .cell:last-child {
border-right: none;
}
.order-grid-body .summary-row .grp-area {
display: grid !important;
grid-template-columns: var(--grp-title-w) var(--grp-title-gap) 1fr;
width: 100% !important;
height: 56px;
padding-left: 0 !important;
transform: none !important;
border-right: 1px solid #d4c79f;
}
.order-grid-body .summary-row .grp-row {
grid-column: 3;
width: 100%;
height: 56px;
margin-left: 0 !important;
justify-content: start !important;
display: grid;
grid-auto-flow: column;
grid-auto-columns: var(--beden-w);
}
.order-grid-body .summary-row .grp-row .cell.beden {
width: var(--beden-w);
display: flex;
align-items: center;
justify-content: center;
padding: 0 !important;
margin: 0 !important;
border-right: 1px solid #d4c79f;
border-left: none !important;
border-top: none !important;
border-bottom: none !important;
min-height: 56px;
height: 56px;
box-sizing: border-box;
}
.order-grid-body .summary-row .grp-row .cell.beden:first-child {
border-left: 1px solid #d4c79f !important;
}
.order-grid-body .summary-row .cell.model,
.order-grid-body .summary-row .cell.renk,
.order-grid-body .summary-row .cell.ana,
.order-grid-body .summary-row .cell.alt {
justify-content: center;
text-align: center;
}
.order-grid-body .summary-row .cell.aciklama {
grid-column: 5 / 6 !important;
position: static !important;
width: var(--col-aciklama) !important;
margin-right: 0 !important;
min-height: 56px !important;
z-index: auto !important;
background: #fff !important;
box-sizing: border-box !important;
border-right: 1px solid #d4c79f !important;
justify-content: flex-start !important;
text-align: left !important;
white-space: nowrap !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
line-height: 1 !important;
padding-left: 6px !important;
padding-right: 6px !important;
display: flex !important;
flex-direction: row !important;
align-items: center !important;
}
.order-grid-body .summary-row .cell.depo-merged {
grid-column: 1 / 6 !important;
justify-content: center !important;
text-align: center !important;
font-weight: 600;
white-space: nowrap !important;
overflow: hidden !important;
text-overflow: ellipsis !important;
}
.order-grid-body .summary-row .cell.adet,
.order-grid-body .summary-row .cell.termin {
justify-content: flex-end;
text-align: right;
padding-right: 10px !important;
font-weight: 700;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.order-grid-body {
margin-top: 0 !important;
padding-top: 0 !important;
}
.order-grid-body > .summary-group,
.order-grid-body > .summary-group:first-child {
margin-top: 0 !important;
padding-top: 0 !important;
}
.detail-table-wrap {
padding: 8px 0 12px 0;
background: #fff;
}
.detail-table :deep(th),
.detail-table :deep(td) {
white-space: nowrap;
}
</style>