|
|
@@ -0,0 +1,1107 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <header-title title="物料清单"></header-title>
|
|
|
+
|
|
|
+ <ele-pro-table
|
|
|
+ ref="table"
|
|
|
+ row-key="id"
|
|
|
+ :columns="materialColumns"
|
|
|
+ :datasource="materialList"
|
|
|
+ cache-key="prenatal-examination-material-list-table-2511031522"
|
|
|
+ autoAmendPage
|
|
|
+ :needPage="false"
|
|
|
+ @refresh="$emit('refresh')"
|
|
|
+ >
|
|
|
+ <template v-slot:toolbar> </template>
|
|
|
+
|
|
|
+ <template v-slot:selectColumn="{ row }">
|
|
|
+ <el-checkbox
|
|
|
+ v-model="row.selected"
|
|
|
+ @change="selectedChange(row)"
|
|
|
+ ></el-checkbox>
|
|
|
+ </template>
|
|
|
+ </ele-pro-table>
|
|
|
+
|
|
|
+ <header-title title="产出清单" style="margin-top: 20px"></header-title>
|
|
|
+
|
|
|
+ <ele-pro-table
|
|
|
+ ref="table"
|
|
|
+ row-key="id"
|
|
|
+ :columns="outputDetailsColumns"
|
|
|
+ :datasource="localOutputDetails"
|
|
|
+ cache-key="prenatal-examination-output-list-table-2511031523"
|
|
|
+ autoAmendPage
|
|
|
+ :needPage="false"
|
|
|
+ @refresh="localOutputDetailsRefresh"
|
|
|
+ >
|
|
|
+ <template v-slot:reportQuantity="{ row }">
|
|
|
+ <div>
|
|
|
+ <el-input-number
|
|
|
+ size="small"
|
|
|
+ v-model.number="row.reportQuantity"
|
|
|
+ controls-position="right"
|
|
|
+ :min="0"
|
|
|
+ :max="reportQuantitymax(row)"
|
|
|
+ @change="reportQuantityChange(row)"
|
|
|
+ ></el-input-number>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template v-slot:qualifiedQuantity="{ row }">
|
|
|
+ <el-input-number
|
|
|
+ size="small"
|
|
|
+ v-model.number="row.qualifiedQuantity"
|
|
|
+ controls-position="right"
|
|
|
+ :min="0"
|
|
|
+ :max="qualifiedQuantityMax(row)"
|
|
|
+ @change="qualifiedQuantityChange(row)"
|
|
|
+ ></el-input-number>
|
|
|
+ </template>
|
|
|
+ <template v-slot:noQualifiedQuantity="{ row }">
|
|
|
+ <el-input-number
|
|
|
+ size="small"
|
|
|
+ v-model.number="row.noQualifiedQuantity"
|
|
|
+ controls-position="right"
|
|
|
+ :min="0"
|
|
|
+ :max="noQualifiedQuantityMax(row)"
|
|
|
+ @change="noQualifiedQuantityChange(row)"
|
|
|
+ ></el-input-number>
|
|
|
+ </template>
|
|
|
+ <template v-slot:msg="{ row }">
|
|
|
+ <el-input
|
|
|
+ v-model="row.msg"
|
|
|
+ type="textarea"
|
|
|
+ rows="1"
|
|
|
+ autosize
|
|
|
+ @change="$emit('update:outputDetails', localOutputDetails)"
|
|
|
+ ></el-input>
|
|
|
+ </template>
|
|
|
+ </ele-pro-table>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import {
|
|
|
+ getMaterialQuotaInfo,
|
|
|
+ getCategoryAndLevelByCategoryId
|
|
|
+ } from '@/api/producetaskrecordrulesrecord/index';
|
|
|
+
|
|
|
+ export default {
|
|
|
+ components: {},
|
|
|
+ props: {
|
|
|
+ // 物料明细
|
|
|
+ pickDetails: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ // 本次产出明细
|
|
|
+ outputDetails: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ // 上到工序产出明细
|
|
|
+ preOutputDetails: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ sumOutputDetails: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ // 工单id
|
|
|
+ workOrderId: {
|
|
|
+ type: [String, Number],
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ // 规则id
|
|
|
+ ruleId: {
|
|
|
+ type: [String, Number],
|
|
|
+ required: false
|
|
|
+ },
|
|
|
+ // 工序id
|
|
|
+ produceTaskId: {
|
|
|
+ type: [String, Number],
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ // 工序实例id
|
|
|
+ produceTaskInstanceId: {
|
|
|
+ type: [String, Number],
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ // 工序名称
|
|
|
+ produceTaskName: {
|
|
|
+ type: String,
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ // BOM产品分类id
|
|
|
+ bomCategoryId: {
|
|
|
+ type: [String, Number],
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ // 产出类型 1-物料本身 2-在制品 3-BOM标准产出
|
|
|
+ outputType: {
|
|
|
+ type: [Number],
|
|
|
+ required: true
|
|
|
+ },
|
|
|
+ // 产品分类id
|
|
|
+ categoryId: {
|
|
|
+ type: [String, Number],
|
|
|
+ required: false
|
|
|
+ },
|
|
|
+ // 执行状态
|
|
|
+ executeStatus: {
|
|
|
+ type: [Number],
|
|
|
+ required: false
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ pickDetails: {
|
|
|
+ handler(newVal) {
|
|
|
+ this.localPickDetails = JSON.parse(JSON.stringify(newVal)).map(
|
|
|
+ (i) => {
|
|
|
+ i.ruleId = this.ruleId;
|
|
|
+ i.bomCategoryId = this.bomCategoryId;
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+ );
|
|
|
+ },
|
|
|
+ deep: true,
|
|
|
+ immediate: true
|
|
|
+ },
|
|
|
+ outputDetails: {
|
|
|
+ handler(newVal) {
|
|
|
+ this.localOutputDetails = JSON.parse(JSON.stringify(newVal)).map(
|
|
|
+ (i) => {
|
|
|
+ i.ruleId = this.ruleId;
|
|
|
+ i.outputType = this.outputType;
|
|
|
+ i.bomCategoryId = this.bomCategoryId;
|
|
|
+ i.id = null;
|
|
|
+ return i;
|
|
|
+ }
|
|
|
+ );
|
|
|
+ },
|
|
|
+ deep: true,
|
|
|
+ immediate: true
|
|
|
+ },
|
|
|
+ outputType: {
|
|
|
+ handler() {
|
|
|
+ // 重置产出明细
|
|
|
+ this.localOutputDetails = [];
|
|
|
+
|
|
|
+ this.localPickDetails = this.localPickDetails.map((item) => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ selected: false
|
|
|
+ };
|
|
|
+ });
|
|
|
+
|
|
|
+ // 根据不同的类型,重置物料明细
|
|
|
+ if (this.outputType == 1) {
|
|
|
+ this.$emit('update:outputDetails', this.localOutputDetails);
|
|
|
+ // 1-物料本身
|
|
|
+ } else if (this.outputType == 2) {
|
|
|
+ // 2-在制品
|
|
|
+ this.categoryInfoSetOutput();
|
|
|
+ } else {
|
|
|
+ // 3 BOM标准产出
|
|
|
+ this.setMaterialQuotaInfo();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ ruleId: {
|
|
|
+ handler() {
|
|
|
+ // 更新物料明细的ruleId
|
|
|
+ this.localPickDetails = this.localPickDetails.map((item) => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ ruleId: this.ruleId
|
|
|
+ };
|
|
|
+ });
|
|
|
+ // 更新产出明细的ruleId
|
|
|
+ this.localOutputDetails = this.localOutputDetails.map((item) => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ ruleId: this.ruleId
|
|
|
+ };
|
|
|
+ });
|
|
|
+ // 通知父组件更新
|
|
|
+ this.$emit('update:pickDetails', this.localPickDetails);
|
|
|
+ this.$emit('update:outputDetails', this.localOutputDetails);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ produceTaskId: {
|
|
|
+ handler() {
|
|
|
+ this.getMaterialQuotaInfo();
|
|
|
+ this.getCategoryAndLevelByCategoryId();
|
|
|
+ },
|
|
|
+ immediate: true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ // 物料清单(包含上到工序产出明细)
|
|
|
+ materialList() {
|
|
|
+ return [...this.preOutputDetails, ...this.localPickDetails];
|
|
|
+ },
|
|
|
+ // 物料清单表头
|
|
|
+ materialColumns() {
|
|
|
+ const list = [
|
|
|
+ {
|
|
|
+ width: 45,
|
|
|
+ type: 'index',
|
|
|
+ columnKey: 'index',
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '类型',
|
|
|
+ prop: 'categoryLevelNamePath',
|
|
|
+ minWidth: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '编码',
|
|
|
+ prop: 'categoryCode',
|
|
|
+ minWidth: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '名称',
|
|
|
+ prop: 'categoryName',
|
|
|
+ minWidth: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'model',
|
|
|
+ label: '型号',
|
|
|
+ align: 'center',
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'specifications',
|
|
|
+ label: '规格',
|
|
|
+ align: 'center',
|
|
|
+ width: 160,
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'brandNo',
|
|
|
+ label: '牌号',
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '工序名称',
|
|
|
+ prop: 'produceTaskName',
|
|
|
+ minWidth: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '数量',
|
|
|
+ prop: 'feedQuantity',
|
|
|
+ minWidth: 120,
|
|
|
+ formatter: (row) => {
|
|
|
+ return (row.quantity || 0) + (row.unit || '');
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '当次消耗数量',
|
|
|
+ prop: '',
|
|
|
+ minWidth: 120,
|
|
|
+ formatter: (row) => {
|
|
|
+ // 产出为物料
|
|
|
+ if (this.outputType == 1) {
|
|
|
+ // 取值产出清单
|
|
|
+ const outputItem = this.localOutputDetails.find(
|
|
|
+ (item) => item.categoryCode === row.categoryCode
|
|
|
+ );
|
|
|
+ return (
|
|
|
+ (outputItem ? outputItem.reportQuantity : 0) +
|
|
|
+ (row.unit || '')
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ // 产出为在制品 或 BOM标准产出
|
|
|
+ // 查询基数
|
|
|
+ if (!this.materialQuotaInfo) {
|
|
|
+ return '0' + (row.unit || '');
|
|
|
+ }
|
|
|
+ // 当前行为在制品 和 BOM标准产出
|
|
|
+ const preOutputItem = this.localOutputDetails.find(
|
|
|
+ (item) => item.categoryCode === row.categoryCode
|
|
|
+ );
|
|
|
+
|
|
|
+ if (preOutputItem) {
|
|
|
+ return (preOutputItem.reportQuantity || 0) + (row.unit || '');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 当前行为原材料
|
|
|
+ const materialItem = this.materialQuotaInfo.materialQuota.find(
|
|
|
+ (item) => item.categoryCode === row.categoryCode
|
|
|
+ );
|
|
|
+ if (!materialItem) {
|
|
|
+ return '0' + (row.unit || '');
|
|
|
+ }
|
|
|
+ // 需要的物料数量比例
|
|
|
+ let count =
|
|
|
+ materialItem.count / this.materialQuotaInfo.baseCount;
|
|
|
+ // 产出清单的报工数量 当次报工+累计报工
|
|
|
+ const outputItem = this.localOutputDetails[0];
|
|
|
+ if (!outputItem) {
|
|
|
+ return '0' + (row.unit || '');
|
|
|
+ }
|
|
|
+ // 当次消耗
|
|
|
+ let needQuantity = outputItem.reportQuantity * count;
|
|
|
+ return needQuantity + (row.unit || '');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '累计消耗数量',
|
|
|
+ prop: '',
|
|
|
+ minWidth: 120,
|
|
|
+ formatter: (row) => {
|
|
|
+ if (this.outputType == 1) {
|
|
|
+ const outputItem = this.localOutputDetails.find(
|
|
|
+ (item) => item.categoryCode == row.categoryCode
|
|
|
+ );
|
|
|
+
|
|
|
+ // 查询其他工单sumOutputDetails中已产生的bom标准产出和在制品的累计消耗数量
|
|
|
+ let preCount = 0;
|
|
|
+ if (this.materialQuotaInfo) {
|
|
|
+ const materialQuotaItem =
|
|
|
+ this.materialQuotaInfo.materialQuota.find(
|
|
|
+ (item) => item.categoryCode === row.categoryCode
|
|
|
+ );
|
|
|
+
|
|
|
+ if (!materialQuotaItem) {
|
|
|
+ return 0 + (row.unit || '');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算比例
|
|
|
+ const proportion =
|
|
|
+ materialQuotaItem.count / this.materialQuotaInfo.baseCount;
|
|
|
+
|
|
|
+ if (this.materialQuotaInfo.standardOutput) {
|
|
|
+ // BOM标准产出
|
|
|
+ const preItem = this.sumOutputDetails.find(
|
|
|
+ (item) =>
|
|
|
+ item.categoryCode ===
|
|
|
+ this.materialQuotaInfo.standardOutput.categoryCode
|
|
|
+ );
|
|
|
+ if (preItem) {
|
|
|
+ preCount += preItem.sumReportQuantity * proportion;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.categoryInfo) {
|
|
|
+ // 在制品
|
|
|
+ const preItem = this.sumOutputDetails.find(
|
|
|
+ (item) =>
|
|
|
+ item.categoryCode === this.categoryInfo.categoryCode
|
|
|
+ );
|
|
|
+ if (preItem) {
|
|
|
+ preCount += preItem.sumReportQuantity * proportion;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let count = 0;
|
|
|
+ if (outputItem) {
|
|
|
+ if (this.executeStatus === 2) {
|
|
|
+ // 已执行,处理重新一键报工时,sumReportQuantity包含了当前报工数量
|
|
|
+ count =
|
|
|
+ row.sumReportQuantity -
|
|
|
+ (outputItem.reportQuantityCopy -
|
|
|
+ outputItem.reportQuantity);
|
|
|
+ } else {
|
|
|
+ count = row.sumReportQuantity + outputItem.reportQuantity;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ count = row.sumReportQuantity;
|
|
|
+ }
|
|
|
+
|
|
|
+ return count + preCount + (row.unit || '');
|
|
|
+ } else {
|
|
|
+ // 当前行为在制品 和 BOM标准产出
|
|
|
+ const output = this.localOutputDetails.find(
|
|
|
+ (item) => item.categoryCode === row.categoryCode
|
|
|
+ );
|
|
|
+
|
|
|
+ if (output) {
|
|
|
+ // 区分已执行状态
|
|
|
+ if (this.executeStatus === 2) {
|
|
|
+ // 已执行,处理重新一键报工时,sumReportQuantity包含了当前报工数量
|
|
|
+ return (
|
|
|
+ output.sumReportQuantity -
|
|
|
+ (output.reportQuantityCopy - output.reportQuantity) +
|
|
|
+ (row.unit || '')
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return (
|
|
|
+ (output.sumReportQuantity || 0) +
|
|
|
+ output.reportQuantity +
|
|
|
+ (row.unit || '')
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 产出为在制品 或 BOM标准产出 累计消耗数量
|
|
|
+ if (!this.materialQuotaInfo) {
|
|
|
+ return row.sumReportQuantity + (row.unit || '');
|
|
|
+ }
|
|
|
+
|
|
|
+ const materialItem = this.materialQuotaInfo.materialQuota.find(
|
|
|
+ (item) => item.categoryCode === row.categoryCode
|
|
|
+ );
|
|
|
+ if (!materialItem) {
|
|
|
+ return row.sumReportQuantity + (row.unit || '');
|
|
|
+ }
|
|
|
+ // 计算在制 标准产出消耗原材料
|
|
|
+ const outputItem = this.localOutputDetails[0];
|
|
|
+ if (!outputItem) {
|
|
|
+ return row.sumReportQuantity + (row.unit || '');
|
|
|
+ }
|
|
|
+ // 单位产出所需物料比例
|
|
|
+ const proportion =
|
|
|
+ materialItem.count / this.materialQuotaInfo.baseCount;
|
|
|
+
|
|
|
+ // 查询其他工单sumOutputDetails中已产生的bom标准产出和在制品的累计消耗数量
|
|
|
+ let preCount = 0;
|
|
|
+ // 如果当前物料不是BOM标准产出,则需要加上BOM标准产出的消耗数量
|
|
|
+ if (
|
|
|
+ outputItem.categoryCode !=
|
|
|
+ this.materialQuotaInfo.standardOutput.categoryCode
|
|
|
+ ) {
|
|
|
+ // BOM标准产出
|
|
|
+ const preItem = this.sumOutputDetails.find(
|
|
|
+ (item) =>
|
|
|
+ item.categoryCode ===
|
|
|
+ this.materialQuotaInfo.standardOutput.categoryCode
|
|
|
+ );
|
|
|
+ if (preItem) {
|
|
|
+ preCount += preItem.sumReportQuantity * proportion;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 在制品
|
|
|
+ if (this.categoryInfo) {
|
|
|
+ if (
|
|
|
+ this.categoryInfo.categoryCode != outputItem.categoryCode
|
|
|
+ ) {
|
|
|
+ const preItem = this.sumOutputDetails.find(
|
|
|
+ (item) =>
|
|
|
+ item.categoryCode === this.categoryInfo.categoryCode
|
|
|
+ );
|
|
|
+ if (preItem) {
|
|
|
+ preCount += preItem.sumReportQuantity * proportion;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let cumulativeOutputQuantity = 0;
|
|
|
+
|
|
|
+ if (this.executeStatus === 2) {
|
|
|
+ // 已执行,处理重新一键报工时,sumReportQuantity包含了当前报工数量
|
|
|
+ cumulativeOutputQuantity =
|
|
|
+ outputItem.sumReportQuantity -
|
|
|
+ (outputItem.reportQuantityCopy - outputItem.reportQuantity);
|
|
|
+ } else {
|
|
|
+ cumulativeOutputQuantity =
|
|
|
+ outputItem.sumReportQuantity + outputItem.reportQuantity;
|
|
|
+ }
|
|
|
+ const needQuantity = cumulativeOutputQuantity * proportion;
|
|
|
+
|
|
|
+ // 已消耗数量转换
|
|
|
+ // const sumReportQuantity = row.sumReportQuantity * proportion;
|
|
|
+ const sumReportQuantity = row.sumReportQuantity;
|
|
|
+
|
|
|
+ return (
|
|
|
+ needQuantity + preCount + sumReportQuantity + (row.unit || '')
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ];
|
|
|
+ if (this.outputType == 1) {
|
|
|
+ list.push({
|
|
|
+ prop: '',
|
|
|
+ label: '选择',
|
|
|
+ slot: 'selectColumn',
|
|
|
+ align: 'center',
|
|
|
+ fixed: 'right'
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ localPickDetails: [],
|
|
|
+ localOutputDetails: [],
|
|
|
+ // bom配置的 标准产出信息
|
|
|
+ materialQuotaInfo: null,
|
|
|
+ // 在制品信息
|
|
|
+ categoryInfo: null,
|
|
|
+ // 产出清单表头
|
|
|
+ outputDetailsColumns: [
|
|
|
+ {
|
|
|
+ width: 45,
|
|
|
+ type: 'index',
|
|
|
+ columnKey: 'index',
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '类型',
|
|
|
+ prop: 'categoryLevelNamePath',
|
|
|
+ minWidth: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '编码',
|
|
|
+ prop: 'categoryCode',
|
|
|
+ minWidth: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '名称',
|
|
|
+ prop: 'categoryName',
|
|
|
+ minWidth: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'model',
|
|
|
+ label: '型号',
|
|
|
+ align: 'center',
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'specifications',
|
|
|
+ label: '规格',
|
|
|
+ align: 'center',
|
|
|
+ width: 160,
|
|
|
+ showOverflowTooltip: true
|
|
|
+ },
|
|
|
+ {
|
|
|
+ prop: 'brandNo',
|
|
|
+ label: '牌号',
|
|
|
+ align: 'center'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '工序名称',
|
|
|
+ prop: 'produceTaskName',
|
|
|
+ minWidth: 120
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '当次报工数量',
|
|
|
+ prop: 'reportQuantity',
|
|
|
+ minWidth: 160,
|
|
|
+ slot: 'reportQuantity'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '当次合格数量',
|
|
|
+ prop: 'qualifiedQuantity',
|
|
|
+ minWidth: 160,
|
|
|
+ slot: 'qualifiedQuantity'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '当次不合格数量',
|
|
|
+ prop: 'noQualifiedQuantity',
|
|
|
+ minWidth: 160,
|
|
|
+ slot: 'noQualifiedQuantity'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '不合格原因',
|
|
|
+ prop: 'msg',
|
|
|
+ minWidth: 160,
|
|
|
+ slot: 'msg'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '已报工数量',
|
|
|
+ prop: 'sumReportQuantity',
|
|
|
+ minWidth: 120,
|
|
|
+ formatter(row) {
|
|
|
+ return (row.sumReportQuantity || 0) + row.unit;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '合格总数',
|
|
|
+ prop: 'sumQualifiedQuantity',
|
|
|
+ minWidth: 120,
|
|
|
+ formatter(row) {
|
|
|
+ return (row.sumQualifiedQuantity || 0) + (row.unit || '');
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '不合格总数',
|
|
|
+ prop: 'sumNoQualifiedQuantity',
|
|
|
+ minWidth: 120,
|
|
|
+ formatter(row) {
|
|
|
+ return (row.sumNoQualifiedQuantity || 0) + (row.unit || '');
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ };
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ // 选择物料
|
|
|
+ openMaterialModal() {
|
|
|
+ this.$refs.materialModalRef.open(
|
|
|
+ {
|
|
|
+ workOrderId: this.workOrderId,
|
|
|
+ ruleId: this.ruleId,
|
|
|
+ produceTaskId: this.produceTaskId
|
|
|
+ },
|
|
|
+ // ...this.localPickDetails, ...this.preOutputDetails
|
|
|
+ []
|
|
|
+ );
|
|
|
+ },
|
|
|
+ materialConfirm(data) {
|
|
|
+ // 选择物料后添加
|
|
|
+ console.log('data', data);
|
|
|
+
|
|
|
+ data.forEach((newItem) => {
|
|
|
+ const index = this.localPickDetails.findIndex(
|
|
|
+ (item) => item.categoryCode === newItem.categoryCode
|
|
|
+ );
|
|
|
+ if (index !== -1) {
|
|
|
+ // 存在则替换数量
|
|
|
+ this.localPickDetails[index].quantity = newItem.quantity;
|
|
|
+ } else {
|
|
|
+ const sumItem = this.sumOutputDetails.find(
|
|
|
+ (item) => item.categoryCode === newItem.categoryCode
|
|
|
+ );
|
|
|
+
|
|
|
+ let sumQualifiedQuantity = 0;
|
|
|
+ let sumNoQualifiedQuantity = 0;
|
|
|
+ let sumReportQuantity = 0;
|
|
|
+
|
|
|
+ if (sumItem) {
|
|
|
+ sumQualifiedQuantity = sumItem.sumQualifiedQuantity;
|
|
|
+ sumNoQualifiedQuantity = sumItem.sumNoQualifiedQuantity;
|
|
|
+ sumReportQuantity = sumItem.sumReportQuantity;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 不存在则添加
|
|
|
+ this.localPickDetails.push({
|
|
|
+ ...newItem,
|
|
|
+ reportQuantity: 0,
|
|
|
+ ruleId: this.ruleId,
|
|
|
+ bomCategoryId: this.bomCategoryId,
|
|
|
+ produceTaskId: this.produceTaskId,
|
|
|
+ produceTaskInstanceId: this.produceTaskInstanceId,
|
|
|
+ produceTaskName: this.produceTaskName,
|
|
|
+ workOrderId: this.workOrderId,
|
|
|
+ sumQualifiedQuantity,
|
|
|
+ sumNoQualifiedQuantity,
|
|
|
+ sumReportQuantity
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ this.$emit('update:pickDetails', this.localPickDetails);
|
|
|
+ },
|
|
|
+ // bom标准产出赋值
|
|
|
+ setMaterialQuotaInfo() {
|
|
|
+ console.log('this.materialQuotaInfo', this.materialQuotaInfo);
|
|
|
+
|
|
|
+ if (this.materialQuotaInfo && this.materialQuotaInfo.standardOutput) {
|
|
|
+ const sumItem = this.sumOutputDetails.find(
|
|
|
+ (i) =>
|
|
|
+ i.categoryCode ===
|
|
|
+ this.materialQuotaInfo.standardOutput.categoryCode
|
|
|
+ );
|
|
|
+
|
|
|
+ let sumQualifiedQuantity = 0;
|
|
|
+ let sumNoQualifiedQuantity = 0;
|
|
|
+ let sumReportQuantity = 0;
|
|
|
+
|
|
|
+ if (sumItem) {
|
|
|
+ sumQualifiedQuantity = sumItem.sumQualifiedQuantity;
|
|
|
+ sumNoQualifiedQuantity = sumItem.sumNoQualifiedQuantity;
|
|
|
+ sumReportQuantity = sumItem.sumReportQuantity;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 赋值产出
|
|
|
+ this.localOutputDetails = [
|
|
|
+ {
|
|
|
+ ...this.materialQuotaInfo.standardOutput,
|
|
|
+ id: null,
|
|
|
+ reportQuantity: 0,
|
|
|
+ reportQuantityCopy: 0,
|
|
|
+ qualifiedQuantity: 0,
|
|
|
+ noQualifiedQuantity: 0,
|
|
|
+ msg: '',
|
|
|
+ sumReportQuantity,
|
|
|
+ sumQualifiedQuantity,
|
|
|
+ sumNoQualifiedQuantity,
|
|
|
+ ruleId: this.ruleId,
|
|
|
+ outputType: this.outputType,
|
|
|
+ produceTaskId: this.produceTaskId,
|
|
|
+ produceTaskInstanceId: this.produceTaskInstanceId,
|
|
|
+ produceTaskName: this.produceTaskName,
|
|
|
+ workOrderId: this.workOrderId
|
|
|
+ }
|
|
|
+ ];
|
|
|
+ this.$emit('update:outputDetails', this.localOutputDetails);
|
|
|
+ } else {
|
|
|
+ this.$message.warning('未配置BOM标准产出信息');
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 获取bom的产出清单
|
|
|
+ async getMaterialQuotaInfo() {
|
|
|
+ if (this.bomCategoryId && this.produceTaskId) {
|
|
|
+ const data = await getMaterialQuotaInfo(
|
|
|
+ this.bomCategoryId,
|
|
|
+ this.produceTaskId
|
|
|
+ );
|
|
|
+ console.log('this.materialQuotaInfo', data);
|
|
|
+ if (JSON.stringify(data) === '{}') {
|
|
|
+ this.materialQuotaInfo = null;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ this.materialQuotaInfo = data;
|
|
|
+ console.log('this.materialQuotaInfo', this.materialQuotaInfo);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // qualifiedQuantityMax 最大合格数量
|
|
|
+ qualifiedQuantityMax(row) {
|
|
|
+ return row.reportQuantity;
|
|
|
+ },
|
|
|
+ noQualifiedQuantityMax(row) {
|
|
|
+ return row.reportQuantity;
|
|
|
+ },
|
|
|
+ selectedChange(row) {
|
|
|
+ console.log('row', row);
|
|
|
+ if (this.outputType != 1) return;
|
|
|
+
|
|
|
+ if (row.selected) {
|
|
|
+ // 判断是否存在
|
|
|
+ const index = this.localOutputDetails.findIndex(
|
|
|
+ (item) => item.categoryId === row.categoryId
|
|
|
+ );
|
|
|
+
|
|
|
+ if (index === -1) {
|
|
|
+ const sumItem = this.sumOutputDetails.find(
|
|
|
+ (i) => i.categoryCode === row.categoryCode
|
|
|
+ );
|
|
|
+
|
|
|
+ let sumQualifiedQuantity = 0;
|
|
|
+ let sumNoQualifiedQuantity = 0;
|
|
|
+ let sumReportQuantity = 0;
|
|
|
+
|
|
|
+ if (sumItem) {
|
|
|
+ sumQualifiedQuantity = sumItem.sumQualifiedQuantity;
|
|
|
+ sumNoQualifiedQuantity = sumItem.sumNoQualifiedQuantity;
|
|
|
+ sumReportQuantity = sumItem.sumReportQuantity;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 不存在则添加
|
|
|
+ this.localOutputDetails.push({
|
|
|
+ ...row,
|
|
|
+ id: null,
|
|
|
+ reportQuantity: 0,
|
|
|
+ reportQuantityCopy: 0,
|
|
|
+ qualifiedQuantity: 0,
|
|
|
+ noQualifiedQuantity: 0,
|
|
|
+ msg: '',
|
|
|
+ sumReportQuantity,
|
|
|
+ sumQualifiedQuantity,
|
|
|
+ sumNoQualifiedQuantity,
|
|
|
+ ruleId: this.ruleId,
|
|
|
+ outputType: this.outputType,
|
|
|
+ bomCategoryId: this.bomCategoryId,
|
|
|
+ produceTaskId: this.produceTaskId,
|
|
|
+ produceTaskInstanceId: this.produceTaskInstanceId,
|
|
|
+ produceTaskName: this.produceTaskName,
|
|
|
+ workOrderId: this.workOrderId
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.$message.warning('该物料已存在于产出清单中');
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 取消选择则删除
|
|
|
+ this.localOutputDetails = this.localOutputDetails.filter(
|
|
|
+ (item) => !(item.categoryId === row.categoryId)
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ this.$emit('update:outputDetails', this.localOutputDetails);
|
|
|
+ },
|
|
|
+ // getCategoryAndLevelByCategoryId 获取产品 在制品信息
|
|
|
+ async getCategoryAndLevelByCategoryId() {
|
|
|
+ const data = await getCategoryAndLevelByCategoryId(this.categoryId);
|
|
|
+ this.categoryInfo = data;
|
|
|
+ console.log('this.categoryInfo 在制品信息', this.categoryInfo);
|
|
|
+ },
|
|
|
+ // 在制品信息 设置产出物
|
|
|
+ categoryInfoSetOutput() {
|
|
|
+ if (this.categoryInfo) {
|
|
|
+ const sumItem = this.sumOutputDetails.find(
|
|
|
+ (i) => i.categoryCode == this.categoryInfo.categoryCode
|
|
|
+ );
|
|
|
+
|
|
|
+ let sumQualifiedQuantity = 0;
|
|
|
+ let sumNoQualifiedQuantity = 0;
|
|
|
+ let sumReportQuantity = 0;
|
|
|
+
|
|
|
+ if (sumItem) {
|
|
|
+ sumQualifiedQuantity = sumItem.sumQualifiedQuantity;
|
|
|
+ sumNoQualifiedQuantity = sumItem.sumNoQualifiedQuantity;
|
|
|
+ sumReportQuantity = sumItem.sumReportQuantity;
|
|
|
+ }
|
|
|
+
|
|
|
+ this.localOutputDetails = [
|
|
|
+ {
|
|
|
+ ...this.categoryInfo,
|
|
|
+ id: null,
|
|
|
+ reportQuantity: 0,
|
|
|
+ reportQuantityCopy: 0,
|
|
|
+ qualifiedQuantity: 0,
|
|
|
+ noQualifiedQuantity: 0,
|
|
|
+ msg: '',
|
|
|
+ sumReportQuantity,
|
|
|
+ sumQualifiedQuantity,
|
|
|
+ sumNoQualifiedQuantity,
|
|
|
+ ruleId: this.ruleId,
|
|
|
+ outputType: this.outputType,
|
|
|
+ produceTaskId: this.produceTaskId,
|
|
|
+ produceTaskInstanceId: this.produceTaskInstanceId,
|
|
|
+ produceTaskName: this.produceTaskName,
|
|
|
+ workOrderId: this.workOrderId
|
|
|
+ }
|
|
|
+ ];
|
|
|
+ }
|
|
|
+
|
|
|
+ this.$emit('update:outputDetails', this.localOutputDetails);
|
|
|
+
|
|
|
+ console.log('this.localOutputDetails', this.localOutputDetails);
|
|
|
+ },
|
|
|
+ // 计算报工数量最大值
|
|
|
+ reportQuantitymax(row) {
|
|
|
+ if (this.outputType == 1) {
|
|
|
+ // 查询物料本身
|
|
|
+ const pickItem = this.localPickDetails.find(
|
|
|
+ (item) => item.categoryCode === row.categoryCode
|
|
|
+ );
|
|
|
+
|
|
|
+ // 查询其他工单sumOutputDetails中已产生的bom标准产出和在制品的累计消耗数量
|
|
|
+ let preCount = 0;
|
|
|
+ if (this.materialQuotaInfo) {
|
|
|
+ const materialQuotaItem = this.materialQuotaInfo.materialQuota.find(
|
|
|
+ (item) => item.categoryCode === row.categoryCode
|
|
|
+ );
|
|
|
+
|
|
|
+ if (materialQuotaItem) {
|
|
|
+ // 计算比例
|
|
|
+ const proportion =
|
|
|
+ materialQuotaItem.count / this.materialQuotaInfo.baseCount;
|
|
|
+
|
|
|
+ if (this.materialQuotaInfo.standardOutput) {
|
|
|
+ // BOM标准产出
|
|
|
+ const preItem = this.sumOutputDetails.find(
|
|
|
+ (item) =>
|
|
|
+ item.categoryCode ===
|
|
|
+ this.materialQuotaInfo.standardOutput.categoryCode
|
|
|
+ );
|
|
|
+ if (preItem) {
|
|
|
+ preCount += preItem.sumReportQuantity * proportion;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.categoryInfo) {
|
|
|
+ // 在制品
|
|
|
+ const preItem = this.sumOutputDetails.find(
|
|
|
+ (item) => item.categoryCode === this.categoryInfo.categoryCode
|
|
|
+ );
|
|
|
+ if (preItem) {
|
|
|
+ preCount += preItem.sumReportQuantity * proportion;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 未找到物料,则返回剩余数量
|
|
|
+ if (!pickItem) return pickItem.quantity - preCount;
|
|
|
+
|
|
|
+ // 已执行,处理重新一键报工时,sumReportQuantity包含了当前报工数量
|
|
|
+ if (this.executeStatus === 2) {
|
|
|
+ return (
|
|
|
+ pickItem.quantity -
|
|
|
+ (pickItem.sumReportQuantity - row.reportQuantityCopy) -
|
|
|
+ preCount
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ return pickItem.quantity - pickItem.sumReportQuantity - preCount;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (row.outputType == 2 || row.outputType == 3) {
|
|
|
+ // 当前行为在制品 和 BOM标准产出
|
|
|
+ const preOutputItem = this.preOutputDetails.find(
|
|
|
+ (item) => item.categoryCode === row.categoryCode
|
|
|
+ );
|
|
|
+
|
|
|
+ // 存在则当前row为在制品或BOM标准产出
|
|
|
+ if (preOutputItem) {
|
|
|
+ // 区分已执行状态
|
|
|
+ if (this.executeStatus === 2) {
|
|
|
+ return (
|
|
|
+ preOutputItem.quantity -
|
|
|
+ (row.sumReportQuantity - row.reportQuantityCopy)
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return preOutputItem.quantity - row.sumReportQuantity;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 基于物料配额限制最大可报工数量(兼容已缓存/已保存一次的编辑场景,并区分已执行状态)
|
|
|
+ if (!this.materialQuotaInfo) return Infinity;
|
|
|
+ const quota = this.materialQuotaInfo.materialQuota || [];
|
|
|
+ if (!quota.length) return Infinity;
|
|
|
+
|
|
|
+ const isExecuted = this.executeStatus === 2;
|
|
|
+
|
|
|
+ const { baseCount } = this.materialQuotaInfo;
|
|
|
+ if (!baseCount) return Infinity;
|
|
|
+
|
|
|
+ // 计算每个物料的最大可报工数量
|
|
|
+ const maxQuantities = quota.map((item) => {
|
|
|
+ const pickItem = this.localPickDetails.find(
|
|
|
+ (p) => p.categoryCode === item.categoryCode
|
|
|
+ );
|
|
|
+ if (!pickItem) {
|
|
|
+ return Infinity;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 单位产出所需物料比例
|
|
|
+ const proportion = item.count / baseCount;
|
|
|
+
|
|
|
+ // 查询其他工单 sumOutputDetails 中已产生的 BOM 标准产出和在制品的累计消耗数量
|
|
|
+ let preOutputConsumedProportion = 0;
|
|
|
+
|
|
|
+ // BOM标准产出
|
|
|
+ if (
|
|
|
+ this.materialQuotaInfo &&
|
|
|
+ this.materialQuotaInfo.standardOutput &&
|
|
|
+ row.categoryCode !==
|
|
|
+ this.materialQuotaInfo.standardOutput.categoryCode
|
|
|
+ ) {
|
|
|
+ const preStd = this.sumOutputDetails.find(
|
|
|
+ (s) =>
|
|
|
+ s.categoryCode ===
|
|
|
+ this.materialQuotaInfo.standardOutput.categoryCode
|
|
|
+ );
|
|
|
+ if (preStd) {
|
|
|
+ preOutputConsumedProportion +=
|
|
|
+ preStd.sumReportQuantity * proportion;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 在制品
|
|
|
+ if (
|
|
|
+ this.categoryInfo &&
|
|
|
+ row.categoryCode !== this.categoryInfo.categoryCode
|
|
|
+ ) {
|
|
|
+ const preWip = this.sumOutputDetails.find(
|
|
|
+ (s) => s.categoryCode === this.categoryInfo.categoryCode
|
|
|
+ );
|
|
|
+ if (preWip) {
|
|
|
+ preOutputConsumedProportion +=
|
|
|
+ preWip.sumReportQuantity * proportion;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 已执行,处理重新一键报工时,sumReportQuantity包含了当前报工数量
|
|
|
+ let consumedQuantity = isExecuted
|
|
|
+ ? row.sumReportQuantity - row.reportQuantityCopy
|
|
|
+ : row.sumReportQuantity;
|
|
|
+
|
|
|
+ // 已执行的比例换算,换算为需要多少物料数量
|
|
|
+ const consumedProportion = consumedQuantity * proportion;
|
|
|
+
|
|
|
+ // 最大可报工数量
|
|
|
+ let maxQuantity =
|
|
|
+ (pickItem.quantity -
|
|
|
+ consumedProportion -
|
|
|
+ preOutputConsumedProportion) /
|
|
|
+ proportion;
|
|
|
+
|
|
|
+ // 向下取整
|
|
|
+ return Math.floor(maxQuantity);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 返回最小的那个物料的最大可报工数量
|
|
|
+ return Math.min(...maxQuantities);
|
|
|
+ }
|
|
|
+ return Infinity;
|
|
|
+ },
|
|
|
+ // 判断生成产出清单的物料数量是合格
|
|
|
+ async validateOutputQuantities() {
|
|
|
+ if (this.localOutputDetails.length == 0) {
|
|
|
+ this.$message.warning(`产出清单不能为空`);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (const item of this.localOutputDetails) {
|
|
|
+ if (!item.reportQuantity) {
|
|
|
+ this.$message.warning(
|
|
|
+ `请填写产出清单【${item.categoryName}】的当次报工数量`
|
|
|
+ );
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.outputType == 1) {
|
|
|
+ if (
|
|
|
+ this.localPickDetails.length == 0 &&
|
|
|
+ this.preOutputDetails.length == 0
|
|
|
+ ) {
|
|
|
+ this.$message.warning(`物料清单不能为空`);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (const item of this.localOutputDetails) {
|
|
|
+ const pickitem = this.localPickDetails.find(
|
|
|
+ (pick) => pick.categoryCode == item.categoryCode
|
|
|
+ );
|
|
|
+
|
|
|
+ const prePickitem = this.preOutputDetails.find(
|
|
|
+ (pick) => pick.categoryCode == item.categoryCode
|
|
|
+ );
|
|
|
+
|
|
|
+ if (pickitem == null && prePickitem == null) {
|
|
|
+ this.$message.warning(
|
|
|
+ `所需物料【${item.categoryName}】未在物料清单中找到`
|
|
|
+ );
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (item.reportQuantity > item.quantity) {
|
|
|
+ this.$message.error(
|
|
|
+ `物料【${item.categoryName}】的报工数量不能超过领料数量`
|
|
|
+ );
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ },
|
|
|
+ // 当次报工修改
|
|
|
+ reportQuantityChange(row) {
|
|
|
+ // 同步当前合格数量 和 不合格数量为0
|
|
|
+ // 默认全部合格
|
|
|
+ row.qualifiedQuantity = row.reportQuantity;
|
|
|
+ row.noQualifiedQuantity = 0;
|
|
|
+ this.$emit('update:outputDetails', this.localOutputDetails);
|
|
|
+ },
|
|
|
+ // qualifiedQuantityChange 当次合格数量变化 计算 noQualifiedQuantity不合格数量
|
|
|
+ qualifiedQuantityChange(row) {
|
|
|
+ row.noQualifiedQuantity = row.reportQuantity - row.qualifiedQuantity;
|
|
|
+ this.$emit('update:outputDetails', this.localOutputDetails);
|
|
|
+ },
|
|
|
+ // 不合格数量变化
|
|
|
+ noQualifiedQuantityChange(row) {
|
|
|
+ row.qualifiedQuantity = row.reportQuantity - row.noQualifiedQuantity;
|
|
|
+ this.$emit('update:outputDetails', this.localOutputDetails);
|
|
|
+ },
|
|
|
+ localOutputDetailsRefresh() {
|
|
|
+ if (this.outputType == 1) {
|
|
|
+ this.$emit('refresh', 'output');
|
|
|
+ } else if (this.outputType == 2) {
|
|
|
+ this.getCategoryAndLevelByCategoryId();
|
|
|
+ } else {
|
|
|
+ this.setMaterialQuotaInfo();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+</script>
|
|
|
+
|
|
|
+<style></style>
|