Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop

This commit is contained in:
shilixia 2022-01-14 16:46:11 +08:00
commit aa76888a57
27 changed files with 1320 additions and 935 deletions

View File

@ -19,19 +19,13 @@
@expand-change="handlerExpand"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column label="任务编号" width="150">
<template slot-scope="scope">{{ scope.row.name }}</template>
<el-table-column label="任务编号" prop="name">
</el-table-column>
<el-table-column label="产品名称">
<template slot-scope="scope">
<div style="overflow: hidden; text-overflow:ellipsis; white-space: nowrap;">{{ scope.row.productName }}</div>
</template>
<el-table-column label="产品名称" prop="productName" width="120" show-overflow-tooltip>
</el-table-column>
<el-table-column label="产品型号">
<template slot-scope="scope">{{ scope.row.productNum }}</template>
<el-table-column label="产品型号" prop="productNum">
</el-table-column>
<el-table-column label="生产数量">
<template slot-scope="scope">{{ scope.row.per }}</template>
<el-table-column label="生产数量" prop="per">
</el-table-column>
</el-table>
</div>

View File

@ -1,19 +1,18 @@
<template>
<div
class="slider"
ref="slider"
class="slider"
>
<div
class="process"
:style="{ width }"
style="font-size: 12px;color: #ffffff;text-align: right"
>
<span v-if="per">{{ per }}</span>
<span v-else>{{ per }}</span>
</div>
<div class="process1"
:style="{width:process1Width}"
style="font-size: 12px;color: #ffffff;text-align: right"
<div
class="process1"
:style="{width:process1Width}"
>
<span v-if="per1"> {{ per1 }}</span>
</div>
@ -122,6 +121,10 @@ export default {
top: 0;
width: 112px;
height: 20px;
font-size: 12px;
color: #ffffff;
text-align: right;
line-height: 20px;
border-radius: 3px;
background: #409eff;
}
@ -131,10 +134,16 @@ export default {
top: 0;
width: 10px;
height: 20px;
font-size: 12px;
color: #ffffff;
text-align: right;
line-height: 20px;
border-radius: 3px;
background: #11c750;
}
.slider .process span{
margin-right: 5px;
}
.slider .block i {
font-size: 25px;

View File

@ -18,6 +18,7 @@
<el-form-item
v-if="item.field_type === 'string'"
:label="item.field_name"
:required="require"
>
<el-input
v-model="checkForm[item.field_key]"
@ -28,21 +29,27 @@
<el-form-item
v-else-if="item.field_type === 'int'"
:label="item.field_name"
:required="require"
>
<el-input
<el-input-number
style="width: 100%;"
v-model="checkForm[item.field_key]"
type="number"
step-strictly
placeholder="请输入"
:min="0"
@input="keyChange($index,item.field_key)"
/>
</el-form-item>
<el-form-item
v-else-if="item.field_type === 'float'"
:label="item.field_name"
:required="require"
>
<el-input
<el-input-number
style="width: 100%;"
v-model="checkForm[item.field_key]"
type="number"
:precision="2"
:step="0.1"
placeholder="请输入"
@input="keyChange($index,item.field_key)"
/>
@ -50,6 +57,7 @@
<el-form-item
v-else-if="item.field_type === 'date'"
:label="item.field_name"
:required="require"
>
<el-date-picker
v-model="checkForm[item.field_key]"
@ -63,6 +71,7 @@
<el-form-item
v-else-if="item.field_type === 'datetime'"
:label="item.field_name"
:required="require"
>
<el-date-picker
v-model="checkForm[item.field_key]"
@ -76,6 +85,7 @@
<el-form-item
v-else-if="item.field_type === 'select'"
:label="item.field_name"
:required="require"
>
<el-select
v-model="checkForm[item.field_key]"
@ -94,6 +104,7 @@
<el-form-item
v-else-if="item.field_type === 'selects'"
:label="item.field_name"
:required="require"
>
<el-select
v-model="checkForm[item.field_key]"
@ -120,8 +131,8 @@
<el-row v-show="hasPicture">
<el-form-item label="图表">
<div>
<!--<img id="canvasImg" :src="img" style="width:500px;height: 300px;display: none">-->
<img id="canvasImg" src="./../../assets/glass.png" style="width:500px;height: 300px;display: none">
<img id="canvasImg" :src="img" style="width:500px;height: 300px;display: none">
<!--<img id="canvasImg" src="./../../assets/glass.png" style="width:500px;height: 300px;display: none">-->
<div style="position: relative;display: flex;flex-direction: column;
border: 1px solid #DCDFE6;">
<canvas id="canvas" width="500" height="300">
@ -229,9 +240,9 @@
let imag= this.formData.filter(item => {
return item.field_type === 'draw';
});
/* that.img = new Image();
that.img = new Image();
that.img.crossOrigin = '';
that.img = 'http://47.95.0.242:2222'+imag[0].draw_template;*/
that.img = 'http://47.95.0.242:2222'+imag[0].draw_template;
setTimeout(function(){
that.canvasInit();
},500);
@ -265,6 +276,7 @@
is_testok:true,
testokTrue:true,
is_save:false,
require:false,
testokFalse:false,
}
},

View File

