557 lines
18 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-dialog v-model="showDialog" title="采购订单审批" width="1200px" @close="closeDialog">
<el-form label-position="right" label-width="110px" v-loading="loading">
<el-form-item label="公司名称:">
<el-select v-model="itemInfo.company_id" placeholder="请选择" clearable filterable style="width: 320px;">
<el-option v-for="it in companyList" :key="it.id" :label="it.name" :value="it.id" />
</el-select>
</el-form-item>
<el-form-item label="选品:">
<el-select v-model="itemInfo.manager_id" placeholder="请选择" clearable filterable style="width: 320px;">
<el-option v-for="it in managerList" :key="it.id" :label="it.username" :value="it.id" />
</el-select>
</el-form-item>
<el-form-item label="供应商名称:">
<el-select v-model="itemInfo.purchase_supplier_id" placeholder="请选择" clearable filterable style="width: 320px;">
<el-option v-for="it in supplierList" :key="it.id" :label="it.supplier_name" :value="it.id" />
</el-select>
</el-form-item>
<el-form-item label="商品信息:">
<el-button type="primary" @click="openGoods()">添加商品</el-button>
<el-table :data="goodsList" style="width: 100%;margin-top: 15px;" border>
<el-table-column prop="goods.title" label="商品名称" />
<el-table-column label="规格名称">
<template #default="scope">
<span>{{ scope.row.sku && scope.row.sku.title || scope.row.title }}</span>
</template>
</el-table-column>
<el-table-column label="预计产品单价(含税)" align="center">
<template #default="scope">
<el-input class="inpt" type="text" v-model="scope.row.expect_unit_price" @input="blurInput(scope.row)" />
</template>
</el-table-column>
<el-table-column label="单位" align="center">
<template #default="scope">
<el-input class="inpt" type="text" v-model="scope.row.unit" />
</template>
</el-table-column>
<el-table-column label="预计采购数量" align="center">
<template #default="scope">
<el-input class="inpt" type="text" v-model="scope.row.expect_quantity" @input="blurInput(scope.row)" />
</template>
</el-table-column>
<el-table-column label="预付款比例(%)" align="center">
<template #default="scope">
<div style="display: flex;align-items: center;">
<el-input type="text" class="inpt" v-model="scope.row.prepayment_ratio" @input="blurInput(scope.row)" />&nbsp;%
</div>
</template>
</el-table-column>
<el-table-column label="交货时间" width="160" align="center">
<template #default="scope">
<el-date-picker
v-model="scope.row.delivery_date"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="选择日期"
style="width: 130px;"
clearable>
</el-date-picker>
</template>
</el-table-column>
<el-table-column label="预计订单金额(元)" align="center" prop="estimated_order_amount" />
<el-table-column label="预付款(元)" align="center" prop="advance_payment" />
<el-table-column label="尾款(元)" align="center" prop="balance_payment" />
<el-table-column label="操作" align="center" width="60">
<template #default="scope">
<el-button type="text" @click="removeGoods(scope.$index, scope.row.id)"><el-icon color="#f00"><DeleteFilled /></el-icon></el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item label="其他费用:">
<el-button type="primary" @click="addFee">添加其他费用</el-button>
<el-table :data="feesList" style="width: 100%;margin-top: 15px;" border>
<el-table-column label="费用名称" align="center">
<template #default="scope">
<el-input type="text" v-model="scope.row.fee_name" />
</template>
</el-table-column>
<el-table-column label="订单金额">
<template #default="scope">
<el-input type="text" v-model="scope.row.amount" @input="getSumData()" />
</template>
</el-table-column>
<el-table-column label="打款信息">
<template #default="scope">
<el-select v-model="scope.row.other_expense_account_id" placeholder="请选择" clearable filterable>
<el-option v-for="it in accountList" :key="it.id" :label="it.name" :value="it.id" />
</el-select>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="100">
<template #default="scope">
<el-button type="danger" size="mini" @click="removeFee(scope.$index)"><el-icon><DeleteFilled /></el-icon></el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item label="备注:">
<el-input v-model="itemInfo.remark" placeholder="请填写备注内容" type="textarea" :rows="4"></el-input>
</el-form-item>
<el-form-item label="逾期交货说明:">
<el-input v-model="itemInfo.late_delivery_explanation" placeholder="请填写逾期交货说明" type="textarea" :rows="4"></el-input>
</el-form-item>
<el-form-item label="总计:">
<div class="sumbox" >
总预计订单金额(元):<span>{{ sumData.total_amount || '0.00' }}</span>
总预付款(元):<span>{{ sumData.pre_pay_amount || '0.00' }}</span>
总尾款(元):<span>{{ sumData.balance_amount || '0.00' }}</span>
</div>
</el-form-item>
<div class="space"></div>
<div class="h5Tit">其余信息</div>
<el-form-item label="开团时间:">
<el-date-picker
v-model="itemInfo.sold_start_time"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择开团时间"
clearable>
</el-date-picker>
</el-form-item>
<el-form-item label="预计到仓时间:">
<el-date-picker
v-model="itemInfo.arrived_time"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="预计到仓时间"
clearable>
</el-date-picker>
</el-form-item>
<el-form-item label="仓库:">
<el-input type="text" v-model="itemInfo.warehouse_name" placeholder="请输入仓库名称" clearable style="width: 320px;" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="closeDialog()">取消</el-button>
<el-button type="primary" @click="commitApproval()" :loading="btnloading">提交审批</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="showGoods" width="900px" title="添加商品">
<div class="searchBox">
<div class="row">
<span class="span">商品名称</span>
<div class="right">
<el-select v-model="filter.goods_ids" placeholder="请选择" clearable filterable class="wid100">
<el-option v-for="it in goodskuList" :key="it.id" :label="it.title" :value="it.id" />
</el-select>
</div>
</div>
<div class="row">
<span class="span">规格名称</span>
<div class="right"><el-input v-model="filter.title" class="wid100" clearable></el-input></div>
</div>
<div class="row">
<span class="span">规格编码</span>
<div class="right"><el-input v-model="filter.sku_code" class="wid100" clearable></el-input></div>
</div>
<el-button type="primary" @click="handleSearch"><el-icon><Search /></el-icon>&nbsp;筛选</el-button>
</div>
<el-table :data="tableList" style="width: 100%" border v-loading="loading1" @select="select"
ref="multipleTable" @select-all="selectAll">
<el-table-column type="selection" width="55" :selectable="checkSelect" />
<el-table-column prop="id" label="ID" width="80" align="center" />
<el-table-column prop="goods.title" label="商品名称" align="center" />
<el-table-column prop="goods.goods_code" label="商品货号" align="center" />
<el-table-column prop="title" label="规格名称" align="center" />
<el-table-column prop="sku_code" label="规格编码" align="center" />
</el-table>
<div class="page-pagination">
<el-pagination
:current-page="page"
background
layout="prev, pager, next, sizes, total"
:total="total"
:page-sizes="[10, 50, 100]"
:page-size="pageSize"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"></el-pagination>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="showGoods = false">取消</el-button>
<el-button type="primary" @click="addGoods">确定</el-button>
</span>
</template>
</el-dialog>
</template>
<script>
import { DeleteFilled, Search } from "@element-plus/icons"
import { reactive, toRefs, watch } from 'vue'
import { get, post } from '@/api/request'
import { ElMessage, ElMessageBox } from 'element-plus'
export default {
components: { DeleteFilled, Search },
props: {
show: {
type: Boolean,
default: false
},
id: {
type: Number,
default: 0,
}
},
setup(props, context) {
const data = reactive({
launchId: 0,
showDialog: false,
companyList: [],
managerList: [],
supplierList: [],
accountList: [],
goodsList: [],
itemInfo: {},
loading: false,
showGoods: false,
feesList: [],
goodskuList: [],
filter: {},
tableList: [],
page: 1,
pageSize: 10,
total: 0,
loading1: false,
chooseList: [],
btnloading: false,
goodsIds: [],
sumData: {}
})
function getDetail() {
data.loading = true
get(`/api/purchaseOrder/${data.launchId}`).then((res) => {
data.itemInfo = res.data
data.sumData.total_amount = res.data.expect_amount
data.sumData.pre_pay_amount = res.data.prepayment_amount
data.sumData.balance_amount = res.data.final_payment_amount
data.feesList = res.data.other_expenses
res.data.products.forEach((item) => {
data.goodsIds.push(item.id)
if(item.expect_unit_price && item.expect_quantity) {
item.estimated_order_amount = (item.expect_unit_price * item.expect_quantity).toFixed(2)
if(item.prepayment_ratio) {
item.advance_payment = ((item.estimated_order_amount * item.prepayment_ratio) / 100).toFixed(2)
item.balance_payment = (((item.estimated_order_amount * 100) - (item.advance_payment * 100)) / 100).toFixed(2)
}
}
})
data.goodsList = res.data.products
data.loading = false
}).catch(() => {
data.loading = false
})
}
function getCompany() {
get(`/api/company/all`, {page: 1, pageSize: 1000}).then((res) => {
data.companyList = res.data
})
}
function getManagerList() {
get('/api/staff', {role_id: 1}).then((res) => {
data.managerList = res.data
})
}
function getSupplier() {
get(`/api/purchaseSupplier`, {page: 1, pageSize: 1000}).then((res) => {
data.supplierList = res.data
})
}
function getAccount() {
get(`/api/otherExpenseAccount`, {page: 1, pageSize: 1000}).then((res) => {
data.accountList = res.data
})
}
const commitApproval = () => {
data.btnloading = true
let products = []
for (let index = 0; index < data.goodsList.length; index++) {
let obj = data.goodsList[index]
products.push({
product_id: obj.goods_id,
sku_id: obj.sku_id,
expect_unit_price: obj.expect_unit_price,
expect_quantity: obj.expect_quantity,
unit: obj.unit,
prepayment_ratio: obj.prepayment_ratio,
delivery_date: obj.delivery_date
})
}
let params = {
company_id: data.itemInfo.company_id,
manager_id: data.itemInfo.manager_id,
purchase_supplier_id: data.itemInfo.purchase_supplier_id,
products: products,
otherExpenses: data.feesList,
remark: data.itemInfo.remark,
late_delivery_explanation: data.itemInfo.late_delivery_explanation,
sold_start_time: data.itemInfo.sold_start_time,
arrived_time: data.itemInfo.arrived_time,
warehouse_name: data.itemInfo.warehouse_name
}
post(`/api/purchaseOrder`, params).then((res) => {
ElMessage({ type: 'success', message: '操作成功' })
closeDialog()
context.emit('refresh')
data.btnloading = false
}).catch(() => {
data.btnloading = false
})
}
function clearForm() {
data.itemInfo = {}
data.feesList = []
data.goodsList = []
data.goodsIds = []
}
function getGoodskuList() {
get(`/api/all/goods`).then((res) => {
data.goodskuList = res.data
})
}
function handleSearch() {
data.page = 1
fetchData()
}
const fetchData = () => {
data.loading1 = true
let params = {
page: data.page,
pageSize: data.pageSize,
...data.filter,
}
get(`/api/goods-skus`, params).then((res) => {
data.tableList = res.data
data.total = res.meta.total
data.loading1 = false
data.chooseList = []
}).catch(() => {
data.loading1 = false
})
}
function handleCurrentChange(e) {
data.page = e
fetchData()
}
function handleSizeChange(e) {
data.page = 1
data.pageSize = e
fetchData()
}
const closeDialog = () => {
clearForm()
context.emit('close')
data.showDialog = false
}
function select(e) {
data.chooseList = e
}
function selectAll(e) {
data.chooseList = e
}
function checkSelect(row) {
if (data.goodsIds.indexOf(row.id) >= 0) {
return false
} else {
return true
}
}
function addGoods() {
if(!data.chooseList.length) {
return ElMessage.info('请选择商品')
}
data.chooseList.forEach((item) => {
item.product_id = item.goods_id
item.sku_id = item.id
data.goodsList.push(item)
data.goodsIds.push(item.id)
})
data.showGoods = false
}
function removeGoods(i, id) {
data.goodsList.splice(i, 1)
let index = data.goodsIds.indexOf(id)
data.goodsIds.splice(index, 1)
}
function addFee() {
data.feesList.push({
fee_name: '',
amount: '',
other_expense_account_id: ''
})
}
function removeFee(i) {
data.feesList.splice(i, 1)
}
function openGoods() {
data.showGoods = true
handleSearch()
}
function blurInput(row) {
if(row.expect_unit_price && row.expect_quantity) {
row.estimated_order_amount = (row.expect_unit_price * row.expect_quantity).toFixed(2)
if(row.prepayment_ratio) {
row.advance_payment = ((row.estimated_order_amount * row.prepayment_ratio) / 100).toFixed(2)
row.balance_payment = (((row.estimated_order_amount * 100) - (row.advance_payment * 100)) / 100).toFixed(2)
}
}
}
watch(() => data.goodsList, (newProps) => {
getSumData()
}, { deep: true })
function getSumData() {
if(data.launchId) {
return
}
let num1 = 0, num2 = 0
for (let index = 0; index < data.goodsList.length; index++) {
let item = data.goodsList[index]
if(item.expect_unit_price && item.expect_quantity) {
num1 += item.expect_unit_price * item.expect_quantity * 100
if(item.prepayment_ratio) {
num2 += num1 * item.prepayment_ratio
}
}
}
for (let index = 0; index < data.feesList.length; index++) {
let item = data.feesList[index]
if(item.amount * 1 > 0) {
num1 += item.amount * 100
num2 += item.amount * 10000
}
}
data.sumData.total_amount = (num1 / 100).toFixed(2)
data.sumData.pre_pay_amount = (num2 / 10000).toFixed(2)
data.sumData.balance_amount = (((data.sumData.total_amount * 100) - (data.sumData.pre_pay_amount * 100)) / 100).toFixed(2)
}
watch(() => props, (newProps) => {
if (newProps.show) {
data.showDialog = true
data.launchId = newProps.id
if(data.launchId) {
getDetail()
}
getCompany()
getManagerList()
getSupplier()
getGoodskuList()
getAccount()
}
}, { deep: true })
return {
...toRefs(data),
getDetail,
getAccount,
closeDialog,
getCompany,
getManagerList,
getSupplier,
clearForm,
commitApproval,
getGoodskuList,
handleSearch,
handleCurrentChange,
handleSizeChange,
select,
selectAll,
checkSelect,
addGoods,
removeGoods,
addFee,
removeFee,
openGoods,
blurInput,
getSumData
}
}
}
</script>
<style scoped lang="scss">
.searchBox{
display: flex;
flex-wrap: wrap;
background-color: #fff;
padding: 15px 0 0 0;
border-radius: 4px;
margin-bottom: 15px;
.row{
display: flex;
align-items: center;
width: 250px;
box-sizing: border-box;
margin-bottom: 15px;
.span{
display: block;
width: 80px;
font-size: 14px;
text-align: right;
box-sizing: border-box;
}
.right{
width: calc(100% - 100px);
}
.wid100{
width: 100%;
}
}
}
.space{
background: repeating-linear-gradient(-45deg, #F56C6C 0, #F56C6C 20%, transparent 0, transparent 25%, #1989fa 0, #1989fa 45%, transparent 0, transparent 50%);
height: 2px;
background-size: 80px;
margin-bottom: 20px;
}
::v-deep .inpt .el-input__inner{
text-align: center;
}
</style>