jianchabioa

This commit is contained in:
shijing 2021-12-06 14:12:11 +08:00
commit 68288515a4
25 changed files with 1502 additions and 370 deletions

View File

@ -58,14 +58,6 @@ export function wproductTest(data) {
data
})
}
//半成品复检
export function wproductRetest(data) {
return request({
url: '/wpm/wproduct/retest/',
method: 'post',
data
})
}
//半成品入库
@ -261,4 +253,14 @@ export function createTool(data) {
})
}
//检验合格的半成品批量入库
export function createputins(data) {
return request({
url: '/wpm/wproduct/putins/',
method: 'post',
data
})
}

View File

@ -112,6 +112,14 @@ export const asyncRoutes = [
component: () => import('@/views/mtm/materialdo.vue'),
meta: { title: '绑定检查表', perms: ['vendor_manage'] },
hidden: true
}
,
{
path: 'materialDetail/:id',
name: 'MaterialDetail',
component: () => import('@/views/mtm/materialDetail.vue'),
meta: { title: '物料详情', perms: ['vendor_manage'] },
hidden: true
},
{
path: 'process',
@ -201,11 +209,19 @@ export const asyncRoutes = [
hidden: true
},
{
path: 'need/:id',
path: 'need',
name: 'need',
component: () => import('@/views/wpm/need'),
meta: { title: '半成品检验', icon: 'example', perms: ['index_manage'] }
}
,
{
path: 'productjy',
name: 'productjy',
component: () => import('@/views/wpm/productjy'),
meta: { title: '成品检验', icon: 'example', perms: ['index_manage'] }
}
]
},
{

View File

@ -92,10 +92,16 @@
@click="handlebind(scope)"
>检查表</el-link
>
<el-link
v-if="checkPermission(['material_update'])"
@click="handleEdit(scope)"
>编辑</el-link
>
<el-link
v-if="checkPermission(['material_update'])"
@click="handledetail(scope)"
>详情</el-link
>
<el-link
v-if="checkPermission(['material_delete'])"
@ -176,7 +182,7 @@
</div>
</template>
<script>
import { getMaterialList, createMaterial,updateMaterial,deleteMaterial,getProcessList } from "@/api/mtm";
import { getMaterialList,getMaterial, createMaterial,updateMaterial,deleteMaterial,getProcessList } from "@/api/mtm";
import checkPermission from "@/utils/permission";
@ -269,6 +275,15 @@ export default {
},
methods: {
checkPermission,
//物料详情
handledetail(scope)
{
this.$router.push({name: "MaterialDetail", params: { id: scope.row.id }, })
},
//选项卡切换
handleClick(tab) {
this.listLoading = true;

View File

@ -0,0 +1,230 @@
<template>
<div class="app-container">
<el-card>
<el-card >
<el-descriptions title="物料基本信息" direction="vertical" :column="8" border>
<el-descriptions-item label="物料编号"> {{materialdetail.number}}</el-descriptions-item>
<el-descriptions-item label="物料名称"> {{materialdetail.name}}</el-descriptions-item>
<el-descriptions-item label="规格型号" :span="2"> {{materialdetail.specification}}</el-descriptions-item>
<el-descriptions-item label="计量单位"> {{materialdetail.unit}} </el-descriptions-item>
<el-descriptions-item label="数量"> {{materialdetail.count}}</el-descriptions-item>
</el-descriptions>
</el-card>
<el-tabs v-model="activeName" type="card" >
<el-tab-pane label="对应的批次" name="3">
<el-table
v-loading="listLoading"
:data="InventoryList"
border
fit
stripe
highlight-current-row
>
<el-table-column type="index" width="50" />
<el-table-column label="物料批次">
<template slot-scope="scope">{{ scope.row.batch }}</template>
</el-table-column>
<el-table-column label="物料名称">
<template slot-scope="scope">{{ scope.row.material_.name }}</template>
</el-table-column>
<el-table-column label="规格型号">
<template slot-scope="scope">{{ scope.row.material_.specification }}</template>
</el-table-column>
<el-table-column label="物料编号">
<template slot-scope="scope">{{
scope.row.material_.number
}}</template>
</el-table-column>
<el-table-column label="仓库名称">
<template slot-scope="scope">{{
scope.row.warehouse_.name
}}</template>
</el-table-column>
<el-table-column label="仓库编号">
<template slot-scope="scope">{{
scope.row.warehouse_.number
}}</template>
</el-table-column>
<el-table-column label="物料总存量">
<template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="关联的订单" name="1">
<el-table
v-loading="listLoading"
:data="orderlist"
border
fit
stripe
highlight-current-row
height="100"
v-el-height-adaptive-table="{bottomOffset: 50}"
>
<el-table-column type="index" width="50" />
<el-table-column label="订单编号" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="客户" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.customer_.name }}</template>
</el-table-column>
<el-table-column label="所属合同" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.contract_.name }}</template>
</el-table-column>
<el-table-column label="产品名称" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.product_.name }}</template>
</el-table-column>
<el-table-column label="产品型号" show-overflow-tooltip>
<template slot-scope="scope">{{ scope.row.product_.specification }}</template>
</el-table-column>
<el-table-column label="产品数量" >
<template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column>
<el-table-column label="交货日期" >
<template slot-scope="scope">{{ scope.row.delivery_date }}</template>
</el-table-column>
<el-table-column label="创建时间" >
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="关联的计划" name="2">
<el-table
:data="productionplanList"
border
fit
stripe
style="width: 100%"
height="300"
>
<el-table-column type="index" width="50" />
<el-table-column label="任务编号" >
<template slot-scope="scope">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="订单编号" >
<template slot-scope="scope">{{ scope.row.order_.number }}</template>
</el-table-column>
<el-table-column label="合同编号" >
<template slot-scope="scope">{{ scope.row.order_.contract_.number }}</template>
</el-table-column>
<el-table-column label="生产数量" >
<template slot-scope="scope">{{ scope.row.count }}</template>
</el-table-column>
<el-table-column label="计划开工时间">
<template slot-scope="scope">{{ scope.row.start_date }}</template>
</el-table-column>
<el-table-column label="计划完工时间" >
<template slot-scope="scope">{{ scope.row.end_date }}</template>
</el-table-column>
<el-table-column label="交付截止时间" >
<template slot-scope="scope">{{ scope.row.order_.delivery_date }}</template>
</el-table-column>
<el-table-column label="是否生成子计划" >
<template slot-scope="scope" >
<el-tag v-if="scope.row.is_planed==false"></el-tag>
<el-tag v-if="scope.row.is_planed==true"></el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间">
<template slot-scope="scope">{{ scope.row.create_time }}</template>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
</el-card>
</div>
</template>
<script>
import checkPermission from "@/utils/permission";
import vueJsonEditor from "vue-json-editor";
import {upUrl, upHeaders} from "@/api/file";
import {getProductionplanList } from "@/api/pm";
import {getmaterialbatchList} from "@/api/inm";
import {getOrderList } from "@/api/sam";
import {getMaterial } from "@/api/mtm";
import { upFile } from "@/api/file";
import {genTree} from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
export default {
components: {Pagination, vueJsonEditor, Treeselect},
data() {
return {
materialdetail:"",
orderlist:"",
productionplanList:"",
InventoryList:"",
activeName:'3',
};
},
computed: {},
watch: {},
created() {
this.material = this.$route.params.id;
this.getMaterial();
this.getOrderList();
this.getplanList();
this.getmaterialbatchList();
},
methods: {
getMaterial(){
getMaterial(this.material).then((response) => {
if (response.data) {
this.materialdetail = response.data;//物料基本信息
}
})
},
getOrderList(){
getOrderList({product:this.material,page:0}).then((response) => {
if (response.data) {
this.orderlist = response.data;//物料关联的订单
}
})
},
getplanList() {
getProductionplanList({product:this.material,page:0}).then((response) => {
if (response.data) {
this.productionplanList = response.data;//物料关联计划
}
});
},
getmaterialbatchList() {
getmaterialbatchList({material:this.material,page:0}).then((response) => {
if (response.data) {
this.InventoryList = response.data;
}
});
},
},
};
</script>