@ -18,6 +18,7 @@
<el-form-item
v-if="item.field_type === 'string'"
:label="item.field_name"
:required="require"
>
<el-input
disabled
@ -36,6 +37,7 @@
<el-form-item
v-else-if="item.field_type === 'int'"
:label="item.field_name"
:required="require"
>
<el-input
disabled
@ -45,17 +47,19 @@
placeholder="请输入"
@input="keyChange($index,item.field_key)"
/>
<el-input
<el-input-number
class="halfWidth"
v-model="checkForm[item.field_key]"
type="number"
step-strictly
placeholder="请输入"
:min="0"
@input="keyChange($index,item.field_key)"
/>
</el-form-item>
<el-form-item
v-else-if="item.field_type === 'float'"
:label="item.field_name"
:required="require"
>
<el-input
disabled
@ -65,17 +69,26 @@
placeholder="请输入"
@input="keyChange($index,item.field_key)"
/>
<el-input
<el-input-number
class="halfWidth"
v-model="checkForm[item.field_key]"
:precision="2"
:step="0.1"
placeholder="请输入"
@input="keyChange($index,item.field_key)"
/>
<!-- <el-input
class="halfWidth"
v-model="checkForm[item.field_key]"
type="number"
placeholder="请输入"
@input="keyChange($index,item.field_key)"
/>
/>-->
</el-form-item>
<el-form-item
v-else-if="item.field_type === 'date'"
:label="item.field_name"
:required="require"
>
<el-date-picker
disabled
@ -98,6 +111,7 @@
<el-form-item
v-else-if="item.field_type === 'datetime'"
:label="item.field_name"
:required="require"
>
<el-date-picker
disabled
@ -120,6 +134,7 @@
<el-form-item
v-else-if="item.field_type === 'select'"
:label="item.field_name"
:required="require"
>
<el-select
disabled
@ -152,6 +167,7 @@
<el-form-item
v-else-if="item.field_type === 'selects'"
:label="item.field_name"
:required="require"
>
<el-select
disabled
@ -300,25 +316,15 @@
obj = item;
that.judgeList.push(obj)
});
//原始表的数据
/*for(let i=0;i<this.origins.length;i++){
let key = this.origins[i].field_key;
that.originForm[key]=this.origins[i].field_key;
that.$set(that.originForm,key,this.origins[i].field_value)
}*/
debugger;
//图片地址
let imag= this.formData.filter(item => {
return item.field_type === 'draw';
});
// that.img = 'http://47.95.0.242:2222'+imag[0].draw_template;
/*let originImag= this.origins.filter(item => {
return item.field_type === 'draw';
});*/
/*that.originImg = new Image();
that.originImg.crossOrigin = '';
that.originImg = imag[0].origin_value;
*/
that.img = new Image();
that.img.crossOrigin = '';
that.img = 'http://47.95.0.242:2222'+imag[0].field_value;
that.originImg = 'http://47.95.0.242:2222'+imag[0].origin_value;
listJudge.forEach(item => {
let obj = new Object();
obj = item;

View File

@ -10,12 +10,23 @@
</div>
</template>
<script>
import tracking from '@/assets/tracking/build/tracking-min.js';
import {faceLogin} from "@/api/testModel";
import { getTickets } from "@/api/workflow";
import tracking from '@/assets/tracking/build/tracking-min.js';
import '@/assets/tracking/build/data/face-min.js';
import {createrecordform,updaterecordform} from "@/api/mtm";
export default {
props: {
dialogType: {
type:String,
default:"new"
},
recordform: {
type:Object,
default:null
}
},
data() {
return {
video: null,
@ -77,16 +88,26 @@
let imgData = {base64:img};
faceLogin(imgData).then((res) => {
if (res.code >= 200) {
debugger;
console.log(res.data);
getTickets( {token:res.data.access,page:1,page_size:10,category:'duty'}).then((resp)=>{
if(resp.code>=200){
debugger;
console.log(resp.data);
}
})
that.uploadLock = false;
this.$message.success(res.data.username+'签到成功!');
const isEdit = that.dialogType === "edit";
if (isEdit) {
updaterecordform(that.recordform.id, that.recordform).then(
(res) => {
if (res.code >= 200) {
that.$emit('func',false);
that.$message.success("成功");
}
}
);
} else {
createrecordform(that.recordform).then((res) => {
if (res.code >= 200) {
that.$emit('func',false);
that.$message.success("成功");
}
});
}
// this.$message.success(res.data.username+'签到成功!');
/*that.$confirm("是否提交?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",

View File

@ -20,7 +20,7 @@
<li @click="refreshSelectedTag(selectedTag)">刷新</li>
<li v-if="!isAffix(selectedTag)" @click="closeSelectedTag(selectedTag)">关闭</li>
<li @click="closeOthersTags">关闭其他</li>
<li @click="closeAllTags(selectedTag)">关闭</li>
<li @click="closeAllTags(selectedTag)">关闭</li>
</ul>
</div>
</template>

View File

@ -1,32 +1,30 @@
<template>
<div class="dashboard-container">
<el-card class="dashboardTopCard">
<div @click="openWord">wendanag</div>
<a href="http://www.xdocin.com/xdoc?_func=to&_format=html&_cache=1&_xdoc=http://47.95.0.242:2222/media/2021/09/07/004-%E8%AF%B7%E5%81%87%E5%8D%95_LL8uZdx.docx" target="_blank">XDOC</a>
<div class="CardTitleWrap">
<div class="CardTitleWrap">
<span class="verticalLine"></span><span class="dashboardCardTitle">数据统计</span>
</div>
<div class="cards">
<div class="cards" @click="toDetail('1')">
<div class="cardCurrentText">本月{{contractTotalCurrent}}</div>
<div class="cardTotalText">{{contractTotalCount}}</div>
<div>合同总数</div>
</div>
<div class="cards">
<div class="cards" @click="toDetail('2')">
<div class="cardCurrentText">本月{{orderTotalCurrent}}</div>
<div class="cardTotalText">{{orderTotalCount}}</div>
<div>生产订单总数</div>
</div>
<div class="cards">
<div class="cards" @click="toDetail('3')">
<div class="cardCurrentText">在制{{planTotalCurrent}}</div>
<div class="cardTotalText">{{planTotalCount}}</div>
<div>已排产生产任务</div>
</div>
<div class="cards">
<div class="cards" @click="toDetail('4')">
<div class="cardCurrentText">本月4</div>
<div class="cardTotalText">20</div>
<div>累计交付产品数</div>
</div>
<div class="cards">
<div class="cards" @click="toDetail('5')">
<div class="cardCurrentText">本月2</div>
<div class="cardTotalText">2</div>
<div>累计不合格产品数</div>
@ -179,38 +177,60 @@
</el-pagination>
</div>
</div>
<div :style="{height:cardTabelHeight+'px'}">
<ul class="lists">
<li class="listItem">
<div class="itemText">
<span>玻璃低于安全库存</span><span>2021-12-30</span>
</div>
</li>
<li class="listItem">
<div class="itemText">
<span>某某批货临近交货日期</span><span>2021-12-20</span>
</div>
</li>
<li class="listItem">
<div class="itemText">
<span>玻璃低于安全库存</span><span>2021-11-30</span>
</div>
</li>
<li class="listItem">
<div class="itemText">
<span>某某批货临近交货日期</span><span>2021-11-20</span>
</div>
</li>
</ul>
</div>
<!--<el-badge :value="count.total_count" class="item" @click.native="gotoTicketPage">
<el-icon class="el-icon-s-management" style="font-size: 70px;color: #d29898"></el-icon>
</el-badge>
<div></div>
<div class="dashboard-text">name: {{ name }}</div>
<div class="dashboard-text">perms:
<span v-for="perm in perms" :key="perm">{{ perm }}</span>
</div>-->
<el-tabs type="card" :style="{height:cardTabelHeight+'px'}" v-model="activeName" @tab-click="activeNameClick">
<el-tab-pane label="库存警告" name="库存警告">
<ul class="lists">
<li class="listItem">
<div class="itemText">
<span>玻璃低于安全库存</span><span>2021-12-30</span>
</div>
</li>
<li class="listItem" v-for="item in warningList" :key="item.id">
<div class="itemText">
<span>{{item}}</span><span>2021-12-20</span>
</div>
</li>
<!--<li class="listItem">
<div class="itemText">
<span>玻璃低于安全库存</span><span>2021-11-30</span>
</div>
</li>
<li class="listItem">
<div class="itemText">
<span>某某批货临近交货日期</span><span>2021-11-20</span>
</div>
</li>-->
</ul>
</el-tab-pane>
<el-tab-pane label="临近交货" name="临近交货">
<ul class="lists">
<li class="listItem">
<div class="itemText">
<span>某某批货临近交货日期</span><span>2021-12-20</span>
</div>
</li>
<li class="listItem" v-for="item in warningList" :key="item.id">
<div class="itemText">
<span>{{item}}</span><span>2021-12-20</span>
</div>
</li>
</ul>
</el-tab-pane>
<el-tab-pane label="过期提醒" name="过期提醒">
<ul class="lists">
<li class="listItem">
<div class="itemText">
<span>某某批货临近过期</span><span>2021-11-20</span>
</div>
</li>
<li class="listItem" v-for="item in warningList" :key="item.id">
<div class="itemText">
<span>{{item}}</span><span>2021-12-20</span>
</div>
</li>
</ul>
</el-tab-pane>
</el-tabs>
</el-card>
</el-col>
</el-row>
@ -220,8 +240,10 @@
<script>
import echarts from 'echarts'
import { mapGetters } from 'vuex';
import { getMaterialList } from "@/api/mtm";
import { getInventoryList } from "@/api/inm";
import { getProductionplanList} from "@/api/pm";
import { getmaterialbatchList } from "@/api/inm";
import { getContractList , getOrderList } from "@/api/sam";
export default {
@ -247,6 +269,7 @@ export default {
planList:[],
stockList:[],
remindList:[],
warningList:[],
list:[
{id:1,name:'HIehd9',card:'3337',sco:'REF-32'},
{id:1,name:'HIehd9',card:'3337',sco:'REF-32'},
@ -260,6 +283,7 @@ export default {
"5":'加工工具',
"6":'辅助工装',
},
activeName:'库存警告',
seriesData:[80,95,96, 96, 96, 98, 99,100],
contractTotalCount:null,//合同总数
contractTotalCurrent:null,
@ -286,49 +310,56 @@ export default {
window.open("http://47.95.0.242:2222/media/2021/09/07/004-%E8%AF%B7%E5%81%87%E5%8D%95_LL8uZdx.docx");
},
getStatisticsData(){
let that = this;
let dat = new Date();
this.week = dat.getDay();
this.currentTime = dat.getTime();
this.currentYear = dat.getFullYear();
that.week = dat.getDay();
that.currentTime = dat.getTime();
that.currentYear = dat.getFullYear();
let month = dat.getMonth() + 1;
this.currentMonth = month>9?month:'0'+month ;
this.currentDay = dat.getDate();
let create_time_start = this.currentYear+'-'+this.currentMonth+'-01';
that.currentMonth = month>9?month:'0'+month ;
that.currentDay = dat.getDate();
let create_time_start = that.currentYear+'-'+that.currentMonth+'-01';
//获取合同数
getContractList({page:1,page_size:1}).then((response) => {
if (response.data) {
this.contractTotalCount = response.data.count;
that.contractTotalCount = response.data.count;
}
});
getContractList({page:1,page_size:1,create_time_start:create_time_start}).then((response) => {
if (response.data) {
this.contractTotalCurrent = response.data.count;
that.contractTotalCurrent = response.data.count;
}
});
//获取生产订单数
getOrderList({page:1,page_size:1}).then((response) => {
if (response.data) {
this.orderTotalCount = response.data.count;
that.orderTotalCount = response.data.count;
}
});
getOrderList({page:1,page_size:1,create_time_start:create_time_start}).then((response) => {
if (response.data) {
this.orderTotalCurrent = response.data.count;
that.orderTotalCurrent = response.data.count;
}
});
//获取已排产任务
getProductionplanList({page:1,page_size:1}).then((response) => {
if (response.data) {
this.planTotalCount = response.data.count;
that.planTotalCount = response.data.count;
}
});
getProductionplanList({page:1,page_size:1,tag:'working'}).then((response) => {
if (response.data) {
this.planTotalCurrent = response.data.count;
that.planTotalCurrent = response.data.count;
}
});
//获取交付产品
//获取不合格产品
getMaterialList({page:0,tag:'low_inm'}).then((response) => {
if (response.data) {
that.warningList = response.data;
}
});
},
gotoTicketPage(){
let path = this.$route.path;
@ -476,16 +507,30 @@ export default {
stockMore(){
this.$router.push({name:'warehouse',params:{}})
},
toDetail(index){
if(index==='1'){
this.$router.push({name:'contract',params:{page:1,page_size:20}})
}else if(index==='2'){
this.$router.push({name:'order',params:{page:1,page_size:20}})
}else if(index==='3'){
this.$router.push({name:'plan',params:{page:1,page_size:20}})
}else if(index==='4'){
this.$router.push({name:'product',params:{page:1,page_size:20,material__type:1}})
}else if(index==='5'){
this.$router.push({name:'product',params:{page:1,page_size:20,material__type:1}})
}
},
//便捷查询按钮
convenientClick(index,type){
let startTime = '',endTime = '',url='',activeIndex = '1',obj = new Object();
let that = this;
let startTime = '',endTime = '',activeIndex = '1';
let dat = new Date();
let week = dat.getDay();//0-6
let currentTime = dat.getTime();
let currentYear = dat.getFullYear();
let currentMonth = dat.getMonth() + 1;
let currentDay = dat.getDate();
endTime = currentYear+'-'+currentMonth+''+currentDay;
endTime = currentYear+'-'+currentMonth+'-'+currentDay;
if(type==='week'){
activeIndex = '1';
let num = week===0?6:week-1;
@ -510,11 +555,16 @@ export default {
}
startTime = yea+'-'+mon+'-01';
}
obj.startTime = startTime;
obj.endTime = endTime;
if(index==='1'){
this.tableDate = null;
this.tableIndex = activeIndex;
this.listLoadingPlan = true;
getProductionplanList({page:0,create_time_start:startTime,create_time_end:endTime}).then((response) => {
if (response.data) {
that.planList = response.data;
}
this.listLoadingPlan = false;
});
}else{
this.chartDate = null;
this.chartIndex = activeIndex;
@ -523,6 +573,7 @@ export default {
},
//选择月份
searchTimeChange(index){
let that = this;
let startDate = '',endDate = '';
let year = null,month = null,days = null;
if(index==='1'){
@ -532,16 +583,23 @@ export default {
month = this.tableDate.split("-")[1];
let d = new Date(year, month, 0);
days = d.getDate();
endDate = this.tableDate + '-'+days;
this.listLoadingPlan = true;
getProductionplanList({page:0,create_time_start:startDate,create_time_end:endDate}).then((response) => {
if (response.data) {
that.planList = response.data;
}
this.listLoadingPlan = false;
});
}else{
this.chartIndex = null;
startDate = this.chartDate+'-01';
year = this.tableDate.split("-")[0];
month = this.tableDate.split("-")[1];
year = this.chartDate.split("-")[0];
month = this.chartDate.split("-")[1];
let d = new Date(year, month, 0);
days = d.getDate();
endDate = this.chartDate + '-'+days;
}
endDate = this.chartDate + '-'+days;
console.log(startDate,endDate);
},
handleStockSizeChange(val){
this.stockPageSize = val;
@ -559,6 +617,36 @@ export default {
this.listLoading = false;
});
},
activeNameClick(tab, event) {
let that = this;
// debugger;
// console.log(tab, event);
if (tab.label === '库存警告') {
getMaterialList({page:0,tag:'low_inm'}).then((response) => {
if (response.data) {
that.warningList = response.data;
that.remindTotal = response.data.length;
}
this.listLoadingPlan = false;
});
}else if(tab.label === '临近交货') {
getmaterialbatchList({page:0,tag:'expired'}).then((response) => {
if (response.data) {
that.warningList = response.data;
that.remindTotal = response.data.length;
}
this.listLoadingPlan = false;
});
} else if(tab.label === '过期提醒'){
getmaterialbatchList({page:0,tag:'expired'}).then((response) => {
if (response.data) {
that.warningList = response.data;
that.remindTotal = response.data.length;
}
this.listLoadingPlan = false;
});
}
},
handleRemindSizeChange(val){
this.remindPageSize = val;
this.remindPage = 1;
@ -572,7 +660,7 @@ export default {
// let he = document.documentElement.clientHeight || document.body.clientHeight;
let hei = document.getElementsByClassName('app-main')[0].clientHeight;
let heig = document.getElementsByClassName('dashboardTopCard')[0].clientHeight;
this.cardTabelHeight = ((hei-heig)/2-80);
this.cardTabelHeight = ((hei-heig-130)/2);
document.getElementById('chartColumn').style.height = this.cardTabelHeight+'px';
this.drawChart();
this.getPlanList();
@ -711,7 +799,7 @@ export default {
.listItem{
height: 40px;
line-height: 40px;
font-size: 18px;
font-size: 16px;
.itemText{
display: flex;
justify-content: space-between;

View File

@ -1,86 +1,77 @@
<template>
<div class="app-container">
<el-card>
<div>
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
>新增物料</el-button
>
<el-input
v-model="listQuery.search"
placeholder="物料名称/物料编号"
style="width: 300px"
class="filter-item"
@keyup.enter.native="handleFilter"
/>
<el-button
class="filter-item"
type="primary"
icon="el-icon-search"
@click="handleFilter"
>搜索</el-button
>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>重置</el-button
>
</div>
<div>
<el-button type="primary" icon="el-icon-plus" @click="handleCreate">
新增物料
</el-button>
<el-input
v-model="listQuery.search"
placeholder="物料名称/物料编号"
style="width: 300px"
class="filter-item"
@keyup.enter.native="handleFilter"
/>
<el-button
class="filter-item"
type="primary"
icon="el-icon-search"
@click="handleFilter"
>搜索
</el-button>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>重置
</el-button>
</div>
</el-card>
<el-card style="margin-top: 2px">
<el-tabs v-model="activeName" type="card" @tab-click="handleClick">
<el-tab-pane label="成品" name="1"></el-tab-pane>
<el-tab-pane label="半成品" name="2"></el-tab-pane>
<el-tab-pane label="主要原料" name="3"></el-tab-pane>
<el-tab-pane label="辅助材料" name="4"></el-tab-pane>
<el-tab-pane label="加工工具" name="5"></el-tab-pane>
<el-tab-pane label="辅助工装" name="6"></el-tab-pane>
</el-tabs>
<el-tabs v-model="activeName" type="card" @tab-click="handleClick">
<el-tab-pane label="成品" name="1"></el-tab-pane>
<el-tab-pane label="半成品" name="2"></el-tab-pane>
<el-tab-pane label="主要原料" name="3"></el-tab-pane>
<el-tab-pane label="辅助材料" name="4"></el-tab-pane>
<el-tab-pane label="加工工具" name="5"></el-tab-pane>
<el-tab-pane label="辅助工装" name="6"></el-tab-pane>
</el-tabs>
<el-table
v-loading="listLoading"
:data="materialList.results"
border
fit
stripe
highlight-current-row
highlight-current-row
max-height="620"
height="100"
height="100"
v-el-height-adaptive-table="{bottomOffset: 40}"
>
<el-table-column type="index" width="50" />
<el-table-column label="物料编号">
<el-table-column type="index" width="50"/>
<el-table-column label="物料编号">
<template slot-scope="scope">
{{ scope.row.number }}
</template>
</template>
</el-table-column>
<el-table-column label="物料类别" >
<template slot-scope="scope"> {{options_[scope.row.type]}}</template>
<el-table-column label="物料类别">
<template slot-scope="scope"> {{options_[scope.row.type]}}</template>
</el-table-column>
<el-table-column label="物料名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="规格型号">
<template slot-scope="scope">{{ scope.row.specification }}</template>
</el-table-column>
<el-table-column label="单片玻璃数量" v-if="materialList.results[0].type==1">
<el-table-column label="单片玻璃数量" v-if="materialList.results[0].type==1">
<template slot-scope="scope">{{ scope.row.piece_count }}</template>
</el-table-column>
<el-table-column label="计量单位">
<template slot-scope="scope">{{ scope.row.unit }}</template>
</el-table-column>
<el-table-column label="创建时间">
<el-table-column label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
<el-table-column
align="center"
label="操作"
@ -91,27 +82,26 @@
v-if="checkPermission(['material_update'])&&scope.row.type!=5&&scope.row.type!=6"
type="primary"
@click="handlebind(scope)"
>检查表</el-link
>
>检查表
</el-link>
<el-link
v-if="checkPermission(['material_update'])"
type="primary"
@click="handleEdit(scope)"
>编辑</el-link
>
<el-link
>编辑
</el-link>
<el-link
v-if="checkPermission(['material_update'])"
type="primary"
@click="handledetail(scope)"
>详情</el-link
>
>详情
</el-link>
<el-link
v-if="checkPermission(['material_delete'])"
type="danger"
@click="handleDelete(scope)"
>删除</el-link
>
>删除
</el-link>
</template>
</el-table-column>
</el-table>
@ -136,46 +126,46 @@
:rules="rule1"
>
<el-form-item label="物料名称" prop="name">
<el-input v-model="material.name" placeholder="物料名称" />
<el-input v-model="material.name" placeholder="物料名称"/>
</el-form-item>
<el-form-item label="物料编号" prop="number">
<el-input v-model="material.number" placeholder="物料编号" />
<el-input v-model="material.number" placeholder="物料编号"/>
</el-form-item>
<el-form-item label="规格型号" prop="specification">
<el-input v-model="material.specification" placeholder="规格型号" />
<el-form-item label="规格型号" prop="specification">
<el-input v-model="material.specification" placeholder="规格型号"/>
</el-form-item>
<el-form-item label="计量单位" prop="unit">
<el-select style="width: 100%" v-model="material.unit" placeholder="请选择">
<el-option
v-for="item in unitoptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
<el-select style="width: 100%" v-model="material.unit" placeholder="请选择">
<el-option
v-for="item in unitoptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="物料类别" prop="type">
<el-select style="width: 100%" v-model="material.type" placeholder="请选择" >
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
<el-form-item label="物料类别" prop="type">
<el-select style="width: 100%" v-model="material.type" placeholder="请选择">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="单片玻璃数量" prop="piece_count" v-if="material.type==1">
<el-input v-model="material.piece_count" placeholder="单片玻璃数量" />
<el-form-item label="单片玻璃数量" prop="piece_count" v-if="material.type==1">
<el-input v-model="material.piece_count" placeholder="单片玻璃数量"/>
</el-form-item>
<el-form-item label="排序" prop="sort_str">
<el-input v-model="material.sort_str" placeholder="排序" />
<el-input v-model="material.sort_str" placeholder="排序"/>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
@ -185,37 +175,44 @@
</div>
</template>
<script>
import { getMaterialList,getMaterial, createMaterial,updateMaterial,deleteMaterial,getProcessList } from "@/api/mtm";
import checkPermission from "@/utils/permission";
import {
getMaterialList,
getMaterial,
createMaterial,
updateMaterial,
deleteMaterial,
getProcessList
} from "@/api/mtm";
import checkPermission from "@/utils/permission";
import { genTree } from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultmaterial = {
name: "",
number: "",
processes:[],
};
export default {
components: { Pagination },
data() {
return {
material: defaultmaterial,
materialList: {
count: 0,
},
processOptions:[],
options_:{
"1":'成品',
"2":'半成品',
"3":'主要原料',
"4":'辅助材料',
"5":'加工工具',
"6":'辅助工装',
},
options: [{
import {genTree} from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultmaterial = {
name: "",
number: "",
processes: [],
};
export default {
components: {Pagination},
data() {
return {
material: defaultmaterial,
materialList: {
count: 0,
},
processOptions: [],
options_: {
"1": '成品',
"2": '半成品',
"3": '主要原料',
"4": '辅助材料',
"5": '加工工具',
"6": '辅助工装',
},
options: [{
value: 1,
label: '成品'
}, {
@ -234,164 +231,162 @@ export default {
value: 6,
label: '辅助工装'
}],
unitoptions:[
unitoptions: [
{
value: '',
label: ''
}, {
value: '',
label: ''
},
{
value: '',
label: ''
}, {
value: 'm2',
label: 'm2'
}, {
value: '',
label: ''
},
value: '',
label: ''
}, {
value: '',
label: ''
},
{
value: '',
label: ''
}, {
value: 'm2',
label: 'm2'
}, {
value: '',
label: ''
},
],
listQuery: {
page: 1,
page_size: 20,
},
activeName:"",
listQuery: {
page: 1,
page_size: 20,
},
activeName: "",
listLoading: true,
dialogVisible: false,
dialogType: "new",
rule1: {
name: [{required: true, message: "请输入", trigger: "blur"}],
number: [{required: true, message: "请输入", trigger: "blur"}],
listLoading: true,
dialogVisible: false,
dialogType: "new",
rule1: {
name: [{ required: true, message: "请输入", trigger: "blur" }],
number: [{ required: true, message: "请输入", trigger: "blur" }],
},
};
},
computed: {},
watch: {},
created() {
this.getList();
this.getProcessList();
},
methods: {
checkPermission,
},
};
},
computed: {},
watch: {},
created() {
this.getList();
this.getProcessList();
//物料详情
handledetail(scope)
{
},
methods: {
checkPermission,
//物料详情
handledetail(scope)
{
this.$router.push({name: "MaterialDetail", params: { id: scope.row.id,type: scope.row.type }, })
},
//选项卡切换
handleClick(tab) {
this.listLoading = true;
this.listQuery.type=tab.name;
getMaterialList(this.listQuery).then((response) => {
if (response.data) {
this.materialList = response.data;
}
this.listLoading = false;
});
},
getList() {
this.listLoading = true;
getMaterialList(this.listQuery).then((response) => {
if (response.data) {
this.materialList = response.data;
}
this.listLoading = false;
});
},
//工序清单
getProcessList() {
getProcessList().then((res) => {
this.processOptions = res.data.results;
});
},
//绑定工序
handlebind(scope)
{
this.$router.push({name: "MaterialDO", params: { id: scope.row.id }, })
}
,
handleFilter() {
this.listQuery.page = 1;
this.getList();
},
resetFilter() {
this.activeName="";
this.listQuery = {
page: 1,
page_size: 20,
}
this.getList();
},
handleCreate() {
this.material = Object.assign({}, defaultmaterial);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleEdit(scope) {
this.material = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteMaterial(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
},
async confirm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
if (isEdit) {
updateMaterial(this.material.id, this.material).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
} else {
createMaterial(this.material).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
},
//选项卡切换
handleClick(tab) {
this.listLoading = true;
this.listQuery.type = tab.name;
getMaterialList(this.listQuery).then((response) => {
if (response.data) {
this.materialList = response.data;
}
} else {
return false;
this.listLoading = false;
});
},
getList() {
this.listLoading = true;
getMaterialList(this.listQuery).then((response) => {
if (response.data) {
this.materialList = response.data;
}
this.listLoading = false;
});
},
//工序清单
getProcessList() {
getProcessList().then((res) => {
this.processOptions = res.data.results;
});
},
//绑定工序
handlebind(scope) {
this.$router.push({name: "MaterialDO", params: {id: scope.row.id},})
}
,
handleFilter() {
this.listQuery.page = 1;
this.getList();
},
resetFilter() {
this.activeName = "";
this.listQuery = {
page: 1,
page_size: 20,
}
});
this.getList();
},
handleCreate() {
this.material = Object.assign({}, defaultmaterial);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleEdit(scope) {
this.material = Object.assign({}, scope.row); // copy obj
this.dialogType = "edit";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Form"].clearValidate();
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error",
})
.then(async () => {
await deleteMaterial(scope.row.id);
this.getList();
this.$message.success("成功");
})
.catch((err) => {
console.error(err);
});
},
async confirm(form) {
this.$refs[form].validate((valid) => {
if (valid) {
const isEdit = this.dialogType === "edit";
if (isEdit) {
updateMaterial(this.material.id, this.material).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
} else {
createMaterial(this.material).then((res) => {
if (res.code >= 200) {
this.getList();
this.dialogVisible = false;
this.$message.success("成功");
}
});
}
} else {
return false;
}
});
},
},
},
};
};
</script>

View File

@ -20,49 +20,43 @@
</el-button>
<!--表格列表-->
<el-table
:data="recordformList.results"
border
fit
stripe
highlight-current-row
height="670"
v-el-height-adaptive-table="{ bottomOffset: 20 }"
v-el-height-adaptive-table="{ bottomOffset: 20 }"
@current-change="handleCurrentChange"
>
<el-table-column type="index" width="50"/>
<el-table-column label="表名称">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="是否启用">
<el-table-column label="是否启用">
<template slot-scope="scope">
<el-tag v-if="scope.row.enabled==false"></el-tag>
<el-tag v-if="scope.row.enabled==true"></el-tag>
</template>
<el-tag v-if="scope.row.enabled==false"></el-tag>
<el-tag v-if="scope.row.enabled==true"></el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-link
v-if="checkPermission(['material_update'])"
@click="handleLook(scope)"
>查看
</el-link
>
</el-link>
<el-link
v-if="checkPermission(['material_update'])"
@click="handleEdit(scope)"
>编辑
</el-link
>
</el-link>
<el-link
v-if="checkPermission(['material_delete'])"
type="danger"
@click="handleDelete(scope)"
>删除
</el-link
>
</el-link>
</template>
</el-table-column>
</el-table>
@ -81,17 +75,15 @@
<el-form-item label="表格名称" prop="name">
<el-input v-model="recordform.name" placeholder="表格名称"/>
</el-form-item>
<el-form-item label="是否启用" prop="name">
<el-switch v-model="recordform.enabled"></el-switch>
</el-form-item>
<el-form-item label="是否启用" prop="name">
<el-switch v-model="recordform.enabled"></el-switch>
</el-form-item>
</el-form>
<div style="text-align: right">
<el-button type="danger" @click="dialogVisible = false"
>取消
</el-button>
<el-button type="primary" @click="recordformconfirm('Forms')"
>确认
<el-button type="danger" @click="dialogVisible = false">取消
</el-button>
<!--<el-button type="primary" @click="recordformconfirm('Forms')">确认</el-button>-->
<el-button type="primary" @click="recordformcon">管理员授权</el-button>
</div>
</el-dialog>
<!--表格展示-->
@ -238,9 +230,9 @@
</el-row>
</el-form>-->
<!--<div style="text-align: right">-->
<!--<el-button type="primary" @click="judgeForm">-->
<!--合格验证-->
<!--</el-button>-->
<!--<el-button type="primary" @click="judgeForm">-->
<!--合格验证-->
<!--</el-button>-->
<!--</div>-->
</el-dialog>
</el-card>
@ -256,8 +248,7 @@
icon="el-icon-plus"
@click="handlefieldCreate"
>新增
</el-button
>
</el-button>
<!--表格字段列表-->
<el-table
:data="fieldList.results"
@ -270,23 +261,18 @@
>
<el-table-column type="index" width="50"/>
<el-table-column label="字段名称">
<template slot-scope="scope">{{
scope.row.field_name
}}
<template slot-scope="scope">
{{scope.row.field_name}}
</template>
</el-table-column>
<el-table-column label="字段类型">
<template slot-scope="scope">{{
options_[scope.row.field_type]
}}
<template slot-scope="scope">
{{options_[scope.row.field_type]}}
</template>
</el-table-column>
<el-table-column label="字段标识">
<template slot-scope="scope">{{
scope.row.field_key
}}
<template slot-scope="scope">
{{scope.row.field_key}}
</template>
</el-table-column>
<!--
@ -317,7 +303,6 @@
<el-tag v-else></el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-link
@ -325,15 +310,13 @@
type="primary"
@click="handlefieldEdit(scope)"
>编辑
</el-link
>
</el-link>
<el-link
v-if="checkPermission(['material_delete'])"
type="danger"
@click="handlefieldDelete(scope)"
>删除
</el-link
>
</el-link>
</template>
</el-table-column>
</el-table>
@ -383,8 +366,7 @@
field.field_type == 'radio' ||
field.field_type == 'checkbox' ||
field.field_type == 'select' ||
field.field_type == 'selects'
"
field.field_type == 'selects'"
>
<el-button @click.prevent="addDomain" style="border: none">
<i class="el-icon-circle-plus-outline"></i>
@ -527,6 +509,17 @@
</el-col>
</el-row>
</el-card>
<el-dialog :visible.sync="limitedPhoto">
<div style="font-size: 28px;color: #333333;text-align: center;font-weight: bold;margin-bottom: 15px;">权限验证</div>
<div class="testTracking">
<faceLogin
name="faceLogin"
:dialogType="dialogType"
:recordform="recordform"
@func="getMsgFormSon"
></faceLogin>
</div>
</el-dialog>
</div>
</template>
@ -536,6 +529,7 @@
import {getEquipmentAll} from "@/api/equipment";
import vueJsonEditor from "vue-json-editor";
import {upUrl, upHeaders} from "@/api/file";
import faceLogin from '@/components/faceLogin/faceLogin.vue'
import {
getrecordformList,
createrecordform,
@ -557,11 +551,11 @@
number: "",
};
const defaultrecordform = {enabled:false};
const defaultrecordform = {enabled: false};
const defaultfield = {};
let preDrawAry = [];
export default {
components: {Pagination, vueJsonEditor, Treeselect, customForm},
components: {Pagination, vueJsonEditor, Treeselect, customForm,faceLogin},
data() {
return {
step: defaultstep,
@ -576,13 +570,15 @@
dialogVisibleForm: false,
dialogTypes: "new",
field: {
field_type: "",
field_type: null,
field_key: "",
field_name: "",
sort: "",
parent: "",
help_text: "",
draw_template: "",//图片模板
field_name: null,
sort: null,
parent: null,
help_text: null,
rule_expression: null,
display_expression: null,
draw_template: null,//图片模板
field_choice: [""],
},
field_choice: [""],
@ -699,6 +695,7 @@
imgData: '',
canvasImg: '',
judgeList: [],
limitedPhoto:false
};
},
computed: {},
@ -836,9 +833,9 @@
that.$set(that.checkForm, key, '')
}
that.dialogVisibleForm = true;
/* setTimeout(function () {
that.canvasInit();
}, 500);*/
/* setTimeout(function () {
that.canvasInit();
}, 500);*/
}
});
that.fieldLists();
@ -888,9 +885,10 @@
this.recordform = Object.assign({}, defaultrecordform);
this.dialogType = "new";
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["Forms"].clearValidate();
});
this.$refs["Forms"].resetFields();
// this.$nextTick(() => {
// this.$refs["Forms"].resetFields();
// });
},
//新增字段
handlefieldCreate() {
@ -898,7 +896,18 @@
// this.field = Object.assign({}, defaultfield);
this.dialogType1 = "new";
this.dialogVisible1 = true;
// this.$refs["Form"].resetFields();
this.$nextTick(() => {
this.field.field_type= null;
this.field.field_key= null;
this.field.field_name= null;
this.field.sort= null;
this.field.parent= null;
this.field.help_text= null;
this.field.draw_template= null;
this.field.field_choice= null;
this.field.rule_expression= null;
this.field.display_expression= null;
this.$refs["Form"].clearValidate();
});
},
@ -1016,6 +1025,16 @@
}
});
},
recordformcon(){
this.recordform.material = this.material;
this.recordform.type = 2;
this.limitedPhoto = true;
},
getMsgFormSon(data){
this.limitedPhoto = data;
this.recordformLists();
this.dialogVisible = false;
},
},
};
</script>

