Add invoice send, status transitions, and live settings/notifications.
Let admins send priced invoices, change order status via allowedTransitions or forced manual jumps, persist notification reads, and save SystemSettings to the API. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -23,6 +23,7 @@ const customerNote = ref('')
|
||||
const showAddModal = ref(false)
|
||||
const formError = ref('')
|
||||
const saving = ref(false)
|
||||
const sending = ref(false)
|
||||
const loading = ref(true)
|
||||
|
||||
const emptyForm = () => ({
|
||||
@@ -46,6 +47,15 @@ const displayOrder = computed(() =>
|
||||
order.value ? mapAdminOrder(order.value) : null,
|
||||
)
|
||||
|
||||
/** تا وقتی سفارش در این وضعیتهاست، فاکتور برای مشتری ارسال نشده است. */
|
||||
const PRE_INVOICE_STATUSES = ['cart', 'submitted', 'awaiting_review', 'pricing', 'needs_correction']
|
||||
|
||||
const invoiceSent = computed(() =>
|
||||
order.value ? !PRE_INVOICE_STATUSES.includes(order.value.status) : false,
|
||||
)
|
||||
|
||||
const canSendInvoice = computed(() => !!order.value?.finalAmount && !invoiceSent.value)
|
||||
|
||||
async function loadOrder() {
|
||||
loading.value = true
|
||||
try {
|
||||
@@ -160,6 +170,36 @@ async function savePricing() {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function sendInvoice() {
|
||||
if (!order.value) return
|
||||
if (!order.value.finalAmount) {
|
||||
toast.error('ابتدا قیمتگذاری را ذخیره کنید تا مبلغ فاکتور مشخص شود.')
|
||||
return
|
||||
}
|
||||
|
||||
const ok = await confirm({
|
||||
title: 'ارسال فاکتور برای مشتری',
|
||||
message: `فاکتور ${formatCurrency(order.value.finalAmount)} برای مشتری ارسال میشود و او روش تسویه را انتخاب میکند. ادامه میدهید؟`,
|
||||
confirmLabel: 'ارسال فاکتور',
|
||||
cancelLabel: 'انصراف',
|
||||
})
|
||||
if (!ok) return
|
||||
|
||||
sending.value = true
|
||||
try {
|
||||
const updated = await ordersApi.updateStatus(order.value.id, {
|
||||
status: 'awaiting_settlement',
|
||||
note: customerNote.value.trim() || undefined,
|
||||
})
|
||||
order.value = updated
|
||||
toast.success('فاکتور برای مشتری ارسال شد.')
|
||||
} catch (err) {
|
||||
toast.error(err instanceof ApiError ? err.message : 'ارسال فاکتور انجام نشد.')
|
||||
} finally {
|
||||
sending.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -176,9 +216,17 @@ async function savePricing() {
|
||||
:disabled="saving || loading"
|
||||
@click="savePricing"
|
||||
>
|
||||
ارسال پیشفاکتور
|
||||
{{ saving ? 'در حال ذخیره…' : 'ذخیره قیمتگذاری' }}
|
||||
</button>
|
||||
<button type="button" class="admin-btn admin-btn--primary admin-btn--sm" @click="goBack">
|
||||
<button
|
||||
type="button"
|
||||
class="admin-btn admin-btn--primary admin-btn--sm"
|
||||
:disabled="!canSendInvoice || sending || saving"
|
||||
@click="sendInvoice"
|
||||
>
|
||||
{{ sending ? 'در حال ارسال…' : 'ارسال فاکتور برای مشتری' }}
|
||||
</button>
|
||||
<button type="button" class="admin-btn admin-btn--outline admin-btn--sm" @click="goBack">
|
||||
بازگشت
|
||||
</button>
|
||||
</div>
|
||||
@@ -326,11 +374,29 @@ async function savePricing() {
|
||||
:disabled="saving"
|
||||
@click="savePricing"
|
||||
>
|
||||
ارسال پیشفاکتور
|
||||
{{ saving ? 'در حال ذخیره…' : 'ذخیره قیمتگذاری' }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="admin-btn admin-btn--primary"
|
||||
:disabled="!canSendInvoice || sending || saving"
|
||||
@click="sendInvoice"
|
||||
>
|
||||
{{ sending ? 'در حال ارسال…' : 'ارسال فاکتور برای مشتری' }}
|
||||
</button>
|
||||
<button type="button" class="admin-btn admin-btn--outline-warning">نیاز به اصلاح</button>
|
||||
<button type="button" class="admin-btn admin-btn--outline-danger">رد سفارش</button>
|
||||
</div>
|
||||
|
||||
<p class="pricing-page__invoice-hint">
|
||||
<template v-if="invoiceSent">
|
||||
فاکتور این سفارش برای مشتری ارسال شده است؛ انتخاب روش تسویه در اختیار اوست.
|
||||
</template>
|
||||
<template v-else-if="canSendInvoice">
|
||||
مبلغ نهایی آماده است. با ارسال فاکتور، مشتری برای انتخاب نقدی یا چک مطلع میشود.
|
||||
</template>
|
||||
<template v-else>
|
||||
ابتدا قیمت واحد اقلام و هزینه حمل را ذخیره کنید تا مبلغ نهایی فاکتور ساخته شود.
|
||||
</template>
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<BaseModal :open="showAddModal" title="افزودن محصول" size="lg" @close="closeAddModal">
|
||||
@@ -473,6 +539,13 @@ async function savePricing() {
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.pricing-page__invoice-hint {
|
||||
margin: 12px 0 0;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.8;
|
||||
color: var(--color-text-muted);
|
||||
}
|
||||
|
||||
.pricing-page__line-total {
|
||||
grid-column: 1 / -1;
|
||||
margin: 0;
|
||||
|
||||
Reference in New Issue
Block a user