View File

@ -46,14 +46,14 @@
<el-descriptions-item>
<template slot="label">
<i class="el-icon-mobile-phone"></i>
产品名称
</template>
{{products.name}}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-location-outline"></i>
产品编号
</template>
{{products.number}}

View File

@ -78,14 +78,12 @@
<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>
@ -101,15 +99,24 @@
</el-tab-pane>
<el-tab-pane label="已合格半成品">
<el-card style="margin-top: 2px">
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
>批量入库</el-button
>
<el-table
v-loading="listLoading"
:data="wproductList1.results"
ref="multipleTable"
border
fit
stripe
highlight-current-row
max-height="600"
>
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column type="index" width="50" />
<el-table-column label="半成品名称">
<template slot-scope="scope">{{ scope.row.material_.name }}</template>
@ -184,8 +191,7 @@
</el-dialog>
<el-dialog title="半成品入库" :close-on-click-modal="false" :visible.sync="dialogFormVisible">
<el-form :model="form">
<!--<el-form-item label="仓库" :label-width="formLabelWidth">-->
<el-form-item label="仓库">
<el-form-item label="仓库" :label-width="formLabelWidth">
<el-select
style="width: 100%"
v-model="form.warehouse"
@ -200,8 +206,7 @@
</el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" >
<!--<el-form-item label="备注" :label-width="formLabelWidth">-->
<el-form-item label="备注" :label-width="formLabelWidth">
<el-input v-model="form.remark" ></el-input>
</el-form-item>
@ -210,12 +215,39 @@
<el-button @click="dialogFormVisible = false"> </el-button>
<el-button type="primary" @click="putin"> </el-button>
</div>
</el-dialog>
<el-dialog title="半成品批量入库" :close-on-click-modal="false" :visible.sync="dialogFormVisibles">
<el-form :model="form">
<el-form-item label="仓库" :label-width="formLabelWidth">
<el-select
style="width: 100%"
v-model="form.warehouse"
placeholder="请选择仓库"
>
<el-option
v-for="item in WarehouseData"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" :label-width="formLabelWidth">
<el-input v-model="form.remark" ></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisibles = false"> </el-button>
<el-button type="primary" @click="putins"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import customForm from '@/components/customForm/index';
import {getwproductList, wproductTest, wproductPutin} from "@/api/wpm";
import { getwproductList ,wproductTest,wproductPutin,createputins} from "@/api/wpm";
import checkPermission from "@/utils/permission";
import { getWarehouseList } from "@/api/inm";
import { getMaterialList, getrecordformList, getrffieldList } from "@/api/mtm";
@ -226,9 +258,8 @@
components: {Pagination,customForm},
data() {
return {
wproduct:null,
testitem: defaultetestitem,
form: {},
form: {remark: "", warehouse: ""},
wproductList: {
count: 0,
},
@ -269,10 +300,6 @@
label: "不合格",
},
],
checkForm: {
hhh: '',
},
formName:'项目检查表',
options: [],
listLoading: true,
fieldList: "",
@ -284,10 +311,11 @@
listQueryrecordform: {
page: 0,
},
hasPicture: false,
mutipID: [],
outerVisible: false,
innerVisible: false,
dialogFormVisible: false,
dialogFormVisibles: false,
testrecord: {},
WarehouseData: "",
};
@ -298,20 +326,9 @@
this.getList();
this.getList2();
this.getList1();
// this.getLists();
this.getLists();
},
methods: {
formFunc(value) {
wproductTest(value).then((res) => {
if (res.code >= 200) {
this.innerVisible = false;
this.outerVisible = false;
this.getList();
this.getList1();
this.getList2();
}
});
},
checkPermission,
//待检半成品列表
getList() {
@ -339,6 +356,7 @@
getList1() {
this.listQuery1.act_state = 30;
this.listQuery1.material__type = 1;
getwproductList(this.listQuery1).then((response) => {
if (response.data) {
this.wproductList1 = response.data;
@ -346,6 +364,32 @@
});
},
//半成品批量入库
handleCreate() {
this.dialogFormVisibles = true;
this.getWarehouseLists();//仓库
},
//批量入库
putins() {
let _this = this
_this.mutipID = []
this.$refs.multipleTable.selection.forEach((item) => {
_this.mutipID.push(item.id);
alert(_this.mutipID);
});
console.log(_this.mutipID);
createputins({warehouse: this.form.warehouse, wproducts: _this.mutipID, remark: this.form.remark}).then((res) => {
if (res.code >= 200) {
this.$message.success("批量入库成功!");
this.dialogFormVisibles = false;
this.getList1();
}
});
},
//仓库列表
getWarehouseLists() {
@ -370,18 +414,11 @@
}
});
},
recordformChange(item){
let that = this;
let arr = this.recordformList.filter(item=>{
return item.id=that.recordform;
})
that.formName = arr[0].name;
},
//根据选择的表渲染检查项目
submitrecordform() {
let that = this;
if (that.recordform != "") {
getrffieldList({form: that.recordform, page: 1,page_size:100}).then((response) => {
if (this.recordform != "") {
getrffieldList({form: this.recordform, page: 1,page_size:100}).then((response) => {
if (response.data) {
that.hasPicture = false;
let fieldList = response.data.results;
@ -389,28 +426,45 @@
let arr = fieldList.filter(item => {
return item.field_type === 'draw'
});
that.judgeList = [];
let listJudge = fieldList.filter(item => {
return item.need_judge === true;
});
listJudge.forEach(item => {
let obj = new Object();
obj = item;
obj.judge = false;
that.judgeList.push(obj)
});
if (arr.length > 0) {
that.hasPicture = true;
}
for (let i = 0; i < fieldList.length; i++) {
let key = fieldList[i].field_key;
that.checkForm[key] = '';
that.$set(that.checkForm, key, '')
}
that.innerVisible = true;
}
});
} else that.$message.error("请选择检查表!");
} else this.$message.error("请选择检查表!");
},
//提交检查项目
submitfield() {
let _this = this;
_this.field = []; //检查项目
this.fieldList.forEach((item) => {
_this.field.push({
form_field: item.id,
field_value: item.sort,
is_testok: item.is_testok//单项检查结果
});
});
console.log(this.recordform);
this.testrecord.form = this.recordform;//检查表
this.testrecord.record_data = _this.field;//检查项列表
this.testrecord.is_testok = this.is_testok;//检查表检查结果
this.testrecord.wproduct = this.wproduct;//半成品ID
wproductTest(this.testrecord).then((res) => {
if (res.code >= 200) {
this.innerVisible = false;
this.outerVisible = false;
this.getList();
this.getList1();
this.getList2();
}
});
},
//半成品入库
handlePutin(scope) {
@ -426,7 +480,18 @@
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>

View File

@ -813,6 +813,7 @@ export default {
handlesubmit() {
submitOperation(this.id).then((res) => {
if (res.code >= 200) {
this.$router.push({name: "operation" })
this.$message.success("操作提交成功!");
}
});

View File

@ -0,0 +1,542 @@
<template>
<div class="app-container">
<el-tabs type="border-card">
<el-tab-pane label="待检成品">
<el-card style="margin-top: 2px">
<el-table
v-loading="listLoading"
:data="wproductList.results"
border
fit
stripe
highlight-current-row
max-height="600"
>
<el-table-column type="index" width="50" />
<el-table-column label="成品名称">
<template slot-scope="scope">{{ scope.row.material_.name }}</template>
</el-table-column>
<el-table-column label="成品编号">
<template slot-scope="scope">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="检测状态">
<template slot-scope="scope">
{{ actstate_[scope.row.act_state] }}
</template>
</el-table-column>
<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
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="wproductList.count > 0"
:total="wproductList.count"
:page.sync="listQuery.page"
:limit.sync="listQuery.page_size"
@pagination="getList"
/>
</el-card>
</el-tab-pane>
<el-tab-pane label="已合格成品">
<el-card style="margin-top: 2px">
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
>批量入库</el-button
>
<el-table
v-loading="listLoading"
:data="wproductList1.results"
ref="multipleTable"
border
fit
stripe
highlight-current-row
max-height="600"
>
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column type="index" width="50" />
<el-table-column label="成品名称">
<template slot-scope="scope">{{ scope.row.material_.name }}</template>
</el-table-column>
<el-table-column label="成品编号">
<template slot-scope="scope">{{ scope.row.number }}</template>
</el-table-column>
<el-table-column label="检测状态">
<template slot-scope="scope">
{{ actstate_[scope.row.act_state] }}
</template>
</el-table-column>
<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="handlePutin(scope)"
>入库</el-link
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="wproductList1.count > 0"
:total="wproductList1.count"
:page.sync="listQuery1.page"
:limit.sync="listQuery1.page_size"
@pagination="getList1"
/>
</el-card>
</el-tab-pane>
</el-tabs>
<el-dialog title="物料检查表" :close-on-click-modal="false" :visible.sync="outerVisible">
<el-select style="width: 100%" v-model="recordform" placeholder="请选择">
<el-option
v-for="item in recordformList"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
<el-dialog
width="50%"
title="检查项目"
: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"
/>
</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
>
</div>
</el-dialog>
<el-dialog title="成品入库" :close-on-click-modal="false" :visible.sync="dialogFormVisible">
<el-form :model="form">
<el-form-item label="仓库" :label-width="formLabelWidth">
<el-select
style="width: 100%"
v-model="form.warehouse"
placeholder="请选择仓库"
>
<el-option
v-for="item in WarehouseData"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" :label-width="formLabelWidth">
<el-input v-model="form.remark" ></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false"> </el-button>
<el-button type="primary" @click="putin"> </el-button>
</div>
</el-dialog>
<el-dialog title="半成品批量入库" :close-on-click-modal="false" :visible.sync="dialogFormVisibles">
<el-form :model="form">
<el-form-item label="仓库" :label-width="formLabelWidth">
<el-select
style="width: 100%"
v-model="form.warehouse"
placeholder="请选择仓库"
>
<el-option
v-for="item in WarehouseData"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="备注" :label-width="formLabelWidth">
<el-input v-model="form.remark" ></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisibles = false"> </el-button>
<el-button type="primary" @click="putins"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getwproductList ,wproductTest,wproductPutin,createputins} from "@/api/wpm";
import checkPermission from "@/utils/permission";
import { getWarehouseList } from "@/api/inm";
import { getMaterialList, getrecordformList, getrffieldList } from "@/api/mtm";
import { genTree } from "@/utils";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultetestitem = {};
export default {
components: { Pagination },
data() {
return {
testitem: defaultetestitem,
form:{remark:"",warehouse:""},
wproductList: {
count: 0,
},
wproductList1: {
count: 0,
},
wproductList2: {
count: 0,
},
listQuery: {
page: 1,
page_size: 20,
},
listQuery1: {
page: 1,
page_size: 20,
},
listQuery2: {
page: 1,
page_size: 20,
},
actstate_: {
6: "待复检",
10: "生产中",
20: "待检验",
30: "已合格",
40: "库存中",
50: "不合格",
60: "待成品检验",
},
choice: [
{
value: true,
label: "合格",
},
{
value: false,
label: "不合格",
},
],
options: [],
listLoading: true,
fieldList: "",
is_testok: "true",
field: [],
recordformList: [],
recordform: "",
fifo_detail: "",
listQueryrecordform: {
page: 0,
},
outerVisible: false,
innerVisible: false,
dialogFormVisible:false,
dialogFormVisibles:false,
testrecord: {},
WarehouseData:"",
};
},
computed: {},
watch: {},
created() {
this.getList();
this.getList1();
this.getLists();
},
methods: {
checkPermission,
//待检成品列表
getList() {
this.listLoading = true;
this.listQuery.act_state = 60;
this.listQuery.material__type = 1;
getwproductList(this.listQuery).then((response) => {
if (response.data) {
this.wproductList = response.data;
}
this.listLoading = false;
});
},
//已合格成品
getList1() {
this.listQuery1.act_state = 30;
this.listQuery1.material__type = 1;
getwproductList(this.listQuery1).then((response) => {
if (response.data) {
this.wproductList1 = response.data;
}
});
},
//半成品批量入库
handleCreate(){
this.dialogFormVisibles=true;
this.getWarehouseLists();//仓库
},
//批量入库
putins(){
let _this=this
_this.mutipID=[]
this.$refs.multipleTable.selection.forEach((item) => {
_this.mutipID.push( item.id );
alert(_this.mutipID);
});
console.log(_this.mutipID);
createputins({warehouse:this.form.warehouse,wproducts: _this.mutipID,remark:this.form.remark}).then((res) => {
if (res.code >= 200) {
this.$message.success("批量入库成功!");
this.dialogFormVisibles=false;
this.getList1();
}
});
},
//仓库列表
getWarehouseLists(){
getWarehouseList({page:0}).then((response) => {
if (response.data) {
this.WarehouseData = response.data;
}
});
},
handleInspection(scope) {
//调该物料对应的检查表
this.outerVisible = true;
this.wproduct=scope.row.id;//半成品ID
this.wproductactstate=scope.row.act_state;//半成品状态
this.listQueryrecordform.material = scope.row.material;//
this.listQueryrecordform.type = 2;
this.recordform="";
getrecordformList(this.listQueryrecordform).then((response) => {
if (response.data) {
this.recordformList = response.data;
}
});
},
//根据选择的表渲染检查项目
submitrecordform() {
if (this.recordform != "") {
getrffieldList({ form: this.recordform, page: 0 }).then((response) => {
if (response.data) {
this.fieldList = response.data;
this.innerVisible = true;
}
});
} else this.$message.error("请选择检查表!");
},
//提交检查项目
submitfield() {
let _this = this;
_this.field = []; //检查项目
this.fieldList.forEach((item) => {
_this.field.push({
form_field:item.id,
field_value:item.sort,
is_testok:item.is_testok//单项检查结果
});
});
console.log(this.recordform);
this.testrecord.form = this.recordform;//检查表
this.testrecord.record_data = _this.field;//检查项列表
this.testrecord.is_testok = this.is_testok;//检查表检查结果
this.testrecord.wproduct = this.wproduct;//半成品ID
wproductTest(this.testrecord).then((res) => {
if (res.code >= 200) {
this.innerVisible = false;
this.outerVisible = false;
this.getList();
this.getList1();
}
});
},
//半成品入库
handlePutin(scope){
this.dialogFormVisible=true;
this.getWarehouseLists();//仓库
this.id=scope.row.id;//半成品id
},
putin(){
wproductPutin(this.id,this.form).then((res) => {
if (res.code >= 200) {
this.$message.success("入库成功!");
this.dialogFormVisible=false;
this.getList1();
}
});
}
},
};
</script>

View File

@ -162,17 +162,12 @@
scope.row.step_.name
}}</template>
</el-table-column>
<el-table-column label="检验状态">
<el-table-column label="进行状态">
<template slot-scope="scope">{{
actstate_[scope.row.act_state]
}}</template>
</el-table-column>
<el-table-column label="所在子工序执行状态">
<template slot-scope="scope">
<el-tag v-if="scope.row.is_executed">已执行</el-tag>
<el-tag v-else>待执行</el-tag>
</template>
</el-table-column>
<el-table-column label="更新时间">
<template slot-scope="scope">{{
@ -701,12 +696,13 @@ export default {
showPrise1: false,
actstate_: {
6: "待复检",
10: "生产",
10: "操作进行",
20: "待检验",
30: "已合格",
40: "库存中",
50: "不合格",
60: "待成品检验",
8:"操作准备中",
},
state_: {
0: "制定中",

View File

@ -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']

View File

@ -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='是否售出'),
),
]

View File

@ -102,5 +102,6 @@ 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)

View File

@ -2,6 +2,7 @@ from rest_framework import serializers
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse,Inventory
from apps.qm.models import TestRecord, TestRecordItem
from apps.sam.serializers import OrderSimpleSerializer
from apps.system.serializers import UserSimpleSerializer
from apps.mtm.serializers import MaterialSimpleSerializer
@ -40,10 +41,18 @@ class MaterialBatchSerializer(serializers. ModelSerializer):
class IProductListSerializer(serializers.ModelSerializer):
material_= MaterialSimpleSerializer(source='material', read_only=True)
warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True)
order_ = serializers.SerializerMethodField()
class Meta:
model = IProduct
fields = '__all__'
def get_order_(self, obj):
if obj.wproduct:
order = obj.wproduct.subproduction_plan.production_plan.order
if order:
return OrderSimpleSerializer(instance=order).data
return None
class FIFOListSerializer(serializers.ModelSerializer):
auditor_ = UserSimpleSerializer(source='auditor', read_only=True)

View File

@ -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']

View File

@ -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='已排数量'),
),
]

View File

@ -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')},
},
),
]

View File

@ -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,12 +58,13 @@ 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 = '订单信息'
@ -71,3 +72,33 @@ class Order(CommonAModel):
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('物品编号', unique=True, 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('是否军检合格', default=True)
class Meta:
unique_together = (
('sale','iproduct'), # 联合唯一
)

View File

@ -1,6 +1,9 @@
from django.db import transaction
from rest_framework import serializers
from .models import Contract, Customer, Order
from apps.inm.models import IProduct
from .models import Contract, Customer, Order, Sale, SaleProduct
from apps.mtm.serializers import MaterialSimpleSerializer
@ -54,3 +57,40 @@ 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
return super().validate(attrs)
@transaction.atomic
def create(self, validated_data):
iproducts = validated_data.pop('iproducts')
validated_data['count'] = len(iproducts)
sale = Sale.objects.create(**validated_data)
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 sale
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__'

View File

@ -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, SaleViewSet
from django.urls import path, include
from rest_framework.routers import DefaultRouter
@ -8,6 +8,7 @@ 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')
urlpatterns = [
path('', include(router.urls)),

View File

@ -1,6 +1,7 @@
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 rest_framework.mixins import CreateModelMixin, ListModelMixin, RetrieveModelMixin
from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer
from apps.sam.models import Contract, Customer, Order, Sale
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from apps.system.mixins import CreateUpdateCustomMixin
from django.shortcuts import render
from rest_framework.decorators import action
@ -57,7 +58,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 +69,23 @@ 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, GenericViewSet):
"""
销售记录
"""
perms_map = {'*': '*'}
queryset = Sale.objects.select_related('customer', 'order', 'product').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()

View File

@ -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='工单数据'),
),
]

View File

@ -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='加签操作的人,工单当前处理人处理完成后会回到该处理人,当处于加签状态下才有效')
@ -210,6 +211,19 @@ class Ticket(CommonBModel):
act_state = models.IntegerField('进行状态', default=1, help_text='当前工单的进行状态', choices=act_state_choices)
multi_all_person = models.JSONField('全部处理的结果', default=dict, blank=True, help_text='需要当前状态处理人全部处理时实际的处理结果json格式')
# 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):
"""
工单流转日志

View File

@ -18,16 +18,17 @@ from django.db import transaction
class PickHalfSerializer(serializers.Serializer):
id = serializers.PrimaryKeyRelatedField(queryset=SubProductionProgress.objects.all(), label='子计划进度ID')
wproducts = serializers.ListField(child=serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), label='半成品ID'),
required=False) # 从半成品表里直接修改状态
wproducts = serializers.ListField(child=serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all())
, label='半成品ID', required=False) # 从半成品表里直接修改状态
class PickHalfsSerializer(serializers.ListSerializer):
child = PickHalfSerializer()
class PickDetailSerializer(serializers.Serializer):
material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label="物料ID")
batch = serializers.CharField(label='物料批次', allow_blank=True)
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
pick_count = serializers.IntegerField(label="领料数量", required=False)
iproducts = serializers.ListField(child=serializers.PrimaryKeyRelatedField(queryset=IProduct.objects.all(), label='库存半成品ID'),
required=False)
iproducts = serializers.PrimaryKeyRelatedField(queryset=IProduct.objects.all(), label='库存半成品ID',required=False, many=True)
class PickSerializer(serializers.Serializer):
subproduction_plan=serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID")
@ -172,8 +173,7 @@ class OperationCreateSerializer(serializers.Serializer):
"""
step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID")
# subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID", required=False)
wproducts = serializers.ListField(child=
serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label="半成品ID列表", required=False)
wproducts = serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), label="半成品ID列表", required=False, many=True)
def validate(self, data):
# subproduction_plan = data['subproduction_plan']
@ -209,8 +209,7 @@ class OperationUpdateSerializer(serializers.ModelSerializer):
class OperationInitSerializer(serializers.Serializer):
step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID")
subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID", required=False)
wproducts = serializers.ListField(child=
serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label="半成品ID列表", required=False)
wproducts = serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), label="半成品ID列表", required=False, many=True)
def validate(self, data):
# subproduction_plan = data['subproduction_plan']
@ -273,8 +272,7 @@ class OperationWproductListSerializer(serializers.ModelSerializer):
class OperationSubmitSerializer(serializers.Serializer):
step = serializers.PrimaryKeyRelatedField(queryset=Step.objects.all(), label="子工序ID")
subproduction_plan = serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID", required=False)
wproducts = serializers.ListField(child=
serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all()), label="半成品ID列表", required=False)
wproducts = serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), label="半成品ID列表", required=False, many=True)
input = DoInputSerializer(many=True, required=False)
output = DoOutputSerializer(many=True, required=False)
forms = OperationRecordSerializer(many=True, required=False)
@ -294,11 +292,6 @@ class WpmTestRecordCreateSerializer(serializers.ModelSerializer):
model = TestRecord
fields = ['form', 'record_data', 'is_testok', 'wproduct']
class WproductPutInSerializer(serializers.Serializer):
"""
半成品入库序列化
"""
class WplanPutInSerializer(serializers.Serializer):
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
remark = serializers.CharField(label="入库备注", required =False)
@ -307,6 +300,12 @@ class WproductPutInSerializer(serializers.Serializer):
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
remark = serializers.CharField(label="入库备注", required =False)
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)
class OperationEquipListSerializer(serializers.Serializer):
equip_ = EquipmentSimpleSerializer(source='equip', read_only=True)
class Meta:

View File

@ -18,7 +18,7 @@ from rest_framework.decorators import action
from apps.wpm.filters import WMaterialFilterSet
from apps.wpm.models import OperationEquip, OperationWproduct, Pick, PickWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem
from apps.wpm.serializers import OperationEquipListSerializer, OperationEquipUpdateSerializer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer
from apps.wpm.serializers import OperationEquipListSerializer, OperationEquipUpdateSerializer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickHalfsSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer, WproductPutInsSerializer
from rest_framework.response import Response
from django.db import transaction
from rest_framework import exceptions, serializers
@ -27,6 +27,7 @@ from apps.wpm.services import WpmServies
from django.utils import timezone
from utils.tools import ranstr
from rest_framework import status
from django.db.models import Count
# Create your views here.
class WPlanViewSet(ListModelMixin, GenericViewSet):
"""
@ -40,7 +41,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
ordering_fields = []
ordering = ['-update_time']
@action(methods=['post', 'get'], detail=True, perms_map={'post':'*', 'get':'*'}, serializer_class=PickHalfSerializer)
@action(methods=['post', 'get'], detail=True, perms_map={'post':'*', 'get':'*'}, serializer_class=PickHalfsSerializer)
@transaction.atomic
def pick_half(self, request, pk=None):
"""
@ -55,7 +56,7 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
material__type=Material.MA_TYPE_HALFGOOD, subproduction_plan=sp).select_related('material')
return Response(SubProductionProgressSerializer(instance=spps, many=True).data)
elif request.method=='POST':
serializer= PickHalfSerializer(data=request.data, many=True)
serializer= PickHalfsSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
vdata = serializer.data
first_step = Step.objects.get(pk=sp.steps[0]['id'])
@ -84,8 +85,6 @@ class WPlanViewSet(ListModelMixin, GenericViewSet):
pw.material = i.material
pw.subproduction_plan = i.suproduction_plan
pw.save()
else:
raise exceptions.APIException('未选择任何玻璃')
sp.is_picked = True
sp.save()
@ -246,47 +245,55 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
return Response()
# @action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WpmTestRecordCreateSerializer)
# @transaction.atomic
# def retest(self, request, pk=None):
# """
# 复检
# """
# serializer = WpmTestRecordCreateSerializer(data=request.data)
# serializer.is_valid(raise_exception=True)
# vdata = serializer.validated_data
# record_data = vdata.pop('record_data')
# wproduct = vdata['wproduct']
# if wproduct.act_state != WProduct.WPR_ACT_STATE_TORETEST:
# raise exceptions.APIException('该产品当前状态不可检验')
# if 'is_testok' not in vdata:
# raise exceptions.APIException('未填写检测结论')
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WproductPutInsSerializer)
@transaction.atomic
def putins(self, request, pk=None):
"""
半成品批量入库
"""
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'])
for i in wproducts:
if i.act_state is not WProduct.WPR_ACT_STATE_OK:
raise exceptions.APIException('存在不可入库半成品')
# 聚合一下
wproducts_a = wproducts.values('subproduction_plan', 'material', 'subproduction_plan__number').annotate(total=Count('id'))
# 创建入库记录
remark = vdata.get('remark', '')
fifo = FIFO.objects.create(type=FIFO.FIFO_TYPE_DO_IN,
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'])
fifoitem = FIFOItem()
fifoitem.is_tested = True
fifoitem.is_testok = True
fifoitem.warehouse = warehouse
fifoitem.material = Material.objects.get(pk=i['material'])
fifoitem.count = i['total']
fifoitem.batch = spi.number
fifoitem.fifo = fifo
fifoitem.subproduction_plan = spi
fifoitem.save()
# obj = serializer.save(create_by = self.request.user,
# material=wproduct.material, number=wproduct.number, subproduction_plan=wproduct.subproduction_plan)
# tris = []
# for m in record_data: # 保存记录详情
# form_field = m['form_field']
# m['field_name'] = form_field.field_name
# m['field_key'] = form_field.field_key
# m['field_type'] = form_field.field_type
# m['field_value'] = m['field_value']
# m['sort'] = form_field.sort
# m['need_judge'] = form_field.need_judge
# m['is_testok'] = m['is_testok'] if 'is_testok' in m else None
# m['test_record'] = obj
# tris.append(TestRecordItem(**m))
# TestRecordItem.objects.bulk_create(tris)
# # 如果检测合格, 变更动态产品进行状态
# if obj.is_testok:
# wproduct.act_state = WProduct.WProduct.WPR_ACT_STATE_DOWAIT
# wproduct.save()
# else:# 如果不合格
# wproduct.act_state = WProduct.WPR_ACT_STATE_NOTOK
# wproduct.save()
# return Response()
wproducts_items = wproducts.filter(subproduction_plan=i['subproduction_plan'], material=i['material'])
ips = []
for i in wproducts_items:
# 创建入库明细半成品
ip = {}
ip['fifoitem'] = fifoitem
ip['wproduct'] = i
ip['number'] = i.number
ip['material'] = i.material
ips.append(FIFOItemProduct(**ip))
FIFOItemProduct.objects.bulk_create(ips)
# 更新库存并修改半成品进行状态
update_inm(fifo)
wproducts.update(act_state=WProduct.WPR_ACT_STATE_INM, warehouse=warehouse, update_by=request.user)
return Response()
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WproductPutInSerializer)
@transaction.atomic