654 lines
24 KiB
Plaintext
654 lines
24 KiB
Plaintext
// src/stores/orderentryStore.js
|
||
import { defineStore } from 'pinia'
|
||
import axios from 'axios'
|
||
import qs from 'qs'
|
||
import { useAuthStore } from 'src/stores/authStore'
|
||
import dayjs from 'src/boot/dayjs'
|
||
import { ref, watch } from 'vue'
|
||
|
||
/* ==========================================================
|
||
Reaktif shared referanslar (bazı UI yardımcıları)
|
||
========================================================== */
|
||
const stockMap = ref({}) // { "48": 12, "50": 7, ... }
|
||
const bedenStock = ref([]) // [{beden:'48', stok:12}, ...]
|
||
const sizeCache = ref({}) // beden/stok cache (component tarafı çağırıyor)
|
||
|
||
/* ==========================================================
|
||
STORE
|
||
========================================================== */
|
||
export const useOrderentryStore = defineStore('orderentry', {
|
||
state: () => ({
|
||
/* 🔹 Ana durumlar */
|
||
orders: [], // grid kaynak array’i (summaryRows ile senkron)
|
||
loading: false,
|
||
selected: null, // UI’de seçili satır
|
||
error: null,
|
||
|
||
/* 🔹 Cari */
|
||
customers: [],
|
||
selectedCustomer: null,
|
||
|
||
/* 🔹 Ürün zinciri */
|
||
products: [],
|
||
colors: [],
|
||
secondColors: [],
|
||
inventory: [],
|
||
|
||
selectedProduct: null,
|
||
selectedColor: null,
|
||
selectedColor2: null,
|
||
|
||
/* 🔹 Transaction & Storage */
|
||
activeTransactionId: null,
|
||
persistKey: 'bss_orderentry_data', // ♻️ kalıcı depolama key’i
|
||
lastSnapshotKey: 'bss_orderentry_snapshot', // son-kaydedilen-sipariş
|
||
|
||
/* 🔹 Düzenleme durumu */
|
||
editingIndex: -1,
|
||
currentOrderId: null, // edit modunda header ID
|
||
header: {}, // backend header modeli
|
||
mode: 'new' // 'new' | 'edit'
|
||
}),
|
||
|
||
getters: {
|
||
/* 🔹 Toplam adet */
|
||
totalQty(state) {
|
||
return state.orders.reduce((sum, r) => sum + (Number(r.adet) || 0), 0)
|
||
},
|
||
/* 🔹 Toplam tutar (string fix2) */
|
||
totalAmount(state) {
|
||
const n = state.orders.reduce((s, r) => s + (Number(r.tutar) || 0), 0)
|
||
return isNaN(n) ? '0.00' : n.toFixed(2)
|
||
},
|
||
/* 🔹 Müşteri bazlı gruplanmış (opsiyonel) */
|
||
groupedByCustomer(state) {
|
||
const out = {}
|
||
for (const row of state.orders) {
|
||
const k = row.musteri || '—'
|
||
if (!out[k]) out[k] = []
|
||
out[k].push(row)
|
||
}
|
||
return out
|
||
},
|
||
/* 🔹 2. renk var mı? */
|
||
hasSecondColor(state) {
|
||
return Array.isArray(state.secondColors) && state.secondColors.length > 0
|
||
},
|
||
/* 🔹 Envanter toplamı */
|
||
totalInventoryQty(state) {
|
||
return state.inventory.reduce((s, r) => s + (Number(r.kullanilabilir) || 0), 0)
|
||
}
|
||
},
|
||
actions: {
|
||
/* ==========================================================
|
||
STORAGE — Kalıcı kayıt yardımcıları
|
||
========================================================== */
|
||
saveToStorage() {
|
||
try {
|
||
const payload = {
|
||
orders: this.orders,
|
||
header: this.header,
|
||
currentOrderId: this.currentOrderId,
|
||
selectedCustomer: this.selectedCustomer,
|
||
activeTransactionId: this.activeTransactionId,
|
||
mode: this.mode,
|
||
savedAt: dayjs().toISOString()
|
||
}
|
||
localStorage.setItem(this.persistKey, JSON.stringify(payload))
|
||
} catch (err) {
|
||
console.warn('⚠️ localStorage kaydı başarısız:', err)
|
||
}
|
||
},
|
||
|
||
/* Kayıt sonrası görüntülenecek "snapshot".
|
||
UI’yi temizlesen bile sayfa yenilenince bu snapshot geri yüklenebilir. */
|
||
saveSnapshot(tag = 'post-submit') {
|
||
try {
|
||
const snap = {
|
||
tag,
|
||
orders: this.orders,
|
||
header: this.header,
|
||
currentOrderId: this.currentOrderId,
|
||
selectedCustomer: this.selectedCustomer,
|
||
mode: this.mode,
|
||
savedAt: dayjs().toISOString()
|
||
}
|
||
localStorage.setItem(this.lastSnapshotKey, JSON.stringify(snap))
|
||
} catch (e) {
|
||
console.warn('⚠️ saveSnapshot hatası:', e)
|
||
}
|
||
},
|
||
|
||
loadFromStorage() {
|
||
try {
|
||
const raw = localStorage.getItem(this.persistKey)
|
||
if (!raw) return
|
||
const data = JSON.parse(raw)
|
||
if (Array.isArray(data.orders)) this.orders = data.orders
|
||
this.header = data.header || {}
|
||
this.currentOrderId = data.currentOrderId || null
|
||
this.selectedCustomer = data.selectedCustomer || null
|
||
this.activeTransactionId = data.activeTransactionId || null
|
||
this.mode = data.mode || 'new'
|
||
console.log(`♻️ Storage yüklendi • mode:${this.mode} • rows:${this.orders.length}`)
|
||
} catch (err) {
|
||
console.warn('⚠️ localStorage okuma hatası:', err)
|
||
}
|
||
},
|
||
|
||
loadSnapshot() {
|
||
try {
|
||
const raw = localStorage.getItem(this.lastSnapshotKey)
|
||
if (!raw) return null
|
||
return JSON.parse(raw)
|
||
} catch (e) {
|
||
console.warn('⚠️ loadSnapshot hatası:', e)
|
||
return null
|
||
}
|
||
},
|
||
|
||
clearStorage() {
|
||
localStorage.removeItem(this.persistKey)
|
||
// snapshot’ı silmiyoruz → kullanıcı isterse elle siler
|
||
},
|
||
/* ==========================================================
|
||
TRANSACTION STATE
|
||
========================================================== */
|
||
setTransaction(id) {
|
||
this.activeTransactionId = id
|
||
this.saveToStorage()
|
||
},
|
||
|
||
async initTransaction() {
|
||
if (this.activeTransactionId) {
|
||
console.log('🔹 Aktif transaction:', this.activeTransactionId)
|
||
return this.activeTransactionId
|
||
}
|
||
try {
|
||
const dummyId = Math.floor(100000 + Math.random() * 900000)
|
||
this.activeTransactionId = dummyId
|
||
this.saveToStorage()
|
||
console.log('🧩 Dummy Transaction başlatıldı:', dummyId)
|
||
return dummyId
|
||
} catch (err) {
|
||
console.error('❌ Dummy transaction başlatılamadı:', err)
|
||
return null
|
||
}
|
||
},
|
||
|
||
clearTransaction() {
|
||
this.activeTransactionId = null
|
||
this.saveToStorage()
|
||
},
|
||
|
||
/* Orders’ı otomatik kaydeden watcher (component’ten çağrılır) */
|
||
watchOrders() {
|
||
watch(
|
||
() => this.orders,
|
||
() => {
|
||
// her değişimde full storage yaz
|
||
this.saveToStorage()
|
||
},
|
||
{ deep: true }
|
||
)
|
||
},
|
||
/* ==========================================================
|
||
CRUD — Frontend grid’i ile senkron temel aksiyonlar
|
||
========================================================== */
|
||
|
||
addRow(row) {
|
||
if (!row) return
|
||
this.orders.push({ ...row })
|
||
this.saveToStorage()
|
||
},
|
||
|
||
updateRow(idOrIndex, patch) {
|
||
if (idOrIndex == null) return
|
||
let idx = -1
|
||
if (typeof idOrIndex === 'number') {
|
||
idx = idOrIndex
|
||
} else {
|
||
// id ile bul
|
||
idx = this.orders.findIndex(r => r.id === idOrIndex)
|
||
}
|
||
if (idx >= 0 && this.orders[idx]) {
|
||
this.orders[idx] = { ...this.orders[idx], ...patch }
|
||
this.saveToStorage()
|
||
}
|
||
},
|
||
|
||
removeRow(idOrIndex) {
|
||
let idx = -1
|
||
if (typeof idOrIndex === 'number') {
|
||
idx = idOrIndex
|
||
} else {
|
||
idx = this.orders.findIndex(r => r.id === idOrIndex)
|
||
}
|
||
if (idx >= 0) {
|
||
this.orders.splice(idx, 1)
|
||
this.saveToStorage()
|
||
}
|
||
},
|
||
/* ==========================================================
|
||
PRICE / LIMIT — Minimum fiyat sorgusu (model + PB)
|
||
Beklenen response: { price, priceTRY, rateToTRY }
|
||
========================================================== */
|
||
async fetchMinPrice(modelCode, pb) {
|
||
if (!modelCode || !pb) return null
|
||
try {
|
||
const baseURL = 'http://localhost:8080'
|
||
const res = await axios.get(`${baseURL}/api/min-price`, {
|
||
params: { code: modelCode, pb }
|
||
})
|
||
const d = res?.data || null
|
||
if (!d) return null
|
||
|
||
// normalize
|
||
return {
|
||
price: Number(d.price ?? d.Price ?? 0),
|
||
priceTRY: Number(d.priceTRY ?? d.PriceTRY ?? d.price_try ?? 0),
|
||
rateToTRY: Number(d.rateToTRY ?? d.RateToTRY ?? d.rate ?? 1)
|
||
}
|
||
} catch (e) {
|
||
console.warn('⚠️ fetchMinPrice hata:', e)
|
||
return null
|
||
}
|
||
},
|
||
/* ==========================================================
|
||
LOAD (EDIT MODE) — Sunucudan Siparişi Açma
|
||
========================================================== */
|
||
async openById(id) {
|
||
if (!id) return
|
||
this.loading = true
|
||
try {
|
||
const auth = useAuthStore()
|
||
const res = await axios.get(`http://localhost:8080/api/order/get/${id}`, {
|
||
headers: { Authorization: `Bearer ${auth.token}` }
|
||
})
|
||
const data = res.data || {}
|
||
|
||
// 🔹 sql.Null* flatten helper
|
||
const flat = (v) => {
|
||
if (v === null || v === undefined) return null
|
||
if (typeof v === 'object' && 'Valid' in v) {
|
||
return v.Valid
|
||
? v.String ?? v.Float64 ?? v.Int32 ?? v.Time ?? null
|
||
: null
|
||
}
|
||
return v
|
||
}
|
||
|
||
/* ============================================================
|
||
🧾 HEADER MAPPING (73 kolon)
|
||
============================================================ */
|
||
const h = data.header || {}
|
||
const header = {
|
||
// Görünen alanlar
|
||
OrderHeaderID: flat(h.OrderHeaderID) || '',
|
||
OrderNumber: flat(h.OrderNumber) || '',
|
||
OrderDate: flat(h.OrderDate)
|
||
? String(flat(h.OrderDate)).substring(0, 10)
|
||
: '',
|
||
AverageDueDate: flat(h.AverageDueDate)
|
||
? String(flat(h.AverageDueDate)).substring(0, 10)
|
||
: '',
|
||
Description: flat(h.Description) || '',
|
||
CurrAccCode: flat(h.CurrAccCode) || '',
|
||
DocCurrencyCode: flat(h.DocCurrencyCode) || 'TRY',
|
||
|
||
// Arka plan alanlar (backend roundtrip)
|
||
OrderTypeCode: flat(h.OrderTypeCode) || 1,
|
||
ProcessCode: flat(h.ProcessCode) || 'WS',
|
||
IsCancelOrder: flat(h.IsCancelOrder) || 0,
|
||
OrderTime: flat(h.OrderTime) || '',
|
||
DocumentNumber: flat(h.DocumentNumber) || '',
|
||
PaymentTerm: flat(h.PaymentTerm) || '',
|
||
InternalDescription: flat(h.InternalDescription) || '',
|
||
CurrAccTypeCode: flat(h.CurrAccTypeCode) || '',
|
||
SubCurrAccID: flat(h.SubCurrAccID) || '',
|
||
ContactID: flat(h.ContactID) || '',
|
||
ShipmentMethodCode: flat(h.ShipmentMethodCode) || '',
|
||
ShippingPostalAddressID: flat(h.ShippingPostalAddressID) || '',
|
||
BillingPostalAddressID: flat(h.BillingPostalAddressID) || '',
|
||
GuarantorContactID: flat(h.GuarantorContactID) || '',
|
||
GuarantorContactID2: flat(h.GuarantorContactID2) || '',
|
||
RoundsmanCode: flat(h.RoundsmanCode) || '',
|
||
DeliveryCompanyCode: flat(h.DeliveryCompanyCode) || '',
|
||
TaxTypeCode: flat(h.TaxTypeCode) || '',
|
||
WithHoldingTaxTypeCode: flat(h.WithHoldingTaxTypeCode) || '',
|
||
DOVCode: flat(h.DOVCode) || '',
|
||
TaxExemptionCode: flat(h.TaxExemptionCode) || 0,
|
||
CompanyCode: flat(h.CompanyCode) || 1,
|
||
OfficeCode: flat(h.OfficeCode) || '101',
|
||
StoreTypeCode: flat(h.StoreTypeCode) || 5,
|
||
StoreCode: flat(h.StoreCode) || 0,
|
||
POSTerminalID: flat(h.POSTerminalID) || 0,
|
||
WarehouseCode: flat(h.WarehouseCode) || '1-0-12',
|
||
ToWarehouseCode: flat(h.ToWarehouseCode) || '',
|
||
OrdererCompanyCode: flat(h.OrdererCompanyCode) || 1,
|
||
OrdererOfficeCode: flat(h.OrdererOfficeCode) || '101',
|
||
OrdererStoreCode: flat(h.OrdererStoreCode) || '',
|
||
GLTypeCode: flat(h.GLTypeCode) || '',
|
||
LocalCurrencyCode: flat(h.LocalCurrencyCode) || 'TRY',
|
||
ExchangeRate: flat(h.ExchangeRate) || 1,
|
||
DiscountReasonCode: flat(h.DiscountReasonCode) || 0,
|
||
SurplusOrderQtyToleranceRate: flat(h.SurplusOrderQtyToleranceRate) || 0,
|
||
IncotermCode1: flat(h.IncotermCode1) || '',
|
||
IncotermCode2: flat(h.IncotermCode2) || '',
|
||
PaymentMethodCode: flat(h.PaymentMethodCode) || '',
|
||
IsInclutedVat: flat(h.IsInclutedVat) || 0,
|
||
IsCreditSale: flat(h.IsCreditSale) || 1,
|
||
IsCreditableConfirmed: flat(h.IsCreditableConfirmed) || 1,
|
||
CreditableConfirmedUser: flat(h.CreditableConfirmedUser) || '',
|
||
CreditableConfirmedDate: flat(h.CreditableConfirmedDate) || '',
|
||
ApplicationCode: flat(h.ApplicationCode) || 'Order',
|
||
ApplicationID: flat(h.ApplicationID) || '',
|
||
CreatedUserName: flat(h.CreatedUserName) || '',
|
||
CreatedDate: flat(h.CreatedDate) || '',
|
||
LastUpdatedUserName: flat(h.LastUpdatedUserName) || '',
|
||
LastUpdatedDate: flat(h.LastUpdatedDate) || '',
|
||
IsProposalBased: flat(h.IsProposalBased) || 0
|
||
}
|
||
|
||
this.header = header
|
||
this.currentOrderId = header.OrderHeaderID || id
|
||
this.mode = 'edit'
|
||
|
||
// 🔹 Cari görünümü (QSelect)
|
||
this.selectedCustomer = {
|
||
value: header.CurrAccCode || '',
|
||
label: `${header.CurrAccCode || ''} - ${flat(h.CurrAccDescription) || ''}`
|
||
}
|
||
|
||
/* ============================================================
|
||
📦 LINES MAPPING (57 kolon)
|
||
============================================================ */
|
||
this.orders = (data.lines || []).map((l, idx) => ({
|
||
// Görünen alanlar
|
||
id: flat(l.OrderLineID) || `row-${idx + 1}`,
|
||
model: flat(l.ItemCode),
|
||
renk: flat(l.ColorCode),
|
||
renk2: flat(l.ItemDim2Code),
|
||
fiyat: Number(flat(l.Price) || 0),
|
||
pb: flat(l.DocCurrencyCode) || flat(l.PriceCurrencyCode) || 'USD',
|
||
adet: Number(flat(l.Qty1) || 0),
|
||
tutar: Number(flat(l.Price) || 0) * Number(flat(l.Qty1) || 0),
|
||
aciklama: flat(l.LineDescription) || '',
|
||
terminTarihi: flat(l.DeliveryDate)
|
||
? String(flat(l.DeliveryDate)).substring(0, 10)
|
||
: '',
|
||
urunAnaGrubu: flat(l.ProductGroup) || '',
|
||
urunAltGrubu: flat(l.ProductSubGroup) || '',
|
||
grpKey: l.grpKey || 'tak',
|
||
bedenMap: l.BedenMap || {},
|
||
|
||
// Backend roundtrip alanları
|
||
SortOrder: flat(l.SortOrder) || 0,
|
||
ItemTypeCode: flat(l.ItemTypeCode) || 1,
|
||
ItemDim1Code: flat(l.ItemDim1Code) || '',
|
||
ItemDim3Code: flat(l.ItemDim3Code) || '',
|
||
Qty2: flat(l.Qty2) || 0,
|
||
CancelQty1: flat(l.CancelQty1) || 0,
|
||
CancelQty2: flat(l.CancelQty2) || 0,
|
||
CancelDate: flat(l.CancelDate) || null,
|
||
OrderCancelReasonCode: flat(l.OrderCancelReasonCode) || '',
|
||
ClosedDate: flat(l.ClosedDate) || null,
|
||
IsClosed: flat(l.IsClosed) || false,
|
||
VatRate: flat(l.VatRate) || 10,
|
||
PCTRate: flat(l.PCTRate) || 0,
|
||
PriceCurrencyCode: flat(l.PriceCurrencyCode) || 'TRY',
|
||
PriceExchangeRate: flat(l.PriceExchangeRate) || header.ExchangeRate || 1,
|
||
CreatedUserName: flat(l.CreatedUserName) || '',
|
||
CreatedDate: flat(l.CreatedDate) || '',
|
||
LastUpdatedUserName: flat(l.LastUpdatedUserName) || '',
|
||
LastUpdatedDate: flat(l.LastUpdatedDate) || '',
|
||
SurplusOrderQtyToleranceRate:
|
||
flat(l.SurplusOrderQtyToleranceRate) || 0
|
||
}))
|
||
|
||
/* ============================================================
|
||
💾 LOCAL STORAGE
|
||
============================================================ */
|
||
localStorage.setItem(
|
||
`bssapp:order:last:${id}`,
|
||
JSON.stringify({ header, lines: this.orders })
|
||
)
|
||
|
||
console.log(`📦 Sipariş (${id}) yüklendi • rows:${this.orders.length}`)
|
||
} catch (err) {
|
||
console.error('❌ openById hatası:', err)
|
||
this.error = err.message
|
||
} finally {
|
||
this.loading = false
|
||
}
|
||
}
|
||
,
|
||
/* ==========================================================
|
||
NEW TEMPLATE — Yeni sipariş başlatma
|
||
========================================================== */
|
||
newOrderTemplate() {
|
||
const today = dayjs().format('YYYY-MM-DD')
|
||
const due = dayjs().add(30, 'day').format('YYYY-MM-DD')
|
||
|
||
this.header = {
|
||
OrderHeaderID: '',
|
||
OrderTypeCode: 1,
|
||
ProcessCode: 'WS',
|
||
OrderNumber: '',
|
||
OrderDate: today,
|
||
AverageDueDate: due,
|
||
Description: '',
|
||
CurrAccCode: '',
|
||
CurrAccDescription: '',
|
||
DocCurrencyCode: 'USD',
|
||
LocalCurrencyCode: 'TRY',
|
||
ExchangeRate: 1,
|
||
CompanyCode: 1,
|
||
OfficeCode: '101',
|
||
StoreTypeCode: 5,
|
||
WarehouseCode: '1-0-12',
|
||
IsCreditSale: true,
|
||
CreatedUserName: '',
|
||
CreatedDate: today,
|
||
LastUpdatedUserName: '',
|
||
LastUpdatedDate: today
|
||
}
|
||
|
||
this.orders = []
|
||
this.currentOrderId = null
|
||
this.activeTransactionId = null
|
||
this.selectedCustomer = null
|
||
this.mode = 'new'
|
||
this.error = null
|
||
|
||
// Temiz bir başlangıcı storage’a yaz
|
||
this.saveToStorage()
|
||
console.log('🧾 Yeni sipariş template yüklendi.')
|
||
},
|
||
/* ==========================================================
|
||
SUBMIT — Create/Update (SQL tablo INSERT/UPDATE)
|
||
➜ Kayıt sonrası: transaction kapanır AMA snapshot tutulur.
|
||
========================================================== */
|
||
async submitAll() {
|
||
const auth = useAuthStore()
|
||
const baseURL = 'http://localhost:8080'
|
||
|
||
const toNullable = (v, type = 'string') => {
|
||
if (v === null || v === undefined || v === '') {
|
||
if (type === 'number') return { Float64: 0, Valid: false }
|
||
if (type === 'time') return { Time: null, Valid: false }
|
||
return { String: '', Valid: false }
|
||
}
|
||
if (type === 'number') return { Float64: Number(v), Valid: true }
|
||
if (type === 'time') return { Time: v, Valid: true }
|
||
return { String: String(v), Valid: true }
|
||
}
|
||
|
||
try {
|
||
this.loading = true
|
||
|
||
// Header payload (backend’in beklediği Null* formatıyla)
|
||
const h = this.header || {}
|
||
const headerPayload = {
|
||
OrderHeaderID: h.OrderHeaderID || this.currentOrderId || '',
|
||
OrderTypeCode: toNullable(1, 'number'),
|
||
ProcessCode: toNullable('WS'),
|
||
OrderNumber: toNullable(h.OrderNumber),
|
||
OrderDate: toNullable(h.OrderDate || dayjs().format('YYYY-MM-DD'), 'time'),
|
||
AverageDueDate: toNullable(h.AverageDueDate || dayjs().add(30, 'day').format('YYYY-MM-DD'), 'time'),
|
||
Description: toNullable(h.Description || ''),
|
||
CurrAccCode: toNullable(h.CurrAccCode || this.selectedCustomer?.value || ''),
|
||
CurrAccDescription: toNullable(h.CurrAccDescription || this.selectedCustomer?.label || ''),
|
||
DocCurrencyCode: toNullable(h.DocCurrencyCode || 'USD'),
|
||
LocalCurrencyCode: toNullable(h.LocalCurrencyCode || 'TRY'),
|
||
ExchangeRate: toNullable(h.ExchangeRate || 1, 'number'),
|
||
CompanyCode: toNullable(1, 'number'),
|
||
OfficeCode: toNullable('101'),
|
||
StoreTypeCode: toNullable(5, 'number'),
|
||
WarehouseCode: toNullable(h.WarehouseCode || '1-0-12'),
|
||
IsCreditSale: true,
|
||
CreatedUserName: toNullable(auth.user?.Username || 'admin'),
|
||
CreatedDate: toNullable(h.CreatedDate || dayjs().format('YYYY-MM-DD'), 'time'),
|
||
LastUpdatedUserName: toNullable(auth.user?.Username || 'admin'),
|
||
LastUpdatedDate: toNullable(dayjs().format('YYYY-MM-DD HH:mm:ss'), 'time')
|
||
}
|
||
|
||
// Lines payload
|
||
const linesPayload = this.orders.map((l, idx) => ({
|
||
OrderLineID: l.id || '',
|
||
SortOrder: idx + 1,
|
||
ItemTypeCode: toNullable(1, 'number'),
|
||
ItemCode: toNullable(l.model),
|
||
ColorCode: toNullable(l.renk),
|
||
ItemDim1Code: toNullable(Object.keys(l.bedenMap?.[l.grpKey] || {})[0] || ''),
|
||
ItemDim2Code: toNullable(l.renk2),
|
||
Qty1: toNullable(Number(l.adet || 0), 'number'),
|
||
Price: toNullable(Number(l.fiyat || 0), 'number'),
|
||
DocCurrencyCode: toNullable(l.pb || 'USD'),
|
||
VatRate: toNullable(10, 'number'),
|
||
PCTRate: toNullable(0, 'number'),
|
||
DeliveryDate: toNullable(l.terminTarihi || null, 'time'),
|
||
LineDescription: toNullable(l.aciklama || ''),
|
||
IsClosed: false,
|
||
CreatedUserName: toNullable(auth.user?.Username || 'admin'),
|
||
CreatedDate: toNullable(dayjs().format('YYYY-MM-DD HH:mm:ss'), 'time'),
|
||
LastUpdatedUserName: toNullable(auth.user?.Username || 'admin'),
|
||
LastUpdatedDate: toNullable(dayjs().format('YYYY-MM-DD HH:mm:ss'), 'time')
|
||
}))
|
||
|
||
// Final payload
|
||
const payload = {
|
||
header: headerPayload,
|
||
lines: linesPayload,
|
||
user: auth.user?.Username || 'admin'
|
||
}
|
||
|
||
let res
|
||
if (this.currentOrderId) {
|
||
// UPDATE
|
||
res = await axios.post(`${baseURL}/api/order/update`, payload, {
|
||
headers: { Authorization: `Bearer ${auth.token}` }
|
||
})
|
||
console.log('✅ UPDATE ok:', res.data)
|
||
} else {
|
||
// CREATE
|
||
res = await axios.post(`${baseURL}/api/order/create`, payload, {
|
||
headers: { Authorization: `Bearer ${auth.token}` }
|
||
})
|
||
console.log('✅ CREATE ok:', res.data)
|
||
if (res.data?.orderID) {
|
||
this.currentOrderId = res.data.orderID
|
||
this.header.OrderHeaderID = res.data.orderID
|
||
this.mode = 'edit'
|
||
}
|
||
}
|
||
|
||
// 🟩 Kayıt sonrası: snapshot’ı al ve storage’a da yaz
|
||
this.saveSnapshot('post-submit')
|
||
this.saveToStorage()
|
||
|
||
// 🧹 Transaction’ı kapat (UI temizliği ayrı fonksiyonda)
|
||
this.clearTransaction()
|
||
this.afterSubmit({ keepLocalStorage: true }) // 👈 önemli
|
||
|
||
} catch (err) {
|
||
console.error('❌ submitAll hatası:', err)
|
||
this.error = err.message
|
||
throw err
|
||
} finally {
|
||
this.loading = false
|
||
}
|
||
},
|
||
/* ==========================================================
|
||
AFTER SUBMIT — UI temizliği (snapshot kalır!)
|
||
keepLocalStorage=true → persistKey SİLİNMEZ
|
||
========================================================== */
|
||
afterSubmit(opts = { keepLocalStorage: true }) {
|
||
try {
|
||
// Snapshot zaten kaydedildi; istenirse persistKey’i bırak
|
||
if (!opts?.keepLocalStorage) {
|
||
localStorage.removeItem(this.persistKey)
|
||
} else {
|
||
// son hal zaten saveToStorage ile yazıldı — dokunma
|
||
}
|
||
|
||
// UI temizliği (hafızada formu boşaltalım)
|
||
// Ama edit’e dönmek istersen, snapshot/loadFromStorage ile geri getirirsin.
|
||
this.orders = []
|
||
// header’ı hafızadan temizliyoruz ama snapshot yerinde.
|
||
this.header = {}
|
||
this.selectedCustomer = null
|
||
this.editingIndex = -1
|
||
// currentOrderId’yi istersen koruyabilirsin; biz editte geri yüklüyoruz.
|
||
// burada null’lıyoruz:
|
||
this.currentOrderId = null
|
||
this.mode = 'new'
|
||
this.loading = false
|
||
this.error = null
|
||
|
||
console.log('🧹 afterSubmit: UI temizlendi, snapshot storage’da.')
|
||
} catch (err) {
|
||
console.warn('⚠️ afterSubmit temizleme hatası:', err)
|
||
}
|
||
},
|
||
|
||
/* ==========================================================
|
||
MANUAL UPDATE — mevcut header/lines yapılarına göre
|
||
(İsteğe bağlı kullanılır)
|
||
========================================================== */
|
||
async updateOrder() {
|
||
if (!this.currentOrderId) {
|
||
console.warn('⚠️ currentOrderId yok, update yapılamaz.')
|
||
return
|
||
}
|
||
try {
|
||
const auth = useAuthStore()
|
||
const payload = {
|
||
header: this.header,
|
||
lines: this.orders,
|
||
username: auth.user?.Username || 'admin'
|
||
}
|
||
const res = await axios.post(
|
||
'http://localhost:8080/api/order/update',
|
||
payload,
|
||
{ headers: { Authorization: `Bearer ${auth.token}` } }
|
||
)
|
||
console.log('✅ Güncelleme tamamlandı:', res.data)
|
||
|
||
// kayıt sonrası snapshot + persist
|
||
this.saveSnapshot('manual-update')
|
||
this.saveToStorage()
|
||
} catch (err) {
|
||
console.error('❌ updateOrder hatası:', err)
|
||
this.error = err.message
|
||
}
|
||
}
|
||
} // actions
|
||
}) // defineStore
|
||
// (opsiyonel) Bu referanslara component tarafından erişmek istersen:
|
||
export const sharedOrderEntryRefs = {
|
||
stockMap,
|
||
bedenStock,
|
||
sizeCache
|
||
}
|