Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
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, bAktif } }
|
||||
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,
|
||||
bAktif: typeof draft.bAktif === 'boolean' ? draft.bAktif : row?.bAktif,
|
||||
__dirty: true
|
||||
}
|
||||
}
|
||||
|
||||
async function fetch ({ search = '', onlyActive = true, 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),
|
||||
bAktif: typeof patch.bAktif === 'boolean' ? patch.bAktif : undefined
|
||||
}
|
||||
}).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
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user