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) } } })