View File

@ -3,29 +3,28 @@
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>生产任务列表</span>
</div>
<el-input
v-model="listQuery1.search"
placeholder="任务编号/订单编号/合同编号/产品名称"
style="width: 300px"
class="filter-item"
@keyup.enter.native="handleFilter"
/>
<el-button
class="filter-item"
type="primary"
icon="el-icon-search"
@click="handleFilter"
>搜索</el-button
>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>重置</el-button
>
<el-input
v-model="listQuery1.search"
placeholder="任务编号/订单编号/合同编号/产品名称"
style="width: 300px"
class="filter-item"
@keyup.enter.native="handleFilter"
/>
<el-button
class="filter-item"
type="primary"
icon="el-icon-search"
@click="handleFilter"
>搜索
</el-button>
<el-button
class="filter-item"
type="primary"
icon="el-icon-refresh-left"
@click="resetFilter"
>重置
</el-button>
<el-table
:data="productionplanList.results"
border
@ -33,11 +32,8 @@
stripe
style="width: 100%"
height="300"
>
<el-table-column type="index" width="50"/>
<el-table-column label="任务编号" width="110">
<template slot-scope="scope">{{ scope.row.number }}</template>
</el-table-column>
@ -47,7 +43,6 @@
<el-table-column label="合同编号" width="110">
<template slot-scope="scope" v-if="scope.row.contract">{{ scope.row.order_.contract_.number }}</template>
</el-table-column>
<el-table-column label="产品名称" width="150" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.product_.name }}</template>
</el-table-column>
@ -60,7 +55,7 @@
<el-table-column label="生产数量" width="110">
<template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column>
<el-table-column label="状态" width="110">
<el-table-column label="状态" width="110">
<template slot-scope="scope">{{ state_[scope.row.state] }}</template>
</el-table-column>
<el-table-column label="计划开工时间" width="110">
@ -135,7 +130,7 @@
<template slot-scope="scope" v-if="scope.row.contract">{{ scope.row.contract_.number }}</template>
</el-table-column>
<el-table-column label="合同名称" show-overflow-tooltip width="110">
<template slot-scope="scope" v-if="scope.row.contract">{{ scope.row.contract_.name }}</template>
<template slot-scope="scope" v-if="scope.row.contract">{{ scope.row.contract_.name }}</template>
</el-table-column>
<el-table-column label="所需产品" show-overflow-tooltip width="150">
<template slot-scope="scope">{{ scope.row.product_.name }}</template>
@ -231,7 +226,7 @@
</div>
</template>
<script>
import gantt from "@/components/Gantt/index";
import gantt from "@/components/Gantt/index";
import {getordertoplan} from "@/api/sam";
import {createProductionplan, getProductionplanList, createsubplan} from "@/api/pm";
import {getMaterialList} from "@/api/mtm";
@ -242,20 +237,21 @@
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaulteorderplan = {};
export default {
components: {Pagination,gantt},
components: {Pagination, gantt},
data() {
return {
orderplan: defaulteorderplan,
orderList: {
count: 0,
},
state_:{
10:'制定中',
20:'已下达',
30:'已接受',
40:'生产中',
50:'已完成',
60:'军检完成'},
state_: {
10: '制定中',
20: '已下达',
30: '已接受',
40: '生产中',
50: '已完成',
60: '军检完成'
},
listQuery: {
page: 1,
page_size: 20,
@ -277,7 +273,7 @@
number: [{required: true, message: "请输入", trigger: "blur"}],
},
proList:[],
proList: [],
};
},
computed: {},
@ -309,7 +305,7 @@
if (response.data) {
this.productionplanList = response.data;
let list = response.data.results;
let arr= [];
let arr = [];
list.forEach(item => {
if (!item.children || item.children.length < 1) {
let startTime = new Date(item.start_date).getTime();
@ -334,18 +330,18 @@
this.listLoading = false;
});
},
//搜索生产计划
handleFilter() {
this.listQuery1.page = 1;
this.getplanList();
},
resetFilter() {
this.listQuery1 = {
page: 1,
page_size: 20,
}
this.getplanList();
},
//搜索生产计划
handleFilter() {
this.listQuery1.page = 1;
this.getplanList();
},
resetFilter() {
this.listQuery1 = {
page: 1,
page_size: 20,
}
this.getplanList();
},
handleclick(scope) {
this.orderID = scope.row.id;
this.countsx = scope.row.count;
@ -403,12 +399,12 @@
});
},
activeNameClick(tab, event){
activeNameClick(tab, event) {
debugger;
console.log(tab, event);
if(tab.label==='甘特图'){
if (tab.label === '甘特图') {
this.ganttShow = true;
}else{
} else {
this.ganttShow = false;
}
},

View File

@ -1,5 +1,6 @@
.vscode/
.vs/
.idea/
venv/
__pycache__/
*.pyc

View File

@ -2,11 +2,13 @@ from django.db.models import base
from rest_framework import urlpatterns
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from apps.develop.views import CleanDataView, UpdateCuttingView, UpdateLastTestResult
from apps.develop.views import CleanDataView, UpdateCuttingView, UpdateFIFOItem, UpdateLastTestResult
urlpatterns = [
path('cleandata/', CleanDataView.as_view()),
path('update_cutting/', UpdateCuttingView.as_view()),
path('update_last_result/', UpdateLastTestResult.as_view())
path('update_last_result/', UpdateLastTestResult.as_view()),
path('update_last_result/', UpdateLastTestResult.as_view()),
path('update_fifoitem/', UpdateFIFOItem.as_view())
]

View File

@ -4,7 +4,7 @@ from rest_framework.decorators import permission_classes
from rest_framework.views import APIView
from rest_framework.permissions import IsAdminUser
from rest_framework.response import Response
from apps.inm.models import FIFO, Inventory, MaterialBatch
from apps.inm.models import FIFO, FIFOItem, Inventory, MaterialBatch
from apps.mtm.models import Material
from apps.pm.models import ProductionPlan
from apps.sam.models import Order
@ -62,3 +62,21 @@ class UpdateLastTestResult(APIView):
i.last_test_result = tr.is_testok
i.save()
return Response()
class UpdateFIFOItem(APIView):
permission_classes = [IsAdminUser]
@transaction.atomic
def post(self, request, format=None):
"""
更新出入库结果
"""
for i in FIFOItem.objects.all():
if i.fifo.type == FIFO.FIFO_TYPE_PUR_IN:
if i.is_testok:
i.need_test = True
i.save()
else:
i.is_testok = None
i.save()
return Response()

View File

@ -27,7 +27,7 @@ class EquipmentSerializer(ModelSerializer):
class EquipmentSimpleSerializer(ModelSerializer):
class Meta:
model = Equipment
fields = ['id', 'number', 'name']
fields = ['id', 'number', 'name', 'state']

View File

@ -3,22 +3,25 @@ from django_filters import rest_framework as filters
from apps.mtm.models import Material
from .models import IProduct, MaterialBatch
from django.utils import timezone
class MbFilterSet(filters.FilterSet):
material = filters.ModelMultipleChoiceFilter(field_name="material", queryset=Material.objects.all())
tag = filters.CharFilter(method="filter_tag")
class Meta:
model = MaterialBatch
fields = ['material', 'warehouse']
def filter_tag(self, queryset, name, value):
if value == 'expired':
queryset = queryset.exclude(expiration_date=None).filter(expiration_date__lte = timezone.now())
queryset = queryset.exclude(expiration_date=None).filter(expiration_date__lte=timezone.now())
return queryset
class IProductFilterSet(filters.FilterSet):
order = filters.NumberFilter(field_name="wproduct__subproduction_plan__production_plan__order")
class Meta:
model = IProduct
fields = ['material', 'warehouse', 'batch', 'order', 'material__type']
fields = ['material', 'warehouse', 'batch', 'order', 'material__type']

View File

@ -0,0 +1,18 @@
# Generated by Django 3.2.9 on 2022-01-14 07:32
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inm', '0025_auto_20220113_0932'),
]
operations = [
migrations.AlterField(
model_name='fifo',
name='inout_date',
field=models.DateField(blank=True, null=True, verbose_name='出入库日期'),
),
]

View File

@ -0,0 +1,33 @@
# Generated by Django 3.2.9 on 2022-01-14 07:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('system', '0003_auto_20210812_0909'),
('inm', '0026_alter_fifo_inout_date'),
]
operations = [
migrations.RemoveField(
model_name='fifoitem',
name='is_tested',
),
migrations.AddField(
model_name='fifoitem',
name='files',
field=models.ManyToManyField(to='system.File', verbose_name='上传材料'),
),
migrations.AddField(
model_name='fifoitem',
name='need_test',
field=models.BooleanField(default=False, verbose_name='是否需要复验'),
),
migrations.AlterField(
model_name='fifoitem',
name='is_testok',
field=models.BooleanField(blank=True, null=True, verbose_name='是否复验合格'),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 3.2.9 on 2022-01-14 08:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('system', '0003_auto_20210812_0909'),
('inm', '0027_auto_20220114_1551'),
]
operations = [
migrations.AlterField(
model_name='fifoitem',
name='files',
field=models.ManyToManyField(blank=True, to='system.File', verbose_name='上传材料'),
),
]

View File

@ -17,6 +17,7 @@ class WareHouse(CommonAModel):
number = models.CharField('仓库编号', max_length=20, unique=True)
name = models.CharField('仓库名称', max_length=20, unique=True)
place = models.CharField('具体地点', max_length=50)
class Meta:
verbose_name = '仓库信息'
verbose_name_plural = verbose_name
@ -24,37 +25,44 @@ class WareHouse(CommonAModel):
def __str__(self):
return self.name
class Inventory(BaseModel):
"""
库存物料
"""
material = models.ForeignKey(Material, on_delete=models.CASCADE, verbose_name='物料信息')
material = models.ForeignKey(
Material, on_delete=models.CASCADE, verbose_name='物料信息')
count = models.PositiveIntegerField('仓库物料存量', default=0)
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
warehouse = models.ForeignKey(
WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
class Meta:
verbose_name = '库存表'
verbose_name_plural = verbose_name
class MaterialBatch(BaseModel):
"""
物料批次
"""
material = models.ForeignKey(Material, on_delete=models.CASCADE, verbose_name='物料信息')
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
material = models.ForeignKey(
Material, on_delete=models.CASCADE, verbose_name='物料信息')
warehouse = models.ForeignKey(
WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
count = models.PositiveIntegerField('存量', default=0)
batch = models.CharField('批次号', max_length=100, default='')
expiration_date = models.DateField('有效期', null=True, blank=True)
class Meta:
verbose_name = '库存表'
verbose_name_plural = verbose_name
class FIFO(CommonADModel):
"""
出入库记录
"""
FIFO_TYPE_DO_OUT = 1 # 生产领料
FIFO_TYPE_DO_OUT = 1 # 生产领料
FIFO_TYPE_SALE_OUT = 2
FIFO_TYPE_PUR_IN = 3
FIFO_TYPE_DO_IN = 4
@ -66,8 +74,9 @@ class FIFO(CommonADModel):
)
type = models.IntegerField('出入库类型', default=1)
is_audited = models.BooleanField('是否审核', default=False)
auditor = models.ForeignKey(User, verbose_name='审核人', on_delete=models.CASCADE, null=True, blank=True)
inout_date = models.DateField('出入库日期')
auditor = models.ForeignKey(
User, verbose_name='审核人', on_delete=models.CASCADE, null=True, blank=True)
inout_date = models.DateField('出入库日期', null=True, blank=True)
remark = models.CharField('备注', max_length=1000, default='')
@ -75,38 +84,46 @@ class FIFOItem(BaseModel):
"""
出入库详细条目
"""
is_tested = models.BooleanField('是否已检验', default=False)
is_testok = models.BooleanField('是否检验合格', default=False)
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='仓库')
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
need_test = models.BooleanField('是否需要复验', default=False)
is_testok = models.BooleanField('是否复验合格', null=True, blank=True)
warehouse = models.ForeignKey(
WareHouse, on_delete=models.CASCADE, verbose_name='仓库')
material = models.ForeignKey(
Material, verbose_name='物料类型', on_delete=models.CASCADE)
count = models.PositiveIntegerField('数量', default=0)
batch = models.CharField('批次号', max_length=100, default='')
fifo = models.ForeignKey(FIFO, verbose_name='关联出入库', on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True)
fifo = models.ForeignKey(FIFO, verbose_name='关联出入库',
on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(
SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True)
files = models.ManyToManyField(File, verbose_name='上传材料', blank=True)
class IProduct(BaseModel):
"""
具体产品条目
"""
number = models.CharField('物品编号', unique=True, max_length=50)
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
material = models.ForeignKey(
Material, verbose_name='物料类型', on_delete=models.CASCADE)
warehouse = models.ForeignKey(
WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
batch = models.CharField('所属批次号', max_length=100, default='')
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False,
null=True, blank=True, related_name='iproduct_wproduct')
null=True, blank=True, related_name='iproduct_wproduct')
is_saled = models.BooleanField('是否售出', default=False)
class FIFOItemProduct(BaseModel):
"""
出入库产品
"""
fifoitem = models.ForeignKey(FIFOItem, verbose_name='关联出入库具体产品', on_delete=models.CASCADE)
fifoitem = models.ForeignKey(
FIFOItem, verbose_name='关联出入库具体产品', on_delete=models.CASCADE)
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True,
related_name='fifoitem_wproduct')
related_name='fifoitem_wproduct')
number = models.CharField('物品编号', max_length=50)
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
iproduct = models.ForeignKey(IProduct, verbose_name='关联库存产品', null=True, blank=True, on_delete=models.SET_NULL)
material = models.ForeignKey(
Material, verbose_name='物料类型', on_delete=models.CASCADE)
iproduct = models.ForeignKey(
IProduct, verbose_name='关联库存产品', null=True, blank=True, on_delete=models.SET_NULL)

