170 lines
4.4 KiB
JavaScript
170 lines
4.4 KiB
JavaScript
import { defineStore } from 'pinia'
|
|
import { computed, ref } from 'vue'
|
|
import { get, post, extractApiErrorDetail } from 'src/services/api'
|
|
|
|
const DRAFT_KEY = 'bssapp:production-product-costing:default-quantities:draft:v1'
|
|
|
|
function safeJsonParse (raw) {
|
|
try {
|
|
return JSON.parse(raw)
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
export const useProductionProductCostingDefaultQtyStore = defineStore('production_product_costing_default_qty', () => {
|
|
const rows = ref([])
|
|
const loading = ref(false)
|
|
const saving = ref(false)
|
|
const error = ref('')
|
|
|
|
// draftByNo: { [nHammaddeTuruNo]: { lDefaultMiktar } }
|
|
const draftByNo = ref({})
|
|
const persistTimer = ref(0)
|
|
|
|
const dirtyNos = computed(() => Object.keys(draftByNo.value || {}).map(k => Number(k)).filter(n => n > 0))
|
|
const hasUnsavedChanges = computed(() => dirtyNos.value.length > 0)
|
|
|
|
function schedulePersistDraft () {
|
|
try {
|
|
if (persistTimer.value) window.clearTimeout(persistTimer.value)
|
|
persistTimer.value = window.setTimeout(() => {
|
|
persistTimer.value = 0
|
|
persistDraftNow()
|
|
}, 350)
|
|
} catch {
|
|
persistDraftNow()
|
|
}
|
|
}
|
|
|
|
function persistDraftNow () {
|
|
try {
|
|
const payload = {
|
|
version: 1,
|
|
savedAt: new Date().toISOString(),
|
|
draftByNo: draftByNo.value || {}
|
|
}
|
|
localStorage.setItem(DRAFT_KEY, JSON.stringify(payload))
|
|
} catch {
|
|
// ignore
|
|
}
|
|
}
|
|
|
|
function hydrateDraft () {
|
|
try {
|
|
const raw = localStorage.getItem(DRAFT_KEY)
|
|
if (!raw) return
|
|
const payload = safeJsonParse(raw)
|
|
if (!payload || typeof payload !== 'object') return
|
|
if (!payload.draftByNo || typeof payload.draftByNo !== 'object') return
|
|
draftByNo.value = payload.draftByNo
|
|
} catch {
|
|
// ignore
|
|
}
|
|
}
|
|
|
|
function clearDraft () {
|
|
draftByNo.value = {}
|
|
try {
|
|
localStorage.removeItem(DRAFT_KEY)
|
|
} catch {
|
|
// ignore
|
|
}
|
|
}
|
|
|
|
function setDraft (nHammaddeTuruNo, patch) {
|
|
const no = Number(nHammaddeTuruNo || 0)
|
|
if (!(no > 0)) return
|
|
const prev = draftByNo.value?.[String(no)] || {}
|
|
draftByNo.value = {
|
|
...(draftByNo.value || {}),
|
|
[String(no)]: {
|
|
...prev,
|
|
...(patch || {})
|
|
}
|
|
}
|
|
schedulePersistDraft()
|
|
}
|
|
|
|
function getEffectiveRow (row) {
|
|
const no = Number(row?.nHammaddeTuruNo || 0)
|
|
if (!(no > 0)) return row
|
|
const draft = draftByNo.value?.[String(no)]
|
|
if (!draft) return row
|
|
return {
|
|
...row,
|
|
lDefaultMiktar: typeof draft.lDefaultMiktar === 'number' ? draft.lDefaultMiktar : row?.lDefaultMiktar,
|
|
__dirty: true
|
|
}
|
|
}
|
|
|
|
async function fetch ({ search = '', limit = 2000 } = {}) {
|
|
loading.value = true
|
|
error.value = ''
|
|
try {
|
|
const data = await get('/pricing/production-product-costing/default-quantities', {
|
|
search: String(search || '').trim(),
|
|
limit
|
|
})
|
|
const base = Array.isArray(data) ? data : []
|
|
rows.value = base.map(getEffectiveRow)
|
|
} catch (e) {
|
|
error.value = extractApiErrorDetail(e) || String(e?.message || e || 'Hata')
|
|
throw e
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
async function calcAvgForRow ({ nHammaddeTuruNo, topN = 10 } = {}) {
|
|
const no = Number(nHammaddeTuruNo || 0)
|
|
if (!(no > 0)) return null
|
|
const resp = await post('/pricing/production-product-costing/default-quantities/calc-avg', {
|
|
nHammaddeTuruNo: no,
|
|
topN: Number(topN || 10)
|
|
})
|
|
return resp
|
|
}
|
|
|
|
async function saveAll () {
|
|
if (!hasUnsavedChanges.value) return { updated: 0 }
|
|
saving.value = true
|
|
error.value = ''
|
|
try {
|
|
const items = dirtyNos.value.map(no => {
|
|
const patch = draftByNo.value?.[String(no)] || {}
|
|
return {
|
|
nHammaddeTuruNo: Number(no),
|
|
lDefaultMiktar: Number(patch.lDefaultMiktar || 0)
|
|
}
|
|
}).filter(it => it.nHammaddeTuruNo > 0 && it.lDefaultMiktar > 0)
|
|
|
|
const resp = await post('/pricing/production-product-costing/default-quantities/update-bulk', { items })
|
|
clearDraft()
|
|
return resp
|
|
} catch (e) {
|
|
error.value = extractApiErrorDetail(e) || String(e?.message || e || 'Hata')
|
|
throw e
|
|
} finally {
|
|
saving.value = false
|
|
}
|
|
}
|
|
|
|
hydrateDraft()
|
|
|
|
return {
|
|
rows,
|
|
loading,
|
|
saving,
|
|
error,
|
|
draftByNo,
|
|
dirtyNos,
|
|
hasUnsavedChanges,
|
|
fetch,
|
|
setDraft,
|
|
calcAvgForRow,
|
|
saveAll,
|
|
clearDraft
|
|
}
|
|
})
|