261 lines
8.0 KiB
JavaScript
261 lines
8.0 KiB
JavaScript
// src/stores/OrderProductionItemStore.js
|
|
import { defineStore } from 'pinia'
|
|
import api from 'src/services/api'
|
|
|
|
function extractApiErrorMessage (err, fallback) {
|
|
const data = err?.response?.data
|
|
if (typeof data === 'string' && data.trim()) return data
|
|
if (data && typeof data === 'object') {
|
|
const msg = String(data.message || '').trim()
|
|
const step = String(data.step || '').trim()
|
|
const detail = String(data.detail || '').trim()
|
|
const parts = [msg]
|
|
if (step) parts.push(`step=${step}`)
|
|
if (detail) parts.push(detail)
|
|
const merged = parts.filter(Boolean).join(' | ')
|
|
if (merged) return merged
|
|
}
|
|
return err?.message || fallback
|
|
}
|
|
|
|
function logApiError (action, err, payload = null) {
|
|
const status = err?.response?.status
|
|
const data = err?.response?.data
|
|
console.error(`[OrderProductionItemStore] ${action} failed`, {
|
|
status,
|
|
payload,
|
|
data,
|
|
message: err?.message
|
|
})
|
|
}
|
|
|
|
export const useOrderProductionItemStore = defineStore('orderproductionitems', {
|
|
state: () => ({
|
|
items: [],
|
|
header: null,
|
|
products: [],
|
|
colorOptionsByCode: {},
|
|
secondColorOptionsByKey: {},
|
|
productAttributesByItemType: {},
|
|
cdItemLookups: null,
|
|
cdItemDraftsByCode: {},
|
|
productAttributeDraftsByCode: {},
|
|
loading: false,
|
|
saving: false,
|
|
error: null
|
|
}),
|
|
|
|
getters: {
|
|
productCodeSet (state) {
|
|
const set = new Set()
|
|
for (const p of (state.products || [])) {
|
|
const code = String(p?.ProductCode || '').trim().toUpperCase()
|
|
if (code) set.add(code)
|
|
}
|
|
return set
|
|
}
|
|
},
|
|
|
|
actions: {
|
|
classifyItemCode (value) {
|
|
const normalized = String(value || '').trim().toUpperCase()
|
|
if (!normalized) {
|
|
return { normalized: '', mode: 'empty', exists: false }
|
|
}
|
|
const exists = this.productCodeSet.has(normalized)
|
|
return {
|
|
normalized,
|
|
mode: exists ? 'existing' : 'new',
|
|
exists
|
|
}
|
|
},
|
|
|
|
async fetchHeader (orderHeaderID) {
|
|
if (!orderHeaderID) {
|
|
this.header = null
|
|
return
|
|
}
|
|
|
|
this.loading = true
|
|
this.error = null
|
|
|
|
try {
|
|
const res = await api.get(`/order/get/${encodeURIComponent(orderHeaderID)}`)
|
|
this.header = res?.data?.header || null
|
|
} catch (err) {
|
|
this.header = null
|
|
this.error = err?.response?.data || err?.message || 'Siparis bilgisi alinamadi'
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
async fetchItems (orderHeaderID) {
|
|
if (!orderHeaderID) {
|
|
this.items = []
|
|
return
|
|
}
|
|
|
|
this.loading = true
|
|
this.error = null
|
|
|
|
try {
|
|
const res = await api.get(`/orders/production-items/${encodeURIComponent(orderHeaderID)}`)
|
|
const data = res?.data
|
|
this.items = Array.isArray(data) ? data : []
|
|
} catch (err) {
|
|
this.items = []
|
|
this.error = err?.response?.data || err?.message || 'Liste alinamadi'
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
async fetchProducts () {
|
|
this.error = null
|
|
try {
|
|
const res = await api.get('/products')
|
|
const data = res?.data
|
|
this.products = Array.isArray(data) ? data : []
|
|
} catch (err) {
|
|
this.products = []
|
|
this.error = err?.response?.data || err?.message || 'Urun listesi alinamadi'
|
|
}
|
|
},
|
|
async fetchColors (productCode) {
|
|
const code = String(productCode || '').trim()
|
|
if (!code) return []
|
|
|
|
if (this.colorOptionsByCode[code]) {
|
|
return this.colorOptionsByCode[code]
|
|
}
|
|
|
|
try {
|
|
const res = await api.get('/product-colors', { params: { code } })
|
|
const data = res?.data
|
|
const list = Array.isArray(data) ? data : []
|
|
this.colorOptionsByCode[code] = list
|
|
return list
|
|
} catch (err) {
|
|
this.error = err?.response?.data || err?.message || 'Renk listesi alinamadi'
|
|
return []
|
|
}
|
|
},
|
|
async fetchSecondColors (productCode, colorCode) {
|
|
const code = String(productCode || '').trim()
|
|
const color = String(colorCode || '').trim()
|
|
if (!code || !color) return []
|
|
|
|
const key = `${code}::${color}`
|
|
if (this.secondColorOptionsByKey[key]) {
|
|
return this.secondColorOptionsByKey[key]
|
|
}
|
|
|
|
try {
|
|
const res = await api.get('/product-secondcolor', { params: { code, color } })
|
|
const data = res?.data
|
|
const list = Array.isArray(data) ? data : []
|
|
this.secondColorOptionsByKey[key] = list
|
|
return list
|
|
} catch (err) {
|
|
this.error = err?.response?.data || err?.message || '2. renk listesi alinamadi'
|
|
return []
|
|
}
|
|
},
|
|
async fetchProductAttributes (itemTypeCode = 1) {
|
|
const key = String(itemTypeCode || 1)
|
|
if (this.productAttributesByItemType[key]) {
|
|
return this.productAttributesByItemType[key]
|
|
}
|
|
try {
|
|
const res = await api.get('/product-attributes', { params: { itemTypeCode } })
|
|
const list = Array.isArray(res?.data) ? res.data : []
|
|
this.productAttributesByItemType[key] = list
|
|
return list
|
|
} catch (err) {
|
|
this.error = err?.response?.data || err?.message || 'Urun ozellikleri alinamadi'
|
|
return []
|
|
}
|
|
},
|
|
async fetchCdItemLookups (force = false) {
|
|
if (this.cdItemLookups && !force) return this.cdItemLookups
|
|
try {
|
|
const res = await api.get('/orders/production-items/cditem-lookups')
|
|
this.cdItemLookups = res?.data || null
|
|
return this.cdItemLookups
|
|
} catch (err) {
|
|
this.error = err?.response?.data || err?.message || 'cdItem lookup listesi alinamadi'
|
|
return null
|
|
}
|
|
},
|
|
setCdItemDraft (itemCode, draft) {
|
|
const code = String(itemCode || '').trim().toUpperCase()
|
|
if (!code) return
|
|
this.cdItemDraftsByCode = {
|
|
...this.cdItemDraftsByCode,
|
|
[code]: {
|
|
...(draft || {}),
|
|
ItemCode: code,
|
|
ItemTypeCode: Number(draft?.ItemTypeCode || 1)
|
|
}
|
|
}
|
|
},
|
|
getCdItemDraft (itemCode) {
|
|
const code = String(itemCode || '').trim().toUpperCase()
|
|
if (!code) return null
|
|
return this.cdItemDraftsByCode[code] || null
|
|
},
|
|
setProductAttributeDraft (itemCode, rows) {
|
|
const code = String(itemCode || '').trim().toUpperCase()
|
|
if (!code) return
|
|
this.productAttributeDraftsByCode = {
|
|
...this.productAttributeDraftsByCode,
|
|
[code]: Array.isArray(rows) ? rows : []
|
|
}
|
|
},
|
|
getProductAttributeDraft (itemCode) {
|
|
const code = String(itemCode || '').trim().toUpperCase()
|
|
if (!code) return []
|
|
return this.productAttributeDraftsByCode[code] || []
|
|
},
|
|
async validateUpdates (orderHeaderID, lines) {
|
|
if (!orderHeaderID) return { missingCount: 0, missing: [] }
|
|
|
|
this.saving = true
|
|
this.error = null
|
|
|
|
try {
|
|
const res = await api.post(
|
|
`/orders/production-items/${encodeURIComponent(orderHeaderID)}/validate`,
|
|
{ lines }
|
|
)
|
|
return res?.data || { missingCount: 0, missing: [] }
|
|
} catch (err) {
|
|
logApiError('validateUpdates', err, { orderHeaderID, lineCount: lines?.length || 0 })
|
|
this.error = extractApiErrorMessage(err, 'Kontrol basarisiz')
|
|
throw err
|
|
} finally {
|
|
this.saving = false
|
|
}
|
|
},
|
|
async applyUpdates (orderHeaderID, lines, insertMissing, cdItems = [], productAttributes = []) {
|
|
if (!orderHeaderID) return { updated: 0, inserted: 0 }
|
|
|
|
this.saving = true
|
|
this.error = null
|
|
|
|
try {
|
|
const res = await api.post(
|
|
`/orders/production-items/${encodeURIComponent(orderHeaderID)}/apply`,
|
|
{ lines, insertMissing, cdItems, productAttributes }
|
|
)
|
|
return res?.data || { updated: 0, inserted: 0 }
|
|
} catch (err) {
|
|
logApiError('applyUpdates', err, { orderHeaderID, lineCount: lines?.length || 0, insertMissing })
|
|
this.error = extractApiErrorMessage(err, 'Guncelleme basarisiz')
|
|
throw err
|
|
} finally {
|
|
this.saving = false
|
|
}
|
|
}
|
|
}
|
|
})
|