View File

@ -1,78 +1,96 @@
from rest_framework import exceptions
from rest_framework import serializers
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse,Inventory
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse, Inventory
from apps.qm.models import TestRecord, TestRecordItem
from apps.system.serializers import UserSimpleSerializer
from apps.mtm.serializers import MaterialSimpleSerializer
from django.db import transaction
class WareHouseSerializer(serializers. ModelSerializer):
create_by_=UserSimpleSerializer('create_by', read_only=True)
class WareHouseSerializer(serializers.ModelSerializer):
create_by_ = UserSimpleSerializer('create_by', read_only=True)
class Meta:
model = WareHouse
fields = '__all__'
class WareHouseCreateUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = WareHouse
fields = ['name', 'number', 'place']
class WareHouseSimpleSerializer(serializers.ModelSerializer):
class Meta:
model = WareHouse
fields = ['name', 'number', 'place']
class InventorySerializer(serializers. ModelSerializer):
material_= MaterialSimpleSerializer(source='material', read_only=True)
class InventorySerializer(serializers.ModelSerializer):
material_ = MaterialSimpleSerializer(source='material', read_only=True)
warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True)
class Meta:
model = Inventory
fields = '__all__'
class MaterialBatchSerializer(serializers. ModelSerializer):
material_= MaterialSimpleSerializer(source='material', read_only=True)
class MaterialBatchSerializer(serializers.ModelSerializer):
material_ = MaterialSimpleSerializer(source='material', read_only=True)
warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True)
class Meta:
model = MaterialBatch
fields = '__all__'
class IProductListSerializer(serializers.ModelSerializer):
material_= MaterialSimpleSerializer(source='material', read_only=True)
material_ = MaterialSimpleSerializer(source='material', read_only=True)
warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True)
is_mtested = serializers.BooleanField(source='wproduct.is_mtested', read_only=True)
is_mtestok = serializers.BooleanField(source='wproduct.is_mtestok', read_only=True)
remark_mtest = serializers.CharField(source='wproduct.remark_mtest', read_only=True)
class Meta:
model = IProduct
fields = '__all__'
class FIFOListSerializer(serializers.ModelSerializer):
auditor_ = UserSimpleSerializer(source='auditor', read_only=True)
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
class Meta:
model=FIFO
model = FIFO
fields = '__all__'
class FIFOItemSerializer(serializers.ModelSerializer):
warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True)
material_= MaterialSimpleSerializer(source='material', read_only=True)
material_ = MaterialSimpleSerializer(source='material', read_only=True)
class Meta:
model= FIFOItem
model = FIFOItem
fields = '__all__'
class IProductInPurSerializer(serializers.ModelSerializer):
class Meta:
model = IProduct
fields = ['number']
class FIFODetailInPurSerializer(serializers.ModelSerializer):
details = IProductInPurSerializer(many=True, required=False)
class Meta:
model = FIFOItem
fields = ['material', 'count', 'batch', 'details', 'warehouse']
class MaterialBatchQuerySerializer(serializers.Serializer):
warehouse = serializers.IntegerField(label="仓库ID", required=False)
materials = serializers.ListField(child=serializers.IntegerField(label="物料ID"), required=False)
@ -83,13 +101,14 @@ class FIFOInPurSerializer(serializers.ModelSerializer):
采购入库序列化
"""
details = FIFODetailInPurSerializer(many=True)
class Meta:
model = FIFO
fields = ['details', 'inout_date']
fields = ['details']
def create(self, validated_data):
details = validated_data.pop('details')
if len(details)>0:
if len(details) > 0:
pass
else:
raise serializers.ValidationError('没有入库内容')
@ -103,7 +122,7 @@ class FIFOInPurSerializer(serializers.ModelSerializer):
# raise serializers.ValidationError('批次号{}在其他仓库已存在'.format(i['batch']))
# except:
# pass
# 创建采购入库
with transaction.atomic():
validated_data['type'] = FIFO.FIFO_TYPE_PUR_IN
@ -137,17 +156,33 @@ class FIFOInPurSerializer(serializers.ModelSerializer):
return obj
class InmTestRecordItemCreateSerializer(serializers.ModelSerializer):
class Meta:
model = TestRecordItem
fields = ['form_field', 'field_value', 'is_testok']
class InmTestRecordCreateSerializer(serializers.ModelSerializer):
record_data = InmTestRecordItemCreateSerializer(many=True)
fifo_item = serializers.PrimaryKeyRelatedField(queryset=FIFOItem.objects.all(), required=True)
is_testok = serializers.BooleanField()
class Meta:
model = TestRecord
fields = ['form', 'record_data', 'is_testok', 'fifo_item']
class FIFOItemUpdateSerializer(serializers.ModelSerializer):
class Meta:
model = FIFOItem
fields = ['need_test', 'files']
def validate(self, attrs):
ins = self.instance
fifo = ins.fifo
if fifo.is_audited:
raise exceptions.APIException('该记录已审核')
if ins.is_testok is not None:
attrs.pop('need_test')
return super().validate(attrs)

View File

@ -1,25 +1,26 @@
from django.shortcuts import render
from rest_framework import serializers
from rest_framework import exceptions
from rest_framework.exceptions import APIException
from rest_framework.mixins import DestroyModelMixin, ListModelMixin, RetrieveModelMixin
from rest_framework.mixins import DestroyModelMixin, ListModelMixin, UpdateModelMixin
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from apps.inm.filters import IProductFilterSet, MbFilterSet
from apps.inm.models import FIFO, FIFOItem, IProduct, MaterialBatch, WareHouse,Inventory
from apps.inm.serializers import FIFOItemSerializer, FIFOInPurSerializer, FIFOListSerializer, IProductListSerializer, InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer,InventorySerializer
from apps.inm.models import FIFO, FIFOItem, IProduct, MaterialBatch, WareHouse, Inventory
from apps.inm.serializers import FIFOItemSerializer, FIFOInPurSerializer, FIFOItemUpdateSerializer, FIFOListSerializer, IProductListSerializer, \
InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, \
WareHouseCreateUpdateSerializer, InventorySerializer
from apps.inm.signals import update_inm
from apps.mtm.models import Material
from apps.pm.services import PmService
from apps.qm.models import TestRecordItem
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
from apps.system.mixins import CreateUpdateModelAMixin
from rest_framework.decorators import action
from rest_framework.response import Response
from django.db import transaction
from django.utils import timezone
from apps.wpm.services import WpmServies
# Create your views here.
class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet):
"""
仓库-增删改查
@ -32,26 +33,30 @@ class WarehouseViewSet(CreateUpdateModelAMixin, ModelViewSet):
ordering_fields = ['create_time']
ordering = ['-create_time']
def get_serializer_class(self):
def get_serializer_class(self):
if self.action in ['create', 'update']:
return WareHouseCreateUpdateSerializer
return WareHouseSerializer
class InventoryViewSet(ListModelMixin, GenericViewSet):
"""
仓库物料表
"""
perms_map = {'*': '*'}
queryset = Inventory.objects.select_related('material', 'warehouse').filter(count__gt=0).all()
queryset = Inventory.objects.select_related(
'material', 'warehouse').filter(count__gt=0).all()
serializer_class = InventorySerializer
filterset_fields = ['material', 'warehouse']
search_fields = []
ordering_fields = ['create_time']
ordering = ['-create_time']
class MaterialBatchViewSet(ListModelMixin, GenericViewSet):
perms_map = {'*': '*'}
queryset = MaterialBatch.objects.select_related('material', 'warehouse').filter(count__gt=0).all()
queryset = MaterialBatch.objects.select_related(
'material', 'warehouse').filter(count__gt=0).all()
serializer_class = MaterialBatchSerializer
# filterset_fields = ['material', 'warehouse']
filterset_class = MbFilterSet
@ -59,7 +64,7 @@ class MaterialBatchViewSet(ListModelMixin, GenericViewSet):
ordering_fields = ['create_time']
ordering = ['-create_time']
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=MaterialBatchQuerySerializer)
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=MaterialBatchQuerySerializer)
def query(self, request, pk=None):
"""
复杂查询
@ -67,27 +72,35 @@ class MaterialBatchViewSet(ListModelMixin, GenericViewSet):
data = request.data
serializer = MaterialBatchQuerySerializer(data=data)
serializer.is_valid(raise_exception=True)
queryset = self.queryset.filter(warehouse__id=data['warehouse'], material__id__in=data['materials'])
queryset = self.queryset.filter(
warehouse__id=data['warehouse'], material__id__in=data['materials'])
return Response(MaterialBatchSerializer(instance=queryset, many=True).data)
class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin, GenericViewSet):
"""
出入库记录详情表
"""
perms_map = {'*': '*'}
queryset = FIFOItem.objects.select_related('material', 'fifo').all()
serializer_class = FIFOItemSerializer
filterset_fields = ['material', 'fifo', 'fifo__type', 'is_tested', 'is_testok']
filterset_fields = ['material', 'fifo',
'fifo__type', 'need_test', 'is_testok']
search_fields = []
ordering_fields = ['create_time']
ordering = ['-create_time']
def get_serializer_class(self):
if self.action == 'update':
return FIFOItemUpdateSerializer
return super().get_serializer_class()
def perform_destroy(self, instance):
if instance.fifo.is_audited:
raise APIException('该出入库记录已通过审核, 无法删除')
return super().perform_destroy(instance)
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=InmTestRecordCreateSerializer)
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=InmTestRecordCreateSerializer)
def test(self, request, pk=None):
"""
检验
@ -99,9 +112,9 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
if 'is_testok' not in vdata:
raise APIException('未填写检验结论')
with transaction.atomic():
obj = serializer.save(create_by = self.request.user)
obj = serializer.save(create_by=self.request.user)
tris = []
for m in record_data: # 保存记录详情
for m in record_data: # 保存记录详情
m['field_value'] = m['field_value']
m['is_testok'] = m['is_testok'] if 'is_testok' in m else True
m['test_record'] = obj
@ -111,10 +124,10 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
# 如果检验合格
if obj.fifo_item:
obj.fifo_item.is_testok = True if obj.is_testok else False
obj.fifo_item.is_tested = True
obj.fifo_item.save()
return Response()
class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
"""
出入库记录
@ -131,14 +144,14 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
if self.action == 'list':
return FIFOListSerializer
return super().get_serializer_class()
def destroy(self, request, *args, **kwargs):
obj = self.get_object()
if obj.is_submited:
raise exceptions.APIException('该记录已审核,不可删除')
return super().destroy(request, *args, **kwargs)
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=FIFOInPurSerializer)
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=FIFOInPurSerializer)
def in_pur(self, request, pk=None):
"""
采购入库
@ -148,13 +161,13 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
serializer.save(create_by=request.user)
return Response()
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer)
@action(methods=['post'], detail=True, perms_map={'post': '*'}, serializer_class=serializers.Serializer)
def audit(self, request, pk=None):
"""
审核通过
"""
obj = self.get_object()
for i in FIFOItem.objects.filter(fifo=obj):
for i in FIFOItem.objects.filter(fifo=obj, need_test=True):
if not i.is_testok:
raise APIException('未检验通过, 不可审核')
if obj.is_audited:
@ -162,19 +175,21 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
with transaction.atomic():
obj.is_audited = True
obj.auditor = request.user
obj.inout_date = timezone.now() # 也是审核日期
obj.save()
update_inm(obj) # 更新库存
update_inm(obj) # 更新库存
return Response()
class IProductViewSet(ListModelMixin, GenericViewSet):
"""
半成品库存表
"""
perms_map = {'*': '*'}
queryset = IProduct.objects.select_related('material', 'warehouse', 'wproduct__subproduction_plan__production_plan__order')
queryset = IProduct.objects.select_related(
'material', 'warehouse', 'wproduct__subproduction_plan__production_plan__order')
serializer_class = IProductListSerializer
filterset_class = IProductFilterSet
search_fields = []
ordering_fields = ['create_time']
ordering = ['-create_time']
ordering = ['-create_time']

View File

@ -150,8 +150,7 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C
warehouse = WareHouse.objects.get(id=i['warehouse'])
material = Material.objects.get(id=i['material'])
fifoitem = FIFOItem()
fifoitem.is_tested = True
fifoitem.is_testok = True
fifoitem.need_test = False
fifoitem.warehouse = warehouse
fifoitem.material = material
fifoitem.count = i['total']

View File

@ -4,39 +4,50 @@ from apps.mtm.models import Material, Step
from apps.wpm.services import WpmServies
from .models import Operation, OperationMaterial, OperationRecord, WMaterial, WProduct
class WMaterialFilterSet(filters.FilterSet):
operation = filters.NumberFilter(method='filter_operation')
class Meta:
model = WMaterial
fields = ['material', 'subproduction_plan', 'subproduction_plan__process', 'subproduction_plan__workshop', 'operation']
fields = ['material', 'subproduction_plan', 'subproduction_plan__process',
'subproduction_plan__workshop', 'operation']
def filter_operation(self, queryset, name, value):
operation = Operation.objects.get(pk=value)
wproducts = WProduct.objects.filter(ow_wproduct__operation=value)
step = operation.step
if wproducts.exists():
subplans = WpmServies.get_subplans_queryset_from_wproducts(wproducts)
subplans = WpmServies.get_subplans_queryset_from_wproducts(
wproducts)
else:
subplans = WpmServies.get_subplans_queyset_from_step(step)
queryset = queryset.filter(subproduction_plan__in=subplans).exclude(material__type=Material.MA_TYPE_HALFGOOD)
queryset = queryset.filter(subproduction_plan__in=subplans).exclude(
material__type=Material.MA_TYPE_HALFGOOD)
return queryset
class WProductFilterSet(filters.FilterSet):
tag = filters.CharFilter(method='filter_tag')
production_plan = filters.NumberFilter(field_name='subproduction_plan__production_plan')
production_plan = filters.NumberFilter(
field_name='subproduction_plan__production_plan')
class Meta:
model = WProduct
fields = ['step', 'subproduction_plan', 'material', 'step__process', 'act_state', 'material__type']
fields = ['step', 'subproduction_plan', 'material',
'step__process', 'act_state', 'material__type']
def filter_tag(self, queryset, name, value):
if value == 'no_scrap':
queryset = queryset.exclude(act_state=WProduct.WPR_ACT_STATE_SCRAP)
return queryset
class CuttingFilterSet(filters.FilterSet):
production_plan = filters.NumberFilter(field_name='subproduction_plan__production_plan')
production_plan = filters.NumberFilter(
field_name='subproduction_plan__production_plan')
class Meta:
model = OperationMaterial
fields = ['operation', 'subproduction_plan', 'material']
@ -44,10 +55,11 @@ class CuttingFilterSet(filters.FilterSet):
class OperationRecordFilterSet(filters.FilterSet):
wproduct = filters.NumberFilter(method='filter_wproduct')
class Meta:
model = OperationRecord
fields = ['operation', 'form']
def filter_wproduct(self, queryset, name, value):
queryset = queryset.filter(operation__ow_operation__wproduct__id=value)
return queryset
return queryset

View File

@ -13,15 +13,20 @@ from utils.model import SoftModel, BaseModel
from simple_history.models import HistoricalRecords
from apps.mtm.models import Material, Process, RecordFormField, Step, RecordForm, SubprodctionMaterial
from apps.em.models import Equipment
class WMaterial(BaseModel):
"""
车间生产物料
"""
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子计划', on_delete=models.CASCADE)
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(
SubProductionPlan, verbose_name='关联子计划', on_delete=models.CASCADE)
material = models.ForeignKey(
Material, verbose_name='关联物料', on_delete=models.CASCADE)
batch = models.CharField('批次号', max_length=100, null=True, blank=True)
count = models.PositiveIntegerField('当前数量', default=0)
class WProduct(CommonAModel):
"""
动态半成品/成品表
@ -37,7 +42,7 @@ class WProduct(CommonAModel):
WPR_ACT_STATE_TOFINALTEST = 60
WPR_ACT_STATE_SCRAP = 70
WPR_ACT_STATE_SELLED = 80
act_state_choices=(
act_state_choices = (
(WPR_ACT_STATE_TORETEST, '待复检'),
(WPR_ACT_STATE_DOWAIT, '操作准备中'),
(WPR_ACT_STATE_DOING, '操作进行中'),
@ -69,7 +74,7 @@ class WProduct(CommonAModel):
NG_DOWN = 60
NG_BACK_FROM = 70
NG_RECALL = 80
ng_choices = (
(NG_BACK_WORK, '返工'),
(NG_BACK_FIX, '返修'),
@ -80,29 +85,39 @@ class WProduct(CommonAModel):
(NG_BACK_FROM, '退回供方'),
(NG_RECALL, '召回')
)
number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50)
material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='w_pre_step')
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, related_name='w_step')
act_state = models.IntegerField('进行状态', default=0, choices=act_state_choices)
number = models.CharField(
'物品编号', unique=True, null=True, blank=True, max_length=50)
material = models.ForeignKey(
Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True,
on_delete=models.CASCADE, related_name='w_pre_step')
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True,
related_name='w_step')
act_state = models.IntegerField(
'进行状态', default=0, choices=act_state_choices)
is_hidden = models.BooleanField('是否隐藏', default=False)
child = models.ForeignKey('self', blank=True, null=True, on_delete=models.CASCADE, related_name='wproduct_child')
child = models.ForeignKey('self', blank=True, null=True,
on_delete=models.CASCADE, related_name='wproduct_child')
remark = models.CharField('备注', max_length=200, null=True, blank=True)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='wproduct_subplan')
scrap_reason = models.IntegerField('报废原因', choices=scrap_reason_choices, null=True, blank=True)
ng_sign = models.PositiveSmallIntegerField('不合格标记', choices=ng_choices, null=True, blank=True)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE,
related_name='wproduct_subplan')
warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
scrap_reason = models.IntegerField(
'报废原因', choices=scrap_reason_choices, null=True, blank=True)
ng_sign = models.PositiveSmallIntegerField(
'不合格标记', choices=ng_choices, null=True, blank=True)
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_operation')
coperation = models.ForeignKey('wpm.operation', verbose_name='创建所关联操作',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_coperation')
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_test')
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_ticket')
warehouse = models.ForeignKey(
WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_operation')
coperation = models.ForeignKey('wpm.operation', verbose_name='创建所关联操作',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_coperation')
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_test')
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_ticket')
is_mtested = models.BooleanField('是否军检', default=False)
is_mtestok = models.BooleanField('是否军检合格', null=True, blank=True)
@ -115,50 +130,68 @@ class WProduct(CommonAModel):
最后提交的工序自检
"""
return self.test_wproduct.filter(type=TestRecord.TEST_PROCESS, is_submited=True).order_by('-id').first()
class WprouctTicket(CommonAModel):
"""
玻璃审批工单
"""
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
wproduct = models.ForeignKey(WProduct, verbose_name='关联产品', on_delete=models.CASCADE)
material = models.ForeignKey(Material, verbose_name='所在物料状态', on_delete=models.CASCADE)
step = models.ForeignKey(Step, verbose_name='所在步骤/发现步骤', on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='所在子生产计划', on_delete=models.CASCADE)
resp_process = models.ForeignKey(Process, verbose_name='责任工序', on_delete=models.CASCADE, null=True, blank=True)
ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单', on_delete=models.CASCADE, related_name='wt_ticket')
decision = models.PositiveSmallIntegerField('最终决定', choices=WProduct.ng_choices, null=True, blank=True)
wproduct = models.ForeignKey(
WProduct, verbose_name='关联产品', on_delete=models.CASCADE)
material = models.ForeignKey(
Material, verbose_name='所在物料状态', on_delete=models.CASCADE)
step = models.ForeignKey(
Step, verbose_name='所在步骤/发现步骤', on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(
SubProductionPlan, verbose_name='所在子生产计划', on_delete=models.CASCADE)
resp_process = models.ForeignKey(
Process, verbose_name='责任工序', on_delete=models.CASCADE, null=True, blank=True)
ticket = models.ForeignKey(
'wf.ticket', verbose_name='关联工单', on_delete=models.CASCADE, related_name='wt_ticket')
decision = models.PositiveSmallIntegerField(
'最终决定', choices=WProduct.ng_choices, null=True, blank=True)
class WproductFlow(CommonAModel):
"""
动态产品表日志
"""
wproduct = models.ForeignKey(WProduct, on_delete=models.CASCADE, verbose_name='关联产品', null=True, blank=True)
wproduct = models.ForeignKey(
WProduct, on_delete=models.CASCADE, verbose_name='关联产品', null=True, blank=True)
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True, on_delete=models.CASCADE, related_name='wl_pre_step')
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True, related_name='wl_step')
act_state = models.IntegerField('进行状态', default=0, choices=WProduct.act_state_choices)
material = models.ForeignKey(
Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
pre_step = models.ForeignKey(Step, verbose_name='已执行到', help_text='已执行完的步骤', null=True, blank=True,
on_delete=models.CASCADE, related_name='wl_pre_step')
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE, null=True, blank=True,
related_name='wl_step')
act_state = models.IntegerField(
'进行状态', default=0, choices=WProduct.act_state_choices)
is_hidden = models.BooleanField('是否隐藏', default=False)
child = models.ForeignKey('self', blank=True, null=True, on_delete=models.CASCADE, related_name='wproduct_child')
child = models.ForeignKey('self', blank=True, null=True,
on_delete=models.CASCADE, related_name='wproduct_child')
remark = models.CharField('备注', max_length=200, null=True, blank=True)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(
SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE)
scrap_reason = models.IntegerField('报废原因', choices= WProduct.scrap_reason_choices, null=True, blank=True)
ng_sign = models.PositiveSmallIntegerField('不合格标记', choices= WProduct.ng_choices, null=True, blank=True)
scrap_reason = models.IntegerField(
'报废原因', choices=WProduct.scrap_reason_choices, null=True, blank=True)
ng_sign = models.PositiveSmallIntegerField(
'不合格标记', choices=WProduct.ng_choices, null=True, blank=True)
warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wpf_operation')
coperation = models.ForeignKey('wpm.operation', verbose_name='创建所关联操作',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wpf_coperation')
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
on_delete=models.SET_NULL, null=True, blank=True)
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
on_delete=models.SET_NULL, null=True, blank=True)
warehouse = models.ForeignKey(
WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wpf_operation')
coperation = models.ForeignKey('wpm.operation', verbose_name='创建所关联操作',
on_delete=models.SET_NULL, null=True, blank=True, related_name='wpf_coperation')
test = models.ForeignKey('qm.testrecord', verbose_name='当前检验',
on_delete=models.SET_NULL, null=True, blank=True)
ticket = models.ForeignKey('wf.ticket', verbose_name='当前工单',
on_delete=models.SET_NULL, null=True, blank=True)
is_mtested = models.BooleanField('是否军检', default=False)
is_mtestok = models.BooleanField('是否军检合格', null=True, blank=True)
@ -179,65 +212,88 @@ class Pick(CommonADModel):
(PICK_FROM_WAREHOUSE, '仓库领取'),
(PICK_FROM_WPRODUCT, '半成品领取'),
)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE)
type = models.PositiveSmallIntegerField(choices=type_choice, default=PICK_FROM_WAREHOUSE)
fifo = models.ForeignKey(FIFO, verbose_name='关联的出入库记录', on_delete=models.CASCADE, null=True, blank=True)
subproduction_plan = models.ForeignKey(
SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE)
type = models.PositiveSmallIntegerField(
choices=type_choice, default=PICK_FROM_WAREHOUSE)
fifo = models.ForeignKey(
FIFO, verbose_name='关联的出入库记录', on_delete=models.CASCADE, null=True, blank=True)
class PickWproduct(BaseModel):
"""
领取半成品时详情
"""
pick = models.ForeignKey(Pick, verbose_name='关联领料', on_delete=models.CASCADE)
wproduct = models.ForeignKey(WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='pw_wproduct')
pick = models.ForeignKey(Pick, verbose_name='关联领料',
on_delete=models.CASCADE)
wproduct = models.ForeignKey(
WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='pw_wproduct')
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
material = models.ForeignKey(Material, verbose_name='领取时的物料状态', on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='领取时所属子生产计划', on_delete=models.CASCADE)
material = models.ForeignKey(
Material, verbose_name='领取时的物料状态', on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(
SubProductionPlan, verbose_name='领取时所属子生产计划', on_delete=models.CASCADE)
class Operation(CommonADModel):
"""
生产操作
"""
step = models.ForeignKey(Step, verbose_name='操作步骤', on_delete=models.CASCADE, null=True, blank=True)
step = models.ForeignKey(Step, verbose_name='操作步骤',
on_delete=models.CASCADE, null=True, blank=True)
remark = models.CharField('操作备注', max_length=200, null=True, blank=True)
is_submited = models.BooleanField('是否提交', default=False)
class OperationWproduct(BaseModel):
"""
生产操作半成品关联表
"""
operation = models.ForeignKey(Operation, verbose_name='关联操作', on_delete=models.CASCADE, related_name='ow_operation')
wproduct = models.ForeignKey(WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='ow_wproduct')
operation = models.ForeignKey(
Operation, verbose_name='关联操作', on_delete=models.CASCADE, related_name='ow_operation')
wproduct = models.ForeignKey(
WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='ow_wproduct')
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
material = models.ForeignKey(Material, verbose_name='操作时的物料状态', on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='ow_subplan')
ng_sign = models.PositiveSmallIntegerField('当时的不合格标记', choices= WProduct.ng_choices, null=True, blank=True)
material = models.ForeignKey(
Material, verbose_name='操作时的物料状态', on_delete=models.CASCADE)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE,
related_name='ow_subplan')
ng_sign = models.PositiveSmallIntegerField(
'当时的不合格标记', choices=WProduct.ng_choices, null=True, blank=True)
place = models.CharField('摆放位置', null=True, blank=True, max_length=200)
class Meta:
unique_together = (
('operation','wproduct')
('operation', 'wproduct')
)
class OperationMaterial(BaseModel):
"""
生产操作物料消耗产出表
"""
type = models.IntegerField('类型', default=0, choices=SubprodctionMaterial.type_choices)
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE, related_name='om_operation')
material = models.ForeignKey(Material, verbose_name='可能产出的产品', on_delete=models.CASCADE,
null=True, blank=True, related_name='om_material')
type = models.IntegerField(
'类型', default=0, choices=SubprodctionMaterial.type_choices)
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE,
related_name='om_operation')
material = models.ForeignKey(Material, verbose_name='可能产出的产品', on_delete=models.CASCADE,
null=True, blank=True, related_name='om_material')
count = models.PositiveSmallIntegerField('消耗或产出数量', null=True, blank=True)
wmaterial = models.ForeignKey(WMaterial, verbose_name='关联的车间物料', on_delete=models.CASCADE, null=True, blank=True)
subproduction_progress = models.ForeignKey(SubProductionProgress, verbose_name='关联的生产进度', on_delete=models.CASCADE, null=True, blank=True)
wmaterial = models.ForeignKey(
WMaterial, verbose_name='关联的车间物料', on_delete=models.CASCADE, null=True, blank=True)
subproduction_progress = models.ForeignKey(SubProductionProgress, verbose_name='关联的生产进度', on_delete=models.CASCADE,
null=True, blank=True)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联的子计划', on_delete=models.CASCADE, null=True, blank=True)
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联的子计划', on_delete=models.CASCADE,
null=True, blank=True)
batch = models.CharField('批次号', max_length=100, null=True, blank=True)
use_scrap = models.BooleanField('是否使用的边角料', default=False)
#以下为冷加工下料清单所用字段
from_material = models.ForeignKey(Material, verbose_name='源物料', on_delete=models.CASCADE,
null=True, blank=True, related_name='om_fmaterial')
# 以下为冷加工下料清单所用字段
from_material = models.ForeignKey(Material, verbose_name='源物料', on_delete=models.CASCADE,
null=True, blank=True, related_name='om_fmaterial')
from_batch = models.CharField('源批次', max_length=100, null=True, blank=True)
count_cut = models.PositiveIntegerField('切裁片数', default=0)
count_real = models.PositiveIntegerField('生产片数', default=0)
@ -246,29 +302,38 @@ class OperationMaterial(BaseModel):
count_podian = models.PositiveIntegerField('破点甩片', default=0)
count_hua = models.PositiveIntegerField('划伤甩片', default=0)
count_other = models.PositiveIntegerField('其他甩片', default=0)
class Meta:
unique_together = (
('operation','material', 'batch')
('operation', 'material', 'batch')
)
class OperationRecord(BaseModel):
"""
记录表格
"""
form = models.ForeignKey(RecordForm, verbose_name='所用的生产记录表格', on_delete=models.CASCADE, related_name='or_form')
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE, related_name='or_operation')
form = models.ForeignKey(RecordForm, verbose_name='所用的生产记录表格',
on_delete=models.CASCADE, related_name='or_form')
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE,
related_name='or_operation')
is_filled = models.BooleanField('是否填写', default=True)
class OperationRecordItem(BaseModel):
"""
记录表格字段值
"""
form_field = models.ForeignKey(RecordFormField, verbose_name='关联字段', on_delete=models.CASCADE, related_name='ori_form_field')
form_field = models.ForeignKey(RecordFormField, verbose_name='关联字段', on_delete=models.CASCADE,
related_name='ori_form_field')
field_value = models.JSONField('录入值', null=True, blank=True)
operation_record = models.ForeignKey(OperationRecord, verbose_name='关联的生产记录', on_delete=models.CASCADE, related_name='item_operation_record')
operation_record = models.ForeignKey(OperationRecord, verbose_name='关联的生产记录', on_delete=models.CASCADE,
related_name='item_operation_record')
class OperationEquip(BaseModel):
operation = models.ForeignKey(Operation, verbose_name='关联操作', on_delete=models.CASCADE, related_name='oe_operation')
equip = models.ForeignKey(Equipment, verbose_name='生产设备', on_delete=models.CASCADE, related_name='oe_equip')
remark = models.TextField('备注', null=True, blank=True)
operation = models.ForeignKey(
Operation, verbose_name='关联操作', on_delete=models.CASCADE, related_name='oe_operation')
equip = models.ForeignKey(Equipment, verbose_name='生产设备',
on_delete=models.CASCADE, related_name='oe_equip')
remark = models.TextField('备注', null=True, blank=True)

