Merge remote-tracking branch 'origin/master'

This commit is contained in:
M_Kececi
2026-04-15 15:54:23 +03:00
parent c925af5ba1
commit 5be7315bdb
13 changed files with 1412 additions and 730 deletions

View File

@@ -278,8 +278,8 @@
color="primary"
icon="save"
class="q-ml-sm"
:loading="orderStore.loading"
:disable="!canSubmitOrder"
:loading="orderStore.loading || isSubmitAllInFlight"
:disable="!canSubmitOrder || orderStore.loading || isSubmitAllInFlight"
@click="confirmAndSubmit"
/>
</div>
@@ -773,16 +773,18 @@
v-if="canMutateRows"
:color="isEditing ? 'positive' : 'primary'"
:label="isEditing ? 'Güncelle' : 'Kaydet'"
:loading="isRowSaveInFlight"
@click="onSaveOrUpdateRow"
:disable="isClosedRow || isViewOnly || !canMutateRows"
:disable="isClosedRow || isViewOnly || !canMutateRows || isRowSaveInFlight"
/>
<q-btn
v-if="canMutateRows"
color="secondary"
label="Kaydet ve Diğer Renge Geç"
:loading="isRowSaveInFlight"
@click="onSaveAndNextColor"
:disable="isClosedRow || isViewOnly || !canMutateRows"
:disable="isClosedRow || isViewOnly || !canMutateRows || isRowSaveInFlight"
/>
<q-btn
v-if="isEditing && canMutateRows"
@@ -930,8 +932,60 @@ const aktifPB = ref('USD') // Varsayılan para birimi (Cari seç
const productCache = reactive({})
const showBulkDueDateDialog = ref(false)
const bulkDueDateValue = ref('')
const isSubmitAllInFlight = ref(false)
const isRowSaveInFlight = ref(false)
function showEditorQtyPriceBlockingDialog(message, details = '') {
const detailHtml = details ? `<br><br><b>Detay:</b><br>${details}` : ''
$q.dialog({
title: 'Kayit Engellendi',
message: `${message}${detailHtml}`,
html: true,
ok: { label: 'Tamam', color: 'negative' }
})
}
function validateEditorRowBeforeSave() {
const adet = Number(form.adet || 0)
const fiyatRaw = String(form.fiyat ?? '').trim()
const fiyat = Number(form.fiyat || 0)
if (adet <= 0) {
showEditorQtyPriceBlockingDialog('Siparis adeti toplam 0 olamaz.')
return false
}
if (!fiyatRaw || !Number.isFinite(fiyat) || fiyat <= 0) {
showEditorQtyPriceBlockingDialog('Urun fiyati girmeden ilerleyemezsiniz.')
return false
}
return true
}
function validateSummaryRowsBeforeSubmit() {
const rows = Array.isArray(orderStore.summaryRows) ? orderStore.summaryRows : []
const invalidRows = rows.filter(r => {
const adet = Number(r?.adet || 0)
const fiyatRaw = String(r?.fiyat ?? '').trim()
const fiyat = Number(r?.fiyat || 0)
return adet <= 0 || !fiyatRaw || !Number.isFinite(fiyat) || fiyat <= 0
})
if (!invalidRows.length) return true
const preview = invalidRows
.slice(0, 8)
.map(r => `${String(r?.model || '').trim() || '-'} / ${String(r?.renk || '').trim() || '-'} (adet=${Number(r?.adet || 0)}, fiyat=${String(r?.fiyat ?? '')})`)
.join('<br>')
showEditorQtyPriceBlockingDialog(
'Urun fiyati girmeden ilerleyemezsiniz.',
preview
)
return false
}
const confirmAndSubmit = async () => {
if (orderStore.loading) return
if (orderStore.loading || isSubmitAllInFlight.value) return
if (!hasSubmitPermission()) {
notifyNoPermission(
@@ -951,6 +1005,11 @@ const confirmAndSubmit = async () => {
return
}
if (!validateSummaryRowsBeforeSubmit()) {
return
}
isSubmitAllInFlight.value = true
try {
// NEW veya EDIT ayrımı store.mode üzerinden
await orderStore.submitAllReal(
@@ -962,6 +1021,8 @@ const confirmAndSubmit = async () => {
)
} catch (err) {
console.error('❌ confirmAndSubmit hata:', err)
} finally {
isSubmitAllInFlight.value = false
}
}
@@ -3077,6 +3138,8 @@ function warnIfSecondColorMissing() {
}
const onSaveOrUpdateRow = async () => {
if (isRowSaveInFlight.value) return
if (!hasRowMutationPermission()) {
notifyNoPermission(
isEditMode.value
@@ -3086,23 +3149,32 @@ const onSaveOrUpdateRow = async () => {
return
}
if (!validateEditorRowBeforeSave()) return
warnIfSecondColorMissing()
await orderStore.saveOrUpdateRowUnified({
form,
isRowSaveInFlight.value = true
try {
const ok = await orderStore.saveOrUpdateRowUnified({
form,
recalcVat: typeof recalcVat === 'function' ? recalcVat : null,
resetEditor: typeof resetEditor === 'function' ? resetEditor : null,
loadProductSizes: async () => {
await orderStore.loadProductSizes(form, true, $q, productCache)
await loadOrderInventory(true)
},
recalcVat: typeof recalcVat === 'function' ? recalcVat : null,
resetEditor: typeof resetEditor === 'function' ? resetEditor : null,
loadProductSizes: async () => {
await orderStore.loadProductSizes(form, true, $q, productCache)
await loadOrderInventory(true)
},
// gerekiyorsa pass edebilirsin (store tarafında zaten optional)
stockMap,
$q
})
showEditor.value = false
// gerekiyorsa pass edebilirsin (store tarafında zaten optional)
stockMap,
$q
})
if (ok !== false) {
showEditor.value = false
}
} finally {
isRowSaveInFlight.value = false
}
}
function normalizeColorValue(val) {
@@ -3122,6 +3194,8 @@ function getNextColorValue() {
}
const onSaveAndNextColor = async () => {
if (isRowSaveInFlight.value) return
if (!hasRowMutationPermission()) {
notifyNoPermission(
isEditMode.value
@@ -3141,19 +3215,27 @@ const onSaveAndNextColor = async () => {
return
}
if (!validateEditorRowBeforeSave()) return
warnIfSecondColorMissing()
const ok = await orderStore.saveOrUpdateRowUnified({
form,
recalcVat: typeof recalcVat === 'function' ? recalcVat : null,
resetEditor: () => {},
loadProductSizes: async () => {
await orderStore.loadProductSizes(form, true, $q, productCache)
await loadOrderInventory(true)
},
stockMap,
$q
})
isRowSaveInFlight.value = true
let ok = false
try {
ok = await orderStore.saveOrUpdateRowUnified({
form,
recalcVat: typeof recalcVat === 'function' ? recalcVat : null,
resetEditor: () => {},
loadProductSizes: async () => {
await orderStore.loadProductSizes(form, true, $q, productCache)
await loadOrderInventory(true)
},
stockMap,
$q
})
} finally {
isRowSaveInFlight.value = false
}
if (!ok) return