Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -80,7 +80,7 @@
|
||||
<q-item-section>Tumunu Temizle</q-item-section>
|
||||
</q-item>
|
||||
<q-separator />
|
||||
<q-item v-for="option in priceOptions" :key="option.value" clickable @click="togglePriceOption(option.value)">
|
||||
<q-item v-for="option in allowedPriceOptions" :key="option.value" clickable @click="togglePriceOption(option.value)">
|
||||
<q-item-section avatar>
|
||||
<q-checkbox
|
||||
dense
|
||||
@@ -165,7 +165,7 @@
|
||||
>
|
||||
<div
|
||||
class="top-x-scroll-inner"
|
||||
:style="{ width: `${tableMinWidth}px` }"
|
||||
:style="{ width: `${tableScrollWidth}px` }"
|
||||
/>
|
||||
</div>
|
||||
<q-table
|
||||
@@ -589,18 +589,6 @@
|
||||
<div class="field-row"><span class="k">Kampanya</span><span class="v">{{ productCardData.campaignLabel || '-' }}</span></div>
|
||||
<div class="field-row"><span class="k">Stok</span><span class="v">{{ formatStock(productCardData.stockQty || 0) }}</span></div>
|
||||
|
||||
<div class="product-card-section">
|
||||
<div class="product-card-section-title">Fiyat Bilgileri</div>
|
||||
<div v-if="productCardPriceRows.length" class="price-info-grid">
|
||||
<div v-for="item in productCardPriceRows" :key="item.key" class="price-info-row">
|
||||
<span class="price-label">{{ item.label }}</span>
|
||||
<span class="price-value">{{ item.price || '-' }}</span>
|
||||
<span class="price-campaign">{{ item.campaignPrice || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="product-card-empty-text">Secili fiyat kolonu yok.</div>
|
||||
</div>
|
||||
|
||||
<div class="product-card-section">
|
||||
<div class="product-card-section-title">Beden Stoklari</div>
|
||||
<q-inner-loading :showing="productCardStockLoading">
|
||||
@@ -615,6 +603,25 @@
|
||||
<div v-else-if="!productCardStockLoading" class="product-card-empty-text">Beden stogu bulunamadi.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="product-card-price-panel">
|
||||
<div class="product-card-section product-card-price-section">
|
||||
<div class="product-card-section-title">Fiyat Bilgileri</div>
|
||||
<div class="price-info-header">
|
||||
<span>Fiyat</span>
|
||||
<span>Liste</span>
|
||||
<span>Kampanyali</span>
|
||||
</div>
|
||||
<div v-if="productCardPriceRows.length" class="price-info-grid">
|
||||
<div v-for="item in productCardPriceRows" :key="item.key" :class="['price-info-row', `price-info-row-${item.currency}`, { 'has-campaign-price': item.hasCampaignPrice }]">
|
||||
<span class="price-label">{{ item.label }}</span>
|
||||
<span class="price-value">{{ item.price || '-' }}</span>
|
||||
<span class="price-campaign">{{ item.campaignPrice || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="product-card-empty-text">Secili fiyat kolonu yok.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
@@ -664,10 +671,18 @@ import api from 'src/services/api'
|
||||
const PAGE_LIMIT = 250
|
||||
const GUIDANCE_MSG = 'Liste icin filtre secin.'
|
||||
|
||||
const priceOptions = ['USD', 'EUR', 'TRY'].flatMap((cur) => [1, 2, 3, 4, 5, 6].map((lv) => ({
|
||||
const allPriceOptions = ['USD', 'EUR', 'TRY'].flatMap((cur) => [1, 2, 3, 4, 5, 6].map((lv) => ({
|
||||
label: `${cur} ${lv}`,
|
||||
value: `${cur.toLowerCase()}${lv}`
|
||||
})))
|
||||
const allowedPriceGroupValues = ref([])
|
||||
const priceGroupRestricted = ref(false)
|
||||
const allowedPriceOptions = computed(() => {
|
||||
if (!priceGroupRestricted.value) return allPriceOptions
|
||||
const allowed = new Set(allowedPriceGroupValues.value || [])
|
||||
return allPriceOptions.filter((x) => allowed.has(x.value))
|
||||
})
|
||||
const priceOptions = allPriceOptions
|
||||
const campaignPairs = priceOptions.map((x) => ({ base: x.value, derived: `${x.value}Campaign` }))
|
||||
const priceColumnNames = campaignPairs.flatMap((p) => [p.base, p.derived])
|
||||
|
||||
@@ -721,8 +736,10 @@ const productCardPriceRows = computed(() => {
|
||||
.map((option) => ({
|
||||
key: option.value,
|
||||
label: option.label,
|
||||
currency: String(option.value || '').slice(0, 3).toLowerCase(),
|
||||
price: formatPrice(row?.[option.value]),
|
||||
campaignPrice: formatPrice(row?.[`${option.value}Campaign`])
|
||||
campaignPrice: formatPrice(row?.[`${option.value}Campaign`]),
|
||||
hasCampaignPrice: Number(row?.[`${option.value}Campaign`] || 0) > 0
|
||||
}))
|
||||
})
|
||||
const selectedProductCodeSet = computed(() => new Set(selectedProductCodes.value || []))
|
||||
@@ -956,6 +973,20 @@ async function fetchServerFilterOptions (field, q = '') {
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchMyPriceGroups () {
|
||||
try {
|
||||
const res = await api.get('/order/price-list/my-price-groups')
|
||||
priceGroupRestricted.value = !!res?.data?.restricted
|
||||
allowedPriceGroupValues.value = Array.isArray(res?.data?.price_groups) ? res.data.price_groups : []
|
||||
normalizeSelectedPriceOptions()
|
||||
} catch (err) {
|
||||
console.warn('[order-price-list][ui] price-groups lookup failed', err?.response?.data || err?.message || err)
|
||||
priceGroupRestricted.value = false
|
||||
allowedPriceGroupValues.value = []
|
||||
normalizeSelectedPriceOptions()
|
||||
}
|
||||
}
|
||||
|
||||
function onTopFilterSearchUrunIlkGrubu (val, update) {
|
||||
update(() => {
|
||||
filterSearch.value.urunIlkGrubu = toText(val)
|
||||
@@ -1306,20 +1337,33 @@ function onPageChange (page) {
|
||||
}
|
||||
|
||||
function togglePriceOption (value) {
|
||||
if (!allowedPriceOptions.value.some((x) => x.value === value)) return
|
||||
const set = new Set(selectedPriceOptions.value || [])
|
||||
if (set.has(value)) set.delete(value)
|
||||
else set.add(value)
|
||||
selectedPriceOptions.value = priceOptions.map((x) => x.value).filter((x) => set.has(x))
|
||||
selectedPriceOptions.value = allowedPriceOptions.value.map((x) => x.value).filter((x) => set.has(x))
|
||||
}
|
||||
|
||||
function selectAllPrices () {
|
||||
selectedPriceOptions.value = priceOptions.map((x) => x.value)
|
||||
selectedPriceOptions.value = allowedPriceOptions.value.map((x) => x.value)
|
||||
}
|
||||
|
||||
function clearAllPrices () {
|
||||
selectedPriceOptions.value = []
|
||||
}
|
||||
|
||||
function normalizeSelectedPriceOptions () {
|
||||
const allowedValues = allowedPriceOptions.value.map((x) => x.value)
|
||||
const allowed = new Set(allowedValues)
|
||||
const current = (selectedPriceOptions.value || []).filter((x) => allowed.has(x))
|
||||
if (current.length > 0 || allowedValues.length === 0) {
|
||||
selectedPriceOptions.value = current
|
||||
return
|
||||
}
|
||||
const preferred = ['usd5', 'try5'].filter((x) => allowed.has(x))
|
||||
selectedPriceOptions.value = preferred.length ? preferred : allowedValues.slice(0, 2)
|
||||
}
|
||||
|
||||
function col (name, label, field, width, extra = {}) {
|
||||
return {
|
||||
name,
|
||||
@@ -1402,6 +1446,7 @@ const filteredRows = computed(() => {
|
||||
return list
|
||||
})
|
||||
const tableMinWidth = computed(() => visibleColumns.value.reduce((sum, c) => sum + extractWidth(c.style), 0))
|
||||
const tableScrollWidth = computed(() => tableMinWidth.value + stickyScrollComp.value + 48)
|
||||
const tableStyle = computed(() => ({
|
||||
width: `${tableMinWidth.value}px`,
|
||||
minWidth: `${tableMinWidth.value}px`,
|
||||
@@ -1609,7 +1654,12 @@ watch([tableMinWidth, rows], async () => {
|
||||
bindTableScrollSync()
|
||||
})
|
||||
|
||||
watch(allowedPriceOptions, () => {
|
||||
normalizeSelectedPriceOptions()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
void fetchMyPriceGroups()
|
||||
void fetchServerFilterOptions('urunIlkGrubu', '')
|
||||
void fetchServerFilterOptions('urunAnaGrubu', '')
|
||||
void fetchServerFilterOptions('productCode', '')
|
||||
@@ -1885,23 +1935,23 @@ onMounted(() => {
|
||||
|
||||
.pricing-table :deep(th.usd-col),
|
||||
.pricing-table :deep(td.usd-col) {
|
||||
background: #ecf9f0;
|
||||
color: #178a3e;
|
||||
font-weight: 700;
|
||||
background: #fff;
|
||||
color: #16803a;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.pricing-table :deep(th.eur-col),
|
||||
.pricing-table :deep(td.eur-col) {
|
||||
background: #fdeeee;
|
||||
color: #c62828;
|
||||
font-weight: 700;
|
||||
background: #fff;
|
||||
color: #b91c1c;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.pricing-table :deep(th.try-col),
|
||||
.pricing-table :deep(td.try-col) {
|
||||
background: #edf4ff;
|
||||
color: #1e63c6;
|
||||
font-weight: 700;
|
||||
background: #fff;
|
||||
color: #185abc;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.pricing-table :deep(th.usd-col),
|
||||
@@ -1910,14 +1960,30 @@ onMounted(() => {
|
||||
.pricing-table :deep(td.usd-col),
|
||||
.pricing-table :deep(td.eur-col),
|
||||
.pricing-table :deep(td.try-col) {
|
||||
font-size: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.pricing-table :deep(td.campaign-price-col),
|
||||
.pricing-table :deep(th.campaign-price-col) {
|
||||
background: #fff3f1;
|
||||
color: #c62828;
|
||||
font-weight: 800;
|
||||
.pricing-table :deep(th.usd-col.campaign-price-col),
|
||||
.pricing-table :deep(td.usd-col.campaign-price-col) {
|
||||
background: #dff6e7;
|
||||
color: #0f6b2f;
|
||||
font-weight: 900;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.pricing-table :deep(th.eur-col.campaign-price-col),
|
||||
.pricing-table :deep(td.eur-col.campaign-price-col) {
|
||||
background: #fde2e2;
|
||||
color: #a61717;
|
||||
font-weight: 900;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.pricing-table :deep(th.try-col.campaign-price-col),
|
||||
.pricing-table :deep(td.try-col.campaign-price-col) {
|
||||
background: #e2edff;
|
||||
color: #174ea6;
|
||||
font-weight: 900;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
@@ -1989,7 +2055,6 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.campaign-price-text {
|
||||
color: #c62828;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
@@ -2100,7 +2165,7 @@ onMounted(() => {
|
||||
|
||||
.product-card-dialog {
|
||||
--pc-media-h: calc(100vh - 180px);
|
||||
--pc-media-w: min(74vw, 1220px);
|
||||
--pc-media-w: min(28vw, 440px);
|
||||
background: #f9f8f5;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
@@ -2115,10 +2180,10 @@ onMounted(() => {
|
||||
|
||||
.product-card-content {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(360px, 420px) minmax(760px, 1fr);
|
||||
grid-template-columns: minmax(360px, 420px) minmax(360px, 440px) minmax(320px, 420px);
|
||||
gap: 14px;
|
||||
align-items: stretch;
|
||||
justify-content: start;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -2126,6 +2191,7 @@ onMounted(() => {
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
height: var(--pc-media-h);
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
@@ -2133,7 +2199,7 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.product-card-carousel {
|
||||
width: var(--pc-media-w);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100%;
|
||||
background: linear-gradient(180deg, #f6f1e6 0%, #efe6d3 100%);
|
||||
@@ -2146,7 +2212,7 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.dialog-image-stage {
|
||||
width: var(--pc-media-w);
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
@@ -2158,7 +2224,7 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.dialog-image-empty {
|
||||
width: var(--pc-media-w);
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: var(--pc-media-h);
|
||||
border: 1px dashed #c5b28d;
|
||||
@@ -2180,6 +2246,14 @@ onMounted(() => {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.product-card-price-panel {
|
||||
grid-column: 3;
|
||||
grid-row: 1;
|
||||
min-width: 0;
|
||||
height: var(--pc-media-h);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.field-row {
|
||||
display: grid;
|
||||
grid-template-columns: 150px 1fr;
|
||||
@@ -2220,6 +2294,13 @@ onMounted(() => {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.product-card-price-section {
|
||||
height: 100%;
|
||||
margin-top: 0;
|
||||
overflow: auto;
|
||||
background: linear-gradient(180deg, #fffdf8 0%, #fff7ec 100%);
|
||||
}
|
||||
|
||||
.product-card-section-title {
|
||||
font-size: 13px;
|
||||
font-weight: 800;
|
||||
@@ -2230,20 +2311,36 @@ onMounted(() => {
|
||||
.price-info-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 4px;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.price-info-header {
|
||||
display: grid;
|
||||
grid-template-columns: 74px 1fr 1fr;
|
||||
gap: 8px;
|
||||
margin-bottom: 6px;
|
||||
padding: 0 8px;
|
||||
color: #6b5a33;
|
||||
font-size: 11px;
|
||||
font-weight: 800;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.price-info-header span:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.price-info-row {
|
||||
display: grid;
|
||||
grid-template-columns: 70px 1fr 1fr;
|
||||
gap: 6px;
|
||||
grid-template-columns: 74px 1fr 1fr;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
min-height: 26px;
|
||||
padding: 4px 6px;
|
||||
min-height: 34px;
|
||||
padding: 6px 8px;
|
||||
border: 1px solid #f0e5d2;
|
||||
border-radius: 6px;
|
||||
background: #fff;
|
||||
font-size: 12px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.price-label {
|
||||
@@ -2253,13 +2350,49 @@ onMounted(() => {
|
||||
|
||||
.price-value,
|
||||
.price-campaign {
|
||||
min-height: 26px;
|
||||
padding: 5px 7px;
|
||||
border-radius: 5px;
|
||||
text-align: right;
|
||||
font-variant-numeric: tabular-nums;
|
||||
font-weight: 800;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.price-campaign {
|
||||
color: #b13a2b;
|
||||
font-weight: 700;
|
||||
color: #8a8a8a;
|
||||
background: #f4f4f4;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.price-info-row-usd .price-value {
|
||||
color: #16803a;
|
||||
}
|
||||
|
||||
.price-info-row-eur .price-value {
|
||||
color: #b91c1c;
|
||||
}
|
||||
|
||||
.price-info-row-try .price-value {
|
||||
color: #185abc;
|
||||
}
|
||||
|
||||
.price-info-row-usd.has-campaign-price .price-campaign {
|
||||
background: #dff6e7;
|
||||
color: #0f6b2f;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.price-info-row-eur.has-campaign-price .price-campaign {
|
||||
background: #fde2e2;
|
||||
color: #a61717;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.price-info-row-try.has-campaign-price .price-campaign {
|
||||
background: #e2edff;
|
||||
color: #174ea6;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.size-stock-grid {
|
||||
@@ -2342,9 +2475,12 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.product-card-images,
|
||||
.product-card-fields {
|
||||
.product-card-fields,
|
||||
.product-card-price-panel {
|
||||
grid-column: 1;
|
||||
grid-row: auto;
|
||||
height: auto;
|
||||
min-height: 320px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user