View File

@ -69,7 +69,6 @@ class PickSerializer(serializers.Serializer):
if isLowLevel:
iproducts = i.pop('iproducts')
i['fifo'] = fifo
i['is_testok'] = True # 默认检验合格
i['subproduction_plan'] = sp
fifoitem = FIFOItem.objects.create(**i)
# 创建再下一个层级
@ -418,12 +417,12 @@ class WplanPutInSerializer(serializers.Serializer):
class WproductPutInSerializer(serializers.Serializer):
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
remark = serializers.CharField(label="入库备注", required =False)
remark = serializers.CharField(label="入库备注", required=False, allow_blank=True)
class WproductPutInsSerializer(serializers.Serializer):
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
wproducts = serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), label='半成品ID', many=True)
remark = serializers.CharField(label="入库备注", required =False)
remark = serializers.CharField(label="入库备注", required=False, allow_blank=True)
class OperationEquipListSerializer(serializers.Serializer):

View File

@ -53,6 +53,9 @@ class WpmServies(object):
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and wproduct.material.type == Material.MA_TYPE_GOOD: # 成品检验
wproduct.act_state = WProduct.WPR_ACT_STATE_TOFINALTEST
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and wproduct.step.type == Step.STEP_TYPE_COMB: # 夹层检验
wproduct.act_state = WProduct.WPR_ACT_STATE_TOCOMBTEST
else:
wproduct.act_state = WProduct.WPR_ACT_STATE_OK
if wproduct.number is None: # 产生半成品编号

File diff suppressed because it is too large Load Diff