|
|
|
@ -1,15 +1,15 @@ |
|
|
|
<template> |
|
|
|
<template> |
|
|
|
<div v-loading="loading" class="detail-page"> |
|
|
|
<div v-loading="loading" class="detail-page"> |
|
|
|
<doc-detail-header |
|
|
|
<doc-detail-header |
|
|
|
:title="this.title" |
|
|
|
:title="this.title" |
|
|
|
:description="headerDescription" |
|
|
|
:description="headerDescription" |
|
|
|
:extra="headerExtra" |
|
|
|
:extra="headerExtra" |
|
|
|
@close="close" |
|
|
|
@close="close" |
|
|
|
/> |
|
|
|
/> |
|
|
|
|
|
|
|
|
|
|
|
<abstract-form :model="form" :rules="rules"> |
|
|
|
<abstract-form :model="form" :rules="rules"> |
|
|
|
<collapse-card header="流程进度"> |
|
|
|
<collapse-card header="流程进度"> |
|
|
|
<doc-steps :status="form.status" :finish="form.finish" :type="type"/> |
|
|
|
<doc-steps :status="form.status" :type="type"/> |
|
|
|
</collapse-card> |
|
|
|
</collapse-card> |
|
|
|
|
|
|
|
|
|
|
|
<collapse-card header="基础信息"> |
|
|
|
<collapse-card header="基础信息"> |
|
|
|
@ -17,12 +17,12 @@ |
|
|
|
<el-input v-if="canSave" :value="form.pid" readonly> |
|
|
|
<el-input v-if="canSave" :value="form.pid" readonly> |
|
|
|
<el-button slot="append" @click="parentDialog=true">选择</el-button> |
|
|
|
<el-button slot="append" @click="parentDialog=true">选择</el-button> |
|
|
|
</el-input> |
|
|
|
</el-input> |
|
|
|
<template v-else>{{form.pid}}</template> |
|
|
|
<template v-else>{{ form.pid }}</template> |
|
|
|
</abstract-form-item> |
|
|
|
</abstract-form-item> |
|
|
|
</collapse-card> |
|
|
|
</collapse-card> |
|
|
|
|
|
|
|
|
|
|
|
<collapse-card header="出库商品"> |
|
|
|
<collapse-card header="出库商品"> |
|
|
|
<abstract-table :data="form.data" :highlight-current-row="false"> |
|
|
|
<abstract-table :data="displayTableData" :highlight-current-row="false"> |
|
|
|
<el-table-column align="center" type="expand"> |
|
|
|
<el-table-column align="center" type="expand"> |
|
|
|
<el-table slot-scope="{row}" :data="row.data" border show-summary |
|
|
|
<el-table slot-scope="{row}" :data="row.data" border show-summary |
|
|
|
:summary-method="summaryStock(row)"> |
|
|
|
:summary-method="summaryStock(row)"> |
|
|
|
@ -35,14 +35,14 @@ |
|
|
|
</template> |
|
|
|
</template> |
|
|
|
<template v-slot="d"> |
|
|
|
<template v-slot="d"> |
|
|
|
<el-input-number |
|
|
|
<el-input-number |
|
|
|
v-if="canSave" |
|
|
|
v-if="canSave" |
|
|
|
v-model="d.row.num" |
|
|
|
v-model="d.row.num" |
|
|
|
controls-position="right" |
|
|
|
controls-position="right" |
|
|
|
:min="0" |
|
|
|
:min="0" |
|
|
|
size="small" |
|
|
|
size="small" |
|
|
|
@change="(nv,ov)=>changeOutboundNum(nv,ov,d.row,row)" |
|
|
|
@change="(nv,ov)=>changeOutboundNum(nv,ov,d.row,row)" |
|
|
|
/> |
|
|
|
/> |
|
|
|
<span v-else>{{d.row.num}}</span> |
|
|
|
<span v-else>{{ d.row.num }}</span> |
|
|
|
</template> |
|
|
|
</template> |
|
|
|
</el-table-column> |
|
|
|
</el-table-column> |
|
|
|
<el-table-column align="center" label="采购订单" prop="cgddid" show-overflow-tooltip/> |
|
|
|
<el-table-column align="center" label="采购订单" prop="cgddid" show-overflow-tooltip/> |
|
|
|
@ -58,21 +58,21 @@ |
|
|
|
|
|
|
|
|
|
|
|
<collapse-card header="附件"> |
|
|
|
<collapse-card header="附件"> |
|
|
|
<upload-file |
|
|
|
<upload-file |
|
|
|
:file-list="form.imageList" |
|
|
|
:file-list="form.imageList" |
|
|
|
:disabled="!canSave" |
|
|
|
:disabled="!canSave" |
|
|
|
@remove="removeUpload" |
|
|
|
@remove="removeUpload" |
|
|
|
@success="uploadSuccess" |
|
|
|
@success="uploadSuccess" |
|
|
|
/> |
|
|
|
/> |
|
|
|
</collapse-card> |
|
|
|
</collapse-card> |
|
|
|
|
|
|
|
|
|
|
|
<collapse-card header="备注"> |
|
|
|
<collapse-card header="备注"> |
|
|
|
<el-input |
|
|
|
<el-input |
|
|
|
v-model="form.remark" |
|
|
|
v-model="form.remark" |
|
|
|
:rows="4" |
|
|
|
:rows="4" |
|
|
|
:readonly="!canSave" |
|
|
|
:readonly="!canSave" |
|
|
|
maxlength="200" |
|
|
|
maxlength="200" |
|
|
|
show-word-limit |
|
|
|
show-word-limit |
|
|
|
type="textarea" |
|
|
|
type="textarea" |
|
|
|
/> |
|
|
|
/> |
|
|
|
</collapse-card> |
|
|
|
</collapse-card> |
|
|
|
</abstract-form> |
|
|
|
</abstract-form> |
|
|
|
@ -95,180 +95,180 @@ |
|
|
|
</template> |
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
|
|
<script> |
|
|
|
<script> |
|
|
|
import bizDocDetailMixin from "@/mixins/bizDocDetailMixin" |
|
|
|
import docDetailMixin from "@/mixins/docDetailMixin" |
|
|
|
import OrderSelector from "./components/OrderSelector" |
|
|
|
import OrderSelector from "./components/OrderSelector" |
|
|
|
import StockSelector from "./components/StockSelector" |
|
|
|
import StockSelector from "./components/StockSelector" |
|
|
|
import {getDetailById as getStockDetail} from "@/api/stock/current" |
|
|
|
import {getDetailById as getStockDetail} from "@/api/stock/current" |
|
|
|
import {getSubById as getParentSubById} from "@/api/document/sell/order" |
|
|
|
import {getSubById as getParentSubById} from "@/api/doc/sell/order" |
|
|
|
import {baseUrl, add, commit, getById, pass, reject, update, withdraw} from "@/api/document/sell/outbound" |
|
|
|
import {baseUrl, add, commit, getById, pass, reject, update, withdraw} from "@/api/doc/sell/outbound" |
|
|
|
import {isEmpty} from "@/utils" |
|
|
|
import {isEmpty} from "@/utils" |
|
|
|
import {plus, sub} from "@/utils/math" |
|
|
|
import {plus, sub} from "@/utils/math" |
|
|
|
import {elAlert} from "@/utils/message" |
|
|
|
import {elAlert} from "@/utils/message" |
|
|
|
import {isInteger} from "@/utils/validate" |
|
|
|
import {isInteger} from "@/utils/validate" |
|
|
|
|
|
|
|
|
|
|
|
export default { |
|
|
|
export default { |
|
|
|
name: "sellOutboundDetail", |
|
|
|
name: "sellOutboundDetail", |
|
|
|
|
|
|
|
|
|
|
|
mixins: [bizDocDetailMixin], |
|
|
|
mixins: [docDetailMixin], |
|
|
|
|
|
|
|
|
|
|
|
components: {OrderSelector, StockSelector}, |
|
|
|
components: {OrderSelector, StockSelector}, |
|
|
|
|
|
|
|
|
|
|
|
data() { |
|
|
|
data() { |
|
|
|
return { |
|
|
|
return { |
|
|
|
baseUrl, |
|
|
|
baseUrl, |
|
|
|
docName: '销售出库单', |
|
|
|
docName: '销售出库单', |
|
|
|
api: { |
|
|
|
api: { |
|
|
|
getById, add, update, commit, withdraw, pass, reject |
|
|
|
getById, add, update, commit, withdraw, pass, reject |
|
|
|
}, |
|
|
|
|
|
|
|
form: { |
|
|
|
|
|
|
|
pid: null |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
rules: { |
|
|
|
|
|
|
|
pid: [{required: true, message: '请选择销售订单', trigger: 'change'}] |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
stockDialog: false, |
|
|
|
|
|
|
|
row: null, |
|
|
|
|
|
|
|
parentDialog: false, |
|
|
|
|
|
|
|
displayTableData: [] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
computed: { |
|
|
|
|
|
|
|
headerDescription() { |
|
|
|
|
|
|
|
const f = this.$options.filters.timestamp2Date |
|
|
|
|
|
|
|
return [ |
|
|
|
|
|
|
|
{label: '创建人:', content: this.form.cname}, |
|
|
|
|
|
|
|
{label: '创建时间:', content: f(this.form.ctime)}, |
|
|
|
|
|
|
|
{label: '审核人:', content: this.form.vname}, |
|
|
|
|
|
|
|
{label: '审核时间:', content: f(this.form.vtime)} |
|
|
|
|
|
|
|
] |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
headerExtra() { |
|
|
|
form: { |
|
|
|
return [ |
|
|
|
pid: null |
|
|
|
{title: '单据状态', content: this.getStatus(this.form.status)} |
|
|
|
}, |
|
|
|
] |
|
|
|
rules: { |
|
|
|
} |
|
|
|
pid: [{required: true, message: '请选择销售订单', trigger: 'change'}] |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
stockDialog: false, |
|
|
|
|
|
|
|
row: null, |
|
|
|
|
|
|
|
parentDialog: false, |
|
|
|
|
|
|
|
displayTableData: [] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
computed: { |
|
|
|
|
|
|
|
headerDescription() { |
|
|
|
|
|
|
|
const f = this.$options.filters.timestamp2Date |
|
|
|
|
|
|
|
return [ |
|
|
|
|
|
|
|
{label: '创建人:', content: this.form.cname}, |
|
|
|
|
|
|
|
{label: '创建时间:', content: f(this.form.ctime)}, |
|
|
|
|
|
|
|
{label: '审核人:', content: this.form.vname}, |
|
|
|
|
|
|
|
{label: '审核时间:', content: f(this.form.vtime)} |
|
|
|
|
|
|
|
] |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
headerExtra() { |
|
|
|
|
|
|
|
return [ |
|
|
|
|
|
|
|
{title: '单据状态', content: this.getStatus(this.form.status)} |
|
|
|
|
|
|
|
] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
methods: { |
|
|
|
methods: { |
|
|
|
afterInit() { |
|
|
|
afterInit() { |
|
|
|
if (this.type === 'add') return |
|
|
|
if (this.type === 'add') return |
|
|
|
let ids = this.form.data.map(i => i.sid).join(',') |
|
|
|
const ids = this.form.data.map(i => i.sid).join(',') |
|
|
|
return Promise.all([ |
|
|
|
return Promise.all([ |
|
|
|
getParentSubById(this.form.pid), |
|
|
|
getParentSubById(this.form.pid), |
|
|
|
getStockDetail(ids) |
|
|
|
getStockDetail(ids) |
|
|
|
]) |
|
|
|
]) |
|
|
|
.then(([r1, r2]) => this.buildDisplayTableData(r1, r2)) |
|
|
|
.then(([r1, r2]) => this.buildDisplayTableData(r1, r2)) |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
//根据销售订单的子表、销售出库的子表、对应的库存来构造展示列表 |
|
|
|
//根据销售订单的子表、销售出库的子表、对应的库存来构造展示列表 |
|
|
|
buildDisplayTableData(orderSubList, stockList) { |
|
|
|
buildDisplayTableData(orderSubList, stockList) { |
|
|
|
this.displayTableData = [] |
|
|
|
this.displayTableData = [] |
|
|
|
let group = {} |
|
|
|
const group = {} |
|
|
|
this.form.data.forEach(i => { |
|
|
|
this.form.data.forEach(i => { |
|
|
|
if (group[i.cid] === undefined) group[i.cid] = [] |
|
|
|
if (group[i.cid] === undefined) group[i.cid] = [] |
|
|
|
let stock = stockList.find(j => j.id === i.sid) |
|
|
|
let stock = stockList.find(j => j.id === i.sid) |
|
|
|
group[i.cid].push({ |
|
|
|
group[i.cid].push({ |
|
|
|
...i, |
|
|
|
...i, |
|
|
|
cgddid: stock ? stock.cgddid : null, |
|
|
|
cgddid: stock ? stock.cgddid : null, |
|
|
|
cgrkid: stock ? stock.cgrkid : null, |
|
|
|
cgrkid: stock ? stock.cgrkid : null, |
|
|
|
max_num: stock ? stock.num : 0 |
|
|
|
maxNum: stock ? stock.num : 0 |
|
|
|
}) |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
orderSubList.forEach(i => { |
|
|
|
|
|
|
|
if (group[i.cid]) { |
|
|
|
|
|
|
|
let num = plus(...group[i.cid].map(j => j.num)) |
|
|
|
|
|
|
|
this.displayTableData.push({...i, num, data: group[i.cid]}) |
|
|
|
|
|
|
|
delete group[i.cid] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}) |
|
|
|
}) |
|
|
|
if (Object.keys(group).length > 0) { |
|
|
|
}) |
|
|
|
elAlert('出库商品不符合销售订单,请重新选择', () => { |
|
|
|
orderSubList.forEach(i => { |
|
|
|
this.displayTableData = [] |
|
|
|
if (group[i.cid]) { |
|
|
|
this.form.data = [] |
|
|
|
let num = plus(...group[i.cid].map(j => j.num)) |
|
|
|
}) |
|
|
|
this.displayTableData.push({...i, num, data: group[i.cid]}) |
|
|
|
|
|
|
|
delete group[i.cid] |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}) |
|
|
|
|
|
|
|
if (Object.keys(group).length > 0) { |
|
|
|
selectParent(id, sub) { |
|
|
|
elAlert('出库商品不符合销售订单,请重新选择', () => { |
|
|
|
this.form.pid = id |
|
|
|
this.displayTableData = [] |
|
|
|
this.displayTableData = sub.map(i => ({...i, num: 0, data: []})) |
|
|
|
this.form.data = [] |
|
|
|
}, |
|
|
|
}) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
openStock(row) { |
|
|
|
selectParent(id, sub) { |
|
|
|
this.row = row |
|
|
|
this.form.pid = id |
|
|
|
this.stockDialog = true |
|
|
|
this.displayTableData = sub.map(i => ({...i, num: 0, data: []})) |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
selectStock(stocks) { |
|
|
|
openStock(row) { |
|
|
|
let res = [] |
|
|
|
this.row = row |
|
|
|
let outboundNum = 0 |
|
|
|
this.stockDialog = true |
|
|
|
let remainNum = this.row.remainNum |
|
|
|
}, |
|
|
|
for (let stock of stocks) { |
|
|
|
|
|
|
|
if (remainNum <= 0) break |
|
|
|
|
|
|
|
let item = { |
|
|
|
|
|
|
|
...stock, |
|
|
|
|
|
|
|
sid: stock.id, |
|
|
|
|
|
|
|
pid: this.form.id, |
|
|
|
|
|
|
|
max_num: stock.num, |
|
|
|
|
|
|
|
num: stock.num > remainNum ? remainNum : stock.num |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
outboundNum = plus(outboundNum, item.num) |
|
|
|
|
|
|
|
res.push(item) |
|
|
|
|
|
|
|
remainNum -= stock.num |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
this.row.num = outboundNum |
|
|
|
|
|
|
|
this.row.data = res |
|
|
|
|
|
|
|
this.stockDialog = false |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
summaryStock(row) { |
|
|
|
selectStock(stocks) { |
|
|
|
return ({data}) => { |
|
|
|
let res = [] |
|
|
|
let sum = ['合计', 0, '', ''] |
|
|
|
let outboundNum = 0 |
|
|
|
data.forEach(i => { |
|
|
|
let remainNum = this.row.remainNum |
|
|
|
sum[1] = plus(sum[1], i.num) |
|
|
|
for (let stock of stocks) { |
|
|
|
}) |
|
|
|
if (remainNum <= 0) break |
|
|
|
row.num = sum[1] |
|
|
|
let item = { |
|
|
|
return sum |
|
|
|
...stock, |
|
|
|
|
|
|
|
sid: stock.id, |
|
|
|
|
|
|
|
pid: this.form.id, |
|
|
|
|
|
|
|
maxNum: stock.num, |
|
|
|
|
|
|
|
num: stock.num > remainNum ? remainNum : stock.num |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
outboundNum = plus(outboundNum, item.num) |
|
|
|
|
|
|
|
res.push(item) |
|
|
|
|
|
|
|
remainNum -= stock.num |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
this.row.num = outboundNum |
|
|
|
|
|
|
|
this.row.data = res |
|
|
|
|
|
|
|
this.stockDialog = false |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
changeOutboundNum(nv, ov, row, displayTableRow) { |
|
|
|
summaryStock(row) { |
|
|
|
if (nv > row.max_num) { |
|
|
|
return ({data}) => { |
|
|
|
return elAlert(`${row.cname}的出库数量超出库存数量`, () => row.num = ov) |
|
|
|
let sum = ['合计', 0, '', ''] |
|
|
|
} |
|
|
|
data.forEach(i => { |
|
|
|
|
|
|
|
sum[1] = plus(sum[1], i.num) |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
row.num = sum[1] |
|
|
|
|
|
|
|
return sum |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
let outboundNum = displayTableRow.data.map(i => i.num) |
|
|
|
changeOutboundNum(nv, ov, row, displayTableRow) { |
|
|
|
outboundNum = outboundNum.length === 0 ? 0 : plus(...outboundNum) |
|
|
|
if (nv > row.maxNum) { |
|
|
|
|
|
|
|
return elAlert(`${row.cname}的出库数量超出库存数量`, () => row.num = ov) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!outboundNum) return |
|
|
|
let outboundNum = displayTableRow.data.map(i => i.num) |
|
|
|
|
|
|
|
outboundNum = outboundNum.length === 0 ? 0 : plus(...outboundNum) |
|
|
|
|
|
|
|
|
|
|
|
if (outboundNum > displayTableRow.remainNum) { |
|
|
|
if (!outboundNum) return |
|
|
|
let correctNum = sub(displayTableRow.remainNum, sub(outboundNum, nv)) |
|
|
|
|
|
|
|
if (correctNum < 0) correctNum = 0 |
|
|
|
|
|
|
|
else if (correctNum > row.max_num) correctNum = row.max_num |
|
|
|
|
|
|
|
return elAlert(`${displayTableRow.cname}的出库数量超出销售数量`, () => row.num = ov) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
validate() { |
|
|
|
if (outboundNum > displayTableRow.remainNum) { |
|
|
|
if (this.type === 'edit' && isEmpty(this.form.id)) { |
|
|
|
let correctNum = sub(displayTableRow.remainNum, sub(outboundNum, nv)) |
|
|
|
return '属性缺失,请关闭弹窗刷新重试' |
|
|
|
if (correctNum < 0) correctNum = 0 |
|
|
|
} |
|
|
|
else if (correctNum > row.maxNum) correctNum = row.maxNum |
|
|
|
|
|
|
|
return elAlert(`${displayTableRow.cname}的出库数量超出销售数量`, () => row.num = ov) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
this.form.data = this.displayTableData.reduce((arr, i) => arr.concat(i.data), []) |
|
|
|
validate() { |
|
|
|
|
|
|
|
if (this.type === 'edit' && isEmpty(this.form.id)) { |
|
|
|
|
|
|
|
return '属性缺失,请关闭弹窗刷新重试' |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (this.form.data.length <= 0) return '出库商品不能为空' |
|
|
|
this.form.data = this.displayTableData.reduce((arr, i) => arr.concat(i.data), []) |
|
|
|
|
|
|
|
|
|
|
|
let index = 1 |
|
|
|
if (this.form.data.length <= 0) return '出库商品不能为空' |
|
|
|
for (let sub of this.form.data) { |
|
|
|
|
|
|
|
if (isEmpty(sub.num)) return `第${index}个商品的出库数量不能为空` |
|
|
|
|
|
|
|
if (sub.num < 0 || !isInteger(sub.num)) return `第${index}个商品的出库数量有误` |
|
|
|
|
|
|
|
index++ |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return null |
|
|
|
let index = 1 |
|
|
|
|
|
|
|
for (let sub of this.form.data) { |
|
|
|
|
|
|
|
if (isEmpty(sub.num)) return `第${index}个商品的出库数量不能为空` |
|
|
|
|
|
|
|
if (sub.num < 0 || !isInteger(sub.num)) return `第${index}个商品的出库数量有误` |
|
|
|
|
|
|
|
index++ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return null |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
</script> |
|
|
|
</script> |
|
|
|
|