ticketDelete
This commit is contained in:
commit
5ac6a2b1bf
|
|
@ -3,16 +3,55 @@ import request from '@/utils/request'
|
||||||
//生产排程
|
//生产排程
|
||||||
export function getProductionplanList(query) {
|
export function getProductionplanList(query) {
|
||||||
return request({
|
return request({
|
||||||
url: 'pm/productionplan/',
|
url: 'pm/production_plan/',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: query
|
params: query
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
export function createProductionplan(data) {
|
export function createProductionplan(data) {
|
||||||
return request({
|
return request({
|
||||||
url: 'pm/productionplan/',
|
url: 'pm/production_plan/',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
//计算物料配置
|
||||||
|
export function createresource(data) {
|
||||||
|
return request({
|
||||||
|
url: '/pm/resource/cal/',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//产品对应的设备
|
||||||
|
export function createequip(data) {
|
||||||
|
return request({
|
||||||
|
url: '/pm/resource/cal_equip/',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//生成子计划
|
||||||
|
export function createsubplan(id, data) {
|
||||||
|
return request({
|
||||||
|
url: `/pm/production_plan/${id}/gen_subplan/`,
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//子计划列表
|
||||||
|
export function getsubproductionplanList(query) {
|
||||||
|
return request({
|
||||||
|
url: '/pm/subproduction_plan/',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//子计划编辑开始结束时间
|
||||||
|
export function updatesubproductionplan(id, data) {
|
||||||
|
return request({
|
||||||
|
url: `/pm/subproduction_plan/${id}/`,
|
||||||
|
method: 'put',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,15 @@ export const asyncRoutes = [
|
||||||
path: 'plan',
|
path: 'plan',
|
||||||
name: 'plan',
|
name: 'plan',
|
||||||
component: () => import('@/views/pm/plan'),
|
component: () => import('@/views/pm/plan'),
|
||||||
meta: { title: '生产计划管理', icon: 'example', perms: ['pm_plan'] }
|
meta: { title: '生产计划管理', icon: 'example', perms: ['index_manage'] }
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{
|
||||||
|
path: 'work/:id',
|
||||||
|
name: 'work',
|
||||||
|
component: () => import('@/views/pm/work'),
|
||||||
|
meta: { title: '生产子计划', perms: ['vendor_manage'] },
|
||||||
|
hidden: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'resources',
|
path: 'resources',
|
||||||
|
|
|
||||||
|
|
@ -144,14 +144,7 @@
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="绑定工序" prop="processes" v-if="material.type==1">
|
|
||||||
<el-transfer
|
|
||||||
v-model="material.processes"
|
|
||||||
:data="processOptions"
|
|
||||||
:titles="['工序清单', '选择的工序清单']"
|
|
||||||
:props="{ key: 'id', label: 'name' }"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="排序" prop="sort_str">
|
<el-form-item label="排序" prop="sort_str">
|
||||||
<el-input v-model="material.sort_str" placeholder="排序" />
|
<el-input v-model="material.sort_str" placeholder="排序" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
|
||||||
|
|
@ -80,13 +80,17 @@
|
||||||
border
|
border
|
||||||
fit
|
fit
|
||||||
stripe
|
stripe
|
||||||
|
highlight-current-row
|
||||||
@current-change="handlespChange"
|
@current-change="handlespChange"
|
||||||
>
|
>
|
||||||
<el-table-column type="index" width="50" />
|
<el-table-column type="index" width="50" />
|
||||||
<el-table-column label="物料编号">
|
<el-table-column label="分解产品名称">
|
||||||
<template slot-scope="scope">{{scope.row.name}}</template>
|
<template slot-scope="scope">{{scope.row.name}}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="单位消耗量">
|
<el-table-column label="工序">
|
||||||
|
<template slot-scope="scope">{{ scope.row.process_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="排序">
|
||||||
<template slot-scope="scope">{{ scope.row.sort }}</template>
|
<template slot-scope="scope">{{ scope.row.sort }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
|
@ -128,6 +132,17 @@
|
||||||
<el-form-item label="名称" prop="name">
|
<el-form-item label="名称" prop="name">
|
||||||
<el-input v-model="subproducation.name" />
|
<el-input v-model="subproducation.name" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="绑定工序" prop="process" >
|
||||||
|
<el-select v-model="subproducation.process" placeholder="请选择" >
|
||||||
|
<el-option
|
||||||
|
v-for="item in processOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="排序" prop="sort">
|
<el-form-item label="排序" prop="sort">
|
||||||
<el-input-number
|
<el-input-number
|
||||||
v-model="subproducation.sort"
|
v-model="subproducation.sort"
|
||||||
|
|
@ -213,17 +228,11 @@
|
||||||
>
|
>
|
||||||
|
|
||||||
<el-form-item label="消耗量" prop="count">
|
<el-form-item label="消耗量" prop="count">
|
||||||
<el-input v-model="inputmaterial.count" placeholder="输入整数或小数" />
|
<el-input-number v-model="inputmaterial.count" :min="0" placeholder="输入整数或小数" />
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="排序" prop="sort">
|
|
||||||
<el-input-number
|
|
||||||
v-model="inputmaterial.sort"
|
|
||||||
:min="-2147483648"
|
|
||||||
:max="2147483647"
|
|
||||||
></el-input-number>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="输入物料" prop="unit">
|
<el-form-item label="输入物料" prop="unit">
|
||||||
<el-select style="width: 100%" v-model="inputmaterial.material" placeholder="请选择">
|
<el-select filterable style="width: 100%" v-model="inputmaterial.material" placeholder="请选择">
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in materialoptions"
|
v-for="item in materialoptions"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
|
|
@ -232,7 +241,13 @@
|
||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="排序" prop="sort">
|
||||||
|
<el-input-number
|
||||||
|
v-model="inputmaterial.sort"
|
||||||
|
:min="-2147483648"
|
||||||
|
:max="2147483647"
|
||||||
|
></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
@ -305,15 +320,9 @@
|
||||||
>
|
>
|
||||||
|
|
||||||
<el-form-item label="产出量" prop="count">
|
<el-form-item label="产出量" prop="count">
|
||||||
<el-input v-model="outputmaterial.count" placeholder="输入整数或小数" />
|
<el-input-number v-model="outputmaterial.count" :min="0" />
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="排序" prop="sort">
|
|
||||||
<el-input-number
|
|
||||||
v-model="outputmaterial.sort"
|
|
||||||
:min="-2147483648"
|
|
||||||
:max="2147483647"
|
|
||||||
></el-input-number>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="输出物料" prop="unit">
|
<el-form-item label="输出物料" prop="unit">
|
||||||
<el-select style="width: 100%" v-model="outputmaterial.material" placeholder="请选择">
|
<el-select style="width: 100%" v-model="outputmaterial.material" placeholder="请选择">
|
||||||
<el-option
|
<el-option
|
||||||
|
|
@ -325,7 +334,13 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="排序" prop="sort">
|
||||||
|
<el-input-number
|
||||||
|
v-model="outputmaterial.sort"
|
||||||
|
:min="-2147483648"
|
||||||
|
:max="2147483647"
|
||||||
|
></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
</el-form>
|
</el-form>
|
||||||
<div style="text-align: right">
|
<div style="text-align: right">
|
||||||
|
|
@ -507,11 +522,12 @@
|
||||||
import { getMaterialList,getMaterial,getInputmaterialList,createInputmaterial,updateInputmaterial
|
import { getMaterialList,getMaterial,getInputmaterialList,createInputmaterial,updateInputmaterial
|
||||||
,deleteInputmaterial,getOutputmaterialList,createOutputmaterial,updateOutputmaterial,deleteOutputmaterial,
|
,deleteInputmaterial,getOutputmaterialList,createOutputmaterial,updateOutputmaterial,deleteOutputmaterial,
|
||||||
getUsedstepList,createUsedstep,deleteUsedstep,getStepList,gettechdocList,createtechdoc,updatetechdoc,deletetechdoc
|
getUsedstepList,createUsedstep,deleteUsedstep,getStepList,gettechdocList,createtechdoc,updatetechdoc,deletetechdoc
|
||||||
,getsubproducationList,createsubproducation,updatesubproducation,deletesubproducation } from "@/api/mtm";
|
,getsubproducationList,createsubproducation,updatesubproducation,deletesubproducation,getProcessList } from "@/api/mtm";
|
||||||
import { quillEditor } from 'vue-quill-editor'
|
import { quillEditor } from 'vue-quill-editor'
|
||||||
import 'quill/dist/quill.core.css'
|
import 'quill/dist/quill.core.css'
|
||||||
import 'quill/dist/quill.snow.css'
|
import 'quill/dist/quill.snow.css'
|
||||||
import 'quill/dist/quill.bubble.css'
|
import 'quill/dist/quill.bubble.css'
|
||||||
|
|
||||||
import { upUrl, upHeaders } from "@/api/file";
|
import { upUrl, upHeaders } from "@/api/file";
|
||||||
import checkPermission from "@/utils/permission";
|
import checkPermission from "@/utils/permission";
|
||||||
import { genTree } from "@/utils";
|
import { genTree } from "@/utils";
|
||||||
|
|
@ -529,7 +545,7 @@ const defaulttechdoc = {
|
||||||
|
|
||||||
};
|
};
|
||||||
const defaultsubproducation = {
|
const defaultsubproducation = {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
@ -541,6 +557,7 @@ export default {
|
||||||
subproducationData:"",
|
subproducationData:"",
|
||||||
inputtableData:"",
|
inputtableData:"",
|
||||||
editorOption: {} ,
|
editorOption: {} ,
|
||||||
|
processOptions:[],
|
||||||
techdoc: defaulttechdoc,
|
techdoc: defaulttechdoc,
|
||||||
subproducation:defaultsubproducation,
|
subproducation:defaultsubproducation,
|
||||||
inputmaterial: defaultinputmaterial,
|
inputmaterial: defaultinputmaterial,
|
||||||
|
|
@ -625,7 +642,12 @@ export default {
|
||||||
this.listLoading = false;
|
this.listLoading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
//工序清单
|
||||||
|
getProcessList() {
|
||||||
|
getProcessList().then((res) => {
|
||||||
|
this.processOptions = genTree(res.data.results);
|
||||||
|
});
|
||||||
|
},
|
||||||
//获取产品,工艺
|
//获取产品,工艺
|
||||||
getMaterial(){
|
getMaterial(){
|
||||||
getMaterial(this.product).then((response) => {
|
getMaterial(this.product).then((response) => {
|
||||||
|
|
@ -639,11 +661,14 @@ export default {
|
||||||
handleCurrentChange(row){
|
handleCurrentChange(row){
|
||||||
this.product=row.id;
|
this.product=row.id;
|
||||||
this.getMaterial();
|
this.getMaterial();
|
||||||
|
this.getProcessList();
|
||||||
this.getsubproducationList();
|
this.getsubproducationList();
|
||||||
|
|
||||||
},
|
},
|
||||||
//点击产品分解弹出输入、输出物料,子工序,技术文件
|
//点击产品分解弹出输入、输出物料,子工序,技术文件
|
||||||
handlespChange(row){
|
handlespChange(row){
|
||||||
this.subproduction = row.id;
|
this.subproduction = row.id;
|
||||||
|
this.processes = row.process;
|
||||||
this.getmaterialList();//物料列表
|
this.getmaterialList();//物料列表
|
||||||
this.getInputmaterialLists();//输入物料
|
this.getInputmaterialLists();//输入物料
|
||||||
|
|
||||||
|
|
@ -911,7 +936,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
getstepList() {
|
getstepList() {
|
||||||
|
this.listQuerystep.process=this.processes;
|
||||||
getStepList(this.listQuerystep).then((response) => {
|
getStepList(this.listQuerystep).then((response) => {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
this.stepoptions = genTree(response.data);
|
this.stepoptions = genTree(response.data);
|
||||||
|
|
@ -1071,3 +1096,4 @@ export default {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,12 @@
|
||||||
<el-table-column label="交付截止时间">
|
<el-table-column label="交付截止时间">
|
||||||
<template slot-scope="scope">{{ scope.row.order_.delivery_date }}</template>
|
<template slot-scope="scope">{{ scope.row.order_.delivery_date }}</template>
|
||||||
</el-table-column>
|
</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="创建时间">
|
<el-table-column label="创建时间">
|
||||||
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -61,13 +66,14 @@
|
||||||
width="100px"
|
width="100px"
|
||||||
>
|
>
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
|
|
||||||
<el-link type="primary"
|
<el-link type="primary"
|
||||||
v-if="checkPermission(['warehouse_update'])"
|
v-if="scope.row.is_planed"
|
||||||
@click="handleclick(scope)"
|
@click="handleselectplan(scope)"
|
||||||
>车间排产</el-link
|
>查看子计划</el-link>
|
||||||
>
|
<el-link type="primary"
|
||||||
|
v-else
|
||||||
|
@click="handleWork(scope)"
|
||||||
|
>生产子计划</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
@ -118,6 +124,8 @@
|
||||||
<el-table-column label="交货日期">
|
<el-table-column label="交货日期">
|
||||||
<template slot-scope="scope">{{ scope.row.delivery_date }}</template>
|
<template slot-scope="scope">{{ scope.row.delivery_date }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
|
||||||
<el-table-column label="创建时间">
|
<el-table-column label="创建时间">
|
||||||
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
@ -159,7 +167,7 @@
|
||||||
<el-input v-model="orderplan.number" placeholder="生产计划编号" />
|
<el-input v-model="orderplan.number" placeholder="生产计划编号" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="排产数量" prop="count">
|
<el-form-item label="排产数量" prop="count">
|
||||||
<el-input type="number" v-model.number="orderplan.count"/>
|
<el-input-number v-model="orderplan.count" :min="0"></el-input-number>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -190,7 +198,7 @@
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { getordertoplan } from "@/api/sam";
|
import { getordertoplan } from "@/api/sam";
|
||||||
import { createProductionplan,getProductionplanList} from "@/api/pm";
|
import { createProductionplan,getProductionplanList,createsubplan} from "@/api/pm";
|
||||||
import { getMaterialList } from "@/api/mtm";
|
import { getMaterialList } from "@/api/mtm";
|
||||||
import checkPermission from "@/utils/permission";
|
import checkPermission from "@/utils/permission";
|
||||||
|
|
||||||
|
|
@ -282,6 +290,31 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
handleWork(scope)
|
||||||
|
{
|
||||||
|
this.$confirm("确认生成子计划?", "提醒", {
|
||||||
|
confirmButtonText: "确认",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
await createsubplan(scope.row.id).then((res) => {
|
||||||
|
if (res.code >= 200) {
|
||||||
|
this.$message.success("生成子计划成功!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
//查看子计划
|
||||||
|
handleselectplan(scope)
|
||||||
|
{
|
||||||
|
this.$router.push({name: "work", params: { id: scope.row.id }, })
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,60 +7,60 @@
|
||||||
<span>合同订单列表</span>
|
<span>合同订单列表</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<el-button type="primary" @click="handlecount"
|
||||||
|
>计算物料</el-button>
|
||||||
<el-table
|
<el-table
|
||||||
:data="orderList.results"
|
:data="orderList.results"
|
||||||
border
|
border
|
||||||
fit
|
fit
|
||||||
stripe
|
stripe
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
@selection-change="handleSelectionChange">
|
||||||
>
|
<el-table-column
|
||||||
|
type="selection"
|
||||||
|
width="55">
|
||||||
|
</el-table-column>
|
||||||
<el-table-column type="index" width="50" />
|
<el-table-column type="index" width="50" />
|
||||||
|
|
||||||
<el-table-column label="订单编号">
|
<el-table-column label="订单编号">
|
||||||
<template slot-scope="scope">{{ scope.row.number }}</template>
|
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="所需产品">
|
||||||
|
<template slot-scope="scope">{{ scope.row.product_.name }}</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.planed_count }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="计划生产数" width="140px">
|
||||||
|
<template slot-scope="scope" >
|
||||||
|
<el-form :model="scope.row">
|
||||||
|
<el-form-item size="mini">
|
||||||
|
<el-input-number v-model="scope.row.pgcount" :min="0"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="产品型号">
|
||||||
|
<template slot-scope="scope">{{ scope.row.product_.specification }}</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="客户">
|
<el-table-column label="客户">
|
||||||
<template slot-scope="scope">{{ scope.row.customer_.name }}</template>
|
<template slot-scope="scope">{{ scope.row.customer_.name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="所属合同">
|
<el-table-column label="所属合同">
|
||||||
<template slot-scope="scope">{{ scope.row.contract_.name }}</template>
|
<template slot-scope="scope">{{ scope.row.contract_.name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="所需产品">
|
|
||||||
<template slot-scope="scope">{{ scope.row.product_.name }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="产品型号">
|
|
||||||
<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.planed_count }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
|
|
||||||
<el-table-column label="交货日期">
|
<el-table-column label="交货日期">
|
||||||
<template slot-scope="scope">{{ scope.row.delivery_date }}</template>
|
<template slot-scope="scope">{{ scope.row.delivery_date }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="创建时间">
|
<el-table-column label="创建时间">
|
||||||
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
|
||||||
align="center"
|
|
||||||
label="操作"
|
|
||||||
width="120px"
|
|
||||||
fixed="right"
|
|
||||||
>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
|
|
||||||
<el-link type="primary"
|
|
||||||
v-if="checkPermission(['warehouse_update'])"
|
|
||||||
@click="handleclick(scope)"
|
|
||||||
>排产</el-link
|
|
||||||
>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
</el-table>
|
||||||
<pagination
|
<pagination
|
||||||
v-show="orderList.count > 0"
|
v-show="orderList.count > 0"
|
||||||
|
|
@ -81,7 +81,7 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<el-table
|
<el-table
|
||||||
:data="orderList.results"
|
:data="materialpzTable"
|
||||||
border
|
border
|
||||||
fit
|
fit
|
||||||
stripe
|
stripe
|
||||||
|
|
@ -90,58 +90,25 @@
|
||||||
>
|
>
|
||||||
<el-table-column type="index" width="50" />
|
<el-table-column type="index" width="50" />
|
||||||
|
|
||||||
<el-table-column label="订单编号">
|
<el-table-column label="物料名称">
|
||||||
|
<template slot-scope="scope">{{ scope.row.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="物料类型">
|
||||||
|
<template slot-scope="scope"> {{options_[scope.row.type]}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="物料编号">
|
||||||
<template slot-scope="scope">{{ scope.row.number }}</template>
|
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="客户">
|
<el-table-column label="生产所需数量">
|
||||||
<template slot-scope="scope">{{ scope.row.customer_.name }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="所属合同">
|
|
||||||
<template slot-scope="scope">{{ scope.row.contract_.name }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="所需产品">
|
|
||||||
<template slot-scope="scope">{{ scope.row.product_.name }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="产品型号">
|
|
||||||
<template slot-scope="scope">{{ scope.row.product_.specification }}</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="所需数量">
|
|
||||||
<template slot-scope="scope">{{ scope.row.count }}</template>
|
<template slot-scope="scope">{{ scope.row.count }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="已派数量">
|
<el-table-column label="库存量">
|
||||||
<template slot-scope="scope">{{ scope.row.planed_count }}</template>
|
<template slot-scope="scope">{{ scope.row.inv_count }}</template>
|
||||||
</el-table-column>
|
</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-column
|
|
||||||
align="center"
|
|
||||||
label="操作"
|
|
||||||
width="120px"
|
|
||||||
fixed="right"
|
|
||||||
>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
|
|
||||||
<el-link type="primary"
|
|
||||||
v-if="checkPermission(['warehouse_update'])"
|
|
||||||
@click="handleclick(scope)"
|
|
||||||
>排产</el-link
|
|
||||||
>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
</el-table>
|
||||||
<pagination
|
|
||||||
v-show="orderList.count > 0"
|
|
||||||
:total="orderList.count"
|
|
||||||
:page.sync="listQuery.page"
|
|
||||||
:limit.sync="listQuery.page_size"
|
|
||||||
@pagination="getorderList"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
@ -154,59 +121,30 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<el-table
|
<el-table
|
||||||
:data="orderList.results"
|
:data="equipmentTable"
|
||||||
border
|
border
|
||||||
fit
|
fit
|
||||||
stripe
|
stripe
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
|
|
||||||
>
|
>
|
||||||
|
|
||||||
<el-table-column type="index" width="50" />
|
<el-table-column type="index" width="50" />
|
||||||
|
|
||||||
<el-table-column label="订单编号">
|
<el-table-column label="设备名称">
|
||||||
<template slot-scope="scope">{{ scope.row.number }}</template>
|
<template slot-scope="scope">{{ scope.row.name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="客户">
|
<el-table-column label="设备状态">
|
||||||
<template slot-scope="scope">{{ scope.row.customer_.name }}</template>
|
<template slot-scope="scope"> {{state_[scope.row.state]}}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="所属合同">
|
<el-table-column label="设备编号">
|
||||||
<template slot-scope="scope">{{ scope.row.contract_.name }}</template>
|
<template slot-scope="scope"> {{scope.row.number}}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="所需产品">
|
<el-table-column label="设备型号">
|
||||||
<template slot-scope="scope">{{ scope.row.product_.name }}</template>
|
<template slot-scope="scope"> {{scope.row.model}}</template>
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="产品型号">
|
|
||||||
<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.planed_count }}</template>
|
|
||||||
</el-table-column>
|
</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-column
|
|
||||||
align="center"
|
|
||||||
label="操作"
|
|
||||||
width="120px"
|
|
||||||
fixed="right"
|
|
||||||
>
|
|
||||||
<template slot-scope="scope">
|
|
||||||
|
|
||||||
<el-link type="primary"
|
|
||||||
v-if="checkPermission(['warehouse_update'])"
|
|
||||||
@click="handleclick(scope)"
|
|
||||||
>排产</el-link
|
|
||||||
>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
</el-table>
|
||||||
<pagination
|
<pagination
|
||||||
v-show="orderList.count > 0"
|
v-show="orderList.count > 0"
|
||||||
|
|
@ -226,7 +164,7 @@
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { getordertoplan } from "@/api/sam";
|
import { getordertoplan } from "@/api/sam";
|
||||||
import { createProductionplan,getProductionplanList} from "@/api/pm";
|
import { createProductionplan,getProductionplanList,createresource,createequip} from "@/api/pm";
|
||||||
import { getMaterialList } from "@/api/mtm";
|
import { getMaterialList } from "@/api/mtm";
|
||||||
import checkPermission from "@/utils/permission";
|
import checkPermission from "@/utils/permission";
|
||||||
|
|
||||||
|
|
@ -243,13 +181,30 @@ export default {
|
||||||
orderplan: defaulteorderplan,
|
orderplan: defaulteorderplan,
|
||||||
orderList: {
|
orderList: {
|
||||||
count: 0,
|
count: 0,
|
||||||
|
},
|
||||||
|
options_:{
|
||||||
|
|
||||||
|
"1":'成品',
|
||||||
|
"2":'半成品',
|
||||||
|
"3":'主要原料',
|
||||||
|
"4":'辅助原料',
|
||||||
|
"5":'加工工具',
|
||||||
|
"6":'辅助工具',
|
||||||
|
|
||||||
|
},
|
||||||
|
state_:{
|
||||||
|
0:'完好',
|
||||||
|
1:'限用',
|
||||||
|
2:'在修',
|
||||||
|
3:'禁用',
|
||||||
},
|
},
|
||||||
listQuery: {
|
listQuery: {
|
||||||
page: 1,
|
page: 1,
|
||||||
page_size: 20,
|
page_size: 20,
|
||||||
},
|
},
|
||||||
|
materialpzTable:"",
|
||||||
|
mutipID:[],
|
||||||
|
equipmentTable:[],
|
||||||
listLoading: true,
|
listLoading: true,
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
dialogType: "new",
|
dialogType: "new",
|
||||||
|
|
@ -278,7 +233,35 @@ export default {
|
||||||
this.listLoading = false;
|
this.listLoading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
handleSelectionChange(row) {
|
||||||
|
let _this=this
|
||||||
|
_this.mutipID=[]
|
||||||
|
row.forEach((item) => {
|
||||||
|
_this.mutipID.push({
|
||||||
|
"id":item.product_.id,
|
||||||
|
"count": item.pgcount
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//物料计算
|
||||||
|
handlecount()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
createresource(this.mutipID).then((res) => {
|
||||||
|
if (res.code >= 200) {
|
||||||
|
this.materialpzTable=res.data;
|
||||||
|
this.$message.success("物料计算成功");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
createequip(this.mutipID).then((res) => {
|
||||||
|
if (res.code >= 200) {
|
||||||
|
this.equipmentTable=res.data;
|
||||||
|
this.$message.success("成功");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
handleclick(scope){
|
handleclick(scope){
|
||||||
this.orderID = scope.row.id;
|
this.orderID = scope.row.id;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-card class="box-card">
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<span>生产任务列表</span>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
:data="subproductionplanList.results"
|
||||||
|
border
|
||||||
|
fit
|
||||||
|
stripe
|
||||||
|
style="width: 100%"
|
||||||
|
max-height="400"
|
||||||
|
>
|
||||||
|
<el-table-column type="index" width="50" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<el-table-column label="生产子计划名">
|
||||||
|
<template slot-scope="scope">{{ scope.row.workshop_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="工序名">
|
||||||
|
<template slot-scope="scope">{{ scope.row.process_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="工序编号">
|
||||||
|
<template slot-scope="scope">{{ scope.row.process_.number }}</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.create_time }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
align="center"
|
||||||
|
label="操作"
|
||||||
|
width="100px"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
|
||||||
|
<el-link type="primary"
|
||||||
|
v-if="checkPermission(['warehouse_update'])"
|
||||||
|
@click="handleclick(scope)"
|
||||||
|
>编辑</el-link
|
||||||
|
>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<pagination
|
||||||
|
v-show="subproductionplanList.count > 0"
|
||||||
|
:total="subproductionplanList.count"
|
||||||
|
:page.sync="listQuery.page"
|
||||||
|
:limit.sync="listQuery.page_size"
|
||||||
|
@pagination="getspList"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
<el-dialog
|
||||||
|
:visible.sync="dialogVisible"
|
||||||
|
>
|
||||||
|
<el-form
|
||||||
|
ref="Form"
|
||||||
|
:model="subproductionplan"
|
||||||
|
label-width="180px"
|
||||||
|
label-position="right"
|
||||||
|
:rules="rule1"
|
||||||
|
>
|
||||||
|
<el-form-item label="子计划开工时间" prop="start_date">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="subproductionplan.start_date"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择日期"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
style="width:100%"
|
||||||
|
>
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="子计划完工时间" prop="end_date">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="subproductionplan.end_date"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择日期"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
style="width:100%"
|
||||||
|
>
|
||||||
|
</el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
<div style="text-align: right">
|
||||||
|
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirm('Form')">确认</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { getsubproductionplanList,updatesubproductionplan } from "@/api/pm";
|
||||||
|
import checkPermission from "@/utils/permission";
|
||||||
|
|
||||||
|
|
||||||
|
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||||
|
const defaultesubproductionplan = {
|
||||||
|
};
|
||||||
|
export default {
|
||||||
|
components: { Pagination },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
subproductionplan: defaultesubproductionplan,
|
||||||
|
subproductionplanList: {
|
||||||
|
count: 0,
|
||||||
|
},
|
||||||
|
listQuery: {
|
||||||
|
page: 1,
|
||||||
|
page_size: 20,
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
listLoading: true,
|
||||||
|
dialogVisible: false,
|
||||||
|
dialogType: "new",
|
||||||
|
rule1: {
|
||||||
|
number: [{ required: true, message: "请输入", trigger: "blur" }],
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
created() {
|
||||||
|
this.id=this.$route.params.id;
|
||||||
|
this.getspList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
checkPermission,
|
||||||
|
//订单列表
|
||||||
|
getspList() {
|
||||||
|
this.listLoading = true;
|
||||||
|
this.listQuery.production_plan = this.id;
|
||||||
|
console.log(this.listQuery)
|
||||||
|
getsubproductionplanList(this.listQuery).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.subproductionplanList = response.data;
|
||||||
|
}
|
||||||
|
this.listLoading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleclick(scope)
|
||||||
|
{
|
||||||
|
this.subproductionplan = Object.assign({}, scope.row); // copy obj
|
||||||
|
this.dialogVisible = true;
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs["Form"].clearValidate();
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
confirm()
|
||||||
|
{
|
||||||
|
updatesubproductionplan(this.subproductionplan.id,this.subproductionplan).then((res) => {
|
||||||
|
if (res.code >= 200) {
|
||||||
|
this.getspList();
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$message.success("成功");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
@ -74,7 +74,7 @@
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
|
|
||||||
<el-link
|
<el-link
|
||||||
v-if="checkPermission(['warehouse_update'])"
|
v-if="scope.row.planed_count==0&&checkPermission(['warehouse_update'])"
|
||||||
@click="handleEdit(scope)"
|
@click="handleEdit(scope)"
|
||||||
>编辑</el-link
|
>编辑</el-link
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ class EquipmentSerializer(ModelSerializer):
|
||||||
def get_step_(self, obj):
|
def get_step_(self, obj):
|
||||||
return Step.objects.filter(equipments=obj).values('id', 'name', 'number')
|
return Step.objects.filter(equipments=obj).values('id', 'name', 'number')
|
||||||
|
|
||||||
|
|
||||||
class EquipmentSimpleSerializer(ModelSerializer):
|
class EquipmentSimpleSerializer(ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Equipment
|
model = Equipment
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Generated by Django 3.2.6 on 2021-10-14 01:44
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('em', '0009_auto_20210916_1108'),
|
||||||
|
('mtm', '0021_auto_20211013_0856'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subproduction',
|
||||||
|
name='process',
|
||||||
|
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='subproduction_process', to='mtm.process', verbose_name='隶属大工序'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='step',
|
||||||
|
name='equipments',
|
||||||
|
field=models.ManyToManyField(related_name='step_equips', to='em.Equipment', verbose_name='使用设备'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -64,7 +64,7 @@ class Step(CommonAModel):
|
||||||
number = models.CharField('步骤编号', max_length=100, null=True, blank=True)
|
number = models.CharField('步骤编号', max_length=100, null=True, blank=True)
|
||||||
instruction_content = models.TextField('相应操作指导', null=True, blank=True)
|
instruction_content = models.TextField('相应操作指导', null=True, blank=True)
|
||||||
sort = models.IntegerField('排序号', default=1)
|
sort = models.IntegerField('排序号', default=1)
|
||||||
equipments = models.ManyToManyField(Equipment, verbose_name='使用设备')
|
equipments = models.ManyToManyField(Equipment, verbose_name='使用设备', related_name='step_equips')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '工序步骤'
|
verbose_name = '工序步骤'
|
||||||
|
|
@ -134,6 +134,7 @@ class SubProduction(CommonAModel):
|
||||||
"""
|
"""
|
||||||
name = models.CharField('命名', max_length=50, null=True, blank=True)
|
name = models.CharField('命名', max_length=50, null=True, blank=True)
|
||||||
product = models.ForeignKey(Material, verbose_name='产品', on_delete=models.CASCADE)
|
product = models.ForeignKey(Material, verbose_name='产品', on_delete=models.CASCADE)
|
||||||
|
process = models.ForeignKey(Process, verbose_name='隶属大工序', on_delete=models.CASCADE, related_name='subproduction_process')
|
||||||
sort = models.IntegerField('排序号', default=1)
|
sort = models.IntegerField('排序号', default=1)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
@ -173,7 +174,7 @@ class UsedStep(CommonAModel):
|
||||||
"""
|
"""
|
||||||
涉及的生产子工序
|
涉及的生产子工序
|
||||||
"""
|
"""
|
||||||
step = models.ForeignKey(Step, verbose_name='子工序', on_delete=models.CASCADE, related_name='usedsteps')
|
step = models.ForeignKey(Step, verbose_name='子工序', on_delete=models.CASCADE, related_name='usedstep')
|
||||||
remark = models.TextField('生产备注', null=True, blank=True)
|
remark = models.TextField('生产备注', null=True, blank=True)
|
||||||
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE)
|
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,9 @@ class MaterialDetailSerializer(serializers.ModelSerializer):
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
def get_processes_(self, obj):
|
def get_processes_(self, obj):
|
||||||
steps = UsedStep.objects.filter(subproduction__product=obj).values_list('step', flat=True)
|
# steps = UsedStep.objects.filter(subproduction__product=obj).values_list('step', flat=True)
|
||||||
objs = Process.objects.filter(step_process__id__in=steps).distinct().order_by('number')
|
# objs = Process.objects.filter(step_process__id__in=steps).distinct().order_by('number')
|
||||||
|
objs = Process.objects.filter(subproduction_process__product=obj, subproduction_process__is_deleted=False, is_deleted=False).order_by('number')
|
||||||
return ProcessSimpleSerializer(instance=objs, many=True).data
|
return ProcessSimpleSerializer(instance=objs, many=True).data
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -61,6 +62,7 @@ class StepDetailSerializer(serializers.ModelSerializer):
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
class SubProductionSerializer(serializers.ModelSerializer):
|
class SubProductionSerializer(serializers.ModelSerializer):
|
||||||
|
process_ = ProcessSimpleSerializer(source='process', read_only=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SubProduction
|
model = SubProduction
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
|
||||||
|
|
@ -74,8 +74,8 @@ class SubProductionViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||||
产品生产分解增删改查
|
产品生产分解增删改查
|
||||||
"""
|
"""
|
||||||
perms_map={'*':'*'}
|
perms_map={'*':'*'}
|
||||||
queryset = SubProduction.objects.all()
|
queryset = SubProduction.objects.select_related('process').all()
|
||||||
filterset_fields = ['product']
|
filterset_fields = ['product', 'process']
|
||||||
search_fields = ['name']
|
search_fields = ['name']
|
||||||
serializer_class = SubProductionSerializer
|
serializer_class = SubProductionSerializer
|
||||||
ordering = ['sort']
|
ordering = ['sort']
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
# Generated by Django 3.2.6 on 2021-10-14 07:03
|
||||||
|
|
||||||
|
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 = [
|
||||||
|
('system', '0003_auto_20210812_0909'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('mtm', '0022_auto_20211014_0944'),
|
||||||
|
('pm', '0002_alter_productionplan_count'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='productionplan',
|
||||||
|
name='is_planed',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='是否已排产'),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SubProductionPlan',
|
||||||
|
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='删除标记')),
|
||||||
|
('start_date', models.DateField(verbose_name='计划开工日期')),
|
||||||
|
('end_date', models.DateField(verbose_name='计划完工日期')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subproductionplan_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('process', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.process', verbose_name='关联大工序')),
|
||||||
|
('production_plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pm.productionplan', 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='subproductionplan_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
('workshop', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='system.organization', verbose_name='生产车间')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': '子生产计划',
|
||||||
|
'verbose_name_plural': '子生产计划',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.6 on 2021-10-15 02:14
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pm', '0003_auto_20211014_1503'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subproductionplan',
|
||||||
|
name='steps',
|
||||||
|
field=models.JSONField(default=list, verbose_name='工艺步骤'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from apps.system.models import CommonAModel
|
from apps.system.models import CommonAModel, Organization
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import AbstractUser
|
from django.contrib.auth.models import AbstractUser
|
||||||
from django.db.models.base import Model
|
from django.db.models.base import Model
|
||||||
|
|
@ -6,10 +6,9 @@ import django.utils.timezone as timezone
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
|
|
||||||
from utils.model import SoftModel, BaseModel
|
from utils.model import SoftModel, BaseModel
|
||||||
from apps.mtm.models import Material
|
from apps.mtm.models import Material, Process, SubProduction
|
||||||
from apps.sam.models import Order
|
from apps.sam.models import Order
|
||||||
|
|
||||||
|
|
||||||
class ProductionPlan(CommonAModel):
|
class ProductionPlan(CommonAModel):
|
||||||
"""
|
"""
|
||||||
生产计划
|
生产计划
|
||||||
|
|
@ -20,7 +19,7 @@ class ProductionPlan(CommonAModel):
|
||||||
count = models.IntegerField('生产数量', default=1)
|
count = models.IntegerField('生产数量', default=1)
|
||||||
start_date = models.DateField('计划开工日期')
|
start_date = models.DateField('计划开工日期')
|
||||||
end_date = models.DateField('计划完工日期')
|
end_date = models.DateField('计划完工日期')
|
||||||
|
is_planed = models.BooleanField('是否已排产', default=False)
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '生产计划'
|
verbose_name = '生产计划'
|
||||||
verbose_name_plural = verbose_name
|
verbose_name_plural = verbose_name
|
||||||
|
|
@ -28,3 +27,24 @@ class ProductionPlan(CommonAModel):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.number
|
return self.number
|
||||||
|
|
||||||
|
class SubProductionPlan(CommonAModel):
|
||||||
|
"""
|
||||||
|
子生产计划
|
||||||
|
"""
|
||||||
|
production_plan = models.ForeignKey(ProductionPlan, verbose_name='关联主生产计划', on_delete=models.CASCADE)
|
||||||
|
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE)
|
||||||
|
start_date = models.DateField('计划开工日期')
|
||||||
|
end_date = models.DateField('计划完工日期')
|
||||||
|
workshop = models.ForeignKey(Organization, verbose_name='生产车间', on_delete=models.CASCADE)
|
||||||
|
process = models.ForeignKey(Process, verbose_name='关联大工序', on_delete=models.CASCADE)
|
||||||
|
steps = models.JSONField('工艺步骤', default=list)
|
||||||
|
class Meta:
|
||||||
|
verbose_name = '子生产计划'
|
||||||
|
verbose_name_plural = verbose_name
|
||||||
|
|
||||||
|
# class ProductionProgress(BaseModel):
|
||||||
|
# """
|
||||||
|
# 子计划生产进度
|
||||||
|
# """
|
||||||
|
# subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE)
|
||||||
|
# material = models.
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
from apps.pm.models import ProductionPlan
|
from apps.pm.models import ProductionPlan, SubProductionPlan
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from apps.sam.serializers import OrderSerializer
|
from apps.sam.serializers import OrderSerializer
|
||||||
from apps.mtm.serializers import MaterialSimpleSerializer
|
from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer
|
||||||
|
from apps.system.serializers import OrganizationSimpleSerializer
|
||||||
|
|
||||||
|
|
||||||
class ProductionPlanCreateFromOrderSerializer(serializers.ModelSerializer):
|
class ProductionPlanCreateFromOrderSerializer(serializers.ModelSerializer):
|
||||||
|
|
@ -15,3 +16,25 @@ class ProductionPlanSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ProductionPlan
|
model = ProductionPlan
|
||||||
fields ='__all__'
|
fields ='__all__'
|
||||||
|
|
||||||
|
class ResourceCalSerializer(serializers.Serializer):
|
||||||
|
id = serializers.IntegerField(label='产品ID')
|
||||||
|
count = serializers.IntegerField(label='生产数量')
|
||||||
|
|
||||||
|
class ResourceCalListSerializer(serializers.ListSerializer):
|
||||||
|
child = ResourceCalSerializer()
|
||||||
|
|
||||||
|
class SubProductionPlanListSerializer(serializers.ModelSerializer):
|
||||||
|
workshop_ = OrganizationSimpleSerializer(source='workshop', read_only=True)
|
||||||
|
process_ = ProcessSimpleSerializer(source='process', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model=SubProductionPlan
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
class SubProductionPlanUpdateSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = SubProductionPlan
|
||||||
|
fields = ['start_date', 'end_date']
|
||||||
|
|
||||||
|
class GenSubPlanSerializer(serializers.Serializer):
|
||||||
|
pass
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
from apps.pm.views import ProductionPlanViewSet
|
from apps.pm.views import ProductionPlanViewSet, ResourceViewSet, SubProductionPlanViewSet
|
||||||
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
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
router.register('productionplan', ProductionPlanViewSet, basename='productionplan')
|
router.register('production_plan', ProductionPlanViewSet, basename='production_plan')
|
||||||
|
router.register('subproduction_plan', SubProductionPlanViewSet, basename='subproduction_plan')
|
||||||
|
router.register('resource', ResourceViewSet, basename='resource')
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', include(router.urls)),
|
path('', include(router.urls)),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,19 @@
|
||||||
|
from rest_framework import serializers
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
from apps.em.models import Equipment
|
||||||
|
from apps.em.serializers import EquipmentSerializer
|
||||||
|
from apps.mtm.models import InputMaterial, Step, SubProduction, UsedStep
|
||||||
from apps.system.mixins import CreateUpdateModelAMixin
|
from apps.system.mixins import CreateUpdateModelAMixin
|
||||||
from apps.pm.serializers import ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer
|
from apps.pm.serializers import GenSubPlanSerializer, ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer, ResourceCalListSerializer, ResourceCalSerializer, SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer
|
||||||
from rest_framework.mixins import CreateModelMixin, ListModelMixin
|
from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin
|
||||||
from apps.pm.models import ProductionPlan
|
from apps.pm.models import ProductionPlan, SubProductionPlan
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from apps.sam.models import Order
|
from apps.sam.models import Order
|
||||||
from rest_framework.exceptions import APIException
|
from rest_framework.exceptions import APIException
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.decorators import action
|
||||||
|
from django.db.models import F
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
def updateOrderPlanedCount(order):
|
def updateOrderPlanedCount(order):
|
||||||
|
|
@ -36,7 +42,9 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
if self.action in ['create']:
|
if self.action in ['create']:
|
||||||
return ProductionPlanCreateFromOrderSerializer
|
return ProductionPlanCreateFromOrderSerializer
|
||||||
return ProductionPlanSerializer
|
elif self.action == 'list':
|
||||||
|
return ProductionPlanSerializer
|
||||||
|
return super().get_serializer_class()
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
data = request.data
|
data = request.data
|
||||||
|
|
@ -51,6 +59,90 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
|
||||||
instance = serializer.save(create_by=request.user, product=order.product)
|
instance = serializer.save(create_by=request.user, product=order.product)
|
||||||
updateOrderPlanedCount(instance.order)
|
updateOrderPlanedCount(instance.order)
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=GenSubPlanSerializer)
|
||||||
|
def gen_subplan(self, request, pk=None):
|
||||||
|
"""
|
||||||
|
生成子计划
|
||||||
|
"""
|
||||||
|
production_plan=self.get_object()
|
||||||
|
if production_plan.is_planed:
|
||||||
|
raise APIException('已生成子计划')
|
||||||
|
subps = SubProduction.objects.filter(product=production_plan.product).order_by('process__number')
|
||||||
|
for i in subps:
|
||||||
|
steps = Step.objects.filter(usedstep__subproduction=i, usedstep__subproduction__is_deleted=False,
|
||||||
|
usedstep__is_deleted=False, is_deleted=False).values('id', 'number', 'name', 'usedstep__remark')
|
||||||
|
SubProductionPlan.objects.create(production_plan=production_plan, subproduction=i,
|
||||||
|
start_date=production_plan.start_date, end_date=production_plan.end_date,
|
||||||
|
workshop=i.process.workshop, process=i.process, create_by=request.user,
|
||||||
|
steps = list(steps))
|
||||||
|
production_plan.is_planed=True
|
||||||
|
production_plan.save()
|
||||||
|
return Response()
|
||||||
|
|
||||||
|
class SubProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, UpdateModelMixin, GenericViewSet):
|
||||||
|
"""
|
||||||
|
子生产计划-列表/修改
|
||||||
|
"""
|
||||||
|
perms_map = {'*': '*'}
|
||||||
|
queryset = SubProductionPlan.objects.select_related('process', 'workshop')
|
||||||
|
search_fields = []
|
||||||
|
filterset_fields = ['production_plan']
|
||||||
|
ordering_fields = ['process__number']
|
||||||
|
ordering = ['process__number']
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
if self.action == 'list':
|
||||||
|
return SubProductionPlanListSerializer
|
||||||
|
elif self.action == 'update':
|
||||||
|
return SubProductionPlanUpdateSerializer
|
||||||
|
return SubProductionPlanListSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class ResourceViewSet(GenericViewSet):
|
||||||
|
|
||||||
|
perms_map = {'*': '*'}
|
||||||
|
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=ResourceCalListSerializer)
|
||||||
|
def cal(self, request, pk=None):
|
||||||
|
"""
|
||||||
|
物料消耗计算
|
||||||
|
"""
|
||||||
|
rdata = request.data
|
||||||
|
serializer = self.get_serializer(data=rdata)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
res_d_list = []
|
||||||
|
res = []
|
||||||
|
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')\
|
||||||
|
.values('material__id', 'material__name', 'material__number', 'material__type', 'count', 'material__count')
|
||||||
|
l_m = list(materials)
|
||||||
|
for m in l_m:
|
||||||
|
if m['material__id'] in res_d_list:
|
||||||
|
index = res_d_list.index(m['material__id'])
|
||||||
|
res[index]['count'] = res[index]['count'] + m['count']*i['count']
|
||||||
|
else:
|
||||||
|
res_d_list.append(m['material__id'])
|
||||||
|
res.append({'id':m['material__id'], 'name':m['material__name'],
|
||||||
|
'type':m['material__type'], 'number':m['material__number'],
|
||||||
|
'count':m['count']*i['count'], 'inv_count':m['material__count']})
|
||||||
|
return Response(res)
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=ResourceCalListSerializer)
|
||||||
|
def cal_equip(self, request, pk=None):
|
||||||
|
"""
|
||||||
|
设备状态查看
|
||||||
|
"""
|
||||||
|
rdata = request.data
|
||||||
|
serializer = self.get_serializer(data=rdata)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
rdata_l = []
|
||||||
|
for i in rdata:
|
||||||
|
rdata_l.append(i['id'])
|
||||||
|
subproductions = SubProduction.objects.filter(product__id__in=rdata_l, is_deleted=False)
|
||||||
|
steps = Step.objects.filter(usedstep__is_deleted=False, usedstep__subproduction__in=subproductions)
|
||||||
|
equips = Equipment.objects.filter(step_equips__in=steps, is_deleted=False)
|
||||||
|
serializer = EquipmentSerializer(instance=equips, many=True)
|
||||||
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
|
||||||
class ResourceCalculate(APIView):
|
|
||||||
pass
|
|
||||||
|
|
@ -16,7 +16,7 @@ class TicketFilterSet(filters.FilterSet):
|
||||||
elif value == 'duty':
|
elif value == 'duty':
|
||||||
queryset = queryset.filter(participant__contains=user.id).exclude(act_state__in=[Ticket.TICKET_ACT_STATE_FINISH, Ticket.TICKET_ACT_STATE_CLOSED])
|
queryset = queryset.filter(participant__contains=user.id).exclude(act_state__in=[Ticket.TICKET_ACT_STATE_FINISH, Ticket.TICKET_ACT_STATE_CLOSED])
|
||||||
elif value == 'worked':
|
elif value == 'worked':
|
||||||
queryset = queryset.filter(ticketflow_ticket__participant=user).exclude(create_by=user)
|
queryset = queryset.filter(ticketflow_ticket__participant=user).exclude(create_by=user).order_by('-update_time').distinct()
|
||||||
elif value == 'all':
|
elif value == 'all':
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Generated by Django 3.2.6 on 2021-10-14 01:44
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wf', '0012_ticketflow_intervene_type'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='ticketflow',
|
||||||
|
name='transition',
|
||||||
|
field=models.ForeignKey(blank=True, help_text='与worklow.Transition关联, 为空时表示认为干预的操作', null=True, on_delete=django.db.models.deletion.CASCADE, to='wf.transition', verbose_name='流转id'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -201,7 +201,7 @@ class TicketFlow(BaseModel):
|
||||||
工单流转日志
|
工单流转日志
|
||||||
"""
|
"""
|
||||||
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE, verbose_name='关联工单', related_name='ticketflow_ticket')
|
ticket = models.ForeignKey(Ticket, on_delete=models.CASCADE, verbose_name='关联工单', related_name='ticketflow_ticket')
|
||||||
transition = models.ForeignKey(Transition, verbose_name='流转id', help_text='与worklow.Transition关联, 为0时表示认为干预的操作', on_delete=models.CASCADE, null=True, blank=True)
|
transition = models.ForeignKey(Transition, verbose_name='流转id', help_text='与worklow.Transition关联, 为空时表示认为干预的操作', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
suggestion = models.CharField('处理意见', max_length=10000, default='', blank=True)
|
suggestion = models.CharField('处理意见', max_length=10000, default='', blank=True)
|
||||||
participant_type = models.IntegerField('处理人类型', default=0, help_text='0.无处理人,1.个人,2.多人', choices=State.state_participanttype_choices)
|
participant_type = models.IntegerField('处理人类型', default=0, help_text='0.无处理人,1.个人,2.多人', choices=State.state_participanttype_choices)
|
||||||
participant = models.ForeignKey(User, verbose_name='处理人', on_delete=models.SET_NULL, null=True, blank=True, related_name='ticketflow_participant')
|
participant = models.ForeignKey(User, verbose_name='处理人', on_delete=models.SET_NULL, null=True, blank=True, related_name='ticketflow_participant')
|
||||||
|
|
|
||||||
|
|
@ -129,4 +129,17 @@ class TicketHandleSerializer(serializers.Serializer):
|
||||||
suggestion = serializers.CharField(label="处理意见", required = False)
|
suggestion = serializers.CharField(label="处理意见", required = False)
|
||||||
|
|
||||||
class TicketRetreatSerializer(serializers.Serializer):
|
class TicketRetreatSerializer(serializers.Serializer):
|
||||||
suggestion = serializers.CharField(label="撤回原因", required = False)
|
suggestion = serializers.CharField(label="撤回原因", required = False)
|
||||||
|
|
||||||
|
class TicketCloseSerializer(serializers.Serializer):
|
||||||
|
suggestion = serializers.CharField(label="关闭原因", required = False)
|
||||||
|
|
||||||
|
class TicketAddNodeSerializer(serializers.Serializer):
|
||||||
|
suggestion = serializers.CharField(label="加签说明", required = False)
|
||||||
|
toadd_user = serializers.IntegerField(label='发送给谁去加签')
|
||||||
|
|
||||||
|
class TicketAddNodeEndSerializer(serializers.Serializer):
|
||||||
|
suggestion = serializers.CharField(label="加签意见", required = False)
|
||||||
|
|
||||||
|
class TicketDestorySerializer(serializers.Serializer):
|
||||||
|
ids = serializers.ListField(child=serializers.IntegerField(), label='工单ID列表')
|
||||||
|
|
@ -32,7 +32,18 @@ class WfService(object):
|
||||||
return wf_state_obj
|
return wf_state_obj
|
||||||
except:
|
except:
|
||||||
raise Exception('工作流状态配置错误')
|
raise Exception('工作流状态配置错误')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_workflow_end_state(workflow:Workflow):
|
||||||
|
"""
|
||||||
|
获取工作流结束状态
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
wf_state_obj = State.objects.get(workflow=workflow, type=State.STATE_TYPE_END, is_deleted=False)
|
||||||
|
return wf_state_obj
|
||||||
|
except:
|
||||||
|
raise Exception('工作流状态配置错误')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_workflow_custom_fields(workflow:Workflow):
|
def get_workflow_custom_fields(workflow:Workflow):
|
||||||
"""
|
"""
|
||||||
|
|
@ -124,7 +135,7 @@ class WfService(object):
|
||||||
"""
|
"""
|
||||||
到达结束状态
|
到达结束状态
|
||||||
"""
|
"""
|
||||||
return dict(destination_participant_type=State.PARTICIPANT_TYPE_PERSONAL,
|
return dict(destination_participant_type=0,
|
||||||
destination_participant=0,
|
destination_participant=0,
|
||||||
multi_all_person={})
|
multi_all_person={})
|
||||||
multi_all_person_dict = {}
|
multi_all_person_dict = {}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
|
from apps.system.models import User
|
||||||
from apps.wf.filters import TicketFilterSet
|
from apps.wf.filters import TicketFilterSet
|
||||||
from django.core.exceptions import AppRegistryNotReady
|
from django.core.exceptions import AppRegistryNotReady
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
||||||
from apps.wf.serializers import CustomFieldSerializer, StateSerializer, TicketCreateSerializer, TicketFlowSerializer, TicketFlowSimpleSerializer, TicketHandleSerializer, TicketRetreatSerializer, TicketSerializer, TransitionSerializer, WorkflowSerializer, TicketListSerializer, TicketDetailSerializer
|
from apps.wf.serializers import CustomFieldSerializer, StateSerializer, TicketAddNodeEndSerializer, TicketAddNodeSerializer, TicketCloseSerializer, TicketCreateSerializer, TicketDestorySerializer, TicketFlowSerializer, TicketFlowSimpleSerializer, TicketHandleSerializer, TicketRetreatSerializer, TicketSerializer, TransitionSerializer, WorkflowSerializer, TicketListSerializer, TicketDetailSerializer
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||||
from rest_framework.decorators import action, api_view
|
from rest_framework.decorators import action, api_view
|
||||||
|
|
@ -11,6 +12,7 @@ from apps.wf.models import CustomField, Ticket, Workflow, State, Transition, Tic
|
||||||
from apps.system.mixins import CreateUpdateCustomMixin, CreateUpdateModelAMixin, OptimizationMixin
|
from apps.system.mixins import CreateUpdateCustomMixin, CreateUpdateModelAMixin, OptimizationMixin
|
||||||
from apps.wf.services import WfService
|
from apps.wf.services import WfService
|
||||||
from rest_framework.exceptions import APIException, PermissionDenied
|
from rest_framework.exceptions import APIException, PermissionDenied
|
||||||
|
from rest_framework import status
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
class WorkflowViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
class WorkflowViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||||
|
|
@ -225,7 +227,7 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
|
||||||
ticket.act_state = Ticket.TICKET_ACT_STATE_ONGOING
|
ticket.act_state = Ticket.TICKET_ACT_STATE_ONGOING
|
||||||
|
|
||||||
if transition.attribute_type == Transition.TRANSITION_ATTRIBUTE_TYPE_REFUSE:
|
if transition.attribute_type == Transition.TRANSITION_ATTRIBUTE_TYPE_REFUSE:
|
||||||
transition.act_state = Ticket.TICKET_ACT_STATE_BACK
|
ticket.act_state = Ticket.TICKET_ACT_STATE_BACK
|
||||||
|
|
||||||
# 只更新必填和可选的字段
|
# 只更新必填和可选的字段
|
||||||
for key, value in ticket.state.state_fields.items():
|
for key, value in ticket.state.state_fields.items():
|
||||||
|
|
@ -312,16 +314,75 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
|
||||||
participant=request.user, transition=None)
|
participant=request.user, transition=None)
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
@action(methods=['post'], detail=True, perms_map={'post':'*'})
|
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=TicketAddNodeSerializer)
|
||||||
def add_node(self, request, pk=None):
|
def add_node(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
加签
|
加签
|
||||||
"""
|
"""
|
||||||
|
ticket = self.get_object()
|
||||||
|
data = request.data
|
||||||
|
add_user = User.objects.get(pk=data['toadd_user'])
|
||||||
|
ticket.participant_type = State.PARTICIPANT_TYPE_PERSONAL
|
||||||
|
ticket.participant = add_user.id
|
||||||
|
ticket.in_add_node = True
|
||||||
|
ticket.add_node_man = request.user
|
||||||
|
ticket.save()
|
||||||
|
# 更新流转记录
|
||||||
|
suggestion = request.data.get('suggestion', '') # 加签说明
|
||||||
|
TicketFlow.objects.create(ticket=ticket, state=ticket.state, ticket_data=WfService.get_ticket_all_field_value(ticket),
|
||||||
|
suggestion=suggestion, participant_type=State.PARTICIPANT_TYPE_PERSONAL, intervene_type=Transition.TRANSITION_INTERVENE_TYPE_ADD_NODE,
|
||||||
|
participant=request.user, transition=None)
|
||||||
|
return Response()
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=TicketAddNodeEndSerializer)
|
||||||
|
def add_node_end(self, request, pk=None):
|
||||||
|
"""
|
||||||
|
加签完成
|
||||||
|
"""
|
||||||
|
ticket = self.get_object()
|
||||||
|
ticket.participant_type = State.PARTICIPANT_TYPE_PERSONAL
|
||||||
|
ticket.in_add_node = False
|
||||||
|
ticket.participant = ticket.add_node_man.id
|
||||||
|
ticket.add_node_man = None
|
||||||
|
ticket.save()
|
||||||
|
# 更新流转记录
|
||||||
|
suggestion = request.data.get('suggestion', '') # 加签意见
|
||||||
|
TicketFlow.objects.create(ticket=ticket, state=ticket.state, ticket_data=WfService.get_ticket_all_field_value(ticket),
|
||||||
|
suggestion=suggestion, participant_type=State.PARTICIPANT_TYPE_PERSONAL, intervene_type=Transition.TRANSITION_INTERVENE_TYPE_ADD_NODE_END,
|
||||||
|
participant=request.user, transition=None)
|
||||||
|
return Response()
|
||||||
|
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=TicketCloseSerializer)
|
||||||
def close(self, request, pk=None):
|
def close(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
关闭工单(超级管理员或者创建人在初始状态)
|
关闭工单(创建人在初始状态)
|
||||||
"""
|
"""
|
||||||
|
ticket = self.get_object()
|
||||||
|
if ticket.state.type == State.STATE_TYPE_START and ticket.create_by==request.user:
|
||||||
|
end_state = WfService.get_workflow_end_state(ticket.workflow)
|
||||||
|
ticket.state = end_state
|
||||||
|
ticket.participant_type = 0
|
||||||
|
ticket.participant = 0
|
||||||
|
ticket.act_state = Ticket.TICKET_ACT_STATE_CLOSED
|
||||||
|
ticket.save()
|
||||||
|
# 更新流转记录
|
||||||
|
suggestion = request.data.get('suggestion', '') # 关闭原因
|
||||||
|
TicketFlow.objects.create(ticket=ticket, state=ticket.state, ticket_data=WfService.get_ticket_all_field_value(ticket),
|
||||||
|
suggestion=suggestion, participant_type=State.PARTICIPANT_TYPE_PERSONAL, intervene_type=Transition.TRANSITION_INTERVENE_TYPE_CLOSE,
|
||||||
|
participant=request.user, transition=None)
|
||||||
|
return Response()
|
||||||
|
else:
|
||||||
|
return Response('工单不可关闭', status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=TicketDestorySerializer)
|
||||||
|
def destory(self, request, pk=None):
|
||||||
|
"""
|
||||||
|
批量物理删除
|
||||||
|
"""
|
||||||
|
Ticket.objects.filter(id__in=request.data.get('ids', [])).delete(soft=False)
|
||||||
|
return Response()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TicketFlowViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
class TicketFlowViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class FitJSONRenderer(JSONRenderer):
|
||||||
data = data[prefix]
|
data = data[prefix]
|
||||||
if isinstance(data, list):
|
if isinstance(data, list):
|
||||||
data = data[0]
|
data = data[0]
|
||||||
response_body.msg = prefix + ":" + data # 取一部分放入msg,方便前端alert
|
response_body.msg = prefix + ":" + str(data) # 取一部分放入msg,方便前端alert
|
||||||
else:
|
else:
|
||||||
response_body.data = data
|
response_body.data = data
|
||||||
renderer_context.get("response").status_code = 200 # 统一成200响应,用code区分
|
renderer_context.get("response").status_code = 200 # 统一成200响应,用code区分
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue