Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
d5336df9fc
|
@ -2,8 +2,8 @@
|
||||||
ENV = 'development'
|
ENV = 'development'
|
||||||
|
|
||||||
# base api
|
# base api
|
||||||
#VUE_APP_BASE_API = 'http://127.0.0.1:8000/api'
|
VUE_APP_BASE_API = 'http://127.0.0.1:8000/api'
|
||||||
VUE_APP_BASE_API = 'http://47.95.0.242:2222/api'
|
#VUE_APP_BASE_API = 'http://47.95.0.242:2222/api'
|
||||||
|
|
||||||
|
|
||||||
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
|
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
|
||||||
|
|
|
@ -67,13 +67,13 @@ export default {
|
||||||
if (hasToken) {
|
if (hasToken) {
|
||||||
this.$store.dispatch("user/getCount", {});
|
this.$store.dispatch("user/getCount", {});
|
||||||
}
|
}
|
||||||
this.timer = window.setInterval(() => {
|
/*this.timer = window.setInterval(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (hasToken) {
|
if (hasToken) {
|
||||||
this.$store.dispatch("user/getCount", {});
|
this.$store.dispatch("user/getCount", {});
|
||||||
}
|
}
|
||||||
},0)
|
},0)
|
||||||
},5000)
|
},5000)*/
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleClickOutside() {
|
handleClickOutside() {
|
||||||
|
|
|
@ -62,7 +62,7 @@ div:focus {
|
||||||
|
|
||||||
// main-container global css
|
// main-container global css
|
||||||
.app-container {
|
.app-container {
|
||||||
padding: 10px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-table--medium td, .el-table--medium th {
|
.el-table--medium td, .el-table--medium th {
|
||||||
|
|
|
@ -24,13 +24,13 @@
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增设备</el-button
|
>新增设备</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="equipmentList.results"
|
:data="equipmentList.results"
|
||||||
|
|
|
@ -24,13 +24,13 @@
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增设备</el-button
|
>新增设备</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="equipmentList.results"
|
:data="equipmentList.results"
|
||||||
|
|
|
@ -24,13 +24,13 @@
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增校准或检定</el-button
|
>新增校准或检定</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="equipmentrecordList.results"
|
:data="equipmentrecordList.results"
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增物料</el-button
|
>新增物料</el-button
|
||||||
>
|
>
|
||||||
|
@ -153,7 +153,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<el-tooltip class="item" effect="dark" content="添加条件" placement="top">
|
<el-tooltip class="item" effect="dark" content="添加条件" placement="top">
|
||||||
<el-button @click="addConditions" style='cursor:pointer;width:95%;color:#fe000c;border:1px dashed #fe000c;height:40px;padding:0px;margin-top:10px;margin-left:20px;font-size:26px'>
|
<el-button @click="addConditions" style='cursor:pointer;width:95%;color:#fe000c;border:1px dashed #fe000c;height:40px;padding:0px;margin-top: 2px;margin-left:20px;font-size:26px'>
|
||||||
+
|
+
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
|
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
|
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
|
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
|
|
|
@ -24,13 +24,13 @@
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增仓库</el-button
|
>新增仓库</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="warehouseList.results"
|
:data="warehouseList.results"
|
||||||
|
|
|
@ -1,130 +1,72 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
|
<el-row :gutter="12">
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-card>
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<span>CPU</span>
|
||||||
|
</div>
|
||||||
|
<el-descriptions :column="1" border>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label"> 逻辑核心数 </template>
|
||||||
|
{{ cpuData.count }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label"> 物理核心数 </template>
|
||||||
|
{{ cpuData.lcount }}
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label"> 当前使用率 </template>
|
||||||
|
{{ cpuData.percent }}%
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-card>
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<span>内存</span>
|
||||||
|
</div>
|
||||||
|
<el-descriptions :column="1" border>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label"> 总内存 </template>
|
||||||
|
{{ memoryData.total }}GB
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label"> 已用内存 </template>
|
||||||
|
{{ memoryData.used }}GB
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label"> 当前使用率 </template>
|
||||||
|
{{ memoryData.percent }}%
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-card>
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<span>硬盘</span>
|
||||||
|
</div>
|
||||||
|
<el-descriptions :column="1" border>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label"> 总大小 </template>
|
||||||
|
{{ diskData.total }}GB
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label"> 已用内存 </template>
|
||||||
|
{{ diskData.used }}GB
|
||||||
|
</el-descriptions-item>
|
||||||
|
<el-descriptions-item>
|
||||||
|
<template slot="label"> 当前使用率 </template>
|
||||||
|
{{ diskData.percent }}%
|
||||||
|
</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
<div class="box-card">
|
<el-card style="margin-top: 6px">
|
||||||
<el-row :gutter="12">
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-card shadow="always">
|
|
||||||
|
|
||||||
<div slot="header" class="clearfix">
|
|
||||||
<span>CPU</span>
|
|
||||||
</div>
|
|
||||||
<el-row class="row">
|
|
||||||
<el-col :span="8">
|
|
||||||
属性
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
值
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row class="rowlist">
|
|
||||||
<el-col :span="8">
|
|
||||||
逻辑核心数
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
{{cpuData.count}}
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row class="rowlist">
|
|
||||||
<el-col :span="8">
|
|
||||||
物理核心数
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
{{cpuData.lcount}}
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row class="rowlist">
|
|
||||||
<el-col :span="8">
|
|
||||||
当前使用率
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
{{cpuData.percent}}%
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-card shadow="always">
|
|
||||||
<div slot="header" class="clearfix">
|
|
||||||
<span>内存</span>
|
|
||||||
</div>
|
|
||||||
<el-row class="row">
|
|
||||||
<el-col :span="8">
|
|
||||||
属性
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
值
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row class="rowlist">
|
|
||||||
<el-col :span="8">
|
|
||||||
使用率
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
{{memoryData.percent}}%
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row class="rowlist">
|
|
||||||
<el-col :span="8">
|
|
||||||
总内存
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
{{memoryData.total}}
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row class="rowlist">
|
|
||||||
<el-col :span="8">
|
|
||||||
已用内存
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
{{memoryData.used}}
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-card shadow="always">
|
|
||||||
<div slot="header" class="clearfix">
|
|
||||||
<span>硬盘</span>
|
|
||||||
</div>
|
|
||||||
<el-row class="row">
|
|
||||||
<el-col :span="8">
|
|
||||||
属性
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
值
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row class="rowlist">
|
|
||||||
<el-col :span="8">
|
|
||||||
已用百分比
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
{{diskData.percent}}%
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row class="rowlist">
|
|
||||||
<el-col :span="8">
|
|
||||||
总大小
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
{{diskData.total}}
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<el-row class="rowlist">
|
|
||||||
<el-col :span="8">
|
|
||||||
已用大小
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
{{diskData.used}}
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-card class="box-card">
|
|
||||||
<div slot="header" class="clearfix">
|
<div slot="header" class="clearfix">
|
||||||
<span>日志列表</span>
|
<span>日志列表</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -141,45 +83,33 @@
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="el-icon-search"
|
icon="el-icon-search"
|
||||||
@click="handleFilter"
|
@click="handleFilter"
|
||||||
>搜索
|
>搜索
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
class="filter-item"
|
class="filter-item"
|
||||||
type="primary"
|
type="primary"
|
||||||
icon="el-icon-refresh-left"
|
icon="el-icon-refresh-left"
|
||||||
@click="resetFilter"
|
@click="resetFilter"
|
||||||
>重置
|
>重置
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-table
|
<el-table
|
||||||
:data="tableData"
|
:data="tableData"
|
||||||
style="width: 100%;height:400px"
|
style="width: 100%"
|
||||||
|
height="100"
|
||||||
|
v-el-height-adaptive-table="{ bottomOffset: 30 }"
|
||||||
>
|
>
|
||||||
<el-table-column
|
<el-table-column prop="name" label="日志名称"> </el-table-column>
|
||||||
prop="name"
|
<el-table-column prop="size" label="日志大小"> </el-table-column>
|
||||||
label="日志名称"
|
<el-table-column fixed="right" label="操作" width="100">
|
||||||
>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
prop="size"
|
|
||||||
label="日志大小"
|
|
||||||
>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
fixed="right"
|
|
||||||
label="操作"
|
|
||||||
width="100"
|
|
||||||
>
|
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button @click="handleClick(scope.row)" type="text" size="small">查看详情</el-button>
|
<el-button @click="handleClick(scope.row)" type="text" size="small"
|
||||||
|
>查看详情</el-button
|
||||||
|
>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<el-dialog
|
<el-dialog :visible.sync="dialogVisible" width="80%" title="日志详情">
|
||||||
:visible.sync="dialogVisible"
|
|
||||||
width="80%"
|
|
||||||
title="日志详情"
|
|
||||||
>
|
|
||||||
<div v-html="logdec" class="dialogDiv"></div>
|
<div v-html="logdec" class="dialogDiv"></div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
@ -188,121 +118,60 @@
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {getlogList, getLog, getServerList} from "@/api/moritor";
|
import { getlogList, getLog, getServerList } from "@/api/moritor";
|
||||||
|
|
||||||
const defaultCMA = {}
|
const defaultCMA = {};
|
||||||
export default {
|
export default {
|
||||||
components: {},
|
components: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tableData: [],
|
tableData: [],
|
||||||
cpuData: [],
|
cpuData: [],
|
||||||
diskData: [],
|
diskData: [],
|
||||||
memoryData: [],
|
memoryData: [],
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
logdec: "",
|
logdec: "",
|
||||||
text: "",
|
text: "",
|
||||||
listQuery: {},
|
listQuery: {},
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
created() {
|
||||||
|
this.getlogList();
|
||||||
|
this.getServerList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getlogList() {
|
||||||
|
getlogList(this.listQuery).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.tableData = response.data;
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
computed: {},
|
handleFilter() {
|
||||||
watch: {},
|
|
||||||
created() {
|
|
||||||
this.getlogList();
|
this.getlogList();
|
||||||
this.getServerList();
|
|
||||||
},
|
},
|
||||||
methods: {
|
resetFilter() {
|
||||||
|
this.getlogList();
|
||||||
getlogList() {
|
|
||||||
getlogList(this.listQuery).then((response) => {
|
|
||||||
if (response.data) {
|
|
||||||
|
|
||||||
this.tableData = response.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleFilter() {
|
|
||||||
this.getlogList();
|
|
||||||
},
|
|
||||||
resetFilter() {
|
|
||||||
|
|
||||||
this.getlogList();
|
|
||||||
},
|
|
||||||
getServerList() {
|
|
||||||
getServerList().then((response) => {
|
|
||||||
if (response.data) {
|
|
||||||
this.cpuData = response.data.cpu;
|
|
||||||
this.diskData = response.data.disk;
|
|
||||||
this.memoryData = response.data.memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleClick(row) {
|
|
||||||
this.dialogVisible = true;
|
|
||||||
getLog(row.name).then((response) => {
|
|
||||||
if (response.data) {
|
|
||||||
this.logdec = response.data.replace(/\n/gm, "<br/>")
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
getServerList() {
|
||||||
</script>
|
getServerList().then((response) => {
|
||||||
<style>
|
if (response.data) {
|
||||||
::-webkit-scrollbar {
|
this.cpuData = response.data.cpu;
|
||||||
width: 10px;
|
this.diskData = response.data.disk;
|
||||||
}
|
this.memoryData = response.data.memory;
|
||||||
::-webkit-scrollbar-track{
|
}
|
||||||
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.2);
|
});
|
||||||
background-color: #fefefe;
|
},
|
||||||
border-radius: 7px;
|
handleClick(row) {
|
||||||
}
|
this.dialogVisible = true;
|
||||||
::-webkit-scrollbar-thumb{
|
getLog(row.name).then((response) => {
|
||||||
border-radius: 7px;
|
if (response.data) {
|
||||||
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.2);
|
this.logdec = response.data.replace(/\n/gm, "<br/>");
|
||||||
background-color: #f5f5f5;
|
}
|
||||||
}
|
});
|
||||||
.dialogDiv{
|
},
|
||||||
height: 70vh;
|
},
|
||||||
overflow-y: scroll;
|
};
|
||||||
}
|
</script>
|
||||||
.text {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item {
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clearfix:before,
|
|
||||||
.clearfix:after {
|
|
||||||
display: table;
|
|
||||||
content: "";
|
|
||||||
}
|
|
||||||
|
|
||||||
.clearfix:after {
|
|
||||||
clear: both
|
|
||||||
}
|
|
||||||
|
|
||||||
.box-card {
|
|
||||||
width: 90%;
|
|
||||||
margin: 0 auto;
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
border-bottom: 1px solid #dfe6ec;
|
|
||||||
color: #909399;
|
|
||||||
font-weight: 500;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rowlist {
|
|
||||||
border-bottom: 1px solid #dfe6ec;
|
|
||||||
color: #606266;
|
|
||||||
font-weight: 500;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -24,13 +24,13 @@
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增物料</el-button
|
>新增物料</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="materialList.results"
|
:data="materialList.results"
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-card>
|
<el-card>
|
||||||
|
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增工序</el-button
|
>新增工序</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="processList.results"
|
:data="processList.results"
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
<el-row :gutter="24">
|
<el-row :gutter="24">
|
||||||
<el-col :span="6" >
|
<el-col :span="6" >
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增</el-button>
|
>新增</el-button>
|
||||||
<el-table
|
<el-table
|
||||||
|
|
|
@ -24,13 +24,13 @@
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增供应商</el-button
|
>新增供应商</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="vendorList.results"
|
:data="vendorList.results"
|
||||||
|
|
|
@ -24,13 +24,13 @@
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增标准</el-button
|
>新增标准</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="standardList.results"
|
:data="standardList.results"
|
||||||
|
|
|
@ -24,13 +24,13 @@
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增项目</el-button
|
>新增项目</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="testitemList.results"
|
:data="testitemList.results"
|
||||||
|
|
|
@ -24,13 +24,13 @@
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增客户</el-button
|
>新增客户</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="contractList.results"
|
:data="contractList.results"
|
||||||
|
|
|
@ -24,13 +24,13 @@
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增客户</el-button
|
>新增客户</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="customerList.results"
|
:data="customerList.results"
|
||||||
|
|
|
@ -24,13 +24,13 @@
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增订单</el-button
|
>新增订单</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="orderList.results"
|
:data="orderList.results"
|
||||||
|
|
|
@ -24,13 +24,13 @@
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增客户</el-button
|
>新增客户</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="contractList.results"
|
:data="contractList.results"
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
highlight-current
|
highlight-current
|
||||||
:expand-on-click-node="false"
|
:expand-on-click-node="false"
|
||||||
:filter-node-method="filterNode"
|
:filter-node-method="filterNode"
|
||||||
style="margin-top:10px;"
|
style="margin-top: 2px;"
|
||||||
@node-click="handleDictTypeClick"
|
@node-click="handleDictTypeClick"
|
||||||
>
|
>
|
||||||
<span class="custom-tree-node" slot-scope="{ node, data }">
|
<span class="custom-tree-node" slot-scope="{ node, data }">
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
v-show="listQuery.type"
|
v-show="listQuery.type"
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="dictList"
|
:data="dictList"
|
||||||
style="width: 100%;margin-top:10px;"
|
style="width: 100%;margin-top: 2px;"
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
row-key="id"
|
row-key="id"
|
||||||
height="100"
|
height="100"
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="fileList.results"
|
:data="fileList.results"
|
||||||
style="width: 100%;margin-top:10px;"
|
style="width: 100%;margin-top: 2px;"
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
row-key="id"
|
row-key="id"
|
||||||
height="100"
|
height="100"
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
!search || data.name.toLowerCase().includes(search.toLowerCase())
|
!search || data.name.toLowerCase().includes(search.toLowerCase())
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
style="width: 100%; margin-top: 10px"
|
style="width: 100%; margin-top: 2px"
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
row-key="id"
|
row-key="id"
|
||||||
height="100"
|
height="100"
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
!search || data.name.toLowerCase().includes(search.toLowerCase())
|
!search || data.name.toLowerCase().includes(search.toLowerCase())
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
style="width: 100%; margin-top: 10px"
|
style="width: 100%; margin-top: 2px"
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
row-key="id"
|
row-key="id"
|
||||||
height="100"
|
height="100"
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
!search || data.name.toLowerCase().includes(search.toLowerCase())
|
!search || data.name.toLowerCase().includes(search.toLowerCase())
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
style="width: 100%; margin-top: 10px"
|
style="width: 100%; margin-top: 2px"
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
row-key="id"
|
row-key="id"
|
||||||
height="100"
|
height="100"
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="tableData"
|
:data="tableData"
|
||||||
style="width: 100%; margin-top: 10px"
|
style="width: 100%; margin-top: 2px"
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
row-key="id"
|
row-key="id"
|
||||||
height="100"
|
height="100"
|
||||||
|
|
|
@ -53,7 +53,7 @@
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="dataList.results"
|
:data="dataList.results"
|
||||||
style="width: 100%; margin-top: 10px"
|
style="width: 100%; margin-top: 2px"
|
||||||
highlight-current-row
|
highlight-current-row
|
||||||
row-key="id"
|
row-key="id"
|
||||||
height="100"
|
height="100"
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-card>
|
<el-card>
|
||||||
|
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增</el-button
|
>新增</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
|
|
||||||
:data="customfieldList"
|
:data="customfieldList"
|
||||||
|
|
|
@ -24,11 +24,11 @@
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate">新增</el-button>
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate">新增</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="workflowList.results"
|
:data="workflowList.results"
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-card>
|
<el-card>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate">新增
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate">新增
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
:data="wfstateList"
|
:data="wfstateList"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
@ -166,7 +166,7 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="字段状态">
|
<el-form-item label="字段状态">
|
||||||
<el-button @click="addWordStatusChange">添加修改</el-button>
|
<el-button @click="addWordStatusChange">添加修改</el-button>
|
||||||
<el-row v-for="(item,$index) in statusChange" :key="item+$index" style="margin-top: 10px">
|
<el-row v-for="(item,$index) in statusChange" :key="item+$index" style="margin-top: 2px">
|
||||||
<el-col :span="11">
|
<el-col :span="11">
|
||||||
<el-select style="width: 100%" v-model="item.name" placeholder="请选择字段">
|
<el-select style="width: 100%" v-model="item.name" placeholder="请选择字段">
|
||||||
<el-option v-for="item in customfieldList" :key="item.id" :label="item.field_name"
|
<el-option v-for="item in customfieldList" :key="item.id" :label="item.field_name"
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
@click="handleFilter"
|
@click="handleFilter"
|
||||||
>搜索</el-button>
|
>搜索</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate">新增</el-button>
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate">新增</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-card>
|
<el-card>
|
||||||
|
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增</el-button
|
>新增</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
:data="wftransitionList"
|
:data="wftransitionList"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
|
|
@ -24,13 +24,13 @@
|
||||||
>重置</el-button
|
>重置</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 10px">
|
<div style="margin-top: 2px">
|
||||||
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
>新增项目</el-button
|
>新增项目</el-button
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-card style="margin-top: 10px">
|
<el-card style="margin-top: 2px">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
:data="testitemList.results"
|
:data="testitemList.results"
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Generated by Django 3.2.6 on 2021-11-02 01:35
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wpm', '0002_auto_20211029_1336'),
|
||||||
|
('inm', '0007_auto_20211028_1331'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='iproduct',
|
||||||
|
name='wproduct',
|
||||||
|
field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.CASCADE, to='wpm.wproduct', verbose_name='关联的动态产品'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='materialbatch',
|
||||||
|
name='batch',
|
||||||
|
field=models.CharField(blank=True, max_length=100, null=True, verbose_name='批次号'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Generated by Django 3.2.6 on 2021-11-02 03:13
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('inm', '0008_auto_20211102_0935'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='fifo',
|
||||||
|
name='is_audited',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='是否审核'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='fifodetail',
|
||||||
|
name='is_tested',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='是否检测'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Generated by Django 3.2.6 on 2021-11-02 08:31
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('inm', '0009_auto_20211102_1113'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='fifodetail',
|
||||||
|
name='is_testok',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='是否检测合格'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='fifodetail',
|
||||||
|
name='is_tested',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='是否已检测'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -41,7 +41,7 @@ class MaterialBatch(BaseModel):
|
||||||
material = models.ForeignKey(Material, on_delete=models.CASCADE, verbose_name='物料信息')
|
material = models.ForeignKey(Material, on_delete=models.CASCADE, verbose_name='物料信息')
|
||||||
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
||||||
count = models.IntegerField('存量', default=0)
|
count = models.IntegerField('存量', default=0)
|
||||||
batch = models.CharField('批次号', max_length=100, null=True, blank=True, unique=True)
|
batch = models.CharField('批次号', max_length=100, null=True, blank=True)
|
||||||
expiration_date = models.DateField('有效期', null=True, blank=True)
|
expiration_date = models.DateField('有效期', null=True, blank=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '库存表'
|
verbose_name = '库存表'
|
||||||
|
@ -60,6 +60,7 @@ class FIFO(CommonAModel):
|
||||||
(4, '生产入库')
|
(4, '生产入库')
|
||||||
)
|
)
|
||||||
type = models.IntegerField('出入库类型', default=1)
|
type = models.IntegerField('出入库类型', default=1)
|
||||||
|
is_audited = models.BooleanField('是否审核', default=False)
|
||||||
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='仓库')
|
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='仓库')
|
||||||
operator = models.ForeignKey(User, verbose_name='操作人', on_delete=models.CASCADE)
|
operator = models.ForeignKey(User, verbose_name='操作人', on_delete=models.CASCADE)
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.DO_NOTHING, null=True, blank=True)
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.DO_NOTHING, null=True, blank=True)
|
||||||
|
@ -71,6 +72,8 @@ class FIFODetail(BaseModel):
|
||||||
"""
|
"""
|
||||||
出入库详细记录
|
出入库详细记录
|
||||||
"""
|
"""
|
||||||
|
is_tested = models.BooleanField('是否已检测', default=False)
|
||||||
|
is_testok = models.BooleanField('是否检测合格', default=False)
|
||||||
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||||
count = models.IntegerField('数量', default=0)
|
count = models.IntegerField('数量', default=0)
|
||||||
batch = models.CharField('批次号', max_length=100, null=True, blank=True)
|
batch = models.CharField('批次号', max_length=100, null=True, blank=True)
|
||||||
|
|
|
@ -83,9 +83,10 @@ class FIFOInPurSerializer(serializers.ModelSerializer):
|
||||||
for i in details:
|
for i in details:
|
||||||
# 校验批次
|
# 校验批次
|
||||||
try:
|
try:
|
||||||
obj = MaterialBatch.objects.get(batch=i['batch'])
|
if i['batch']:
|
||||||
if obj.warehouse != validated_data['warehouse']:
|
obj = MaterialBatch.objects.get(batch=i['batch'], material=i['material'])
|
||||||
raise serializers.ValidationError('批次号{}在其他仓库已存在'.format(i['batch']))
|
if obj.warehouse != validated_data['warehouse']:
|
||||||
|
raise serializers.ValidationError('批次号{}在其他仓库已存在'.format(i['batch']))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -1,35 +1,38 @@
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
|
||||||
from apps.inm.models import FIFODetail, Inventory, MaterialBatch
|
from apps.inm.models import Inventory, MaterialBatch, FIFO, FIFODetail
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=FIFODetail)
|
def update_inm(instance:FIFO, type:int=1):
|
||||||
def update_by_fifodetail(sender, instance, created, **kwargs):
|
"""
|
||||||
if created:
|
更新库存(正反)
|
||||||
fifo = instance.fifo
|
"""
|
||||||
material = instance.material
|
warehouse = instance.warehouse
|
||||||
warehouse = fifo.warehouse
|
if instance.type in [3]: # 采购入库
|
||||||
if fifo.type in [3]: # 采购入库
|
# 更新相关表
|
||||||
# 更新相关表
|
for i in FIFODetail.objects.filter(fifo=instance):
|
||||||
|
material = i.material
|
||||||
o1, _ = Inventory.objects.get_or_create(material=material, warehouse=warehouse, \
|
o1, _ = Inventory.objects.get_or_create(material=material, warehouse=warehouse, \
|
||||||
defaults={'material':material, 'warehouse':warehouse, 'count':0})
|
defaults={'material':material, 'warehouse':warehouse, 'count':0})
|
||||||
o1.count = o1.count + instance.count
|
o1.count = o1.count + i.count
|
||||||
o1.save()
|
o1.save()
|
||||||
o2, _ = MaterialBatch.objects.get_or_create(material=material, warehouse=warehouse, batch=instance.batch,\
|
o2, _ = MaterialBatch.objects.get_or_create(material=material, warehouse=warehouse, batch=i.batch,\
|
||||||
defaults={'material':material, 'warehouse':warehouse, 'count':0, 'batch':instance.batch})
|
defaults={'material':material, 'warehouse':warehouse, 'count':0, 'batch':i.batch})
|
||||||
o2.count = o2.count + instance.count
|
o2.count = o2.count + i.count
|
||||||
o2.save()
|
o2.save()
|
||||||
material.count = material.count + instance.count
|
material.count = material.count + i.count
|
||||||
material.save()
|
material.save()
|
||||||
elif fifo.type in [1]: # 生产领料
|
elif instance.type in [1]: # 生产领料
|
||||||
# 更新相关表
|
# 更新相关表
|
||||||
|
for i in FIFODetail.objects.filter(fifo=instance):
|
||||||
|
material = i.material
|
||||||
o1 = Inventory.objects.get(material=material, warehouse=warehouse)
|
o1 = Inventory.objects.get(material=material, warehouse=warehouse)
|
||||||
o1.count = o1.count - instance.count
|
o1.count = o1.count - i.count
|
||||||
o1.save()
|
o1.save()
|
||||||
o2 = MaterialBatch.objects.get(material=material, warehouse=warehouse, batch=instance.batch)
|
o2 = MaterialBatch.objects.get(material=material, warehouse=warehouse, batch=i.batch)
|
||||||
o2.count = o2.count - instance.count
|
o2.count = o2.count - i.count
|
||||||
o2.save()
|
o2.save()
|
||||||
material.count = material.count - instance.count
|
material.count = material.count - i.count
|
||||||
material.save()
|
material.save()
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
from rest_framework.exceptions import APIException
|
||||||
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin
|
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||||
from apps.inm.filters import MbFilterSet
|
from apps.inm.filters import MbFilterSet
|
||||||
|
|
||||||
from apps.inm.models import FIFO, FIFODetail, MaterialBatch, WareHouse,Inventory
|
from apps.inm.models import FIFO, FIFODetail, MaterialBatch, WareHouse,Inventory
|
||||||
from apps.inm.serializers import FIFODetailSerializer, FIFOInPurSerializer, FIFOListSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer,InventorySerializer
|
from apps.inm.serializers import FIFODetailSerializer, FIFOInPurSerializer, FIFOListSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer,InventorySerializer
|
||||||
|
from apps.inm.signals import update_inm
|
||||||
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
@ -72,7 +74,7 @@ class FIFODetailViewSet(ListModelMixin, GenericViewSet):
|
||||||
search_fields = []
|
search_fields = []
|
||||||
ordering_fields = ['create_time']
|
ordering_fields = ['create_time']
|
||||||
ordering = ['-create_time']
|
ordering = ['-create_time']
|
||||||
|
|
||||||
class FIFOViewSet(ListModelMixin, GenericViewSet):
|
class FIFOViewSet(ListModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
出入库记录
|
出入库记录
|
||||||
|
@ -80,7 +82,10 @@ class FIFOViewSet(ListModelMixin, GenericViewSet):
|
||||||
perms_map = {'*': '*'}
|
perms_map = {'*': '*'}
|
||||||
queryset = FIFO.objects.select_related('warehouse', 'operator')
|
queryset = FIFO.objects.select_related('warehouse', 'operator')
|
||||||
serializer_class = FIFOListSerializer
|
serializer_class = FIFOListSerializer
|
||||||
filterset_fields = ['warehouse', 'type']
|
filterset_fields = '__all__'
|
||||||
|
ordering_fields = '__all__'
|
||||||
|
search_fields = ['warehouse__name', 'warehouse__number']
|
||||||
|
ordering = ['-pk']
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
if self.action == 'list':
|
if self.action == 'list':
|
||||||
|
@ -96,4 +101,18 @@ class FIFOViewSet(ListModelMixin, GenericViewSet):
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
serializer.save(create_by=request.user)
|
serializer.save(create_by=request.user)
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=serializers.Serializer)
|
||||||
|
def audit(self, request, pk=None):
|
||||||
|
"""
|
||||||
|
审核通过
|
||||||
|
"""
|
||||||
|
obj = self.get_object()
|
||||||
|
for i in FIFODetail.objects.filter(fifo=obj):
|
||||||
|
if not i.is_testok:
|
||||||
|
raise APIException('未检验通过, 不可审核')
|
||||||
|
obj.is_audited = True
|
||||||
|
obj.save()
|
||||||
|
update_inm(obj) # 更新库存
|
||||||
|
return Response()
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.6 on 2021-11-02 08:31
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('mtm', '0026_auto_20211101_1522'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='recordformfield',
|
||||||
|
name='need_judge',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='需要判定项目'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,40 @@
|
||||||
|
# Generated by Django 3.2.6 on 2021-11-02 09:07
|
||||||
|
|
||||||
|
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),
|
||||||
|
('mtm', '0027_alter_recordformfield_need_judge'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SubprodctionMaterial',
|
||||||
|
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='删除标记')),
|
||||||
|
('is_main', models.BooleanField(default=False, verbose_name='是否主产出')),
|
||||||
|
('count', models.FloatField(default=0, verbose_name='消耗量/产出量')),
|
||||||
|
('type', models.IntegerField(default=1, verbose_name='物料应用类型')),
|
||||||
|
('sort', models.IntegerField(default=1, verbose_name='排序号')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subprodctionmaterial_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subplan_material', to='mtm.material', verbose_name='物料')),
|
||||||
|
('subproduction', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.subproduction', verbose_name='关联生产分解')),
|
||||||
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subprodctionmaterial_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='SubplanMaterial',
|
||||||
|
),
|
||||||
|
]
|
|
@ -88,6 +88,7 @@ class RecordForm(CommonAModel):
|
||||||
type = models.IntegerField('表格类型', choices=type_choices, default=1)
|
type = models.IntegerField('表格类型', choices=type_choices, default=1)
|
||||||
step = models.ForeignKey(Step, verbose_name='关联子工序', on_delete=models.CASCADE, null=True, blank=True)
|
step = models.ForeignKey(Step, verbose_name='关联子工序', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE, null=True, blank=True)
|
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '记录表格'
|
verbose_name = '记录表格'
|
||||||
verbose_name_plural = verbose_name
|
verbose_name_plural = verbose_name
|
||||||
|
@ -130,7 +131,7 @@ class RecordFormField(CommonAModel):
|
||||||
field_choice = models.JSONField('radio、checkbox、select的选项', default=dict, blank=True, null=True,
|
field_choice = models.JSONField('radio、checkbox、select的选项', default=dict, blank=True, null=True,
|
||||||
help_text='radio,checkbox,select,multiselect类型可供选择的选项,格式为json如:{"1":"中国", "2":"美国"},注意数字也需要引号')
|
help_text='radio,checkbox,select,multiselect类型可供选择的选项,格式为json如:{"1":"中国", "2":"美国"},注意数字也需要引号')
|
||||||
sort = models.IntegerField('排序号', default=1)
|
sort = models.IntegerField('排序号', default=1)
|
||||||
need_judge = models.BooleanField('需要判定', default=False)
|
need_judge = models.BooleanField('需要判定项目', default=False)
|
||||||
high_limit = models.FloatField('上限值', null=True, blank=True)
|
high_limit = models.FloatField('上限值', null=True, blank=True)
|
||||||
high_rule = models.IntegerField('上限规则', choices=high_rule_choices, null=True, blank=True)
|
high_rule = models.IntegerField('上限规则', choices=high_rule_choices, null=True, blank=True)
|
||||||
low_limit = models.FloatField('下限值', null=True, blank=True)
|
low_limit = models.FloatField('下限值', null=True, blank=True)
|
||||||
|
@ -159,7 +160,7 @@ class SubProduction(CommonAModel):
|
||||||
verbose_name = '产品生产工序'
|
verbose_name = '产品生产工序'
|
||||||
verbose_name_plural = verbose_name
|
verbose_name_plural = verbose_name
|
||||||
|
|
||||||
class SubplanMaterial(CommonAModel):
|
class SubprodctionMaterial(CommonAModel):
|
||||||
"""
|
"""
|
||||||
输入/输出物料/工具工装
|
输入/输出物料/工具工装
|
||||||
"""
|
"""
|
||||||
|
@ -170,7 +171,7 @@ class SubplanMaterial(CommonAModel):
|
||||||
)
|
)
|
||||||
material = models.ForeignKey(Material, verbose_name='物料', on_delete=models.CASCADE, related_name='subplan_material')
|
material = models.ForeignKey(Material, verbose_name='物料', on_delete=models.CASCADE, related_name='subplan_material')
|
||||||
is_main = models.BooleanField('是否主产出', default=False) # 以该产品完成度计算进度
|
is_main = models.BooleanField('是否主产出', default=False) # 以该产品完成度计算进度
|
||||||
count = models.FloatField('消耗量/产出量', default=1)
|
count = models.FloatField('消耗量/产出量', default=0)
|
||||||
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE)
|
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE)
|
||||||
type = models.IntegerField('物料应用类型', default=1)
|
type = models.IntegerField('物料应用类型', default=1)
|
||||||
sort = models.IntegerField('排序号', default=1)
|
sort = models.IntegerField('排序号', default=1)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from apps.em.serializers import EquipmentSimpleSerializer
|
from apps.em.serializers import EquipmentSimpleSerializer
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.exceptions import ParseError, ValidationError
|
from rest_framework.exceptions import ParseError, ValidationError
|
||||||
from .models import Material, Process, RecordForm, RecordFormField, Step, SubplanMaterial, TechDoc, UsedStep, SubProduction
|
from .models import Material, Process, RecordForm, RecordFormField, Step, SubprodctionMaterial, TechDoc, UsedStep, SubProduction
|
||||||
from apps.system.serializers import FileSimpleSerializer, OrganizationSimpleSerializer
|
from apps.system.serializers import FileSimpleSerializer, OrganizationSimpleSerializer
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,53 +69,53 @@ class SubProductionSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class OtherMaterialSerializer(serializers.ModelSerializer):
|
class OtherMaterialSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SubplanMaterial
|
model = SubprodctionMaterial
|
||||||
fields = ['sort', 'material', 'subproduction']
|
fields = ['sort', 'material', 'subproduction']
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
if SubplanMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False, type=3).exists():
|
if SubprodctionMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False, type=3).exists():
|
||||||
raise ValidationError('该物料已存在')
|
raise ValidationError('该物料已存在')
|
||||||
validated_data['type']=3
|
validated_data['type']=3
|
||||||
return super().create(validated_data)
|
return super().create(validated_data)
|
||||||
|
|
||||||
class SubplanMaterialListSerializer(serializers.ModelSerializer):
|
class SubprodctionMaterialListSerializer(serializers.ModelSerializer):
|
||||||
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SubplanMaterial
|
model = SubprodctionMaterial
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
class InputMaterialSerializer(serializers.ModelSerializer):
|
class InputMaterialSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SubplanMaterial
|
model = SubprodctionMaterial
|
||||||
fields = ['count', 'sort', 'material', 'subproduction']
|
fields = ['count', 'sort', 'material', 'subproduction']
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
if SubplanMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False, type=1).exists():
|
if SubprodctionMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False, type=1).exists():
|
||||||
raise ValidationError('该物料已存在')
|
raise ValidationError('该物料已存在')
|
||||||
validated_data['type']=1
|
validated_data['type']=1
|
||||||
return super().create(validated_data)
|
return super().create(validated_data)
|
||||||
|
|
||||||
class InputMaterialUpdateSerializer(serializers.ModelSerializer):
|
class InputMaterialUpdateSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SubplanMaterial
|
model = SubprodctionMaterial
|
||||||
fields = ['count', 'sort']
|
fields = ['count', 'sort']
|
||||||
|
|
||||||
class OutputMaterialSerializer(serializers.ModelSerializer):
|
class OutputMaterialSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SubplanMaterial
|
model = SubprodctionMaterial
|
||||||
fields = ['count', 'sort', 'material', 'subproduction', 'is_main']
|
fields = ['count', 'sort', 'material', 'subproduction', 'is_main']
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
if SubplanMaterial.objects.filter(subproduction=validated_data['subproduction'], is_deleted=False, is_main=True, type=2).exists():
|
if SubprodctionMaterial.objects.filter(subproduction=validated_data['subproduction'], is_deleted=False, is_main=True, type=2).exists():
|
||||||
raise ValidationError('主产出只能有1个')
|
raise ValidationError('主产出只能有1个')
|
||||||
if SubplanMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False, type=2).exists():
|
if SubprodctionMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False, type=2).exists():
|
||||||
raise ValidationError('该物料已存在')
|
raise ValidationError('该物料已存在')
|
||||||
validated_data['type']=2
|
validated_data['type']=2
|
||||||
return super().create(validated_data)
|
return super().create(validated_data)
|
||||||
|
|
||||||
class OutputMaterialUpdateSerializer(serializers.ModelSerializer):
|
class OutputMaterialUpdateSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SubplanMaterial
|
model = SubprodctionMaterial
|
||||||
fields = ['count', 'sort', 'is_main']
|
fields = ['count', 'sort', 'is_main']
|
||||||
|
|
||||||
|
|
||||||
|
@ -151,6 +151,11 @@ class UsedStepListSerializer(serializers.ModelSerializer):
|
||||||
queryset = queryset.select_related('step')
|
queryset = queryset.select_related('step')
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
class RecordFormSimpleSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = RecordForm
|
||||||
|
fields = ['id', 'name']
|
||||||
class RecordFormSerializer(serializers.ModelSerializer):
|
class RecordFormSerializer(serializers.ModelSerializer):
|
||||||
step_ = StepSimpleSerializer(source='step', read_only=True)
|
step_ = StepSimpleSerializer(source='step', read_only=True)
|
||||||
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
||||||
|
@ -182,6 +187,26 @@ class RecordFormFieldSerializer(serializers.ModelSerializer):
|
||||||
model = RecordFormField
|
model = RecordFormField
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
class RecordFormDetailSerializer(serializers.ModelSerializer):
|
||||||
|
step_ = StepSimpleSerializer(source='step', read_only=True)
|
||||||
|
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
||||||
|
form_fields = serializers.SerializerMethodField()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = RecordForm
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def setup_eager_loading(queryset):
|
||||||
|
""" Perform necessary eager loading of data. """
|
||||||
|
queryset = queryset.select_related('step', 'material')
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
def get_form_fields(self, obj):
|
||||||
|
serializer = RecordFormFieldSerializer(instance=RecordFormField.objects.filter(form=obj, is_deleted=False), many=True)
|
||||||
|
return serializer.data
|
||||||
|
|
||||||
|
|
||||||
class RecordFormFieldCreateSerializer(serializers.ModelSerializer):
|
class RecordFormFieldCreateSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = RecordFormField
|
model = RecordFormField
|
||||||
|
|
|
@ -2,8 +2,8 @@ from django.shortcuts import render
|
||||||
from rest_framework.viewsets import ModelViewSet, GenericViewSet
|
from rest_framework.viewsets import ModelViewSet, GenericViewSet
|
||||||
from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin
|
from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin
|
||||||
|
|
||||||
from apps.mtm.models import Material, Process, RecordForm, RecordFormField, Step, SubplanMaterial, TechDoc, UsedStep, SubProduction
|
from apps.mtm.models import Material, Process, RecordForm, RecordFormField, Step, SubprodctionMaterial, TechDoc, UsedStep, SubProduction
|
||||||
from apps.mtm.serializers import InputMaterialSerializer, InputMaterialUpdateSerializer, MaterialDetailSerializer, MaterialSerializer, MaterialSimpleSerializer, OtherMaterialSerializer, OutputMaterialSerializer, OutputMaterialUpdateSerializer, ProcessSerializer, RecordFormCreateSerializer, RecordFormFieldCreateSerializer, RecordFormFieldSerializer, RecordFormFieldUpdateSerializer, RecordFormSerializer, RecordFormUpdateSerializer, StepDetailSerializer, StepSerializer, SubProductionSerializer, SubplanMaterialListSerializer, TechDocCreateSerializer, TechDocListSerializer, TechDocUpdateSerializer, UsedStepCreateSerializer, UsedStepListSerializer, UsedStepUpdateSerializer
|
from apps.mtm.serializers import InputMaterialSerializer, InputMaterialUpdateSerializer, MaterialDetailSerializer, MaterialSerializer, MaterialSimpleSerializer, OtherMaterialSerializer, OutputMaterialSerializer, OutputMaterialUpdateSerializer, ProcessSerializer, RecordFormCreateSerializer, RecordFormDetailSerializer, RecordFormFieldCreateSerializer, RecordFormFieldSerializer, RecordFormFieldUpdateSerializer, RecordFormSerializer, RecordFormUpdateSerializer, StepDetailSerializer, StepSerializer, SubProductionSerializer, SubprodctionMaterialListSerializer, TechDocCreateSerializer, TechDocListSerializer, TechDocUpdateSerializer, UsedStepCreateSerializer, UsedStepListSerializer, UsedStepUpdateSerializer
|
||||||
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
@ -85,14 +85,14 @@ class InputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||||
输入物料-增删改查
|
输入物料-增删改查
|
||||||
"""
|
"""
|
||||||
perms_map = {'*':'*'}
|
perms_map = {'*':'*'}
|
||||||
queryset = SubplanMaterial.objects.select_related('material').filter(type=1)
|
queryset = SubprodctionMaterial.objects.select_related('material').filter(type=1)
|
||||||
serializer_class = InputMaterialSerializer
|
serializer_class = InputMaterialSerializer
|
||||||
filterset_fields = ['subproduction']
|
filterset_fields = ['subproduction']
|
||||||
ordering = ['sort', '-create_time']
|
ordering = ['sort', '-create_time']
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
if self.action == 'list':
|
if self.action == 'list':
|
||||||
return SubplanMaterialListSerializer
|
return SubprodctionMaterialListSerializer
|
||||||
elif self.action == 'update':
|
elif self.action == 'update':
|
||||||
return InputMaterialUpdateSerializer
|
return InputMaterialUpdateSerializer
|
||||||
return InputMaterialSerializer
|
return InputMaterialSerializer
|
||||||
|
@ -102,14 +102,14 @@ class OutputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||||
输出物料-增删改查
|
输出物料-增删改查
|
||||||
"""
|
"""
|
||||||
perms_map = {'*':'*'}
|
perms_map = {'*':'*'}
|
||||||
queryset = SubplanMaterial.objects.select_related('material').filter(type=2)
|
queryset = SubprodctionMaterial.objects.select_related('material').filter(type=2)
|
||||||
serializer_class = OutputMaterialSerializer
|
serializer_class = OutputMaterialSerializer
|
||||||
filterset_fields = ['subproduction']
|
filterset_fields = ['subproduction']
|
||||||
ordering = ['sort', '-create_time']
|
ordering = ['sort', '-create_time']
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
if self.action == 'list':
|
if self.action == 'list':
|
||||||
return SubplanMaterialListSerializer
|
return SubprodctionMaterialListSerializer
|
||||||
elif self.action == 'update':
|
elif self.action == 'update':
|
||||||
return OutputMaterialUpdateSerializer
|
return OutputMaterialUpdateSerializer
|
||||||
return OutputMaterialSerializer
|
return OutputMaterialSerializer
|
||||||
|
@ -119,14 +119,14 @@ class OtherMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, DestroyModel
|
||||||
其他物料-增删改查
|
其他物料-增删改查
|
||||||
"""
|
"""
|
||||||
perms_map = {'*':'*'}
|
perms_map = {'*':'*'}
|
||||||
queryset = SubplanMaterial.objects.select_related('material').filter(type=3)
|
queryset = SubprodctionMaterial.objects.select_related('material').filter(type=3)
|
||||||
serializer_class = OutputMaterialSerializer
|
serializer_class = OutputMaterialSerializer
|
||||||
filterset_fields = ['subproduction']
|
filterset_fields = ['subproduction']
|
||||||
ordering = ['sort', '-create_time']
|
ordering = ['sort', '-create_time']
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
if self.action == 'list':
|
if self.action == 'list':
|
||||||
return SubplanMaterialListSerializer
|
return SubprodctionMaterialListSerializer
|
||||||
return OtherMaterialSerializer
|
return OtherMaterialSerializer
|
||||||
|
|
||||||
class UsedStepViewSet(OptimizationMixin, CreateModelMixin, DestroyModelMixin, ListModelMixin, UpdateModelMixin, GenericViewSet):
|
class UsedStepViewSet(OptimizationMixin, CreateModelMixin, DestroyModelMixin, ListModelMixin, UpdateModelMixin, GenericViewSet):
|
||||||
|
@ -153,12 +153,15 @@ class RecordFormViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet
|
||||||
queryset = RecordForm.objects.all()
|
queryset = RecordForm.objects.all()
|
||||||
filterset_fields = ['step', 'type', 'material']
|
filterset_fields = ['step', 'type', 'material']
|
||||||
search_fields = ['name']
|
search_fields = ['name']
|
||||||
|
ordering='id'
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
if self.action =='create':
|
if self.action =='create':
|
||||||
return RecordFormCreateSerializer
|
return RecordFormCreateSerializer
|
||||||
elif self.action == 'update':
|
elif self.action == 'update':
|
||||||
return RecordFormUpdateSerializer
|
return RecordFormUpdateSerializer
|
||||||
|
elif self.action == 'retrieve':
|
||||||
|
return RecordFormDetailSerializer
|
||||||
return RecordFormSerializer
|
return RecordFormSerializer
|
||||||
|
|
||||||
@action(methods=['get'], detail=True, perms_map={'get':'*'}, pagination_class=None, serializer_class=RecordFormFieldSerializer)
|
@action(methods=['get'], detail=True, perms_map={'get':'*'}, pagination_class=None, serializer_class=RecordFormFieldSerializer)
|
||||||
|
@ -170,6 +173,8 @@ class RecordFormViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet
|
||||||
serializer = self.serializer_class(instance=RecordFormField.objects.filter(form=instance, is_deleted=False), many=True)
|
serializer = self.serializer_class(instance=RecordFormField.objects.filter(form=instance, is_deleted=False), many=True)
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class RecordFormFieldViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet):
|
class RecordFormFieldViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -5,7 +5,7 @@ from apps.em.models import Equipment
|
||||||
from apps.em.serializers import EquipmentSerializer
|
from apps.em.serializers import EquipmentSerializer
|
||||||
from apps.inm.models import MaterialBatch
|
from apps.inm.models import MaterialBatch
|
||||||
from apps.inm.serializers import MaterialBatchSerializer
|
from apps.inm.serializers import MaterialBatchSerializer
|
||||||
from apps.mtm.models import Step, SubProduction, UsedStep
|
from apps.mtm.models import Step, SubProduction, SubprodctionMaterial, UsedStep
|
||||||
from apps.system.mixins import CreateUpdateModelAMixin
|
from apps.system.mixins import CreateUpdateModelAMixin
|
||||||
from apps.pm.serializers import GenSubPlanSerializer, PickNeedSerializer, PlanDestorySerializer, ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer, ResourceCalListSerializer, ResourceCalSerializer, SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer, SubProductionProgressSerializer
|
from apps.pm.serializers import GenSubPlanSerializer, PickNeedSerializer, PlanDestorySerializer, ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer, ResourceCalListSerializer, ResourceCalSerializer, SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer, SubProductionProgressSerializer
|
||||||
from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin
|
from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin
|
||||||
|
@ -87,7 +87,7 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
|
||||||
start_date=production_plan.start_date, end_date=production_plan.end_date,
|
start_date=production_plan.start_date, end_date=production_plan.end_date,
|
||||||
workshop=i.process.workshop, process=i.process, create_by=request.user,
|
workshop=i.process.workshop, process=i.process, create_by=request.user,
|
||||||
steps = list(steps))
|
steps = list(steps))
|
||||||
for m in SubProduction.objects.filter(subproduction=i, is_deleted=False).order_by('sort'):
|
for m in SubprodctionMaterial.objects.filter(subproduction=i, is_deleted=False).order_by('sort'):
|
||||||
SubProductionProgress.objects.create(material=m.material, type=m.type, count=m.count*production_plan.count, subproduction_plan=instance)
|
SubProductionProgress.objects.create(material=m.material, type=m.type, count=m.count*production_plan.count, subproduction_plan=instance)
|
||||||
production_plan.is_planed=True
|
production_plan.is_planed=True
|
||||||
production_plan.save()
|
production_plan.save()
|
||||||
|
@ -187,8 +187,9 @@ class ResourceViewSet(GenericViewSet):
|
||||||
res_d_list = []
|
res_d_list = []
|
||||||
res = []
|
res = []
|
||||||
for i in rdata:
|
for i in rdata:
|
||||||
materials = InputMaterial.objects.filter(subproduction__product__id=i['id'],
|
# 计算输入物料
|
||||||
subproduction__is_deleted=False, is_deleted=False, material__type__in=[3,4]).order_by('material__number')\
|
materials = SubprodctionMaterial.objects.filter(subproduction__product__id=i['id'],
|
||||||
|
subproduction__is_deleted=False, is_deleted=False, material__type__in=[3,4], type=1).order_by('material__number')\
|
||||||
.values('material__id', 'material__name', 'material__number', 'material__type', 'count', 'material__count')
|
.values('material__id', 'material__name', 'material__number', 'material__type', 'count', 'material__count')
|
||||||
l_m = list(materials)
|
l_m = list(materials)
|
||||||
for m in l_m:
|
for m in l_m:
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Generated by Django 3.2.6 on 2021-11-02 08:31
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pum', '0002_vendor_material'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='vendor',
|
||||||
|
name='material',
|
||||||
|
),
|
||||||
|
]
|
|
@ -18,7 +18,6 @@ class Vendor(CommonAModel):
|
||||||
contact_phone = models.CharField('联系电话', max_length=11, unique=True)
|
contact_phone = models.CharField('联系电话', max_length=11, unique=True)
|
||||||
address = models.CharField('地址', max_length=200, null=True, blank=True)
|
address = models.CharField('地址', max_length=200, null=True, blank=True)
|
||||||
description = models.CharField('描述', max_length=200, blank=True, null=True)
|
description = models.CharField('描述', max_length=200, blank=True, null=True)
|
||||||
material = models.CharField('供应的物料', max_length=200, blank=True, null=True)
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '供应商信息'
|
verbose_name = '供应商信息'
|
||||||
verbose_name_plural = verbose_name
|
verbose_name_plural = verbose_name
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
# Generated by Django 3.2.6 on 2021-11-02 08:31
|
||||||
|
|
||||||
|
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', '0010_auto_20211102_1631'),
|
||||||
|
('mtm', '0027_alter_recordformfield_need_judge'),
|
||||||
|
('qm', '0002_alter_analysisitem_rules'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='TestRecord',
|
||||||
|
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='删除标记')),
|
||||||
|
('record_data', models.JSONField(blank=True, default=dict, verbose_name='记录数据')),
|
||||||
|
('is_testok', models.BooleanField(default=True, verbose_name='是否合格')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='testrecord_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('fifo_detail', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='inm.fifodetail', verbose_name='关联的出入库批次')),
|
||||||
|
('form', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.recordform', verbose_name='所用表格')),
|
||||||
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='testrecord_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -38,4 +38,15 @@ class AnalysisItem(CommonAModel):
|
||||||
rules =models.JSONField('判定规则', default=list)
|
rules =models.JSONField('判定规则', default=list)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '检验分析项'
|
verbose_name = '检验分析项'
|
||||||
|
|
||||||
|
class TestRecord(CommonAModel):
|
||||||
|
"""
|
||||||
|
检验记录
|
||||||
|
"""
|
||||||
|
|
||||||
|
form = models.ForeignKey('mtm.recordform', verbose_name='所用表格', on_delete=models.CASCADE)
|
||||||
|
record_data = models.JSONField('记录数据', default=dict, blank=True)
|
||||||
|
is_testok = models.BooleanField('是否合格', default=True)
|
||||||
|
fifo_detail = models.ForeignKey('inm.fifodetail', verbose_name='关联的出入库批次', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
from apps.mtm.models import RecordForm, RecordFormField
|
||||||
|
from apps.mtm.serializers import RecordFormFieldSerializer, RecordFormSimpleSerializer
|
||||||
from apps.system.serializers import FileSimpleSerializer
|
from apps.system.serializers import FileSimpleSerializer
|
||||||
from .models import Standard, TestItem
|
from .models import Standard, TestItem, TestRecord
|
||||||
|
|
||||||
class StandardCreateUpdateSerializer(serializers.ModelSerializer):
|
class StandardCreateUpdateSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -31,3 +33,41 @@ class TestItemSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class AnalysisItemSerializer(serializers.ModelSerializer):
|
class AnalysisItemSerializer(serializers.ModelSerializer):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TestRecordCreateSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = TestRecord
|
||||||
|
fields = ['form', 'record_data', 'is_testok', 'fifo_detail']
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
if 'is_testok' not in validated_data:
|
||||||
|
raise serializers.ValidationError('未填写检测结论')
|
||||||
|
return super().create(validated_data)
|
||||||
|
|
||||||
|
class TestRecordListSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = TestRecord
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class TestRecordDetailSerializer(serializers.ModelSerializer):
|
||||||
|
form_ = RecordFormSimpleSerializer(source='form', read_only=True)
|
||||||
|
record_data_ = serializers.SerializerMethodField()
|
||||||
|
class Meta:
|
||||||
|
model = TestRecord
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def setup_eager_loading(queryset):
|
||||||
|
queryset = queryset.select_related('form','fifo_detail')
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
def get_record_data_(self, obj):
|
||||||
|
record_data = obj.record_data
|
||||||
|
all_fields = RecordFormField.objects.filter(form=obj.form, is_deletd=False).order_by('sort')
|
||||||
|
all_fields_l = RecordFormFieldSerializer(instance=all_fields, many=True).data
|
||||||
|
for i in all_fields_l:
|
||||||
|
key = i['field_key']
|
||||||
|
i['field_value'] = record_data.get(key, None)
|
||||||
|
return all_fields_l
|
|
@ -1,4 +1,4 @@
|
||||||
from apps.qm.views import StandardViewSet, TestItemViewSet
|
from apps.qm.views import StandardViewSet, TestItemViewSet, TestRecordViewSet
|
||||||
from django.db.models import base
|
from django.db.models import base
|
||||||
from rest_framework import urlpatterns
|
from rest_framework import urlpatterns
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
|
@ -7,6 +7,7 @@ from rest_framework.routers import DefaultRouter
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
router.register('standard', StandardViewSet, basename='standard')
|
router.register('standard', StandardViewSet, basename='standard')
|
||||||
router.register('testitem', TestItemViewSet, basename='testitem')
|
router.register('testitem', TestItemViewSet, basename='testitem')
|
||||||
|
router.register('testrecord', TestRecordViewSet, basename='testrecord')
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', include(router.urls)),
|
path('', include(router.urls)),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from apps.qm.serializers import StandardCreateUpdateSerializer, StandardSerializer, TestItemCreateUpdateSerializer, TestItemSerializer
|
from apps.qm.serializers import StandardCreateUpdateSerializer, StandardSerializer, TestItemCreateUpdateSerializer, TestItemSerializer, TestRecordCreateSerializer, TestRecordDetailSerializer, TestRecordListSerializer
|
||||||
from apps.qm.models import Standard, TestItem
|
from apps.qm.models import Standard, TestItem, TestRecord
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
from apps.system.mixins import CreateUpdateModelAMixin
|
from apps.system.mixins import CreateUpdateModelAMixin
|
||||||
|
@ -37,3 +37,29 @@ class TestItemViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||||
if self.action in ['create', 'update']:
|
if self.action in ['create', 'update']:
|
||||||
return TestItemCreateUpdateSerializer
|
return TestItemCreateUpdateSerializer
|
||||||
return TestItemSerializer
|
return TestItemSerializer
|
||||||
|
|
||||||
|
class TestRecordViewSet(ModelViewSet):
|
||||||
|
"""
|
||||||
|
检测记录
|
||||||
|
"""
|
||||||
|
perms_map = {'*': '*'}
|
||||||
|
queryset = TestRecord.objects.select_related('fifo_detail', 'form').all()
|
||||||
|
serializer_class = TestRecordListSerializer
|
||||||
|
ordering = ['-id']
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
if self.action == 'create':
|
||||||
|
return TestRecordCreateSerializer
|
||||||
|
elif self.action == 'list':
|
||||||
|
return TestRecordListSerializer
|
||||||
|
elif self.action == 'retrieve':
|
||||||
|
return TestRecordDetailSerializer
|
||||||
|
return super().get_serializer_class()
|
||||||
|
|
||||||
|
def perform_create(self, serializer):
|
||||||
|
obj = serializer.save(create_by = self.request.user)
|
||||||
|
# 如果检测合格
|
||||||
|
if obj.fifo_detail:
|
||||||
|
obj.fifo_detail.is_testok = True if obj.is_testok else False
|
||||||
|
obj.fifo_detail.is_tested = True
|
||||||
|
obj.fifo_detail.save()
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Generated by Django 3.2.6 on 2021-11-02 01:35
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pm', '0009_auto_20211029_1017'),
|
||||||
|
('wpm', '0002_auto_20211029_1336'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='wproduct',
|
||||||
|
name='production_plan',
|
||||||
|
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='pm.productionplan', verbose_name='关联主生产计划'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='wproduct',
|
||||||
|
name='subproduction_plan',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pm.subproductionplan', verbose_name='当前子生产计划'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,6 +1,7 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework.serializers import ModelSerializer
|
||||||
from apps.inm.models import FIFO, FIFODetail, MaterialBatch, WareHouse
|
from apps.inm.models import FIFO, FIFODetail, MaterialBatch, WareHouse
|
||||||
|
from apps.inm.signals import update_inm
|
||||||
from apps.mtm.models import Material
|
from apps.mtm.models import Material
|
||||||
from apps.mtm.serializers import MaterialSimpleSerializer
|
from apps.mtm.serializers import MaterialSimpleSerializer
|
||||||
|
|
||||||
|
@ -37,28 +38,33 @@ class PickSerializer(serializers.Serializer):
|
||||||
validated_data['operator'] = operator
|
validated_data['operator'] = operator
|
||||||
validated_data['type'] = 1
|
validated_data['type'] = 1
|
||||||
validated_data['inout_date'] = timezone.now()
|
validated_data['inout_date'] = timezone.now()
|
||||||
fifo = FIFO.objects.create(validated_data)
|
fifo = FIFO.objects.create(**validated_data)
|
||||||
for i in picks:
|
for i in picks:
|
||||||
# 更新出库详情
|
# 更新出库详情
|
||||||
i['fifo'] = fifo
|
i['fifo'] = fifo
|
||||||
|
i['count'] = i.pop('pick_count')
|
||||||
FIFODetail.objects.create(**i)
|
FIFODetail.objects.create(**i)
|
||||||
# 更新车间物料
|
# 更新车间物料
|
||||||
wm = WMaterial.objects.get_or_create(material=i['material'], batch=i['batch'], \
|
wm, _ = WMaterial.objects.get_or_create(material=i['material'], batch=i['batch'], \
|
||||||
process=validated_data['process'],defaults={
|
process=sp.process,defaults={
|
||||||
'material':i['material'],
|
'material':i['material'],
|
||||||
'batch':i['batch'],
|
'batch':i['batch'],
|
||||||
'process':validated_data['process'],
|
'process':sp.process,
|
||||||
'workshop':validated_data['workshop'],
|
'workshop':sp.workshop,
|
||||||
'count':0
|
'count':0
|
||||||
})
|
})
|
||||||
wm.count = wm.count + i['pick_count']
|
wm.count = wm.count + i['count']
|
||||||
wm.save()
|
wm.save()
|
||||||
# 更新子计划进度
|
# 更新子计划物料情况
|
||||||
spp = SubProductionProgress.objects.get(material=i['material'], subproduction_plan=sp, type=1)
|
spp = SubProductionProgress.objects.get(material=i['material'], subproduction_plan=sp, type=1)
|
||||||
spp.count_real = spp.count_real + i['pick_count']
|
spp.count_real = spp.count_real + i['count']
|
||||||
spp.save()
|
spp.save()
|
||||||
sp.is_picked=True
|
sp.is_picked=True
|
||||||
sp.save()
|
sp.save()
|
||||||
|
# 更新库存
|
||||||
|
fifo.is_audited = True
|
||||||
|
fifo.save()
|
||||||
|
update_inm(fifo)
|
||||||
return fifo
|
return fifo
|
||||||
|
|
||||||
class WMaterialListSerializer(serializers.ModelSerializer):
|
class WMaterialListSerializer(serializers.ModelSerializer):
|
||||||
|
@ -67,5 +73,5 @@ class WMaterialListSerializer(serializers.ModelSerializer):
|
||||||
"""
|
"""
|
||||||
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Material
|
model = WMaterial
|
||||||
fields = '__all__'
|
fields = '__all__'
|
|
@ -31,4 +31,10 @@ class WMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, GenericViewSet):
|
||||||
serializer= PickSerializer(data=request.data, context={'request': request})
|
serializer= PickSerializer(data=request.data, context={'request': request})
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
class DoFormInit(CreateAPIView):
|
||||||
|
"""
|
||||||
|
生产操作表单创建
|
||||||
|
"""
|
||||||
|
perms_map={'*':'*'}
|
|
@ -0,0 +1,6 @@
|
||||||
|
from rest_framework.viewsets import GenericViewSet
|
||||||
|
|
||||||
|
class MyGenericViewSet(GenericViewSet):
|
||||||
|
filterset_fields = '__all__'
|
||||||
|
ordering_fields = '__all__'
|
||||||
|
ordering = ['-pk']
|
Loading…
Reference in New Issue