ERP:增加 ERP 销售出库的编辑界面

This commit is contained in:
YunaiV 2024-02-11 16:12:12 +08:00
parent c0db4df880
commit 00a386dd7c
7 changed files with 149 additions and 63 deletions

View File

@ -10,7 +10,7 @@ export interface SaleOrderVO {
totalPrice: number // 合计金额,单位:元 totalPrice: number // 合计金额,单位:元
status: number // 状态 status: number // 状态
remark: string // 备注 remark: string // 备注
inCount: number // 销售入库数量 outCount: number // 销售出库数量
returnCount: number // 销售退货数量 returnCount: number // 销售退货数量
} }

View File

@ -43,6 +43,24 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8">
<el-form-item label="销售人员" prop="saleUserId">
<el-select
v-model="formData.saleUserId"
clearable
filterable
placeholder="请选择销售人员"
class="!w-1/1"
>
<el-option
v-for="item in userList"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="16"> <el-col :span="16">
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
<el-input <el-input
@ -140,6 +158,7 @@ import SaleOrderItemForm from './components/SaleOrderItemForm.vue'
import { CustomerApi, CustomerVO } from '@/api/erp/sale/customer' import { CustomerApi, CustomerVO } from '@/api/erp/sale/customer'
import { AccountApi, AccountVO } from '@/api/erp/finance/account' import { AccountApi, AccountVO } from '@/api/erp/finance/account'
import { erpPriceInputFormatter, erpPriceMultiply } from '@/utils' import { erpPriceInputFormatter, erpPriceMultiply } from '@/utils'
import * as UserApi from '@/api/system/user'
/** ERP 销售订单表单 */ /** ERP 销售订单表单 */
defineOptions({ name: 'SaleOrderForm' }) defineOptions({ name: 'SaleOrderForm' })
@ -155,6 +174,7 @@ const formData = ref({
id: undefined, id: undefined,
customerId: undefined, customerId: undefined,
accountId: undefined, accountId: undefined,
saleUserId: undefined,
orderTime: undefined, orderTime: undefined,
remark: undefined, remark: undefined,
fileUrl: '', fileUrl: '',
@ -173,6 +193,7 @@ const disabled = computed(() => formType.value === 'detail')
const formRef = ref() // Ref const formRef = ref() // Ref
const customerList = ref<CustomerVO[]>([]) // const customerList = ref<CustomerVO[]>([]) //
const accountList = ref<AccountVO[]>([]) // const accountList = ref<AccountVO[]>([]) //
const userList = ref<UserApi.UserVO[]>([]) //
/** 子表的表单 */ /** 子表的表单 */
const subTabsName = ref('item') const subTabsName = ref('item')
@ -211,6 +232,8 @@ const open = async (type: string, id?: number) => {
} }
// //
customerList.value = await CustomerApi.getCustomerSimpleList() customerList.value = await CustomerApi.getCustomerSimpleList()
//
userList.value = await UserApi.getSimpleUserList()
// //
accountList.value = await AccountApi.getAccountSimpleList() accountList.value = await AccountApi.getAccountSimpleList()
const defaultAccount = accountList.value.find((item) => item.defaultStatus) const defaultAccount = accountList.value.find((item) => item.defaultStatus)
@ -251,6 +274,7 @@ const resetForm = () => {
id: undefined, id: undefined,
customerId: undefined, customerId: undefined,
accountId: undefined, accountId: undefined,
saleUserId: undefined,
orderTime: undefined, orderTime: undefined,
remark: undefined, remark: undefined,
fileUrl: undefined, fileUrl: undefined,

View File

@ -153,7 +153,6 @@ const formLoading = ref(false) // 表单的加载中
const formData = ref([]) const formData = ref([])
const formRules = reactive({ const formRules = reactive({
inId: [{ required: true, message: '出库编号不能为空', trigger: 'blur' }], inId: [{ required: true, message: '出库编号不能为空', trigger: 'blur' }],
warehouseId: [{ required: true, message: '仓库不能为空', trigger: 'blur' }],
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }], productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }],
count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }] count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }]
}) })

View File

@ -92,7 +92,7 @@
<el-table-column <el-table-column
label="出库数量" label="出库数量"
align="center" align="center"
prop="inCount" prop="outCount"
:formatter="erpCountTableColumnFormatter" :formatter="erpCountTableColumnFormatter"
/> />
<el-table-column <el-table-column

View File

@ -182,7 +182,7 @@
<el-table-column <el-table-column
label="出库数量" label="出库数量"
align="center" align="center"
prop="inCount" prop="outCount"
:formatter="erpCountTableColumnFormatter" :formatter="erpCountTableColumnFormatter"
/> />
<el-table-column <el-table-column

View File

