added some text handling 2
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import type { TableInput } from '@core/type/baseTable'
|
||||
import useAxios from '@core/utils/useAxios'
|
||||
import type { Withdraw } from '@/model/wallet'
|
||||
|
||||
export interface PhysicalWithdrawProductOption {
|
||||
product_id: number
|
||||
title: string
|
||||
wallet_id: number
|
||||
available: number
|
||||
unit: string
|
||||
is_main_wallet?: boolean
|
||||
}
|
||||
|
||||
export interface PhysicalWithdrawAddressOption {
|
||||
id: number
|
||||
province?: string
|
||||
city?: string
|
||||
address?: string
|
||||
phone?: string
|
||||
zip?: string
|
||||
default_address?: boolean
|
||||
}
|
||||
|
||||
export interface PhysicalWithdrawOptions {
|
||||
products: PhysicalWithdrawProductOption[]
|
||||
addresses: PhysicalWithdrawAddressOption[]
|
||||
}
|
||||
|
||||
export interface PhysicalWithdrawLineInput {
|
||||
wallet_id: number
|
||||
value: number
|
||||
}
|
||||
|
||||
export interface CreatePhysicalWithdrawPayload {
|
||||
customer_id: number
|
||||
address_id: number
|
||||
wallets: PhysicalWithdrawLineInput[]
|
||||
}
|
||||
|
||||
export const getPhysicalWithdrawTable = async (params?: TableInput) =>
|
||||
await useAxios.post<Array<Withdraw>>('/admin/wallet/withdraw_physical/table', params)
|
||||
|
||||
export const getPhysicalWithdrawOptions = async (customerId: number) =>
|
||||
await useAxios.get<PhysicalWithdrawOptions>(`/admin/wallet/withdraw_physical/options/${customerId}`)
|
||||
|
||||
export const createPhysicalWithdraw = async (payload: CreatePhysicalWithdrawPayload) =>
|
||||
await useAxios.post<{ id: number }>('/admin/wallet/withdraw_physical', payload)
|
||||
|
||||
export const adjustPhysicalWithdraw = async (
|
||||
withdrawId: number,
|
||||
payload: { transaction_id: number; direction: 'increase' | 'decrease' }
|
||||
) => await useAxios.post(`/admin/wallet/withdraw_physical/${withdrawId}/adjust`, payload)
|
||||
|
||||
export const approvePhysicalWithdraw = async (withdrawId: number, sts = 51) =>
|
||||
await useAxios.put(`/admin/wallet/withdraw/${withdrawId}`, { sts })
|
||||
@@ -60,8 +60,10 @@ export interface WalletTableSums {
|
||||
}
|
||||
|
||||
export interface WithdrawTransaction {
|
||||
id?: number
|
||||
title?: string
|
||||
gold?: number
|
||||
product?: { title?: string; amount?: number }
|
||||
}
|
||||
|
||||
export interface Withdraw {
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<a-form ref="formRef" :model="form" layout="vertical" autocomplete="off">
|
||||
<a-form-item label="مشتری" name="customer_id" :rules="inputRules()">
|
||||
<BasicSelect
|
||||
v-model:value="form.customer_id"
|
||||
show-search
|
||||
:options="customerOptions"
|
||||
placeholder="انتخاب مشتری"
|
||||
@change="onCustomerChange"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="form.customer_id" label="آدرس تحویل" name="address_id" :rules="inputRules()">
|
||||
<BasicSelect
|
||||
v-model:value="form.address_id"
|
||||
:options="addressOptions"
|
||||
placeholder="انتخاب آدرس"
|
||||
:loading="optionsLoading"
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<div v-if="form.customer_id" class="space-y-3">
|
||||
<div class="text-sm font-semibold">محصولات</div>
|
||||
<div
|
||||
v-for="(line, index) in form.lines"
|
||||
:key="`${line.wallet_id}-${index}`"
|
||||
class="grid grid-cols-1 gap-2 rounded-lg border border-gray-200 p-3 md:grid-cols-[1fr_120px_auto]"
|
||||
>
|
||||
<a-form-item
|
||||
class="!mb-0"
|
||||
:name="['lines', index, 'wallet_id']"
|
||||
:rules="inputRules()"
|
||||
label="محصول"
|
||||
>
|
||||
<BasicSelect
|
||||
v-model:value="line.wallet_id"
|
||||
:options="productOptionsForLine(index)"
|
||||
placeholder="انتخاب محصول"
|
||||
:loading="optionsLoading"
|
||||
@change="() => onProductChange(index)"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
class="!mb-0"
|
||||
:name="['lines', index, 'value']"
|
||||
:rules="inputRules()"
|
||||
label="مقدار"
|
||||
>
|
||||
<BasicInput v-model:value="line.value" type="number" min="0" />
|
||||
</a-form-item>
|
||||
<div class="flex items-end">
|
||||
<BaseButton
|
||||
v-if="form.lines.length > 1"
|
||||
type="text"
|
||||
danger
|
||||
class="mb-1"
|
||||
@click="removeLine(index)"
|
||||
>
|
||||
حذف
|
||||
</BaseButton>
|
||||
</div>
|
||||
<div v-if="line.wallet_id" class="col-span-full text-xs text-gray-500">
|
||||
موجودی: {{ availableForWallet(line.wallet_id) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BaseButton type="dashed" block icon="vuesax-linear:add" @click="addLine">افزودن محصول</BaseButton>
|
||||
</div>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { inputRules } from '@/utils/inputRules'
|
||||
import type { Customer } from '@/model/customer'
|
||||
import type { FormInstance } from 'ant-design-vue'
|
||||
import {
|
||||
getPhysicalWithdrawOptions,
|
||||
type PhysicalWithdrawAddressOption,
|
||||
type PhysicalWithdrawProductOption
|
||||
} from '@/api/physicalWithdraw'
|
||||
|
||||
export interface PhysicalWithdrawFormLine {
|
||||
wallet_id?: number
|
||||
value?: number
|
||||
}
|
||||
|
||||
export interface PhysicalWithdrawForm {
|
||||
customer_id?: number
|
||||
address_id?: number
|
||||
lines: PhysicalWithdrawFormLine[]
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
form: PhysicalWithdrawForm
|
||||
customers: Customer[]
|
||||
}>()
|
||||
|
||||
const formRef = ref<FormInstance>()
|
||||
const optionsLoading = ref(false)
|
||||
const products = ref<PhysicalWithdrawProductOption[]>([])
|
||||
const addresses = ref<PhysicalWithdrawAddressOption[]>([])
|
||||
|
||||
const customerOptions = computed(() =>
|
||||
(props.customers ?? []).map((customer) => ({
|
||||
label: `${customer.name ?? '-'} (${customer.mobile ?? '-'})`,
|
||||
value: customer.id
|
||||
}))
|
||||
)
|
||||
|
||||
const addressOptions = computed(() =>
|
||||
addresses.value.map((addr) => ({
|
||||
label: [addr.province, addr.city, addr.address].filter(Boolean).join(' / '),
|
||||
value: addr.id
|
||||
}))
|
||||
)
|
||||
|
||||
function productOptionsForLine(index: number) {
|
||||
const usedWalletIds = props.form.lines
|
||||
.map((line, i) => (i === index ? undefined : line.wallet_id))
|
||||
.filter(Boolean)
|
||||
|
||||
return products.value
|
||||
.filter((product) => !usedWalletIds.includes(product.wallet_id))
|
||||
.map((product) => ({
|
||||
label: `${product.title} (موجودی: ${product.available} ${product.unit})`,
|
||||
value: product.wallet_id
|
||||
}))
|
||||
}
|
||||
|
||||
function availableForWallet(walletId?: number) {
|
||||
const product = products.value.find((item) => item.wallet_id === walletId)
|
||||
if (!product) return '-'
|
||||
return `${product.available} ${product.unit}`
|
||||
}
|
||||
|
||||
function addLine() {
|
||||
props.form.lines.push({ wallet_id: undefined, value: undefined })
|
||||
}
|
||||
|
||||
function removeLine(index: number) {
|
||||
props.form.lines.splice(index, 1)
|
||||
}
|
||||
|
||||
function onProductChange(index: number) {
|
||||
const line = props.form.lines[index]
|
||||
const product = products.value.find((item) => item.wallet_id === line.wallet_id)
|
||||
if (product && !line.value) {
|
||||
line.value = 1
|
||||
}
|
||||
}
|
||||
|
||||
async function onCustomerChange() {
|
||||
props.form.address_id = undefined
|
||||
props.form.lines = [{ wallet_id: undefined, value: undefined }]
|
||||
products.value = []
|
||||
addresses.value = []
|
||||
|
||||
if (!props.form.customer_id) return
|
||||
|
||||
try {
|
||||
optionsLoading.value = true
|
||||
const data = await getPhysicalWithdrawOptions(props.form.customer_id)
|
||||
products.value = data.products ?? []
|
||||
addresses.value = data.addresses ?? []
|
||||
if (addresses.value.length === 1) {
|
||||
props.form.address_id = addresses.value[0].id
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
optionsLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function validateFields() {
|
||||
return formRef.value?.validateFields()
|
||||
}
|
||||
|
||||
function resetFields() {
|
||||
formRef.value?.resetFields()
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
validateFields,
|
||||
resetFields
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<div class="h-full min-h-0 min-w-0 max-w-full overflow-hidden">
|
||||
<BasicShowContext title="لیست برداشت فیزیکی">
|
||||
<div class="flex h-full min-h-0 flex-col">
|
||||
<BaseTable class="h-full min-h-0 min-w-0" v-bind="tblProps" @register="submit" ref="tbl">
|
||||
<template #extraHeader>
|
||||
<BaseButton type="primary" size="small" icon="vuesax-linear:add-square" @click="emits('add')">
|
||||
ثبت برداشت فیزیکی
|
||||
</BaseButton>
|
||||
</template>
|
||||
<template #action="{ record }">
|
||||
<div class="flex flex-col items-center gap-2 py-1">
|
||||
<div
|
||||
v-for="tx in record.transaction ?? []"
|
||||
:key="tx.id"
|
||||
class="flex w-full max-w-[220px] items-center justify-between gap-2 rounded border border-gray-200 px-2 py-1"
|
||||
>
|
||||
<span class="truncate text-xs">{{ tx.title?.trim() || 'محصول' }}</span>
|
||||
<span class="shrink-0 text-xs font-semibold">{{ Math.abs(Number(tx.gold ?? 0)) }}</span>
|
||||
<div v-if="canAdjust(record)" class="flex shrink-0 gap-1">
|
||||
<BaseButton
|
||||
size="small"
|
||||
class="!min-w-0 !px-2"
|
||||
:loading="isAdjusting(record.id, tx.id, 'decrease')"
|
||||
@click="handleAdjust(record, tx, 'decrease')"
|
||||
>
|
||||
کم
|
||||
</BaseButton>
|
||||
<BaseButton
|
||||
size="small"
|
||||
type="primary"
|
||||
class="!min-w-0 !px-2"
|
||||
:loading="isAdjusting(record.id, tx.id, 'increase')"
|
||||
@click="handleAdjust(record, tx, 'increase')"
|
||||
>
|
||||
زیاد
|
||||
</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap items-center justify-center gap-2">
|
||||
<BaseButton
|
||||
v-if="canApprove(record)"
|
||||
size="small"
|
||||
type="primary"
|
||||
:loading="isApproving(record.id)"
|
||||
@click="handleApprove(record)"
|
||||
>
|
||||
تایید
|
||||
</BaseButton>
|
||||
<ADropdown v-if="canChangeStatus(record)" :trigger="['click']">
|
||||
<BaseButton size="small">وضعیت</BaseButton>
|
||||
<template #overlay>
|
||||
<a-menu class="flex flex-col">
|
||||
<a-menu-item
|
||||
v-for="(item, key) in statusOptions(record.sts)"
|
||||
:key="key"
|
||||
class="border-none px-2 py-1"
|
||||
@click="handleStatusChange(record.id, Number(key))"
|
||||
>
|
||||
{{ item.title }}
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</ADropdown>
|
||||
<a-tooltip v-if="record.sts >= 50 && record.sts <= 70">
|
||||
<template #title>دریافت فاکتور</template>
|
||||
<Icon
|
||||
icon="vuesax-linear:document-download"
|
||||
color="#1D4ED8"
|
||||
class="cursor-pointer"
|
||||
@click="$router.push({ name: 'factor', params: { id: record.id } })"
|
||||
/>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</BaseTable>
|
||||
</div>
|
||||
</BasicShowContext>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="tsx" setup>
|
||||
import type { TableInput } from '@core/type/baseTable'
|
||||
import useBaseTable from '@core/components/BaseTableOld/hooks/useBaseTable'
|
||||
import Icon from '@core/components/BaseIcon/src/Icon.vue'
|
||||
import { getPhysicalWithdrawColumns } from '../hooks/physicalWithdrawColumns'
|
||||
import {
|
||||
adjustPhysicalWithdraw,
|
||||
approvePhysicalWithdraw,
|
||||
getPhysicalWithdrawTable
|
||||
} from '@/api/physicalWithdraw'
|
||||
import { updateSts } from '@/api/wallet'
|
||||
import { message } from 'ant-design-vue'
|
||||
import type { Withdraw } from '@/model/wallet'
|
||||
import { status as physicalStatusMap } from '@/pages/menuPages/withdraw/information/hooks/status'
|
||||
|
||||
const emits = defineEmits(['add'])
|
||||
|
||||
const [submit, reload] = useBaseTable()
|
||||
const adjustingKey = ref('')
|
||||
const approvingId = ref<number | null>(null)
|
||||
|
||||
const tblProps = computed(() => ({
|
||||
columns: getPhysicalWithdrawColumns(),
|
||||
api: (params: TableInput) => getPhysicalWithdrawTable(params)
|
||||
}))
|
||||
|
||||
function canAdjust(record: Withdraw) {
|
||||
return Number(record.sts) === 50
|
||||
}
|
||||
|
||||
function canApprove(record: Withdraw) {
|
||||
return Number(record.sts) === 50
|
||||
}
|
||||
|
||||
function canChangeStatus(record: Withdraw) {
|
||||
const sts = Number(record.sts)
|
||||
return sts >= 50 && sts <= 53
|
||||
}
|
||||
|
||||
function statusOptions(currentSts: number) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(physicalStatusMap).filter(([key]) => Number(key) !== Number(currentSts))
|
||||
)
|
||||
}
|
||||
|
||||
function adjustKey(withdrawId?: number, transactionId?: number, direction?: string) {
|
||||
return `${withdrawId ?? 0}-${transactionId ?? 0}-${direction ?? ''}`
|
||||
}
|
||||
|
||||
function isAdjusting(withdrawId?: number, transactionId?: number, direction?: string) {
|
||||
return adjustingKey.value === adjustKey(withdrawId, transactionId, direction)
|
||||
}
|
||||
|
||||
function isApproving(withdrawId?: number) {
|
||||
return approvingId.value === withdrawId
|
||||
}
|
||||
|
||||
async function handleAdjust(
|
||||
record: Withdraw,
|
||||
tx: { id?: number },
|
||||
direction: 'increase' | 'decrease'
|
||||
) {
|
||||
if (!record.id || !tx.id) return
|
||||
const key = adjustKey(record.id, tx.id, direction)
|
||||
adjustingKey.value = key
|
||||
try {
|
||||
await adjustPhysicalWithdraw(record.id, { transaction_id: tx.id, direction })
|
||||
message.success('مقدار بروزرسانی شد')
|
||||
await reload()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
if (adjustingKey.value === key) adjustingKey.value = ''
|
||||
}
|
||||
}
|
||||
|
||||
async function handleApprove(record: Withdraw) {
|
||||
if (!record.id) return
|
||||
approvingId.value = record.id
|
||||
try {
|
||||
await approvePhysicalWithdraw(record.id, 51)
|
||||
message.success('برداشت فیزیکی تایید شد')
|
||||
await reload()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
approvingId.value = null
|
||||
}
|
||||
}
|
||||
|
||||
async function handleStatusChange(withdrawId: number, sts: number) {
|
||||
try {
|
||||
await updateSts(withdrawId, { sts })
|
||||
message.success('وضعیت ثبت شد')
|
||||
await reload()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
fetch: reload
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,96 @@
|
||||
import type { BaseTableColumn } from '@core/type/baseTable'
|
||||
import { toJalali } from '@core/utils/useDataTime'
|
||||
import CustomTag from '@/components/CustomTag.vue'
|
||||
import type { Withdraw } from '@/model/wallet'
|
||||
|
||||
function formatProductsSummary(record: Withdraw): string {
|
||||
const lines = record.transaction ?? []
|
||||
if (!lines.length) return '-'
|
||||
|
||||
return lines
|
||||
.map((tx) => {
|
||||
const qty = Math.abs(Number(tx.gold ?? 0))
|
||||
const title = String(tx.title ?? '').trim() || 'محصول'
|
||||
return `${title}: ${qty}`
|
||||
})
|
||||
.join(' | ')
|
||||
}
|
||||
|
||||
function formatAddress(record: Withdraw & { address?: { province?: string; city?: string; address?: string } }): string {
|
||||
const addr = record.address ?? (record as { Address?: { province?: string; city?: string; address?: string } }).Address
|
||||
if (!addr) return '-'
|
||||
const parts = [addr.province, addr.city, addr.address].filter(Boolean)
|
||||
return parts.length ? parts.join(' / ') : '-'
|
||||
}
|
||||
|
||||
export function getPhysicalWithdrawColumns(): BaseTableColumn[] {
|
||||
return [
|
||||
{
|
||||
title: 'ردیف',
|
||||
dataIndex: 'id',
|
||||
key: 'row',
|
||||
filterable: false,
|
||||
sortable: false,
|
||||
customRender: (record: { index: number }) => record.index + 1
|
||||
},
|
||||
{
|
||||
title: 'کد سند',
|
||||
dataIndex: 'id',
|
||||
key: 'id',
|
||||
type: 'Number'
|
||||
},
|
||||
{
|
||||
title: 'مشتری',
|
||||
dataIndex: 'customer.name',
|
||||
key: 'customer.name',
|
||||
type: 'Text'
|
||||
},
|
||||
{
|
||||
title: 'محصولات',
|
||||
dataIndex: 'transaction',
|
||||
key: 'products',
|
||||
filterable: false,
|
||||
sortable: false,
|
||||
customRender: ({ record }) => (
|
||||
<div class="max-w-xs whitespace-normal text-center text-xs leading-5">{formatProductsSummary(record)}</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'آدرس',
|
||||
dataIndex: 'address',
|
||||
key: 'address',
|
||||
filterable: false,
|
||||
sortable: false,
|
||||
customRender: ({ record }) => (
|
||||
<div class="max-w-xs whitespace-normal text-center text-xs leading-5">{formatAddress(record)}</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'وضعیت',
|
||||
dataIndex: 'sts',
|
||||
key: 'sts',
|
||||
filterable: false,
|
||||
customRender: ({ record }) => (
|
||||
<CustomTag textColor="#ca8a04" bgColor="#fef3c7">
|
||||
{record?.sts_str ?? '-'}
|
||||
</CustomTag>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'تاریخ ثبت',
|
||||
dataIndex: 'created_at',
|
||||
key: 'created_at',
|
||||
type: 'DateTime',
|
||||
customRender: (record: { record: { created_at?: string } }) => toJalali(record.record.created_at)
|
||||
},
|
||||
{
|
||||
title: 'عملیات',
|
||||
dataIndex: 'action',
|
||||
key: 'action',
|
||||
width: 260,
|
||||
slot: 'action',
|
||||
filterable: false,
|
||||
fixed: 'right'
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<div class="h-full min-h-0">
|
||||
<BasicMainCard>
|
||||
<div class="flex h-full min-h-0 w-full flex-col overflow-hidden">
|
||||
<tbl ref="table" class="min-h-0 flex-1 w-full" @add="openCreate" />
|
||||
</div>
|
||||
</BasicMainCard>
|
||||
|
||||
<BasicActionSheet
|
||||
v-model:visible="createVisible"
|
||||
title="ثبت برداشت فیزیکی"
|
||||
modal-width="32rem"
|
||||
drawer-height="90vh"
|
||||
:loading="loading"
|
||||
:show-button="true"
|
||||
:show-cancel="true"
|
||||
:show-ok="true"
|
||||
ok-text="ثبت"
|
||||
cancel-text="انصراف"
|
||||
@ok="submitCreate"
|
||||
@close="closeCreate"
|
||||
@cancel="closeCreate"
|
||||
>
|
||||
<PhysicalWithdrawEditorFormBody
|
||||
ref="editorRef"
|
||||
:form="form"
|
||||
:customers="customers"
|
||||
/>
|
||||
</BasicActionSheet>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { message } from 'ant-design-vue'
|
||||
import tbl from './components/table.vue'
|
||||
import BasicActionSheet from '@/components/BasicActionSheet.vue'
|
||||
import PhysicalWithdrawEditorFormBody, {
|
||||
type PhysicalWithdrawForm
|
||||
} from './components/PhysicalWithdrawEditorFormBody.vue'
|
||||
import { createPhysicalWithdraw } from '@/api/physicalWithdraw'
|
||||
import { getCustomersList } from '@/api/customer'
|
||||
import type { Customer } from '@/model/customer'
|
||||
|
||||
const table = ref<{ fetch: () => Promise<void> } | null>(null)
|
||||
const editorRef = ref<{
|
||||
validateFields?: () => Promise<unknown>
|
||||
resetFields?: () => void
|
||||
}>()
|
||||
const loading = ref(false)
|
||||
const createVisible = ref(false)
|
||||
const customers = ref<Customer[]>([])
|
||||
|
||||
const form = ref<PhysicalWithdrawForm>({
|
||||
customer_id: undefined,
|
||||
address_id: undefined,
|
||||
lines: [{ wallet_id: undefined, value: undefined }]
|
||||
})
|
||||
|
||||
async function loadCustomers() {
|
||||
try {
|
||||
customers.value = (await getCustomersList()) ?? []
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
form.value = {
|
||||
customer_id: undefined,
|
||||
address_id: undefined,
|
||||
lines: [{ wallet_id: undefined, value: undefined }]
|
||||
}
|
||||
editorRef.value?.resetFields?.()
|
||||
}
|
||||
|
||||
function openCreate() {
|
||||
resetForm()
|
||||
createVisible.value = true
|
||||
}
|
||||
|
||||
function closeCreate() {
|
||||
createVisible.value = false
|
||||
}
|
||||
|
||||
async function submitCreate() {
|
||||
try {
|
||||
await editorRef.value?.validateFields?.()
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
const lines = form.value.lines.filter((line) => line.wallet_id && Number(line.value) > 0)
|
||||
if (!lines.length) {
|
||||
message.error('حداقل یک محصول با مقدار معتبر انتخاب کنید')
|
||||
return
|
||||
}
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
await createPhysicalWithdraw({
|
||||
customer_id: Number(form.value.customer_id),
|
||||
address_id: Number(form.value.address_id),
|
||||
wallets: lines.map((line) => ({
|
||||
wallet_id: Number(line.wallet_id),
|
||||
value: Number(line.value)
|
||||
}))
|
||||
})
|
||||
message.success('برداشت فیزیکی با موفقیت ثبت شد')
|
||||
createVisible.value = false
|
||||
resetForm()
|
||||
await table.value?.fetch?.()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void loadCustomers()
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,31 @@
|
||||
import type { RouteRecordRaw } from 'vue-router'
|
||||
|
||||
const PhysicalWithdraw: RouteRecordRaw = {
|
||||
name: 'physicalWithdraw',
|
||||
path: '/physical-withdraw',
|
||||
component: () => import('@core/layouts/BasicLayout.vue'),
|
||||
redirect: { name: 'physicalWithdrawMain' },
|
||||
meta: {
|
||||
icon: 'vuesax-linear:truck-tick',
|
||||
title: 'برداشت فیزیکی',
|
||||
disabled: false,
|
||||
hideMenu: false,
|
||||
hideChildren: true,
|
||||
order: 7.5
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: 'physicalWithdrawMain',
|
||||
path: '',
|
||||
component: () => import('@/pages/menuPages/physicalWithdraw/index.vue'),
|
||||
meta: {
|
||||
icon: 'vuesax-linear:truck-tick',
|
||||
title: 'برداشت فیزیکی',
|
||||
disabled: false,
|
||||
hideMenu: false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export default PhysicalWithdraw
|
||||
Reference in New Issue
Block a user