Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
6097bcaa62
|
|
@ -19,7 +19,7 @@
|
|||
<el-input
|
||||
v-model="checkForm[item.field_key]"
|
||||
placeholder="请输入"
|
||||
@input="keyChange(item.field_key)"
|
||||
@input="keyChange($index,item.field_key)"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
v-model="checkForm[item.field_key]"
|
||||
type="number"
|
||||
placeholder="请输入"
|
||||
@input="keyChange(item.field_key)"
|
||||
@input="keyChange($index,item.field_key)"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
v-model="checkForm[item.field_key]"
|
||||
type="number"
|
||||
placeholder="请输入"
|
||||
@input="keyChange(item.field_key)"
|
||||
@input="keyChange($index,item.field_key)"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
|
|
@ -54,7 +54,7 @@
|
|||
placeholder="选择日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
style="width: 100%"
|
||||
@change="keyChange(item.field_key)"
|
||||
@change="keyChange($index,item.field_key)"
|
||||
/>
|
||||
<!--</el-date-picker>-->
|
||||
</el-form-item>
|
||||
|
|
@ -68,7 +68,7 @@
|
|||
placeholder="选择日期"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
style="width: 100%"
|
||||
@change="keyChange(item.field_key)"
|
||||
@change="keyChange($index,item.field_key)"
|
||||
/>
|
||||
<!--</el-date-picker>-->
|
||||
</el-form-item>
|
||||
|
|
@ -80,7 +80,7 @@
|
|||
v-model="checkForm[item.field_key]"
|
||||
style="width: 100%"
|
||||
placeholder="请选择"
|
||||
@change="keyChange(item.field_key)"
|
||||
@change="keyChange($index,item.field_key)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item1 in item.field_choice"
|
||||
|
|
@ -100,12 +100,14 @@
|
|||
style="width: 100%"
|
||||
multiple
|
||||
placeholder="请选择"
|
||||
@change="keyChange($index,item.field_key)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item1 in item.field_choice"
|
||||
:key="item1"
|
||||
:label="item1"
|
||||
:value="item1"
|
||||
@change="keyChange($index,item.field_key)"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
|
|
@ -135,11 +137,22 @@
|
|||
</div>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<div style="text-align: right">
|
||||
<el-button type="primary" @click="judgeForm">
|
||||
合格验证
|
||||
</el-button>
|
||||
|
||||
<el-row>
|
||||
<el-form-item label="是否合格">
|
||||
<!--<el-radio-group v-model="is_testok">
|
||||
<el-radio :label="testokTrue">检查合格</el-radio>
|
||||
<el-radio :label="testokFalse">检查不合格</el-radio>
|
||||
</el-radio-group>-->
|
||||
<el-radio v-model="is_testok" :label="testokTrue">检查合格</el-radio>
|
||||
<el-radio v-model="is_testok" :label="testokFalse">检查不合格</el-radio>
|
||||
</el-form-item>
|
||||
<div class="dialog-footer" style="text-align: right">
|
||||
<el-button @click="innerVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitfield">提交检查项目</el-button>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -159,6 +172,10 @@
|
|||
type:Number,
|
||||
default:0
|
||||
},
|
||||
wproduct: {
|
||||
type:Number,
|
||||
default:0
|
||||
},
|
||||
hasPicture:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
|
|
@ -167,24 +184,28 @@
|
|||
mounted() {
|
||||
let that = this;
|
||||
this.form = this.formID;
|
||||
// debugger;
|
||||
// console.log(this.results);
|
||||
this.formData=this.results;
|
||||
this.formData=[...this.formData];
|
||||
let formData=this.results;
|
||||
that.wproductId=this.wproduct;
|
||||
formData.forEach(item => {
|
||||
let obj = new Object();
|
||||
obj = item;
|
||||
obj.is_testok = true;//是否合格
|
||||
that.formData.push(obj)
|
||||
});
|
||||
that.formData=[...that.formData];
|
||||
|
||||
for(let i=0;i<this.results.length;i++){
|
||||
let key = this.results[i].field_key;
|
||||
//checkForm接收表单数据的对象
|
||||
that.checkForm[key]='';
|
||||
that.$set(that.checkForm,key,'')
|
||||
}
|
||||
// debugger;
|
||||
// console.log(that.checkForm);
|
||||
let listJudge = this.formData.filter(item => {
|
||||
return item.need_judge === true;
|
||||
});
|
||||
listJudge.forEach(item => {
|
||||
let obj = new Object();
|
||||
obj = item;
|
||||
obj.judge = false;
|
||||
that.judgeList.push(obj)
|
||||
});
|
||||
setTimeout(function(){
|
||||
|
|
@ -193,8 +214,16 @@
|
|||
},
|
||||
data(){
|
||||
return{
|
||||
field:[],
|
||||
checkForm:{},
|
||||
testrecord:{
|
||||
form:this.formID,
|
||||
record_data:[],
|
||||
is_testok:true,
|
||||
wproduct:null,
|
||||
},
|
||||
canvas:null,
|
||||
wproductId:null,
|
||||
ctx:null,
|
||||
myCanvas_rect:null,
|
||||
Txt:null,
|
||||
|
|
@ -207,6 +236,9 @@
|
|||
canvasImg:'',
|
||||
formData:[],//表单数组
|
||||
judgeList:[],//判定数组
|
||||
is_testok:true,
|
||||
testokTrue:true,
|
||||
testokFalse:false,
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
|
|
@ -276,15 +308,63 @@
|
|||
return true;
|
||||
}
|
||||
},
|
||||
keyChange(key){
|
||||
key;
|
||||
this.$forceUpdate();
|
||||
/* debugger;
|
||||
let y = this.checkForm[key];
|
||||
this.$set(this.checkForm,key,y);*/
|
||||
// this.filterBlock();
|
||||
keyChange(index,key){
|
||||
let that = this;
|
||||
let reg = /\{(.+?)\}/g;
|
||||
that.$forceUpdate();
|
||||
that.$nextTick(()=>{
|
||||
if(that.formData[index].need_judge===true){
|
||||
let arr = [],str = '';
|
||||
let item = that.formData[index].rule_expression.replace(/`/g,'');
|
||||
if(item.indexOf('||')>-1){
|
||||
arr = item.split('||');
|
||||
}else if(item.indexOf('&&')>-1){
|
||||
arr = item.split('&&');
|
||||
}else{
|
||||
arr.push(item);
|
||||
}
|
||||
//对每个条件进行判定,如果符合,
|
||||
for (let i = 0;i<arr.length;i++){
|
||||
//获取判断依据
|
||||
let a = '`'+ arr[i]+'`';
|
||||
let tem =a.match(reg)[0];
|
||||
let ky = tem.replace(/\{|\}/g, '');//qipao
|
||||
//有值时进行判断
|
||||
if(that.checkForm[ky]!==''&&that.checkForm[ky]!==null&&that.checkForm[ky]!==undefined){
|
||||
//替换变量
|
||||
a = a.replace(ky, 'yyy');
|
||||
let yyy = "'"+that.checkForm[ky]+"'";
|
||||
if(eval(eval( a))){
|
||||
str += 'true';
|
||||
}else{
|
||||
str += 'false';
|
||||
}
|
||||
}
|
||||
}
|
||||
if(item.indexOf('&&')>-1){
|
||||
if(str.indexOf('false')>-1){
|
||||
that.formData[index].is_testok = true;
|
||||
}else{
|
||||
that.formData[index].is_testok = false;
|
||||
}
|
||||
}else{
|
||||
if(str.indexOf('true')>-1){
|
||||
that.formData[index].is_testok = false;
|
||||
}else{
|
||||
that.formData[index].is_testok = true;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
that.formData[index].is_testok = true;
|
||||
}
|
||||
that.judgeList = that.formData.filter(item => {
|
||||
return item.need_judge === true;
|
||||
});
|
||||
that.judgeForm();
|
||||
})
|
||||
},
|
||||
/* base64ToFile */
|
||||
/* 图片保存 */
|
||||
//初始化canvas
|
||||
canvasInit(){
|
||||
let that = this;
|
||||
preDrawAry = [];
|
||||
|
|
@ -299,6 +379,7 @@
|
|||
that.draw();
|
||||
},500);
|
||||
},
|
||||
//画布添加背景模板图
|
||||
draw(){
|
||||
let canvasImg = document.getElementById("canvasImg");
|
||||
canvasImg.style.width = '500px';
|
||||
|
|
@ -360,7 +441,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 文字
|
||||
word1(){
|
||||
let canvas3 = document.getElementById('canvas');
|
||||
|
|
@ -462,6 +542,7 @@
|
|||
// console.log(res);
|
||||
})
|
||||
},
|
||||
//base64ToFile
|
||||
base64ToFile(baseUrl) {
|
||||
let arr = baseUrl.split(',');
|
||||
// let type = arr[0].match(/:(.*?);/)[1]; // 解锁图片类型
|
||||
|
|
@ -474,7 +555,8 @@
|
|||
// let fileOfBlob = new File([bufferArray], new Date()+'.jpg');
|
||||
return new File([bufferArray ],'draw.jpg');
|
||||
},
|
||||
/* base64ToFile */
|
||||
/* 图片保存 */
|
||||
//最终表格判定
|
||||
judgeForm(){
|
||||
let that = this ,
|
||||
reg = /\{(.+?)\}/g,
|
||||
|
|
@ -508,21 +590,56 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
if(str.indexOf('true')>-1){
|
||||
that.judgeList[i].judge = true;
|
||||
if(item.indexOf('&&')>-1){
|
||||
if(str.indexOf('false')>-1){
|
||||
that.judgeList[i].is_testok = true;
|
||||
}else{
|
||||
that.judgeList[i].judge = false;
|
||||
that.judgeList[i].is_testok = false;
|
||||
}
|
||||
}else{
|
||||
if(str.indexOf('true')>-1){
|
||||
that.judgeList[i].is_testok = false;
|
||||
}else{
|
||||
that.judgeList[i].is_testok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
let real = that.judgeList.filter(item=>{
|
||||
return item.judge==true;
|
||||
return item.is_testok===false;
|
||||
});
|
||||
if(real.length>0){
|
||||
that.is_testok = false;
|
||||
alert("检验不合格!")
|
||||
}else{
|
||||
that.is_testok = true;
|
||||
alert("检验合格!")
|
||||
}
|
||||
},
|
||||
//提交检查项目
|
||||
submitfield() {
|
||||
let that = this;
|
||||
debugger;
|
||||
console.log(that.checkForm);
|
||||
debugger;
|
||||
that.field = []; //检查项目
|
||||
that.formData.forEach((item) => {
|
||||
debugger;
|
||||
console.log(that.checkForm[item.field_key]);
|
||||
debugger;
|
||||
that.field.push({
|
||||
form_field: item.id,
|
||||
field_value: that.checkForm[item.field_key],
|
||||
is_testok: item.is_testok//单项检查结果
|
||||
});
|
||||
});
|
||||
console.log(that.field);
|
||||
debugger;
|
||||
that.testrecord.form = that.formID;//检查表
|
||||
that.testrecord.record_data = that.field;//检查项列表
|
||||
that.testrecord.is_testok = that.is_testok;//检查表检查结果
|
||||
that.testrecord.wproduct = that.wproductId;//半成品ID
|
||||
this.$emit('formFunc',that.testrecord);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@
|
|||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
@click="handleInspection(scope)"
|
||||
>检验</el-link
|
||||
>检验
|
||||
</el-link
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
|
@ -77,13 +78,13 @@
|
|||
<el-table-column label="所在子工序">
|
||||
<template slot-scope="scope">{{ scope.row.step_.name }}</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column align="center" label="操作" width="220px">
|
||||
<template slot-scope="scope">
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
@click="handleInspection(scope)"
|
||||
>检验</el-link
|
||||
>检验
|
||||
</el-link
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
|
@ -100,7 +101,8 @@
|
|||
<el-tab-pane label="已合格半成品">
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||
>批量入库</el-button
|
||||
>批量入库
|
||||
</el-button
|
||||
>
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
|
|
@ -140,7 +142,8 @@
|
|||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
@click="handlePutin(scope)"
|
||||
>入库</el-link
|
||||
>入库
|
||||
</el-link
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
|
@ -157,7 +160,7 @@
|
|||
</el-tabs>
|
||||
|
||||
<el-dialog title="物料检查表" :close-on-click-modal="false" :visible.sync="outerVisible">
|
||||
<el-select style="width: 100%" v-model="recordform" placeholder="请选择">
|
||||
<el-select style="width: 100%" v-model="recordform" placeholder="请选择" @change="recordformChange">
|
||||
<el-option
|
||||
v-for="item in recordformList"
|
||||
:key="item.id"
|
||||
|
|
@ -169,146 +172,21 @@
|
|||
|
||||
<el-dialog
|
||||
width="50%"
|
||||
title="检查项目"
|
||||
:title="formName"
|
||||
:visible.sync="innerVisible"
|
||||
append-to-body
|
||||
>
|
||||
<el-form label-width="100px" label-position="right">
|
||||
<el-row
|
||||
:gutter="2"
|
||||
v-for="(item, $index) in fieldList"
|
||||
:key="$index"
|
||||
>
|
||||
<el-col :span="12">
|
||||
<el-form-item
|
||||
v-if="item.field_type === 'string'"
|
||||
:label="item.field_name"
|
||||
>
|
||||
<el-input placeholder="请输入" v-model="item.sort" />
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-else-if="item.field_type === 'int'"
|
||||
:label="item.field_name"
|
||||
>
|
||||
<el-input
|
||||
width="120"
|
||||
type="number"
|
||||
placeholder="请输入"
|
||||
v-model="item.sort"
|
||||
<customForm
|
||||
:results="fieldList"
|
||||
:hasPicture="hasPicture"
|
||||
:formID="recordform"
|
||||
:wproduct="wproduct"
|
||||
@formFunc="formFunc"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-else-if="item.field_type === 'float'"
|
||||
:label="item.field_name"
|
||||
>
|
||||
<el-input
|
||||
type="number"
|
||||
placeholder="请输入"
|
||||
v-model="item.sort"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-else-if="item.field_type === 'date'"
|
||||
:label="item.field_name"
|
||||
>
|
||||
<el-date-picker
|
||||
v-model="item.create_time"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
value-format="yyyy-MM-dd"
|
||||
style="width: 100%"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-else-if="item.field_type === 'datetime'"
|
||||
:label="item.field_name"
|
||||
>
|
||||
<el-date-picker
|
||||
v-model="item.create_time"
|
||||
type="datetime"
|
||||
placeholder="选择日期"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
style="width: 100%"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-else-if="item.field_type === 'select'"
|
||||
:label="item.field_name"
|
||||
>
|
||||
<el-select
|
||||
style="width: 100%"
|
||||
v-model="item.sort"
|
||||
placeholder="请选择"
|
||||
>
|
||||
<el-option
|
||||
v-for="item1 in item.field_choice"
|
||||
:key="item1"
|
||||
:label="item1"
|
||||
:value="item1"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-else-if="item.field_type === 'selects'"
|
||||
:label="item.field_name"
|
||||
>
|
||||
<el-select
|
||||
style="width: 100%"
|
||||
v-model="optio"
|
||||
multiple
|
||||
placeholder="请选择"
|
||||
>
|
||||
<el-option
|
||||
v-for="item1 in item.field_choice"
|
||||
:key="item1"
|
||||
:label="item1"
|
||||
:value="item1"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="是否检验合格" width="50px">
|
||||
<el-select
|
||||
style="width: 100%"
|
||||
v-model="item.is_testok"
|
||||
placeholder="请选择"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in choice"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-form-item label="是否合格" prop="sort_str">
|
||||
<el-radio v-model="is_testok" label="true">检查合格</el-radio>
|
||||
<el-radio v-model="is_testok" label="false">检查不合格</el-radio>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="innerVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitfield"
|
||||
>提交检查项目</el-button
|
||||
>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="outerVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="submitrecordform"
|
||||
>填写检查项目</el-button
|
||||
>
|
||||
<el-button type="primary" @click="submitrecordform">填写检查项目</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<el-dialog title="半成品入库" :close-on-click-modal="false" :visible.sync="dialogFormVisible">
|
||||
|
|
@ -368,6 +246,7 @@
|
|||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import customForm from '@/components/customForm/index';
|
||||
import {getwproductList, wproductTest, wproductPutin, createputins} from "@/api/wpm";
|
||||
import checkPermission from "@/utils/permission";
|
||||
import {getWarehouseList} from "@/api/inm";
|
||||
|
|
@ -376,7 +255,7 @@ import { genTree } from "@/utils";
|
|||
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||
const defaultetestitem = {};
|
||||
export default {
|
||||
components: { Pagination },
|
||||
components: {Pagination, customForm},
|
||||
data() {
|
||||
return {
|
||||
testitem: defaultetestitem,
|
||||
|
|
@ -402,6 +281,8 @@ export default {
|
|||
page: 1,
|
||||
page_size: 20,
|
||||
},
|
||||
formLabelWidth:'',
|
||||
formLabelWidthL:'',
|
||||
actstate_: {
|
||||
6: "待复检",
|
||||
10: "生产中",
|
||||
|
|
@ -433,12 +314,15 @@ export default {
|
|||
page: 0,
|
||||
},
|
||||
mutipID: [],
|
||||
wproduct:null,
|
||||
hasPicture: false,
|
||||
outerVisible: false,
|
||||
innerVisible: false,
|
||||
dialogFormVisible: false,
|
||||
dialogFormVisibles: false,
|
||||
testrecord: {},
|
||||
WarehouseData: "",
|
||||
formName:'项目检查表',
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
|
|
@ -447,7 +331,7 @@ export default {
|
|||
this.getList();
|
||||
this.getList2();
|
||||
this.getList1();
|
||||
this.getLists();
|
||||
// this.getLists();
|
||||
},
|
||||
methods: {
|
||||
checkPermission,
|
||||
|
|
@ -503,7 +387,11 @@ export default {
|
|||
});
|
||||
console.log(_this.mutipID);
|
||||
|
||||
createputins({warehouse:this.form.warehouse,wproducts: _this.mutipID,remark:this.form.remark}).then((res) => {
|
||||
createputins({
|
||||
warehouse: this.form.warehouse,
|
||||
wproducts: _this.mutipID,
|
||||
remark: this.form.remark
|
||||
}).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
this.$message.success("批量入库成功!");
|
||||
this.dialogFormVisibles = false;
|
||||
|
|
@ -513,12 +401,10 @@ export default {
|
|||
},
|
||||
//仓库列表
|
||||
getWarehouseLists() {
|
||||
|
||||
getWarehouseList({page: 0}).then((response) => {
|
||||
if (response.data) {
|
||||
this.WarehouseData = response.data;
|
||||
}
|
||||
|
||||
});
|
||||
},
|
||||
handleInspection(scope) {
|
||||
|
|
@ -535,13 +421,29 @@ export default {
|
|||
}
|
||||
});
|
||||
},
|
||||
recordformChange(){
|
||||
let that = this;
|
||||
let arr = this.recordformList.filter(item=>{
|
||||
return item.id=that.recordform;
|
||||
})
|
||||
that.formName = arr[0].name;
|
||||
},
|
||||
//根据选择的表,渲染检查项目
|
||||
submitrecordform() {
|
||||
let that = this;
|
||||
if (this.recordform != "") {
|
||||
getrffieldList({ form: this.recordform, page: 0 }).then((response) => {
|
||||
getrffieldList({form: this.recordform, page: 1, page_size: 100}).then((response) => {
|
||||
if (response.data) {
|
||||
this.fieldList = response.data;
|
||||
this.innerVisible = true;
|
||||
that.hasPicture = false;
|
||||
let fieldList = response.data.results;
|
||||
that.fieldList = [...fieldList];
|
||||
let arr = fieldList.filter(item => {
|
||||
return item.field_type === 'draw'
|
||||
});
|
||||
if (arr.length > 0) {
|
||||
that.hasPicture = true;
|
||||
}
|
||||
that.innerVisible = true;
|
||||
}
|
||||
});
|
||||
} else this.$message.error("请选择检查表!");
|
||||
|
|
@ -566,7 +468,6 @@ export default {
|
|||
this.testrecord.wproduct = this.wproduct;//半成品ID
|
||||
|
||||
|
||||
|
||||
wproductTest(this.testrecord).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
this.innerVisible = false;
|
||||
|
|
@ -578,8 +479,6 @@ export default {
|
|||
});
|
||||
|
||||
|
||||
|
||||
|
||||
},
|
||||
//半成品入库
|
||||
handlePutin(scope) {
|
||||
|
|
@ -595,7 +494,18 @@ export default {
|
|||
this.getList1();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
formFunc(value) {
|
||||
wproductTest(value).then((res) => {
|
||||
if (res.code >= 200) {
|
||||
this.innerVisible = false;
|
||||
this.outerVisible = false;
|
||||
this.getList();
|
||||
this.getList1();
|
||||
this.getList2();
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,17 @@
|
|||
from django_filters import rest_framework as filters
|
||||
|
||||
from apps.mtm.models import Material
|
||||
from .models import MaterialBatch
|
||||
from .models import IProduct, MaterialBatch
|
||||
class MbFilterSet(filters.FilterSet):
|
||||
material = filters.ModelMultipleChoiceFilter(field_name="material", queryset=Material.objects.all())
|
||||
class Meta:
|
||||
model = MaterialBatch
|
||||
fields = ['material', 'warehouse']
|
||||
|
||||
|
||||
class IProductFilterSet(filters.FilterSet):
|
||||
|
||||
order = filters.NumberFilter(field_name="wproduct__subproduction_plan__production_plan__order")
|
||||
class Meta:
|
||||
model = IProduct
|
||||
fields = ['material', 'warehouse', 'batch', 'order']
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-06 01:58
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inm', '0019_auto_20211201_1011'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='iproduct',
|
||||
name='is_saled',
|
||||
field=models.BooleanField(default=False, verbose_name='是否售出'),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-07 00:42
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inm', '0020_iproduct_is_saled'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='fifoitemproduct',
|
||||
name='iproduct',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='inm.iproduct', verbose_name='关联库存产品'),
|
||||
),
|
||||
]
|
||||
|
|
@ -84,15 +84,6 @@ class FIFOItem(BaseModel):
|
|||
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)
|
||||
|
||||
class FIFOItemProduct(BaseModel):
|
||||
"""
|
||||
出入库产品
|
||||
"""
|
||||
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)
|
||||
number = models.CharField('物品编号', max_length=50)
|
||||
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||
|
||||
class IProduct(BaseModel):
|
||||
"""
|
||||
具体产品条目
|
||||
|
|
@ -102,5 +93,18 @@ class IProduct(BaseModel):
|
|||
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)
|
||||
is_saled = models.BooleanField('是否售出', default=False)
|
||||
|
||||
class FIFOItemProduct(BaseModel):
|
||||
"""
|
||||
出入库产品
|
||||
"""
|
||||
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)
|
||||
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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ def update_inm(instance:FIFO, type:int=1):
|
|||
ips2.append(IProduct(**ip))
|
||||
IProduct.objects.bulk_create(ips2)
|
||||
|
||||
elif instance.type in [FIFO.FIFO_TYPE_DO_OUT]: # 生产领料
|
||||
elif instance.type in [FIFO.FIFO_TYPE_DO_OUT, FIFO.FIFO_TYPE_SALE_OUT]: # 生产领料 销售出库
|
||||
# 更新相关表
|
||||
for i in FIFOItem.objects.filter(fifo=instance):
|
||||
material = i.material
|
||||
|
|
@ -51,6 +51,7 @@ def update_inm(instance:FIFO, type:int=1):
|
|||
material.save()
|
||||
|
||||
# 删除IProduct
|
||||
if instance.type == FIFO.FIFO_TYPE_DO_OUT:
|
||||
numbers = FIFOItemProduct.objects.filter(fifoitem=i).values_list('number', flat=True)
|
||||
IProduct.objects.filter(number__in=numbers).delete()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ from rest_framework import serializers
|
|||
from rest_framework.exceptions import APIException
|
||||
from rest_framework.mixins import DestroyModelMixin, ListModelMixin, RetrieveModelMixin
|
||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||
from apps.inm.filters import MbFilterSet
|
||||
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
|
||||
|
|
@ -167,9 +167,9 @@ class IProductViewSet(ListModelMixin, GenericViewSet):
|
|||
半成品库存表
|
||||
"""
|
||||
perms_map = {'*': '*'}
|
||||
queryset = IProduct.objects.select_related('material', 'warehouse').all()
|
||||
queryset = IProduct.objects.select_related('material', 'warehouse', 'wproduct__subproduction_plan__production_plan__order').filter(is_saled=False)
|
||||
serializer_class = IProductListSerializer
|
||||
filterset_fields = ['material', 'warehouse', 'batch']
|
||||
filterset_class = IProductFilterSet
|
||||
search_fields = []
|
||||
ordering_fields = ['create_time']
|
||||
ordering = ['-create_time']
|
||||
|
|
@ -209,13 +209,13 @@ class RecordFormDetailSerializer(serializers.ModelSerializer):
|
|||
|
||||
def get_form_fields(self, obj):
|
||||
serializer = RecordFormFieldSerializer(instance=RecordFormField.objects.filter(form=obj, is_deleted=False), many=True)
|
||||
vdata = serializer.data
|
||||
data = serializer.data
|
||||
if obj.type == RecordForm.RF_TYPE_TEST:
|
||||
for i in vdata:
|
||||
for i in data:
|
||||
if i['need_judge']:
|
||||
i['is_testok'] = False
|
||||
i['is_teskok_robot'] = False
|
||||
return serializer.data
|
||||
return data
|
||||
|
||||
|
||||
class RecordFormFieldCreateSerializer(serializers.ModelSerializer):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-03 07:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('sam', '0004_order_planed_count'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='order',
|
||||
name='delivered_count',
|
||||
field=models.PositiveIntegerField(default=0, verbose_name='交货数量'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='order',
|
||||
name='count',
|
||||
field=models.PositiveIntegerField(default=0, verbose_name='所需数量'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='order',
|
||||
name='planed_count',
|
||||
field=models.PositiveIntegerField(default=0, verbose_name='已排数量'),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-06 01:58
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('inm', '0020_iproduct_is_saled'),
|
||||
('mtm', '0041_alter_material_type'),
|
||||
('sam', '0005_auto_20211203_1501'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='order',
|
||||
name='delivered_count',
|
||||
field=models.PositiveIntegerField(default=0, verbose_name='已交货数量'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='order',
|
||||
name='number',
|
||||
field=models.CharField(max_length=100, unique=True, verbose_name='订单编号'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Sale',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||
('count', models.PositiveIntegerField(default=0, verbose_name='交货数量')),
|
||||
('is_audited', models.BooleanField(default=False, verbose_name='是否审核')),
|
||||
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sale_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||
('customer', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sam.customer', verbose_name='客户')),
|
||||
('order', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sam.order', verbose_name='关联订单')),
|
||||
('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='所需产品')),
|
||||
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sale_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='SaleProduct',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||
('number', models.CharField(max_length=50, unique=True, verbose_name='物品编号')),
|
||||
('is_mtested', models.BooleanField(default=False, verbose_name='是否军检')),
|
||||
('is_mtestok', models.BooleanField(default=True, verbose_name='是否军检合格')),
|
||||
('iproduct', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sale_iproduct', to='inm.iproduct', verbose_name='关联库存产品')),
|
||||
('sale', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sam.sale', verbose_name='关联销售记录')),
|
||||
],
|
||||
options={
|
||||
'unique_together': {('sale', 'iproduct')},
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-06 05:26
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('sam', '0006_auto_20211206_0958'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='saleproduct',
|
||||
name='remark',
|
||||
field=models.TextField(blank=True, null=True, verbose_name='备注'),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-06 06:15
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('sam', '0007_saleproduct_remark'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='saleproduct',
|
||||
name='number',
|
||||
field=models.CharField(max_length=50, verbose_name='物品编号'),
|
||||
),
|
||||
]
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-07 00:42
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('sam', '0008_alter_saleproduct_number'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='saleproduct',
|
||||
name='is_mtestok',
|
||||
field=models.BooleanField(blank=True, null=True, verbose_name='是否军检合格'),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
from apps.system.models import CommonAModel
|
||||
from apps.system.models import CommonADModel, CommonAModel
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.db.models.base import Model
|
||||
|
|
@ -58,16 +58,45 @@ class Order(CommonAModel):
|
|||
"""
|
||||
订单信息
|
||||
"""
|
||||
number = models.CharField('订单编号', max_length=100)
|
||||
number = models.CharField('订单编号', max_length=100, unique=True)
|
||||
customer = models.ForeignKey(Customer, verbose_name='客户', on_delete=models.CASCADE)
|
||||
contract = models.ForeignKey(Contract, verbose_name='所属合同', null=True, blank=True, on_delete=models.SET_NULL)
|
||||
product = models.ForeignKey(Material, verbose_name='所需产品', on_delete=models.CASCADE)
|
||||
count = models.IntegerField('所需数量', default=0)
|
||||
planed_count = models.IntegerField('已排数量', default=0)
|
||||
count = models.PositiveIntegerField('所需数量', default=0)
|
||||
planed_count = models.PositiveIntegerField('已排数量', default=0)
|
||||
delivered_count = models.PositiveIntegerField('已交货数量', default=0)
|
||||
delivery_date = models.DateField('交货日期')
|
||||
class Meta:
|
||||
verbose_name = '订单信息'
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Sale(CommonADModel):
|
||||
"""
|
||||
销售记录
|
||||
"""
|
||||
customer = models.ForeignKey(Customer, verbose_name='客户', on_delete=models.CASCADE)
|
||||
order = models.ForeignKey(Order, verbose_name='关联订单', on_delete=models.CASCADE, null=True, blank=True)
|
||||
product = models.ForeignKey(Material, verbose_name='所需产品', on_delete=models.CASCADE)
|
||||
count = models.PositiveIntegerField('交货数量', default=0)
|
||||
is_audited = models.BooleanField('是否审核', default=False)
|
||||
|
||||
|
||||
class SaleProduct(BaseModel):
|
||||
"""
|
||||
具体产品
|
||||
"""
|
||||
sale = models.ForeignKey(Sale, verbose_name='关联销售记录', on_delete=models.CASCADE)
|
||||
number = models.CharField('物品编号', max_length=50)
|
||||
iproduct = models.ForeignKey('inm.iproduct', verbose_name='关联库存产品', on_delete=models.CASCADE, related_name='sale_iproduct')
|
||||
is_mtested = models.BooleanField('是否军检', default=False)
|
||||
is_mtestok = models.BooleanField('是否军检合格', null=True, blank=True)
|
||||
remark = models.TextField('备注', null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
unique_together = (
|
||||
('sale','iproduct'), # 联合唯一
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
from rest_framework import serializers
|
||||
from django.db import transaction
|
||||
from rest_framework import exceptions, serializers
|
||||
|
||||
from .models import Contract, Customer, Order
|
||||
from apps.inm.models import IProduct
|
||||
from apps.inm.serializers import IProductListSerializer
|
||||
|
||||
from .models import Contract, Customer, Order, Sale, SaleProduct
|
||||
|
||||
from apps.mtm.serializers import MaterialSimpleSerializer
|
||||
|
||||
|
|
@ -54,3 +58,52 @@ class OrderSimpleSerializer(serializers.ModelSerializer):
|
|||
class Meta:
|
||||
model = Order
|
||||
fields = '__all__'
|
||||
|
||||
class SaleCreateSerializer(serializers.ModelSerializer):
|
||||
iproducts = serializers.PrimaryKeyRelatedField(queryset=IProduct.objects.all(), many=True)
|
||||
class Meta:
|
||||
model = Sale
|
||||
fields = ['customer', 'order', 'product', 'iproducts']
|
||||
|
||||
def validate(self, attrs):
|
||||
order = attrs.get('order', None)
|
||||
if order:
|
||||
if order.customer:
|
||||
attrs['customer'] = order.customer
|
||||
attrs['product'] = order.product
|
||||
for i in attrs['iproducts']:
|
||||
if i.material is not attrs['product']:
|
||||
raise exceptions.APIException('产品选取错误')
|
||||
return super().validate(attrs)
|
||||
|
||||
|
||||
class SaleListSerializer(serializers.ModelSerializer):
|
||||
customer_ = CustomerSimpleSerializer(source='customer', read_only=True)
|
||||
order_ = OrderSimpleSerializer(source='order', read_only=True)
|
||||
product_ = MaterialSimpleSerializer(source='product', read_only=True)
|
||||
class Meta:
|
||||
model = Sale
|
||||
fields = '__all__'
|
||||
|
||||
class SaleProductListSerializer(serializers.ModelSerializer):
|
||||
iproduct_ = IProductListSerializer(source='iproduct', read_only=True)
|
||||
class Meta:
|
||||
model = SaleProduct
|
||||
fields = '__all__'
|
||||
|
||||
class SaleProductCreateSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = SaleProduct
|
||||
fields = ['sale', 'iproduct']
|
||||
|
||||
def create(self, validated_data):
|
||||
validated_data['number'] = validated_data['iproduct'].number
|
||||
instance = SaleProduct.objects.create(**validated_data)
|
||||
instance.sale.count = SaleProduct.objects.filter(sale=instance.sale).count()
|
||||
instance.sale.save()
|
||||
return instance
|
||||
|
||||
class SaleProductMtestSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = SaleProduct
|
||||
fields = ['remark', 'is_mtestok']
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
from django.db.models import base
|
||||
from rest_framework import urlpatterns
|
||||
from apps.sam.views import CustomerViewSet,ContractViewSet,OrderViewSet
|
||||
from apps.sam.views import CustomerViewSet,ContractViewSet,OrderViewSet, SaleProductViewSet, SaleViewSet
|
||||
from django.urls import path, include
|
||||
from rest_framework.routers import DefaultRouter
|
||||
|
||||
|
|
@ -8,6 +8,8 @@ router = DefaultRouter()
|
|||
router.register('customer', CustomerViewSet, basename='customer')
|
||||
router.register('contract', ContractViewSet, basename='contract')
|
||||
router.register('order', OrderViewSet, basename='order')
|
||||
router.register('sale', SaleViewSet, basename='sale')
|
||||
router.register('sale_product', SaleProductViewSet, basename='sale_product')
|
||||
|
||||
urlpatterns = [
|
||||
path('', include(router.urls)),
|
||||
|
|
|
|||
|
|
@ -1,11 +1,19 @@
|
|||
from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer
|
||||
from apps.sam.models import Contract, Customer, Order
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
from django.db import transaction
|
||||
from django.db.models.aggregates import Count
|
||||
from rest_framework import exceptions, serializers
|
||||
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin
|
||||
from apps.mtm.models import Material
|
||||
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, WareHouse
|
||||
from apps.inm.signals import update_inm
|
||||
from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer, SaleProductMtestSerializer
|
||||
from apps.sam.models import Contract, Customer, Order, Sale, SaleProduct
|
||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||
from apps.system.mixins import CreateUpdateCustomMixin
|
||||
from django.shortcuts import render
|
||||
from rest_framework.decorators import action
|
||||
from django.db.models import F
|
||||
from rest_framework.response import Response
|
||||
from django.utils import timezone
|
||||
# Create your views here.
|
||||
class CustomerViewSet(CreateUpdateCustomMixin, ModelViewSet):
|
||||
"""
|
||||
|
|
@ -57,7 +65,7 @@ class OrderViewSet(CreateUpdateCustomMixin, ModelViewSet):
|
|||
def get_serializer_class(self):
|
||||
if self.action in ['create', 'update']:
|
||||
return OrderCreateUpdateSerializer
|
||||
return OrderSerializer
|
||||
return super().get_serializer_class()
|
||||
|
||||
@action(methods=['get'], detail=False, perms_map={'get':'*'})
|
||||
def toplan(self, request, pk=None):
|
||||
|
|
@ -68,3 +76,144 @@ class OrderViewSet(CreateUpdateCustomMixin, ModelViewSet):
|
|||
return self.get_paginated_response(serializer.data)
|
||||
serializer = self.get_serializer(queryset, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, CreateModelMixin, DestroyModelMixin, GenericViewSet):
|
||||
"""
|
||||
销售记录
|
||||
"""
|
||||
perms_map = {'*': '*'}
|
||||
queryset = Sale.objects.select_related('customer', 'order', 'product', 'order__contract').all()
|
||||
serializer_class = SaleListSerializer
|
||||
search_fields = ['customer__name', 'order__number']
|
||||
filterset_fields = ['product', 'order', 'customer']
|
||||
ordering_fields = ['create_time']
|
||||
ordering = ['-create_time']
|
||||
|
||||
def get_serializer_class(self):
|
||||
if self.action == 'create':
|
||||
return SaleCreateSerializer
|
||||
elif self.action == 'retrieve':
|
||||
return SaleListSerializer
|
||||
return super().get_serializer_class()
|
||||
|
||||
def create(self, request, *args, **kwargs):
|
||||
data = request.data
|
||||
serializer = SaleCreateSerializer(data=data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.validated_data
|
||||
with transaction.atomic():
|
||||
iproducts = vdata.pop('iproducts')
|
||||
vdata['count'] = len(iproducts)
|
||||
sale = Sale.objects.create(**vdata)
|
||||
i_l = []
|
||||
for i in iproducts:
|
||||
i_d ={}
|
||||
i_d['sale'] = sale
|
||||
i_d['number'] = i.number
|
||||
i_d['iproduct'] = i
|
||||
i_l.append(SaleProduct(**i_d))
|
||||
SaleProduct.objects.bulk_create(i_l)
|
||||
return Response()
|
||||
|
||||
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer)
|
||||
@transaction.atomic
|
||||
def audit(self, request, pk=None):
|
||||
"""
|
||||
审核
|
||||
"""
|
||||
obj = self.get_object()
|
||||
if obj.is_audited:
|
||||
raise exceptions.APIException('已审核通过')
|
||||
# 创建出库记录
|
||||
fifo = FIFO()
|
||||
fifo.type = FIFO.FIFO_TYPE_SALE_OUT
|
||||
fifo.is_audited = True
|
||||
fifo.auditor = request.user
|
||||
fifo.inout_date = timezone.now()
|
||||
fifo.create_by = request.user
|
||||
fifo.save()
|
||||
# 出库条目
|
||||
spds = SaleProduct.objects.filter(sale=obj)
|
||||
for i in spds:
|
||||
if i.is_mtested and i.is_mtestok:
|
||||
pass
|
||||
else:
|
||||
raise exceptions.APIException('存在未军检产品')
|
||||
# 创建出库条目
|
||||
ips = IProduct.objects.filter(sale_iproduct__sale=obj)
|
||||
items = ips.values('warehouse', 'material', 'batch').annotate(total=Count('id'))
|
||||
for i in items:
|
||||
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.warehouse = warehouse
|
||||
fifoitem.material = material
|
||||
fifoitem.count = i['total']
|
||||
fifoitem.batch = i['batch']
|
||||
fifoitem.fifo = fifo
|
||||
fifoitem.save()
|
||||
items_p = ips.filter(warehouse=warehouse, batch=i['batch'])
|
||||
ipxs = []
|
||||
for i in items_p:
|
||||
# 创建出库明细半成品
|
||||
ip = {}
|
||||
ip['fifoitem'] = fifoitem
|
||||
ip['number'] = i.number
|
||||
ip['material'] = i.material
|
||||
ip['iproduct'] = i
|
||||
ipxs.append(FIFOItemProduct(**ip))
|
||||
FIFOItemProduct.objects.bulk_create(ipxs)
|
||||
# 更新成品库情况
|
||||
ips.update(is_saled=True)
|
||||
# 更新库存
|
||||
update_inm(fifo)
|
||||
# 变更审核状态
|
||||
obj.is_audited = True
|
||||
obj.save()
|
||||
# 变更订单状态
|
||||
if obj.order:
|
||||
order = obj.order
|
||||
order.delivered_count = order.delivered_count + obj.count
|
||||
order.save()
|
||||
return Response()
|
||||
|
||||
class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, GenericViewSet):
|
||||
"""
|
||||
销售记录关联产品
|
||||
"""
|
||||
perms_map = {'*': '*'}
|
||||
queryset = SaleProduct.objects.select_related('iproduct', 'iproduct__material', 'iproduct__warehouse').all()
|
||||
serializer_class = SaleProductListSerializer
|
||||
search_fields = []
|
||||
filterset_fields = ['sale', 'iproduct']
|
||||
ordering_fields = ['create_time']
|
||||
ordering = ['id']
|
||||
|
||||
def get_serializer_class(self):
|
||||
if self.action == 'create':
|
||||
return SaleProductCreateSerializer
|
||||
return super().get_serializer_class()
|
||||
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
obj = self.get_object()
|
||||
obj.sale.count = SaleProduct.objects.filter(sale=obj.sale).count()
|
||||
obj.sale.save()
|
||||
obj.delete()
|
||||
return Response()
|
||||
|
||||
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=SaleProductMtestSerializer)
|
||||
def mtest(self, request, pk=None):
|
||||
"""
|
||||
军检
|
||||
"""
|
||||
obj = self.get_object()
|
||||
if obj.is_mtested:
|
||||
raise exceptions.APIException('已进行军检')
|
||||
obj.remark = request.data.get('remark', None)
|
||||
obj.is_mtested = True
|
||||
obj.is_mtestok = request.data.get('is_mtestok')
|
||||
obj.save()
|
||||
return Response()
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-03 07:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wf', '0016_auto_20211024_2349'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='customfield',
|
||||
name='field_type',
|
||||
field=models.CharField(choices=[('string', '字符串'), ('int', '整型'), ('float', '浮点'), ('boolean', '布尔'), ('date', '日期'), ('datetime', '日期时间'), ('radio', '单选'), ('checkbox', '多选'), ('select', '单选下拉'), ('selects', '多选下拉'), ('textarea', '文本域'), ('selectuser', '单选用户'), ('selectusers', '多选用户'), ('file', '附件'), ('draw', '绘图')], help_text='5.字符串,10.整形,15.浮点型,20.布尔,25.日期,30.日期时间,35.单选框,40.多选框,45.下拉列表,50.多选下拉列表,55.文本域,60.用户名, 70.多选的用户名, 80.附件(只保存路径,多个使用逗号隔开)', max_length=50, verbose_name='类型'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='ticket',
|
||||
name='ticket_data',
|
||||
field=models.JSONField(default=dict, help_text='工单自定义字段内容', verbose_name='工单数据'),
|
||||
),
|
||||
]
|
||||
|
|
@ -152,7 +152,8 @@ class CustomField(CommonAModel):
|
|||
('textarea', '文本域'),
|
||||
('selectuser', '单选用户'),
|
||||
('selectusers', '多选用户'),
|
||||
('file', '附件')
|
||||
('file', '附件'),
|
||||
('draw', '绘图')
|
||||
)
|
||||
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, verbose_name='所属工作流')
|
||||
field_type = models.CharField('类型', max_length=50, choices=field_type_choices, help_text='5.字符串,10.整形,15.浮点型,20.布尔,25.日期,30.日期时间,35.单选框,40.多选框,45.下拉列表,50.多选下拉列表,55.文本域,60.用户名, 70.多选的用户名, 80.附件(只保存路径,多个使用逗号隔开)')
|
||||
|
|
@ -201,7 +202,7 @@ class Ticket(CommonBModel):
|
|||
state = models.ForeignKey(State, on_delete=models.CASCADE, verbose_name='当前状态', related_name='ticket_state')
|
||||
parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE, verbose_name='父工单')
|
||||
parent_state = models.ForeignKey(State, null=True, blank=True, on_delete=models.CASCADE, verbose_name='父工单状态', related_name='ticket_parent_state')
|
||||
ticket_data = models.JSONField('工单数据', default=dict, help_text='工单所有字段内容')
|
||||
ticket_data = models.JSONField('工单数据', default=dict, help_text='工单自定义字段内容')
|
||||
in_add_node = models.BooleanField('加签状态中', default=False, help_text='是否处于加签状态下')
|
||||
add_node_man = models.ForeignKey(User, verbose_name='加签人', on_delete=models.SET_NULL, null=True, blank=True, help_text='加签操作的人,工单当前处理人处理完成后会回到该处理人,当处于加签状态下才有效')
|
||||
|
||||
|
|
@ -211,16 +212,17 @@ class Ticket(CommonBModel):
|
|||
multi_all_person = models.JSONField('全部处理的结果', default=dict, blank=True, help_text='需要当前状态处理人全部处理时实际的处理结果,json格式')
|
||||
|
||||
|
||||
class TicketData():
|
||||
"""
|
||||
工单数据,自定义字段值
|
||||
"""
|
||||
form_field = models.ForeignKey(CustomField, verbose_name='关联字段', on_delete=models.SET_NULL, db_constraint=False, null=True, blank=True)
|
||||
field_name = models.CharField('字段名', max_length=50)
|
||||
field_key = models.CharField('字段标识', max_length=50)
|
||||
field_type = models.CharField('字段类型', choices=CustomField.field_type_choices, max_length=50)
|
||||
field_value = models.JSONField('录入值', default=dict, blank=True)
|
||||
sort = models.IntegerField('排序号', default=1)
|
||||
# class TicketCustomField(BaseModel):
|
||||
# """
|
||||
# 工单数据,自定义字段值
|
||||
# """
|
||||
# ticket = models.ForeignKey(Ticket, verbose_name='关联工单', on_delete=models.CASCADE)
|
||||
# form_field = models.ForeignKey(CustomField, verbose_name='关联字段', on_delete=models.SET_NULL, db_constraint=False, null=True, blank=True)
|
||||
# field_name = models.CharField('字段名', max_length=50)
|
||||
# field_key = models.CharField('字段标识', max_length=50)
|
||||
# field_type = models.CharField('字段类型', choices=CustomField.field_type_choices, max_length=50)
|
||||
# field_value = models.JSONField('录入值', default=dict, blank=True)
|
||||
# sort = models.IntegerField('排序号', default=1)
|
||||
|
||||
class TicketFlow(BaseModel):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
|
|||
elif request.method=='POST':
|
||||
serializer= PickHalfsSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.data
|
||||
vdata = serializer.validated_data
|
||||
first_step = Step.objects.get(pk=sp.steps[0]['id'])
|
||||
# 创建领料记录
|
||||
pick = Pick()
|
||||
|
|
@ -68,12 +68,12 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
|
|||
pick.save()
|
||||
for i in vdata:
|
||||
if 'wproducts' in i and len(i['wproducts'])>0:
|
||||
spp = SubProductionProgress.objects.get(pk=i['id'])
|
||||
spp = i['id']
|
||||
spp.count_pick = spp.count_pick + len(i['wproducts'])
|
||||
# if spp.count_pick > spp.count:
|
||||
# raise exceptions.APIException('超过计划数')
|
||||
spp.save()
|
||||
wps = WProduct.objects.filter(pk__in=[x for x in i['wproducts']], act_state=WProduct.WPR_ACT_STATE_OK)
|
||||
wps = WProduct.objects.filter(pk__in=[x.id for x in i['wproducts']], act_state=WProduct.WPR_ACT_STATE_OK)
|
||||
wps.update(step=first_step,
|
||||
act_state=WProduct.WPR_ACT_STATE_TORETEST, is_hidden=False, warehouse=None,
|
||||
subproduction_plan=sp, update_by=request.user, update_time=timezone.now())
|
||||
|
|
@ -99,11 +99,11 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
|
|||
"""
|
||||
serializer= WplanPutInSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.data
|
||||
vdata = serializer.validated_data
|
||||
subplan = self.get_object()
|
||||
material = subplan.main_product
|
||||
batch = subplan.number
|
||||
warehouse = WareHouse.objects.get(id=vdata['warehouse'])
|
||||
warehouse = vdata['warehouse']
|
||||
wproducts = WProduct.objects.filter(subproduction_plan=subplan,
|
||||
act_state=WProduct.WPR_ACT_STATE_OK, material=material, is_deleted=False)
|
||||
if wproducts.exists():
|
||||
|
|
@ -253,9 +253,9 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
|||
"""
|
||||
serializer= WproductPutInsSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.data
|
||||
wproducts = WProduct.objects.filter(pk__in=[x for x in vdata['wproducts']])
|
||||
warehouse = WareHouse.objects.get(id=vdata['warehouse'])
|
||||
vdata = serializer.validated_data
|
||||
wproducts = WProduct.objects.filter(pk__in=[x.id for x in vdata['wproducts']])
|
||||
warehouse = vdata['warehouse']
|
||||
for i in wproducts:
|
||||
if i.act_state is not WProduct.WPR_ACT_STATE_OK:
|
||||
raise exceptions.APIException('存在不可入库半成品')
|
||||
|
|
@ -267,12 +267,12 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
|||
is_audited=True, auditor=request.user, inout_date=timezone.now(), create_by=request.user, remark=remark)
|
||||
# 创建入库明细
|
||||
for i in wproducts_a:
|
||||
spi = SubProductionPlan.objects.get(pk=i['subproduction_plan'])
|
||||
spi = i['subproduction_plan']
|
||||
fifoitem = FIFOItem()
|
||||
fifoitem.is_tested = True
|
||||
fifoitem.is_testok = True
|
||||
fifoitem.warehouse = warehouse
|
||||
fifoitem.material = Material.objects.get(pk=i['material'])
|
||||
fifoitem.material = i['material']
|
||||
fifoitem.count = i['total']
|
||||
fifoitem.batch = spi.number
|
||||
fifoitem.fifo = fifo
|
||||
|
|
@ -303,9 +303,9 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
|||
"""
|
||||
serializer= WproductPutInSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.data
|
||||
vdata = serializer.validated_data
|
||||
wproduct = self.get_object()
|
||||
warehouse = WareHouse.objects.get(id=vdata['warehouse'])
|
||||
warehouse = vdata['warehouse']
|
||||
if wproduct.act_state != WProduct.WPR_ACT_STATE_OK:
|
||||
raise exceptions.APIException('半成品不可入库')
|
||||
material = wproduct.material
|
||||
|
|
@ -598,11 +598,11 @@ class OperationRecordViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
|||
def submit(self, request, pk=None):
|
||||
serializer = OperationRecordSubmitSerializer(data=request.data, context={'request':self.request})
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.data
|
||||
vdata = serializer.validated_data
|
||||
opr = self.get_object()
|
||||
wrds = []
|
||||
for m in vdata['record_data']: # 保存记录详情
|
||||
form_field = RecordFormField.objects.get(pk=m['form_field'])
|
||||
form_field = m['form_field']
|
||||
m['form_field'] = form_field
|
||||
m['field_name'] = form_field.field_name
|
||||
m['field_key'] = form_field.field_key
|
||||
|
|
|
|||
Loading…
Reference in New Issue