@ -1,5 +1,5 @@
<template> <template>
<Dialog :title="dialogTitle" v-model="dialogVisible" width="1080"> <Dialog :title="dialogTitle" v-model="dialogVisible" width="1440">
<el-form <el-form
ref="formRef" ref="formRef"
:model="formData" :model="formData"
@ -25,6 +25,17 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8">
<el-form-item label="关联订单" prop="orderNo">
<el-input v-model="formData.orderNo" readonly>
<template #append>
<el-button @click="openSaleOrderOutEnableList">
<Icon icon="ep:search" /> 选择
</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="客户" prop="customerId"> <el-form-item label="客户" prop="customerId">
<el-select <el-select
@ -44,17 +55,24 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="关联订单" prop="orderNo"> <el-form-item label="销售人员" prop="saleUserId">
<el-input v-model="formData.orderNo" readonly> <el-select
<template #append> v-model="formData.saleUserId"
<el-button @click="openSaleOrderOutEnableList"> clearable
<Icon icon="ep:search" /> 选择 filterable
</el-button> placeholder="请选择销售人员"
</template> class="!w-1/1"
</el-input> >
<el-option
v-for="item in userList"
:key="item.id"
:label="item.nickname"
:value="item.id"
/>
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="16">
<el-form-item label="备注" prop="remark"> <el-form-item label="备注" prop="remark">
<el-input <el-input
type="textarea" type="textarea"
@ -105,6 +123,18 @@
<el-input disabled v-model="formData.totalPrice" :formatter="erpPriceInputFormatter" /> <el-input disabled v-model="formData.totalPrice" :formatter="erpPriceInputFormatter" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8">
<el-form-item label="其它费用" prop="otherPrice">
<el-input-number
v-model="formData.otherPrice"
controls-position="right"
:min="0"
:precision="2"
placeholder="请输入其它费用"
class="!w-1/1"
/>
</el-form-item>
</el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="结算账户" prop="accountId"> <el-form-item label="结算账户" prop="accountId">
<el-select <el-select
@ -124,13 +154,13 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="收取订金" prop="depositPrice"> <el-form-item label="本次收款" prop="payPrice">
<el-input-number <el-input-number
v-model="formData.depositPrice" v-model="formData.payPrice"
controls-position="right" controls-position="right"
:min="0" :min="0"
:precision="2" :precision="2"
placeholder="请输入收取订金" placeholder="请输入本次收款"
class="!w-1/1" class="!w-1/1"
/> />
</el-form-item> </el-form-item>
@ -156,6 +186,7 @@ import { AccountApi, AccountVO } from '@/api/erp/finance/account'
import { erpPriceInputFormatter, erpPriceMultiply } from '@/utils' import { erpPriceInputFormatter, erpPriceMultiply } from '@/utils'
import SaleOrderOutEnableList from '@/views/erp/sale/order/components/SaleOrderOutEnableList.vue' import SaleOrderOutEnableList from '@/views/erp/sale/order/components/SaleOrderOutEnableList.vue'
import { SaleOrderVO } from '@/api/erp/sale/order' import { SaleOrderVO } from '@/api/erp/sale/order'
import * as UserApi from '@/api/system/user'
/** ERP 销售出库表单 */ /** ERP 销售出库表单 */
defineOptions({ name: 'SaleOutForm' }) defineOptions({ name: 'SaleOutForm' })
@ -171,25 +202,29 @@ const formData = ref({
id: undefined, id: undefined,
customerId: undefined, customerId: undefined,
accountId: undefined, accountId: undefined,
saleUserId: undefined,
outTime: undefined, outTime: undefined,
remark: undefined, remark: undefined,
fileUrl: '', fileUrl: '',
discountPercent: 0, discountPercent: 0,
discountPrice: 0, discountPrice: 0,
totalPrice: 0, totalPrice: 0,
depositPrice: 0, otherPrice: 0,
payPrice: 0,
orderNo: undefined, orderNo: undefined,
items: [], items: [],
no: undefined // no: undefined //
}) })
const formRules = reactive({ const formRules = reactive({
customerId: [{ required: true, message: '客户不能为空', trigger: 'blur' }], customerId: [{ required: true, message: '客户不能为空', trigger: 'blur' }],
outTime: [{ required: true, message: '出库时间不能为空', trigger: 'blur' }] outTime: [{ required: true, message: '出库时间不能为空', trigger: 'blur' }],
payPrice: [{ required: true, message: '本次收款不能为空', trigger: 'blur' }]
}) })
const disabled = computed(() => formType.value === 'detail') const disabled = computed(() => formType.value === 'detail')
const formRef = ref() // Ref const formRef = ref() // Ref
const customerList = ref<CustomerVO[]>([]) // const customerList = ref<CustomerVO[]>([]) //
const accountList = ref<AccountVO[]>([]) // const accountList = ref<AccountVO[]>([]) //
const userList = ref<UserApi.UserVO[]>([]) //
/** 子表的表单 */ /** 子表的表单 */
const subTabsName = ref('item') const subTabsName = ref('item')
@ -202,11 +237,17 @@ watch(
if (!val) { if (!val) {
return return
} }
//
const totalPrice = val.items.reduce((prev, curr) => prev + curr.totalPrice, 0) const totalPrice = val.items.reduce((prev, curr) => prev + curr.totalPrice, 0)
const discountPrice = const discountPrice =
val.discountPercent != null ? erpPriceMultiply(totalPrice, val.discountPercent / 100.0) : 0 val.discountPercent != null ? erpPriceMultiply(totalPrice, val.discountPercent / 100.0) : 0
// debugger
// TODO
const payPrice = totalPrice - discountPrice + val.otherPrice
//
formData.value.discountPrice = discountPrice formData.value.discountPrice = discountPrice
formData.value.totalPrice = totalPrice - discountPrice formData.value.totalPrice = totalPrice - discountPrice
formData.value.payPrice = payPrice
}, },
{ deep: true } { deep: true }
) )
@ -228,15 +269,14 @@ const open = async (type: string, id?: number) => {
} }
// //
customerList.value = await CustomerApi.getCustomerSimpleList() customerList.value = await CustomerApi.getCustomerSimpleList()
//
userList.value = await UserApi.getSimpleUserList()
// //
accountList.value = await AccountApi.getAccountSimpleList() accountList.value = await AccountApi.getAccountSimpleList()
const defaultAccount = accountList.value.find((item) => item.defaultStatus) const defaultAccount = accountList.value.find((item) => item.defaultStatus)
if (defaultAccount) { if (defaultAccount) {
formData.value.accountId = defaultAccount.id formData.value.accountId = defaultAccount.id
} }
// TODO
// saleOrderOutEnableListRef.value.open()
} }
defineExpose({ open }) // open defineExpose({ open }) // open
@ -247,18 +287,17 @@ const openSaleOrderOutEnableList = () => {
} }
const handleSaleOrderChange = (order: SaleOrderVO) => { const handleSaleOrderChange = (order: SaleOrderVO) => {
debugger //
formData.value.orderId = order.id
formData.value.orderNo = order.no formData.value.orderNo = order.no
// formData.value.customerId = order.customerId formData.value.customerId = order.customerId
// formData.value.accountId = order.accountId formData.value.accountId = order.accountId
// formData.value.items = order.items.map((item) => { formData.value.saleUserId = order.saleUserId
// return { formData.value.discountPercent = order.discountPercent
// productId: item.productId, formData.value.remark = order.remark
// count: item.count, formData.value.fileUrl = order.fileUrl
// productPrice: item.productPrice, //
// taxPercent: item.taxPercent formData.value.items = order.items.filter((item) => item.count > item.outCount)
// }
// })
} }
/** 提交表单 */ /** 提交表单 */
@ -292,13 +331,15 @@ const resetForm = () => {
id: undefined, id: undefined,
customerId: undefined, customerId: undefined,
accountId: undefined, accountId: undefined,
saleUserId: undefined,
outTime: undefined, outTime: undefined,
remark: undefined, remark: undefined,
fileUrl: undefined, fileUrl: undefined,
discountPercent: 0, discountPercent: 0,
discountPrice: 0, discountPrice: 0,
totalPrice: 0, totalPrice: 0,
depositPrice: 0, otherPrice: 0,
payPrice: 0,
items: [] items: []
} }
formRef.value?.resetFields() formRef.value?.resetFields()

