Files
bssapp/ui/src/stores/ProductPricingStore.js
2026-04-20 10:19:02 +03:00

175 lines
5.1 KiB
JavaScript

import { defineStore } from 'pinia'
import api from 'src/services/api'
function toText (value) {
return String(value ?? '').trim()
}
function toNumber (value) {
const n = parseFlexibleNumber(value)
return Number.isFinite(n) ? Number(n.toFixed(2)) : 0
}
function parseFlexibleNumber (value) {
if (typeof value === 'number') return value
const text = String(value ?? '').trim().replace(/\s/g, '')
if (!text) return 0
const lastComma = text.lastIndexOf(',')
const lastDot = text.lastIndexOf('.')
let normalized = text
if (lastComma >= 0 && lastDot >= 0) {
// Keep the last separator as decimal, remove the other as thousand.
if (lastComma > lastDot) {
normalized = text.replace(/\./g, '').replace(',', '.')
} else {
normalized = text.replace(/,/g, '')
}
} else if (lastComma >= 0) {
normalized = text.replace(/\./g, '').replace(',', '.')
} else {
normalized = text.replace(/,/g, '')
}
const n = Number(normalized)
return Number.isFinite(n) ? n : 0
}
function mapRow (raw, index, baseIndex = 0) {
return {
id: baseIndex + index + 1,
productCode: toText(raw?.ProductCode),
stockQty: toNumber(raw?.StockQty),
stockEntryDate: toText(raw?.StockEntryDate),
lastPricingDate: toText(raw?.LastPricingDate),
askiliYan: toText(raw?.AskiliYan),
kategori: toText(raw?.Kategori),
urunIlkGrubu: toText(raw?.UrunIlkGrubu),
urunAnaGrubu: toText(raw?.UrunAnaGrubu),
urunAltGrubu: toText(raw?.UrunAltGrubu),
icerik: toText(raw?.Icerik),
karisim: toText(raw?.Karisim),
marka: toText(raw?.Marka),
brandGroupSelection: toText(raw?.BrandGroupSec),
costPrice: toNumber(raw?.CostPrice),
expenseForBasePrice: 0,
basePriceUsd: 0,
basePriceTry: 0,
usd1: 0,
usd2: 0,
usd3: 0,
usd4: 0,
usd5: 0,
usd6: 0,
eur1: 0,
eur2: 0,
eur3: 0,
eur4: 0,
eur5: 0,
eur6: 0,
try1: 0,
try2: 0,
try3: 0,
try4: 0,
try5: 0,
try6: 0
}
}
export const useProductPricingStore = defineStore('product-pricing-store', {
state: () => ({
rows: [],
loading: false,
error: '',
hasMore: true
}),
actions: {
async fetchRows (options = {}) {
this.loading = true
this.error = ''
const limit = Number(options?.limit) > 0 ? Number(options.limit) : 500
const afterProductCode = toText(options?.afterProductCode)
const append = Boolean(options?.append)
const baseIndex = append ? this.rows.length : 0
const startedAt = Date.now()
console.info('[product-pricing][frontend] request:start', {
at: new Date(startedAt).toISOString(),
timeout_ms: 180000,
limit,
after_product_code: afterProductCode || null,
append
})
try {
const params = { limit }
if (afterProductCode) params.after_product_code = afterProductCode
const res = await api.request({
method: 'GET',
url: '/pricing/products',
params,
timeout: 180000
})
const traceId = res?.headers?.['x-trace-id'] || null
const hasMoreHeader = String(res?.headers?.['x-has-more'] || '').toLowerCase()
const nextCursorHeader = toText(res?.headers?.['x-next-cursor'])
const data = Array.isArray(res?.data) ? res.data : []
const mapped = data.map((x, i) => mapRow(x, i, baseIndex))
if (append) {
const merged = [...this.rows]
const seen = new Set(this.rows.map((x) => x?.productCode))
for (const row of mapped) {
const key = row?.productCode
if (key && seen.has(key)) continue
merged.push(row)
if (key) seen.add(key)
}
this.rows = merged
} else {
this.rows = mapped
}
this.hasMore = hasMoreHeader ? hasMoreHeader === 'true' : mapped.length === limit
console.info('[product-pricing][frontend] request:success', {
trace_id: traceId,
duration_ms: Date.now() - startedAt,
row_count: this.rows.length,
fetched_count: mapped.length,
has_more: this.hasMore,
next_cursor: nextCursorHeader || null
})
return {
traceId,
fetched: mapped.length,
hasMore: this.hasMore,
nextCursor: nextCursorHeader
}
} catch (err) {
if (!append) this.rows = []
this.hasMore = false
const msg = err?.response?.data || err?.message || 'Urun fiyatlandirma listesi alinamadi'
this.error = toText(msg)
console.error('[product-pricing][frontend] request:error', {
trace_id: err?.response?.headers?.['x-trace-id'] || null,
duration_ms: Date.now() - startedAt,
timeout_ms: err?.config?.timeout ?? null,
status: err?.response?.status || null,
message: this.error
})
throw err
} finally {
this.loading = false
}
},
updateCell (row, field, val) {
if (!row || !field) return
row[field] = toNumber(val)
},
updateBrandGroupSelection (row, val) {
if (!row) return
row.brandGroupSelection = toText(val)
}
}
})