View File

@ -10,18 +10,22 @@
> >
<el-table :data="formData" show-summary :summary-method="getSummaries" class="-mt-10px"> <el-table :data="formData" show-summary :summary-method="getSummaries" class="-mt-10px">
<el-table-column label="序号" type="index" align="center" width="60" /> <el-table-column label="序号" type="index" align="center" width="60" />
<el-table-column label="产品名称" min-width="180"> <el-table-column label="仓库名称" min-width="125">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.productId`" :rules="formRules.productId" class="mb-0px!"> <el-form-item
:prop="`${$index}.warehouseId`"
:rules="formRules.warehouseId"
class="mb-0px!"
>
<el-select <el-select
v-model="row.productId" v-model="row.warehouseId"
clearable clearable
filterable filterable
@change="onChangeProduct($event, row)" placeholder="请选择仓库"
placeholder="请选择产品" @change="onChangeWarehouse($event, row)"
> >
<el-option <el-option
v-for="item in productList" v-for="item in warehouseList"
:key="item.id" :key="item.id"
:label="item.name" :label="item.name"
:value="item.id" :value="item.id"
@ -30,6 +34,13 @@
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="产品名称" min-width="180">
<template #default="{ row }">
<el-form-item class="mb-0px!">
<el-input disabled v-model="row.productName" />
</el-form-item>
</template>
</el-table-column>
<el-table-column label="库存" min-width="100"> <el-table-column label="库存" min-width="100">
<template #default="{ row }"> <template #default="{ row }">
<el-form-item class="mb-0px!"> <el-form-item class="mb-0px!">
@ -51,6 +62,20 @@
</el-form-item> </el-form-item>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="原数量" fixed="right" min-width="80">
<template #default="{ row }">
<el-form-item class="mb-0px!">
<el-input disabled v-model="row.totalCount" :formatter="erpCountInputFormatter" />
</el-form-item>
</template>
</el-table-column>
<el-table-column label="已出库" fixed="right" min-width="80">
<template #default="{ row }">
<el-form-item class="mb-0px!">
<el-input disabled v-model="row.outCount" :formatter="erpCountInputFormatter" />
</el-form-item>
</template>
</el-table-column>
<el-table-column label="数量" prop="count" fixed="right" min-width="140"> <el-table-column label="数量" prop="count" fixed="right" min-width="140">
<template #default="{ row, $index }"> <template #default="{ row, $index }">
<el-form-item :prop="`${$index}.count`" :rules="formRules.count" class="mb-0px!"> <el-form-item :prop="`${$index}.count`" :rules="formRules.count" class="mb-0px!">
@ -126,17 +151,15 @@
</el-table-column> </el-table-column>
<el-table-column align="center" fixed="right" label="操作" width="60"> <el-table-column align="center" fixed="right" label="操作" width="60">
<template #default="{ $index }"> <template #default="{ $index }">
<el-button @click="handleDelete($index)" link></el-button> <el-button :disabled="formData.length === 1" @click="handleDelete($index)" link>
</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</el-form> </el-form>
<el-row justify="center" class="mt-3" v-if="!disabled">
<el-button @click="handleAdd" round>+ 添加出库产品</el-button>
</el-row>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ProductApi, ProductVO } from '@/api/erp/product/product'
import { StockApi } from '@/api/erp/stock/stock' import { StockApi } from '@/api/erp/stock/stock'
import { import {
erpCountInputFormatter, erpCountInputFormatter,
@ -144,6 +167,7 @@ import {
erpPriceMultiply, erpPriceMultiply,
getSumValue getSumValue
} from '@/utils' } from '@/utils'
import { WarehouseApi, WarehouseVO } from '@/api/erp/stock/warehouse'
const props = defineProps<{ const props = defineProps<{
items: undefined items: undefined
@ -158,13 +182,26 @@ const formRules = reactive({
count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }] count: [{ required: true, message: '产品数量不能为空', trigger: 'blur' }]
}) })
const formRef = ref([]) // Ref const formRef = ref([]) // Ref
const productList = ref<ProductVO[]>([]) // const warehouseList = ref<WarehouseVO[]>([]) //
const defaultWarehouse = ref<WarehouseVO>(undefined) //
/** 初始化设置出库项 */ /** 初始化设置出库项 */
watch( watch(
() => props.items, () => props.items,
async (val) => { async (val) => {
val.forEach((item) => {
item.totalCount = item.count
item.count = item.totalCount - item.outCount
if (item.warehouseId == null) {
item.warehouseId = defaultWarehouse.value?.id
}
if (item.stockCount === null && item.warehouseId != null) {
setStockCount(item)
}
})
formData.value = val formData.value = val
// TODO
}, },
{ immediate: true } { immediate: true }
) )
@ -235,18 +272,6 @@ const handleDelete = (index: number) => {
formData.value.splice(index, 1) formData.value.splice(index, 1)
} }
/** 处理产品变更 */
const onChangeProduct = (productId, row) => {
const product = productList.value.find((item) => item.id === productId)
if (product) {
row.productUnitName = product.unitName
row.productBarCode = product.barCode
row.productPrice = product.salePrice
}
//
setStockCount(row)
}
/** 加载库存 */ /** 加载库存 */
const setStockCount = async (row: any) => { const setStockCount = async (row: any) => {
if (!row.productId) { if (!row.productId) {
@ -264,10 +289,7 @@ defineExpose({ validate })
/** 初始化 */ /** 初始化 */
onMounted(async () => { onMounted(async () => {
productList.value = await ProductApi.getProductSimpleList() warehouseList.value = await WarehouseApi.getWarehouseSimpleList()
// defaultWarehouse.value = warehouseList.value.find((item) => item.defaultStatus)
if (formData.value.length === 0) {
handleAdd()
}
}) })
</script> </script>