Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
f41c41836c
|
@ -36,6 +36,12 @@ export function getContractList(query) {
|
|||
params: query
|
||||
})
|
||||
}
|
||||
export function getContract(id) {
|
||||
return request({
|
||||
url: `/sam/contract/${id}/`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
export function createContract(data) {
|
||||
return request({
|
||||
url: '/sam/contract/',
|
||||
|
|
|
@ -276,13 +276,21 @@ export const asyncRoutes = [
|
|||
path: 'customer',
|
||||
name: 'customer',
|
||||
component: () => import('@/views/sam/customer'),
|
||||
meta: { title: '客户信息', icon: 'example', perms: ['index_manage'] }
|
||||
meta: { title: '客户管理', icon: 'example', perms: ['index_manage'] }
|
||||
},
|
||||
{
|
||||
path: 'contract',
|
||||
name: 'contract',
|
||||
component: () => import('@/views/sam/contract'),
|
||||
meta: { title: '合同信息', icon: 'example', perms: ['index_manage'] }
|
||||
meta: { title: '合同管理', icon: 'example', perms: ['index_manage'] }
|
||||
}
|
||||
,
|
||||
{
|
||||
path: 'contractdetail/:id',
|
||||
name: 'contractdetail',
|
||||
component: () => import('@/views/sam/contractdetail'),
|
||||
meta: { title: '合同详情', perms: ['vendor_manage'] },
|
||||
hidden: true
|
||||
}
|
||||
|
||||
,
|
||||
|
@ -290,9 +298,17 @@ export const asyncRoutes = [
|
|||
path: 'order',
|
||||
name: 'order',
|
||||
component: () => import('@/views/sam/order'),
|
||||
meta: { title: '订单信息', icon: 'example', perms: ['index_manage'] }
|
||||
meta: { title: '订单管理', icon: 'example', perms: ['index_manage'] }
|
||||
}
|
||||
|
||||
,
|
||||
{
|
||||
path: 'orderdetail/:id',
|
||||
name: 'orderdetail',
|
||||
component: () => import('@/views/sam/orderdetail'),
|
||||
meta: { title: '订单详情', perms: ['vendor_manage'] },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'sales',
|
||||
name: 'sales',
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
</div>
|
||||
|
||||
</el-card>
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card >
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="equipmentList.results"
|
||||
|
@ -37,8 +37,8 @@
|
|||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="设备编号">
|
||||
|
@ -104,6 +104,7 @@
|
|||
|
||||
<el-link
|
||||
v-if="checkPermission(['equipment_update'])"
|
||||
type="primary"
|
||||
@click="handleEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
</div>
|
||||
|
||||
</el-card>
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card >
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="equipmentList.results"
|
||||
|
@ -38,7 +38,7 @@
|
|||
stripe
|
||||
highlight-current-row
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="设备名称" width="120" show-overflow-tooltip>
|
||||
|
@ -113,6 +113,7 @@
|
|||
|
||||
<el-link
|
||||
v-if="checkPermission(['equipment_update'])"
|
||||
type="primary"
|
||||
@click="handleEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
</div>
|
||||
|
||||
</el-card>
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card >
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="equipmentrecordList.results"
|
||||
|
@ -37,7 +37,8 @@
|
|||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
max-height="600"
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
|
||||
<el-table-column type="index" width="50" />
|
||||
|
@ -72,6 +73,7 @@
|
|||
|
||||
<el-link
|
||||
v-if="checkPermission(['equipment_update'])"
|
||||
type="primary"
|
||||
@click="handleEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card >
|
||||
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
|
@ -37,9 +37,9 @@
|
|||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
max-height="700"
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="出入记录ID">
|
||||
|
@ -70,11 +70,13 @@
|
|||
<template slot-scope="scope">
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
type="primary"
|
||||
@click="handleDetail(scope)"
|
||||
>查看</el-link
|
||||
>
|
||||
<el-link
|
||||
v-if="scope.row.is_audited == false"
|
||||
type="primary"
|
||||
@click="handleAudit(scope)"
|
||||
>审核</el-link
|
||||
>
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
<template slot-scope="scope">
|
||||
<el-link
|
||||
v-if="scope.row.is_tested == false"
|
||||
type="primary"
|
||||
@click="handleMaterial(scope)"
|
||||
>检查</el-link
|
||||
>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card >
|
||||
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
|
@ -34,7 +34,8 @@
|
|||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
max-height="600"
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card >
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="InventoryList.results"
|
||||
|
@ -33,9 +33,9 @@
|
|||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
max-height="700"
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="物料批次">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card >
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="iproductData.results"
|
||||
|
@ -9,9 +9,9 @@
|
|||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
max-height="700"
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="成品编号">
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
</div>
|
||||
|
||||
</el-card>
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card >
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="warehouseList.results"
|
||||
|
@ -37,9 +37,9 @@
|
|||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
max-height="700"
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="仓库名称">
|
||||
|
@ -60,11 +60,13 @@
|
|||
<template slot-scope="scope">
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
type="primary"
|
||||
@click="handleMaterial(scope)"
|
||||
>查看物料</el-link
|
||||
>
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
type="primary"
|
||||
@click="handleEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card >
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="iproductData.results"
|
||||
|
@ -9,9 +9,9 @@
|
|||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
max-height="700"
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="半成品编号">
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
highlight-current-row
|
||||
max-height="620"
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 10}"
|
||||
v-el-height-adaptive-table="{bottomOffset: 40}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="物料编号">
|
||||
|
@ -89,17 +89,20 @@
|
|||
<template slot-scope="scope">
|
||||
<el-link
|
||||
v-if="checkPermission(['material_update'])"
|
||||
type="primary"
|
||||
@click="handlebind(scope)"
|
||||
>检查表</el-link
|
||||
>
|
||||
|
||||
<el-link
|
||||
v-if="checkPermission(['material_update'])"
|
||||
type="primary"
|
||||
@click="handleEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
<el-link
|
||||
v-if="checkPermission(['material_update'])"
|
||||
type="primary"
|
||||
@click="handledetail(scope)"
|
||||
>详情</el-link
|
||||
>
|
||||
|
@ -391,3 +394,4 @@ export default {
|
|||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -228,3 +228,4 @@ getMaterial(){
|
|||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -311,6 +311,7 @@
|
|||
<template slot-scope="scope">
|
||||
<el-link
|
||||
v-if="checkPermission(['material_update'])"
|
||||
type="primary"
|
||||
@click="handlefieldEdit(scope)"
|
||||
>编辑
|
||||
</el-link
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
>
|
||||
<el-link
|
||||
v-if="checkPermission(['process_update'])"
|
||||
type="primary"
|
||||
@click="handleEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
|
|
|
@ -41,16 +41,10 @@
|
|||
</el-card>
|
||||
<el-card >
|
||||
|
||||
<el-descriptions class="margin-top" title="产品信息" :column="3" border>
|
||||
<el-descriptions class="margin-top" title="产品信息" :column="1" border>
|
||||
|
||||
|
||||
|
||||
<el-descriptions-item>
|
||||
<template slot="label">
|
||||
|
||||
产品名称
|
||||
</template>
|
||||
{{products.name}}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item>
|
||||
<template slot="label">
|
||||
|
||||
|
@ -59,6 +53,14 @@
|
|||
{{products.number}}
|
||||
</el-descriptions-item>
|
||||
|
||||
|
||||
<el-descriptions-item>
|
||||
<template slot="label">
|
||||
|
||||
产品名称
|
||||
</template>
|
||||
{{products.name}}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
</el-card>
|
||||
|
@ -115,6 +117,7 @@
|
|||
|
||||
<el-link
|
||||
v-if="checkPermission(['material_update'])"
|
||||
type="primary"
|
||||
@click="handlesubproducationEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
|
@ -213,6 +216,7 @@
|
|||
|
||||
<el-link
|
||||
v-if="checkPermission(['material_update'])"
|
||||
type="primary"
|
||||
@click="handleinputEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
|
@ -314,6 +318,7 @@
|
|||
|
||||
<el-link
|
||||
v-if="checkPermission(['material_update'])"
|
||||
type="primary"
|
||||
@click="handleoutputEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
|
@ -411,6 +416,7 @@
|
|||
|
||||
<el-link
|
||||
v-if="checkPermission(['material_update'])"
|
||||
type="primary"
|
||||
@click="handleotherEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
|
@ -498,6 +504,7 @@
|
|||
<el-link
|
||||
type="primary"
|
||||
@click="handlesearch(scope)"
|
||||
|
||||
>查看</el-link
|
||||
>
|
||||
<el-link
|
||||
|
@ -576,6 +583,7 @@
|
|||
|
||||
<el-link
|
||||
v-if="checkPermission(['process_update'])"
|
||||
type="primary"
|
||||
@click="handletechdocEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
<template slot-scope="scope">
|
||||
<el-link
|
||||
v-if="checkPermission(['step_update'])"
|
||||
type="primary"
|
||||
@click="handleEditStep(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
|
@ -160,10 +161,12 @@
|
|||
<template slot-scope="scope">
|
||||
<el-link
|
||||
v-if="checkPermission(['material_update'])"
|
||||
type="primary"
|
||||
@click="handleLook(scope)"
|
||||
>查看</el-link>
|
||||
<el-link
|
||||
v-if="checkPermission(['material_update'])"
|
||||
type="primary"
|
||||
@click="handleEdit(scope)"
|
||||
>编辑</el-link>
|
||||
<el-link
|
||||
|
@ -332,6 +335,7 @@
|
|||
|
||||
<el-link
|
||||
v-if="checkPermission(['material_update'])"
|
||||
type="primary"
|
||||
@click="handlefieldEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
stripe
|
||||
style="width: 100%"
|
||||
height="300"
|
||||
|
||||
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
|
||||
|
@ -254,6 +254,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
checkPermission,
|
||||
|
||||
//订单列表
|
||||
getorderList() {
|
||||
this.listLoading = true;
|
||||
|
@ -345,4 +346,15 @@ export default {
|
|||
},
|
||||
};
|
||||
|
||||
</script>
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
.el-table .warning-row {
|
||||
background: oldlace;
|
||||
}
|
||||
|
||||
.el-table .success-row {
|
||||
background: #f0f9eb;
|
||||
}
|
||||
</style>
|
|
@ -17,7 +17,7 @@
|
|||
stripe
|
||||
highlight-current-row
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
v-el-height-adaptive-table="{bottomOffset: 40}"
|
||||
>
|
||||
<el-table-column
|
||||
type="selection"
|
||||
|
@ -93,7 +93,7 @@
|
|||
fit
|
||||
stripe
|
||||
style="width: 100%"
|
||||
height="320"
|
||||
height="310"
|
||||
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
|
@ -134,7 +134,7 @@
|
|||
fit
|
||||
stripe
|
||||
style="width: 100%"
|
||||
height="300"
|
||||
height="320"
|
||||
>
|
||||
|
||||
<el-table-column type="index" width="50" />
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
|
||||
|
||||
<el-table-column label="子计划编号">
|
||||
<template slot-scope="scope">{{scope.row.id}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品名称">
|
||||
<template slot-scope="scope">{{ scope.row.product_.name }}</template>
|
||||
</el-table-column>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card>
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="iproductData.results"
|
||||
|
@ -10,8 +10,8 @@
|
|||
stripe
|
||||
highlight-current-row
|
||||
max-height="700"
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="成品编号">
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
</div>
|
||||
|
||||
</el-card>
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card >
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="contractList.results"
|
||||
|
@ -38,27 +38,27 @@
|
|||
stripe
|
||||
highlight-current-row
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="合同名称" width="130" show-overflow-tooltip>
|
||||
<template slot-scope="scope">{{ scope.row.name }}</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="合同编号" width="130">
|
||||
<el-table-column label="合同编号" >
|
||||
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="合同金额(元)" width="130">
|
||||
<el-table-column label="合同金额(元)">
|
||||
<template slot-scope="scope">{{ scope.row.amount }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开票金额(元)" width="130">
|
||||
<el-table-column label="开票金额(元)" >
|
||||
<template slot-scope="scope">{{ scope.row.invoice }}</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="客户名称" width="130" show-overflow-tooltip>
|
||||
<template slot-scope="scope">{{ scope.row.customer_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="签订日期" width="130">
|
||||
<el-table-column label="签订日期" >
|
||||
<template slot-scope="scope">{{ scope.row.sign_date }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="描述" width="130" show-overflow-tooltip>
|
||||
|
@ -76,6 +76,7 @@
|
|||
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
type="primary"
|
||||
@click="handleEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
|
@ -85,6 +86,14 @@
|
|||
@click="handleDelete(scope)"
|
||||
>删除</el-link
|
||||
>
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_delete'])"
|
||||
type="primary"
|
||||
@click="handleDetail(scope)"
|
||||
>详情</el-link
|
||||
>
|
||||
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -279,6 +288,10 @@ export default {
|
|||
}
|
||||
});
|
||||
},
|
||||
//合同详情
|
||||
handleDetail(scope){
|
||||
this.$router.push({name: "contractdetail", params: { id: scope.row.id }, })
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-descriptions title="基本信息" direction="vertical" :column="8" border>
|
||||
<el-descriptions-item label="合同名称"> {{contractdetail.name}}</el-descriptions-item>
|
||||
<el-descriptions-item label="编号" > {{contractdetail.number}}</el-descriptions-item>
|
||||
<el-descriptions-item label="金额" :span="2" > {{contractdetail.amount}}</el-descriptions-item>
|
||||
<el-descriptions-item label="客户名称" v-if="contractdetail.customer"> {{contractdetail.customer_.name}} </el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>关联订单</span>
|
||||
</div>
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="OrderList"
|
||||
border
|
||||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
|
||||
<el-table-column label="订单编号" width="160" show-overflow-tooltip>
|
||||
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="客户" width="200" show-overflow-tooltip>
|
||||
<template slot-scope="scope">{{ scope.row.customer_.name }}</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="产品名称" width="200" show-overflow-tooltip>
|
||||
<template slot-scope="scope">{{ scope.row.product_.name }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品型号" width="120" show-overflow-tooltip>
|
||||
<template slot-scope="scope">{{ scope.row.product_.specification }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="产品数量" >
|
||||
<template slot-scope="scope">{{ scope.row.count }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="交货日期" >
|
||||
<template slot-scope="scope">{{ scope.row.delivery_date }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="已交货数量" >
|
||||
<template slot-scope="scope">{{ scope.row.delivered_count }}</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="创建时间" width="160" >
|
||||
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="操作"
|
||||
width="220px"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
|
||||
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_delete'])"
|
||||
type="primary"
|
||||
@click="handleDetail(scope)"
|
||||
>详情</el-link
|
||||
>
|
||||
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {getContract,getOrderList} from "@/api/sam";
|
||||
import checkPermission from "@/utils/permission";
|
||||
|
||||
|
||||
import { genTree } from "@/utils";
|
||||
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||
|
||||
export default {
|
||||
components: { Pagination },
|
||||
data() {
|
||||
return {
|
||||
|
||||
contractdetail:"",
|
||||
OrderList:"",
|
||||
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
created() {
|
||||
this.id = this.$route.params.id;
|
||||
this.getdetail();
|
||||
this.getList();
|
||||
|
||||
|
||||
},
|
||||
methods: {
|
||||
checkPermission,
|
||||
getList() {
|
||||
getOrderList({contract:this.id,page:0}).then((response) => {
|
||||
if (response.data) {
|
||||
this.OrderList = response.data;
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
//详情
|
||||
getdetail() {
|
||||
|
||||
getContract(this.id).then((response) => {
|
||||
if (response.data) {
|
||||
this.contractdetail = response.data;
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
|
||||
//订单详情
|
||||
handleDetail(scope){
|
||||
this.$router.push({name: "orderdetail", params: { id: scope.row.id }, })
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -29,7 +29,7 @@
|
|||
</div>
|
||||
|
||||
</el-card>
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card >
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="customerList.results"
|
||||
|
@ -38,7 +38,7 @@
|
|||
stripe
|
||||
highlight-current-row
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="客户名称" width="200" show-overflow-tooltip>
|
||||
|
@ -70,6 +70,7 @@
|
|||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
@click="handleEdit(scope)"
|
||||
type="primary"
|
||||
>编辑</el-link
|
||||
>
|
||||
<el-link
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
</div>
|
||||
|
||||
</el-card>
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card >
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="orderList.results"
|
||||
|
@ -38,7 +38,7 @@
|
|||
stripe
|
||||
highlight-current-row
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
|
||||
|
@ -79,8 +79,9 @@
|
|||
<template slot-scope="scope">
|
||||
|
||||
<el-link
|
||||
v-if="scope.row.planed_count==0&&checkPermission(['warehouse_update'])"
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
@click="handleEdit(scope)"
|
||||
type="primary"
|
||||
>编辑</el-link
|
||||
>
|
||||
<el-link
|
||||
|
@ -89,6 +90,12 @@
|
|||
@click="handleDelete(scope)"
|
||||
>删除</el-link
|
||||
>
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_delete'])"
|
||||
type="primary"
|
||||
@click="handleDetail(scope)"
|
||||
>详情</el-link
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -127,8 +134,8 @@
|
|||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="所需数量" prop="count">
|
||||
<el-input type="number" v-model="order.count"></el-input>
|
||||
<el-form-item label="所需数量" prop="count" >
|
||||
<el-input-number type="number" v-model="order.count" :min="0"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="交货日期" prop="delivery_date">
|
||||
<el-date-picker
|
||||
|
@ -322,6 +329,10 @@ export default {
|
|||
}
|
||||
});
|
||||
},
|
||||
//订单详情
|
||||
handleDetail(scope){
|
||||
this.$router.push({name: "orderdetail", params: { id: scope.row.id }, })
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-descriptions title="基本信息" :column="4" border>
|
||||
<el-descriptions-item label="订单编号"> {{orderdetail.number}}</el-descriptions-item>
|
||||
<el-descriptions-item label="产品名称" > {{orderdetail.product_.name}}</el-descriptions-item>
|
||||
<el-descriptions-item label="产品型号" > {{orderdetail.product_.specification}}</el-descriptions-item>
|
||||
<el-descriptions-item label="产品数量" > {{orderdetail.count}} </el-descriptions-item>
|
||||
<el-descriptions-item label="已交货数量" > {{orderdetail.delivered_count}}</el-descriptions-item>
|
||||
<el-descriptions-item label="已排产数量"> {{orderdetail.planed_count}}</el-descriptions-item>
|
||||
<el-descriptions-item label="交货日期" > {{orderdetail.delivery_date}}</el-descriptions-item>
|
||||
|
||||
|
||||
</el-descriptions>
|
||||
</el-card>
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>关联生产任务</span>
|
||||
</div>
|
||||
<el-table
|
||||
:data="productionplan"
|
||||
border
|
||||
fit
|
||||
stripe
|
||||
style="width: 100%"
|
||||
height="300"
|
||||
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
|
||||
|
||||
|
||||
<el-table-column label="任务编号">
|
||||
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="合同编号" >
|
||||
<template slot-scope="scope">{{ scope.row.order_.contract_.number }}</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="产品名称" width="150" show-overflow-tooltip>
|
||||
<template slot-scope="scope">{{ scope.row.product_.name }}</template>
|
||||
</el-table-column>
|
||||
<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.product_.unit }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="生产数量" >
|
||||
<template slot-scope="scope">{{ scope.row.count }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计划开工时间" >
|
||||
<template slot-scope="scope">{{ scope.row.start_date }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计划完工时间" >
|
||||
<template slot-scope="scope">{{ scope.row.end_date }}</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="是否生成子计划">
|
||||
<template slot-scope="scope" >
|
||||
<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="创建时间" width="160">
|
||||
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import {getOrder} from "@/api/sam";
|
||||
import {getProductionplanList} from "@/api/pm";
|
||||
|
||||
import checkPermission from "@/utils/permission";
|
||||
|
||||
|
||||
import { genTree } from "@/utils";
|
||||
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||
|
||||
export default {
|
||||
components: { Pagination },
|
||||
data() {
|
||||
return {
|
||||
|
||||
productionplan:"",
|
||||
orderdetail:"",
|
||||
|
||||
};
|
||||
},
|
||||
computed: {},
|
||||
watch: {},
|
||||
created() {
|
||||
this.id = this.$route.params.id;
|
||||
this.getdetail();
|
||||
this.getList();
|
||||
|
||||
|
||||
},
|
||||
methods: {
|
||||
checkPermission,
|
||||
getList() {
|
||||
getProductionplanList({order:this.id,page:0}).then((response) => {
|
||||
if (response.data) {
|
||||
this.productionplan = response.data;
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
//详情
|
||||
getdetail() {
|
||||
|
||||
getOrder(this.id).then((response) => {
|
||||
if (response.data) {
|
||||
this.orderdetail = response.data;
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -29,7 +29,7 @@
|
|||
</div>
|
||||
|
||||
</el-card>
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card >
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="contractList.results"
|
||||
|
@ -37,7 +37,8 @@
|
|||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
max-height="600"
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="合同名称">
|
||||
|
@ -75,6 +76,7 @@
|
|||
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
type="primary"
|
||||
@click="handleEdit(scope)"
|
||||
>编辑</el-link
|
||||
>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
</div>
|
||||
|
||||
</el-card>
|
||||
<el-card style="margin-top: 2px">
|
||||
<el-card >
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="saleList.results"
|
||||
|
@ -37,7 +37,8 @@
|
|||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
|
||||
height="100"
|
||||
v-el-height-adaptive-table="{bottomOffset: 42}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
<el-table-column label="产品名称" show-overflow-tooltip>
|
||||
|
@ -66,14 +67,14 @@
|
|||
<template slot-scope="scope">
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_delete'])"
|
||||
|
||||
type="primary"
|
||||
@click="handleDetail(scope)"
|
||||
>详情</el-link
|
||||
>
|
||||
|
||||
<el-link
|
||||
v-if="scope.row.is_audited==false"
|
||||
|
||||
type="primary"
|
||||
@click="handleAudit(scope)"
|
||||
>审核</el-link
|
||||
>
|
||||
|
@ -152,6 +153,7 @@
|
|||
stripe
|
||||
highlight-current-row
|
||||
ref="multipleTable"
|
||||
|
||||
>
|
||||
<el-table-column
|
||||
type="selection"
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
fit
|
||||
stripe
|
||||
highlight-current-row
|
||||
max-height="600"
|
||||
max-height="700"
|
||||
|
||||
>
|
||||
<el-table-column type="index" width="50"/>
|
||||
<el-table-column label="半成品名称">
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
style="width: 100%"
|
||||
max-height="670"
|
||||
highlight-current-row
|
||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
||||
v-el-height-adaptive-table="{bottomOffset: 30}"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
|
||||
|
@ -70,11 +70,13 @@
|
|||
<template slot-scope="scope">
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
type="primary"
|
||||
@click="handleoperation(scope)"
|
||||
>前往操作</el-link>
|
||||
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
type="danger"
|
||||
@click="handleDelete(scope)"
|
||||
>删除</el-link>
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@
|
|||
<template slot-scope="scope">
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
type="danger"
|
||||
@click="handleDeletewproduct(scope)"
|
||||
>删除</el-link
|
||||
>
|
||||
|
@ -129,6 +130,7 @@
|
|||
<template slot-scope="scope">
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
type="danger"
|
||||
@click="handleDeletequip(scope)"
|
||||
>删除</el-link
|
||||
>
|
||||
|
@ -165,6 +167,7 @@
|
|||
<template slot-scope="scope">
|
||||
<el-link
|
||||
v-if="checkPermission(['warehouse_update'])"
|
||||
type="primary"
|
||||
@click="handlerecord(scope)"
|
||||
>填写表单</el-link
|
||||
>
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
@current-change="handleCurrentChange"
|
||||
>
|
||||
<el-table-column type="index" width="50" />
|
||||
|
||||
<el-table-column label="子计划编号">
|
||||
<template slot-scope="scope">{{scope.row.id}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="任务编号">
|
||||
<template slot-scope="scope">{{
|
||||
scope.row.number
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-16 01:45
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('inm', '0022_auto_20211208_1408'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='fifoitem',
|
||||
name='is_tested',
|
||||
field=models.BooleanField(default=False, verbose_name='是否已检验'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='fifoitem',
|
||||
name='is_testok',
|
||||
field=models.BooleanField(default=False, verbose_name='是否检验合格'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,37 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-16 01:45
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mtm', '0042_alter_recordformfield_field_type'),
|
||||
('qm', '0019_auto_20211214_1504'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='testrecorditem',
|
||||
name='field_key',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='testrecorditem',
|
||||
name='field_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='testrecorditem',
|
||||
name='field_type',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='testrecorditem',
|
||||
name='form_field',
|
||||
field=models.ForeignKey(db_constraint=False, on_delete=django.db.models.deletion.CASCADE, to='mtm.recordformfield', verbose_name='关联自定义表格字段'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='testrecorditem',
|
||||
name='test_record',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='item_test_record', to='qm.testrecord', verbose_name='关联的检验记录'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,21 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-16 02:20
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('qm', '0020_auto_20211216_0945'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='testrecord',
|
||||
name='is_testok_robot',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='testrecorditem',
|
||||
name='is_testok_robot',
|
||||
),
|
||||
]
|
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-16 06:01
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mtm', '0042_alter_recordformfield_field_type'),
|
||||
('qm', '0021_auto_20211216_1020'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='testrecorditem',
|
||||
name='field_value',
|
||||
field=models.JSONField(blank=True, null=True, verbose_name='录入值'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='testrecorditem',
|
||||
name='form_field',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.recordformfield', verbose_name='关联自定义表格字段'),
|
||||
),
|
||||
]
|
|
@ -62,7 +62,6 @@ class TestRecord(CommonADModel):
|
|||
form = models.ForeignKey('mtm.recordform', verbose_name='所用表格', on_delete=models.CASCADE)
|
||||
type = models.PositiveSmallIntegerField(choices=type_choice, default=TEST_PROCESS)
|
||||
is_testok = models.BooleanField('是否合格', default=True)
|
||||
is_testok_robot = models.BooleanField('自动判定的是否合格', default=True)
|
||||
number = models.CharField('产品编号', null=True, blank=True, max_length=50)
|
||||
wproduct = models.ForeignKey('wpm.wproduct', verbose_name='关联的动态产品', on_delete=models.CASCADE, null=True, blank=True, related_name='test_wproduct')
|
||||
material = models.ForeignKey('mtm.material', verbose_name='关联的物料状态', on_delete=models.CASCADE, null=True, blank=True)
|
||||
|
@ -78,12 +77,8 @@ class TestRecordItem(BaseModel):
|
|||
"""
|
||||
记录表格字段值
|
||||
"""
|
||||
form_field = models.ForeignKey(RecordFormField, verbose_name='关联自定义表格字段', on_delete=models.CASCADE, db_constraint=False)
|
||||
field_name = models.CharField('字段名', max_length=50)
|
||||
field_key = models.CharField('字段标识', max_length=50)
|
||||
field_type = models.CharField('字段类型', choices=RecordForm.type_choices, max_length=50)
|
||||
field_value = models.JSONField('录入值', default=dict, blank=True)
|
||||
form_field = models.ForeignKey(RecordFormField, verbose_name='关联自定义表格字段', on_delete=models.CASCADE)
|
||||
field_value = models.JSONField('录入值', null=True, blank=True)
|
||||
is_hidden = models.BooleanField('是否隐藏', default=False)
|
||||
is_testok = models.BooleanField('是否合格', null=True, blank=True)
|
||||
is_testok_robot = models.BooleanField('自动判定的是否合格', null=True, blank=True)
|
||||
test_record = models.ForeignKey(TestRecord, verbose_name='关联的检验记录', on_delete=models.CASCADE, related_name='item_test_record')
|
|
@ -48,10 +48,15 @@ class TestRecordItemUpdateSerializer(serializers.ModelSerializer):
|
|||
|
||||
|
||||
class TestRecordItemSerializer(serializers.ModelSerializer):
|
||||
field_key = serializers.CharField(source='form_field.field_key', read_only=True)
|
||||
field_name = serializers.CharField(source='form_field.field_name', read_only=True)
|
||||
field_type = serializers.CharField(source='form_field.field_type', read_only=True)
|
||||
need_judge = serializers.BooleanField(source='form_field.need_judge', read_only=True)
|
||||
field_choice = serializers.JSONField(source='form_field.field_choice', read_only=True)
|
||||
rule_expression = serializers.JSONField(source='form_field.rule_expression', read_only=True)
|
||||
display_expression = serializers.JSONField(source='form_field.display_expression', read_only=True)
|
||||
is_hidden = serializers.BooleanField(source='form_field.is_hidden', read_only=True)
|
||||
parent = serializers.PrimaryKeyRelatedField(source='form_field.parent', read_only=True)
|
||||
help_text = serializers.CharField(source='form_field.help_text', read_only=True)
|
||||
sort = serializers.IntegerField(source='form_field.sort', read_only=True)
|
||||
class Meta:
|
||||
|
@ -97,7 +102,7 @@ class TestRecordDetailSerializer(serializers.ModelSerializer):
|
|||
def to_representation(self, instance):
|
||||
ret = super().to_representation(instance)
|
||||
if instance.origin_test and instance.type == TestRecord.TEST_PROCESS_RE:
|
||||
origin_test = ret['origin_test']
|
||||
origin_test = ret['origin_test_']
|
||||
o_dict = {}
|
||||
for i in origin_test['record_data']:
|
||||
o_dict[i['field_key']] = i['field_value']
|
||||
|
|
|
@ -84,9 +84,11 @@ class TestRecordViewSet(ListModelMixin, UpdateModelMixin, RetrieveModelMixin, De
|
|||
obj = self.get_object()
|
||||
# 校验是否有未填项目
|
||||
if obj.type != TestRecord.TEST_PROCESS_RE:
|
||||
if TestRecordItem.objects.filter(field_value__isnull=True, is_hidden=False).exists():
|
||||
if TestRecordItem.objects.filter(field_value__isnull=True, is_hidden=False, test_record=obj).exists():
|
||||
raise exceptions.APIException('存在未填写项目')
|
||||
with transaction.atomic():
|
||||
obj.is_submited=True
|
||||
obj.save()
|
||||
WpmServies.update_wproduct_by_test(obj, request.user)
|
||||
return Response()
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ class Workflow(CommonAModel):
|
|||
name = models.CharField('名称', max_length=50)
|
||||
key = models.CharField('工作流标识', unique=True, max_length=20, null=True, blank=True)
|
||||
sn_prefix = models.CharField('流水号前缀', max_length=50, default='hb')
|
||||
description = models.CharField('描述', max_length=200)
|
||||
description = models.CharField('描述', max_length=200, null=True, blank=True)
|
||||
view_permission_check = models.BooleanField('查看权限校验', default=True, help_text='开启后,只允许工单的关联人(创建人、曾经的处理人)有权限查看工单')
|
||||
limit_expression = models.JSONField('限制表达式', default=dict, blank=True, help_text='限制周期({"period":24} 24小时), 限制次数({"count":1}在限制周期内只允许提交1次), 限制级别({"level":1} 针对(1单个用户 2全局)限制周期限制次数,默认特定用户);允许特定人员提交({"allow_persons":"zhangsan,lisi"}只允许张三提交工单,{"allow_depts":"1,2"}只允许部门id为1和2的用户提交工单,{"allow_roles":"1,2"}只允许角色id为1和2的用户提交工单)')
|
||||
display_form_str = models.JSONField('展现表单字段', default=list, blank=True, help_text='默认"[]",用于用户只有对应工单查看权限时显示哪些字段,field_key的list的json,如["days","sn"],内置特殊字段participant_info.participant_name:当前处理人信息(部门名称、角色名称),state.state_name:当前状态的状态名,workflow.workflow_name:工作流名称')
|
||||
|
@ -68,7 +68,7 @@ class State(CommonAModel):
|
|||
STATE_FIELD_READONLY= 1 # 字段只读
|
||||
STATE_FIELD_REQUIRED = 2 # 字段必填
|
||||
STATE_FIELD_OPTIONAL = 3 # 字段可选
|
||||
|
||||
STATE_FIELD_HIDDEN = 4 # 字段隐藏
|
||||
state_filter_choices=(
|
||||
(0, '无'),
|
||||
(1, '和工单同属一及上级部门'),
|
||||
|
@ -83,7 +83,7 @@ class State(CommonAModel):
|
|||
enable_retreat = models.BooleanField('允许撤回', default=False, help_text='开启后允许工单创建人在此状态直接撤回工单到初始状态')
|
||||
participant_type = models.IntegerField('参与者类型', choices=state_participanttype_choices, default=1, blank=True, help_text='0.无处理人,1.个人,2.多人,3.部门,4.角色,5.变量(支持工单创建人,创建人的leader),6.脚本,7.工单的字段内容(如表单中的"测试负责人",需要为用户名或者逗号隔开的多个用户名),8.父工单的字段内容。 初始状态请选择类型5,参与人填create_by')
|
||||
participant = models.JSONField('参与者', default=list, blank=True, help_text='可以为空(无处理人的情况,如结束状态)、userid、userid列表\部门id\角色id\变量(create_by,create_by_tl)\脚本记录的id等,包含子工作流的需要设置处理人为loonrobot')
|
||||
state_fields = models.JSONField('表单字段', default=dict, help_text='json格式字典存储,包括读写属性1:只读,2:必填,3:可选. 示例:{"create_time":1,"title":2, "sn":1}, 内置特殊字段participant_info.participant_name:当前处理人信息(部门名称、角色名称),state.state_name:当前状态的状态名,workflow.workflow_name:工作流名称') # json格式存储,包括读写属性1:只读,2:必填,3:可选,4:不显示, 字典的字典
|
||||
state_fields = models.JSONField('表单字段', default=dict, help_text='json格式字典存储,包括读写属性1:只读,2:必填,3:可选, 4:隐藏 示例:{"create_time":1,"title":2, "sn":1}, 内置特殊字段participant_info.participant_name:当前处理人信息(部门名称、角色名称),state.state_name:当前状态的状态名,workflow.workflow_name:工作流名称') # json格式存储,包括读写属性1:只读,2:必填,3:可选,4:不显示, 字典的字典
|
||||
distribute_type = models.IntegerField('分配方式', default=1, choices=state_distribute_choices, help_text='1.主动接单(如果当前处理人实际为多人的时候,需要先接单才能处理) 2.直接处理(即使当前处理人实际为多人,也可以直接处理) 3.随机分配(如果实际为多人,则系统会随机分配给其中一个人) 4.全部处理(要求所有参与人都要处理一遍,才能进入下一步)')
|
||||
filter_policy = models.IntegerField('参与人过滤策略', default=0, choices=state_filter_choices)
|
||||
participant_cc = models.JSONField('抄送给', default=list, blank=True, help_text='抄送给(userid列表)')
|
||||
|
@ -197,7 +197,7 @@ class Ticket(CommonBModel):
|
|||
('worked', '我处理的'),
|
||||
('cc', '抄送我的')
|
||||
)
|
||||
title = models.CharField('标题', max_length=500, blank=True, default='', help_text="工单标题")
|
||||
title = models.CharField('标题', max_length=500, null=True, blank=True, help_text="工单标题")
|
||||
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, verbose_name='关联工作流')
|
||||
sn = models.CharField('流水号', max_length=25, help_text="工单的流水号")
|
||||
state = models.ForeignKey(State, on_delete=models.CASCADE, verbose_name='当前状态', related_name='ticket_state')
|
||||
|
|
|
@ -49,7 +49,7 @@ class TicketSimpleSerializer(serializers.ModelSerializer):
|
|||
fields = '__all__'
|
||||
|
||||
class TicketCreateSerializer(serializers.ModelSerializer):
|
||||
transition = serializers.IntegerField(label='流转ID')
|
||||
transition = serializers.PrimaryKeyRelatedField(queryset=Transition.objects.all(), write_only=True)
|
||||
class Meta:
|
||||
model=Ticket
|
||||
fields=['title','workflow', 'ticket_data', 'transition']
|
||||
|
|
|
@ -54,6 +54,13 @@ class WfService(object):
|
|||
"""
|
||||
return CustomField.objects.filter(is_deleted=False, workflow=workflow).order_by('sort')
|
||||
|
||||
@staticmethod
|
||||
def get_workflow_custom_fields_list(workflow:Workflow):
|
||||
"""
|
||||
获取工单字段key List
|
||||
"""
|
||||
return list(CustomField.objects.filter(is_deleted=False, workflow=workflow).order_by('sort').values_list('field_key', flat=True))
|
||||
|
||||
@classmethod
|
||||
def get_ticket_transitions(cls, ticket:Ticket):
|
||||
"""
|
||||
|
|
|
@ -77,6 +77,11 @@ class WorkflowViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
|||
ret['workflow'] = pk
|
||||
ret['transitions'] = TransitionSerializer(instance=transitions, many=True).data
|
||||
field_list = CustomFieldSerializer(instance=WfService.get_workflow_custom_fields(wf), many=True).data
|
||||
for i in field_list:
|
||||
if i['field_key'] in start_state.state_fields:
|
||||
i['field_attribute'] = start_state.state_fields[i['field_key']]
|
||||
else:
|
||||
i['field_attribute'] = State.STATE_FIELD_READONLY
|
||||
ret['field_list'] = field_list
|
||||
return Response(ret)
|
||||
|
||||
|
@ -137,15 +142,27 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
|
|||
rdata = request.data
|
||||
serializer = self.get_serializer(data=rdata)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
start_state = WfService.get_workflow_start_state(rdata['workflow'])
|
||||
transition = Transition.objects.get(pk=rdata['transition'])
|
||||
ticket_data = rdata['ticket_data']
|
||||
vdata = serializer.validated_data #校验之后的数据
|
||||
start_state = WfService.get_workflow_start_state(vdata['workflow'])
|
||||
transition = vdata['transition']
|
||||
ticket_data = vdata['ticket_data']
|
||||
|
||||
save_ticket_data = {}
|
||||
#校验必填项
|
||||
if transition.field_require_check:
|
||||
for key, value in start_state.state_fields.items(): #校验必填项
|
||||
for key, value in start_state.state_fields.items():
|
||||
if value == State.STATE_FIELD_REQUIRED:
|
||||
if key not in ticket_data or not ticket_data[key]:
|
||||
raise APIException('字段{}必填'.format(key))
|
||||
ticket = serializer.save(state=start_state, create_by=request.user, act_state=Ticket.TICKET_ACT_STATE_DRAFT, belong_dept=request.user.dept) # 先创建出来
|
||||
save_ticket_data[key] = ticket_data[key]
|
||||
elif value == State.STATE_FIELD_OPTIONAL:
|
||||
save_ticket_data[key] = ticket_data[key]
|
||||
|
||||
ticket = serializer.save(state=start_state,
|
||||
create_by=request.user,
|
||||
act_state=Ticket.TICKET_ACT_STATE_DRAFT,
|
||||
belong_dept=request.user.dept,
|
||||
ticket_data=save_ticket_data) # 先创建出来
|
||||
|
||||
next_state = WfService.get_next_state_by_transition_and_ticket_info(ticket=ticket, transition=transition)
|
||||
participant_info = WfService.get_ticket_state_participant_info(state=next_state, ticket=ticket, ticket_data=ticket.ticket_data)
|
||||
|
@ -159,7 +176,7 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
|
|||
act_state = Ticket.TICKET_ACT_STATE_DRAFT
|
||||
else:
|
||||
act_state = Ticket.TICKET_ACT_STATE_ONGOING
|
||||
title = rdata.get('title', '')
|
||||
title = vdata['title']
|
||||
title_template = ticket.workflow.title_template
|
||||
if title_template:
|
||||
all_ticket_data = {**rdata, **rdata['ticket_data']}
|
||||
|
@ -224,6 +241,7 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
|
|||
if value == State.STATE_FIELD_REQUIRED:
|
||||
if key not in ticket_data or not ticket_data[key]:
|
||||
raise APIException('字段{}必填'.format(key))
|
||||
|
||||
destination_state = WfService.get_next_state_by_transition_and_ticket_info(ticket, transition, ticket_data, request)
|
||||
multi_all_person = ticket.multi_all_person
|
||||
if multi_all_person:
|
||||
|
@ -265,7 +283,7 @@ class TicketViewSet(OptimizationMixin, CreateUpdateCustomMixin, CreateModelMixin
|
|||
ticket.act_state = Ticket.TICKET_ACT_STATE_BACK
|
||||
|
||||
# 只更新必填和可选的字段
|
||||
for key, value in ticket.state.state_fields.items():
|
||||
for key, value in source_state.state_fields.items():
|
||||
if value in (State.STATE_FIELD_REQUIRED, State.STATE_FIELD_OPTIONAL):
|
||||
source_ticket_data[key] = ticket_data[key]
|
||||
ticket.ticket_data = source_ticket_data
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-16 01:45
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wpm', '0032_auto_20211214_1245'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='operationrecorditem',
|
||||
name='field_key',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='operationrecorditem',
|
||||
name='field_name',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='operationrecorditem',
|
||||
name='field_type',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='operationrecorditem',
|
||||
name='sort',
|
||||
),
|
||||
]
|
|
@ -0,0 +1,25 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-16 03:27
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('mtm', '0042_alter_recordformfield_field_type'),
|
||||
('wpm', '0033_auto_20211216_0945'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='operationrecorditem',
|
||||
name='form_field',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ori_form_field', to='mtm.recordformfield', verbose_name='关联字段'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='operationrecorditem',
|
||||
name='operation_record',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='item_operation_record', to='wpm.operationrecord', verbose_name='关联的生产记录'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.2.9 on 2021-12-16 06:01
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('wpm', '0034_auto_20211216_1127'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='operationrecorditem',
|
||||
name='field_value',
|
||||
field=models.JSONField(blank=True, null=True, verbose_name='录入值'),
|
||||
),
|
||||
]
|
|
@ -35,6 +35,7 @@ class WProduct(CommonAModel):
|
|||
WPR_ACT_STATE_INM = 40
|
||||
WPR_ACT_STATE_NOTOK = 50
|
||||
WPR_ACT_STATE_TOFINALTEST = 60
|
||||
WPR_ACT_STATE_SCRAP = 70
|
||||
act_state_choices=(
|
||||
(WPR_ACT_STATE_TORETEST, '待复检'),
|
||||
(WPR_ACT_STATE_DOWAIT, '操作准备中'),
|
||||
|
@ -44,7 +45,8 @@ class WProduct(CommonAModel):
|
|||
(WPR_ACT_STATE_OK, '已合格'),
|
||||
(WPR_ACT_STATE_INM, '已入库'),
|
||||
(WPR_ACT_STATE_NOTOK, '不合格'),
|
||||
(WPR_ACT_STATE_TOFINALTEST, '待成品检验')
|
||||
(WPR_ACT_STATE_TOFINALTEST, '待成品检验'),
|
||||
(WPR_ACT_STATE_SCRAP, '已报废')
|
||||
)
|
||||
number = models.CharField('物品编号', unique=True, null=True, blank=True, max_length=50)
|
||||
material = models.ForeignKey(Material, verbose_name='所属物料状态', on_delete=models.CASCADE)
|
||||
|
@ -55,6 +57,7 @@ class WProduct(CommonAModel):
|
|||
child = models.ForeignKey('self', blank=True, null=True, on_delete=models.CASCADE)
|
||||
remark = models.CharField('备注', max_length=200, null=True, blank=True)
|
||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='wproduct_subplan')
|
||||
|
||||
warehouse = models.ForeignKey(WareHouse, verbose_name='所在仓库', on_delete=models.SET_NULL, null=True, blank=True)
|
||||
operation = models.ForeignKey('wpm.operation', verbose_name='当前操作',
|
||||
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_operation')
|
||||
|
@ -69,40 +72,7 @@ class WProduct(CommonAModel):
|
|||
最后提交的工序自检
|
||||
"""
|
||||
return self.test_wproduct.filter(type=TestRecord.TEST_PROCESS, is_submited=True).order_by('-id').first()
|
||||
|
||||
# @property
|
||||
# def last_test(self):
|
||||
# """
|
||||
# 最后提交的检验
|
||||
# """
|
||||
# return self.test_wproduct.filter(is_submited=True).order_by('-id').first()
|
||||
|
||||
# @property
|
||||
# def current_test(self):
|
||||
# """
|
||||
# 当前未提交的检验
|
||||
# """
|
||||
# trs = self.test_wproduct.filter(is_submited=False).order_by('-id')
|
||||
# if trs.count() == 1:
|
||||
# return trs[0]
|
||||
# elif trs.count() == 0:
|
||||
# return None
|
||||
# else:
|
||||
# raise exceptions.APIException('存在多条未提交检验记录')
|
||||
|
||||
# @property
|
||||
# def current_ticket(self):
|
||||
# """
|
||||
# 当前是否有进行中工单
|
||||
# """
|
||||
# tickets = Ticket.objects.filter(wt_ticket__wproduct=self, act_state=Ticket.TICKET_ACT_STATE_ONGOING).order_by('-id')
|
||||
# if tickets.count() == 1:
|
||||
# return tickets[0]
|
||||
# elif tickets.count() == 0:
|
||||
# return None
|
||||
# else:
|
||||
# raise exceptions.APIException('存在多条进行中工单')
|
||||
|
||||
|
||||
|
||||
class WprouctTicket(CommonAModel):
|
||||
"""
|
||||
|
@ -187,13 +157,9 @@ class OperationRecordItem(BaseModel):
|
|||
"""
|
||||
记录表格字段值
|
||||
"""
|
||||
form_field = models.ForeignKey(RecordFormField, verbose_name='关联字段', on_delete=models.CASCADE, db_constraint=False)
|
||||
field_name = models.CharField('字段名', max_length=50)
|
||||
field_key = models.CharField('字段标识', max_length=50)
|
||||
field_type = models.CharField('字段类型', choices=RecordForm.type_choices, max_length=50)
|
||||
field_value = models.JSONField('录入值', default=dict, blank=True)
|
||||
sort = models.IntegerField('排序号', default=1)
|
||||
operation_record = models.ForeignKey(OperationRecord, verbose_name='关联的生产记录', on_delete=models.CASCADE)
|
||||
form_field = models.ForeignKey(RecordFormField, verbose_name='关联字段', on_delete=models.CASCADE, related_name='ori_form_field')
|
||||
field_value = models.JSONField('录入值', null=True, blank=True)
|
||||
operation_record = models.ForeignKey(OperationRecord, verbose_name='关联的生产记录', on_delete=models.CASCADE, related_name='item_operation_record')
|
||||
|
||||
class OperationEquip(BaseModel):
|
||||
operation = models.ForeignKey(Operation, verbose_name='关联操作', on_delete=models.CASCADE, related_name='oe_operation')
|
||||
|
|
|
@ -244,19 +244,18 @@ class DoOutputSerializer(serializers.Serializer):
|
|||
material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label='物料ID')
|
||||
count_output = serializers.IntegerField(min_value=0, label='产出数量')
|
||||
|
||||
class OperationRecordItemSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = OperationRecordItem
|
||||
fields = ['form_field', 'field_value']
|
||||
class OperationRecordItemUpdateSerializer(serializers.Serializer):
|
||||
id = serializers.PrimaryKeyRelatedField(queryset=OperationRecordItem.objects.all())
|
||||
field_value = serializers.JSONField(allow_null=True, required=False)
|
||||
|
||||
class OperationRecordSubmitSerializer(serializers.ModelSerializer):
|
||||
record_data = OperationRecordItemSerializer(many=True)
|
||||
record_data = OperationRecordItemUpdateSerializer(many=True)
|
||||
class Meta:
|
||||
model = OperationRecord
|
||||
fields = ['record_data']
|
||||
|
||||
class OperationRecordSerializer(serializers.ModelSerializer):
|
||||
record_data = OperationRecordItemSerializer(many=True)
|
||||
record_data = OperationRecordItemUpdateSerializer(many=True)
|
||||
class Meta:
|
||||
model = OperationRecord
|
||||
fields = ['form', 'record_data']
|
||||
|
@ -392,4 +391,26 @@ class OperationMaterialCreate3Serializer(serializers.ModelSerializer):
|
|||
validated_data['type'] = SubprodctionMaterial.SUB_MA_TYPE_TOOL
|
||||
return super().create(validated_data)
|
||||
|
||||
|
||||
|
||||
class OperationRecordItemSerializer(serializers.ModelSerializer):
|
||||
field_key = serializers.CharField(source='form_field.field_key', read_only=True)
|
||||
field_name = serializers.CharField(source='form_field.field_name', read_only=True)
|
||||
field_type = serializers.CharField(source='form_field.field_type', read_only=True)
|
||||
field_choice = serializers.JSONField(source='form_field.field_choice', read_only=True)
|
||||
is_hidden = serializers.BooleanField(source='form_field.is_hidden', read_only=True)
|
||||
help_text = serializers.CharField(source='form_field.help_text', read_only=True)
|
||||
sort = serializers.IntegerField(source='form_field.sort', read_only=True)
|
||||
class Meta:
|
||||
model = OperationRecordItem
|
||||
fields = '__all__'
|
||||
|
||||
class OperationRecordDetailSerializer(serializers.ModelSerializer):
|
||||
form_ = RecordFormSimpleSerializer(source='form', read_only=True)
|
||||
record_data = serializers.SerializerMethodField()
|
||||
create_by_ = UserSimpleSerializer(source='create_by', read_only=True)
|
||||
class Meta:
|
||||
model = OperationRecord
|
||||
fields = '__all__'
|
||||
|
||||
def get_record_data(self, obj):
|
||||
return OperationRecordItemSerializer(instance=obj.item_operation_record.order_by('form_field__sort'), many=True).data
|
|
@ -17,10 +17,11 @@ from apps.qm.serializers import TestRecordDetailSerializer
|
|||
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
||||
from rest_framework.decorators import action
|
||||
from apps.wf.models import Workflow
|
||||
from apps.wf.serializers import WorkflowSimpleSerializer
|
||||
from apps.wpm.filters import WMaterialFilterSet
|
||||
from apps.wpm.models import OperationEquip, OperationWproduct, Pick, PickWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem
|
||||
|
||||
from apps.wpm.serializers import OperationEquipListSerializer, OperationEquipUpdateSerializer, OperationMaterialCreate1ListSerailizer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2ListSerailizer, OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickHalfsSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestFormInitSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer, WproductPutInsSerializer
|
||||
from apps.wpm.serializers import OperationEquipListSerializer, OperationEquipUpdateSerializer, OperationMaterialCreate1ListSerailizer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2ListSerailizer, OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, OperationRecordDetailSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickHalfsSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestFormInitSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer, WproductPutInsSerializer
|
||||
from rest_framework.response import Response
|
||||
from django.db import transaction
|
||||
from rest_framework import exceptions, serializers
|
||||
|
@ -188,7 +189,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
|||
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WpmTestFormInitSerializer)
|
||||
def test_init(self, request, pk=None):
|
||||
"""
|
||||
检验表单初始化
|
||||
检验记录创建及初始化
|
||||
"""
|
||||
serializer = WpmTestFormInitSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
@ -198,78 +199,41 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
|||
if wproduct.test:
|
||||
raise exceptions.APIException('存在进行中检验')
|
||||
|
||||
data = RecordFormDetailSerializer(instance=form).data
|
||||
data['origin_test'] = None
|
||||
data['form'] = form.id
|
||||
# 如果是复检, 需要带入原数据
|
||||
if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST:
|
||||
# 查找最近一条检验记录
|
||||
trs = wproduct.last_process_test
|
||||
if trs:
|
||||
origin_test = TestRecordDetailSerializer(instance=trs).data
|
||||
data['origin_test_'] = origin_test
|
||||
data['origin_test'] = origin_test.get('id', None)
|
||||
o_dict = {}
|
||||
for i in origin_test['record_data']:
|
||||
o_dict[i['field_key']] = i['field_value']
|
||||
for i in data['form_fields']:
|
||||
i['origin_value'] = o_dict[i['field_key']] if i['field_key'] in o_dict else None
|
||||
i['is_hidden'] = o_dict[i['is_hidden']] if i['is_hidden'] in o_dict else False
|
||||
else:
|
||||
raise exceptions.APIException('原工序检验记录不存在')
|
||||
|
||||
# 后续加入系统自带数据
|
||||
return Response(data)
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WpmTestRecordCreateSerializer)
|
||||
@transaction.atomic
|
||||
def test(self, request, pk=None):
|
||||
"""
|
||||
检验记录提交
|
||||
"""
|
||||
serializer = WpmTestRecordCreateSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
vdata = serializer.validated_data
|
||||
record_data = vdata.pop('record_data')
|
||||
wproduct = vdata['wproduct']
|
||||
# 根据情况创建一条检验记录
|
||||
if wproduct.act_state not in [WProduct.WPR_ACT_STATE_TOTEST,
|
||||
WProduct.WPR_ACT_STATE_TORETEST, WProduct.WPR_ACT_STATE_TOFINALTEST, WProduct.WPR_ACT_STATE_TOCOMBTEST]:
|
||||
raise exceptions.APIException('该产品当前状态不可检验')
|
||||
if 'is_testok' not in vdata:
|
||||
raise exceptions.APIException('未填写检验结论')
|
||||
|
||||
savedict = dict(create_by = self.request.user,
|
||||
material=wproduct.material, number=wproduct.number, subproduction_plan=wproduct.subproduction_plan, step=wproduct.step)
|
||||
|
||||
savedict = dict(
|
||||
create_by = self.request.user,
|
||||
wproduct=wproduct,
|
||||
material=wproduct.material,
|
||||
number=wproduct.number,
|
||||
subproduction_plan=wproduct.subproduction_plan,
|
||||
step=wproduct.step,
|
||||
form=form)
|
||||
if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST:
|
||||
if not vdata['origin_test']:
|
||||
raise exceptions.APIException('自检记录不存在')
|
||||
# 查找最近一条检验记录
|
||||
trs = wproduct.last_process_test
|
||||
savedict['origin_test'] = trs
|
||||
if not trs:
|
||||
raise exceptions.APIException('原工序检验记录不存在')
|
||||
savedict['type'] = TestRecord.TEST_PROCESS_RE
|
||||
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOFINALTEST:
|
||||
savedict['type'] = TestRecord.TEST_FINAL
|
||||
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOCOMBTEST:
|
||||
savedict['type'] = TestRecord.TEST_COMB
|
||||
obj = serializer.save(**savedict)
|
||||
tris = []
|
||||
for m in record_data: # 保存记录详情
|
||||
form_field = m['form_field']
|
||||
m['field_name'] = form_field.field_name
|
||||
m['field_key'] = form_field.field_key
|
||||
m['field_type'] = form_field.field_type
|
||||
m['is_testok'] = m['is_testok'] if 'is_testok' in m else None
|
||||
m['is_hidden'] = m['is_hidden'] if 'is_hidden' in m else None
|
||||
m['test_record'] = obj
|
||||
tris.append(TestRecordItem(**m))
|
||||
TestRecordItem.objects.bulk_create(tris)
|
||||
|
||||
# 如果提交检验
|
||||
if obj.is_submited:
|
||||
WpmServies.update_wproduct_by_test(obj, request.user)
|
||||
else:
|
||||
# 保存当前检验
|
||||
wproduct.test = obj
|
||||
wproduct.update_by = request.user
|
||||
wproduct.save()
|
||||
return Response()
|
||||
tr = TestRecord.objects.create(**savedict)
|
||||
wproduct.test = tr
|
||||
wproduct.save()
|
||||
# 创建检验条目
|
||||
for i in RecordFormField.objects.filter(form=form, is_deleted=False):
|
||||
tri = TestRecordItem()
|
||||
tri.test_record = tr
|
||||
tri.form_field = i
|
||||
tri.is_hidden = i.is_hidden
|
||||
tri.save()
|
||||
return Response(TestRecordDetailSerializer(instance=tr).data)
|
||||
|
||||
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WproductPutInsSerializer)
|
||||
@transaction.atomic
|
||||
|
@ -368,12 +332,29 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
|||
wproduct.save()
|
||||
return Response()
|
||||
|
||||
@action(methods=['get'], detail=False, perms_map={'post':'*'})
|
||||
@action(methods=['post'], detail=True, perms_map={'post':'*'})
|
||||
def scrap(self, request, pk=None):
|
||||
"""
|
||||
报废操作
|
||||
"""
|
||||
obj = self.get_object()
|
||||
if obj.ow_wproduct.ow_operation.count() >4 or obj.act_state != WProduct.WPR_ACT_STATE_NOTOK:
|
||||
raise exceptions.APIException('该产品不支持直接报废')
|
||||
obj.act_state = WProduct.WPR_ACT_STATE_SCRAP
|
||||
obj.update_by = request.user
|
||||
obj.save()
|
||||
return Response()
|
||||
|
||||
@action(methods=['get'], detail=False, perms_map={'get':'*'})
|
||||
def workflows(self, request, pk=None):
|
||||
"""
|
||||
可发起的工作流
|
||||
"""
|
||||
wfs = Workflow.objects.get()
|
||||
wfs = Workflow.objects.filter(key__startswith= 'wp')
|
||||
return WorkflowSimpleSerializer(instance=wfs, many=True).data
|
||||
|
||||
|
||||
|
||||
class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, GenericViewSet):
|
||||
"""
|
||||
生产操作记录
|
||||
|
@ -449,6 +430,13 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
opr.form = i
|
||||
opr.is_filled = False
|
||||
opr.save()
|
||||
opri_list = []
|
||||
for m in RecordFormField.objects.filter(form=i, is_deleted=False):
|
||||
opri_dict = {}
|
||||
opri_dict['operation_record'] = opr
|
||||
opri_dict['form_field'] = m
|
||||
opri_list.append(OperationRecordItem(**opri_dict))
|
||||
OperationRecordItem.objects.bulk_create(opri_list)
|
||||
# 查询需要使用的生产设备
|
||||
for i in step.equipments.all():
|
||||
ope = OperationEquip()
|
||||
|
@ -532,7 +520,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
WProduct.objects.create(**wpr)
|
||||
elif step.type == Step.STEP_TYPE_COMB:
|
||||
oms_w = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT,
|
||||
subproduction_progress__ismain=True)
|
||||
subproduction_progress__is_main=True)
|
||||
if len(oms_w) == 1:
|
||||
oms_w = oms_w[0]
|
||||
# 校验单片数量是否正确, 暂时未写
|
||||
|
@ -555,7 +543,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
|||
wps = WProduct.objects.filter(ow_wproduct__operation = op)
|
||||
wps.update(is_hidden=True, child=wproduct, update_by=request.user, update_time=timezone.now())
|
||||
else:
|
||||
raise exceptions.APIException('产出物料错误')
|
||||
raise exceptions.APIException('产出物料未填写或填写错误')
|
||||
op.is_submited = True
|
||||
op.save()
|
||||
return Response()
|
||||
|
@ -614,7 +602,7 @@ class OperationEquipViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin,
|
|||
instance.delete()
|
||||
return Response()
|
||||
|
||||
class OperationRecordViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin, GenericViewSet):
|
||||
class OperationRecordViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||
"""
|
||||
操作使用的自定义表格
|
||||
"""
|
||||
|
@ -628,6 +616,8 @@ class OperationRecordViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin
|
|||
def get_serializer_class(self):
|
||||
if self.action == 'update':
|
||||
return OperationRecordSubmitSerializer
|
||||
elif self.action == 'retrieve':
|
||||
return OperationRecordDetailSerializer
|
||||
return super().get_serializer_class()
|
||||
@transaction.atomic()
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
|
@ -637,16 +627,6 @@ class OperationRecordViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin
|
|||
instance.delete()
|
||||
return Response()
|
||||
|
||||
@action(methods=['get'], detail=True, perms_map={'get':'*'})
|
||||
def init(self, request, pk=None):
|
||||
'''
|
||||
表格初始化
|
||||
'''
|
||||
obj = self.get_object()
|
||||
data = RecordFormDetailSerializer(instance=obj.form).data
|
||||
# 后续加入系统带入数据
|
||||
return Response(data)
|
||||
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
serializer = OperationRecordSubmitSerializer(data=request.data)
|
||||
|
@ -655,18 +635,12 @@ class OperationRecordViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin
|
|||
opr = self.get_object()
|
||||
if opr.operation.is_submited:
|
||||
raise exceptions.APIException('操作已提交不可修改')
|
||||
wrds = []
|
||||
for m in vdata['record_data']: # 保存记录详情
|
||||
form_field = m['form_field']
|
||||
m['form_field'] = form_field
|
||||
m['field_name'] = form_field.field_name
|
||||
m['field_key'] = form_field.field_key
|
||||
m['field_type'] = form_field.field_type
|
||||
m['sort'] = form_field.sort
|
||||
m['operation_record'] = opr
|
||||
wrds.append(OperationRecordItem(**m))
|
||||
OperationRecordItem.objects.bulk_create(wrds)
|
||||
for i in vdata['record_data']:
|
||||
ori = i['id']
|
||||
ori.field_value = i['field_value']
|
||||
ori.save()
|
||||
opr.is_filled = True
|
||||
opr.update_by = request.user
|
||||
opr.save()
|
||||
return Response()
|
||||
|
||||
|
|
Loading…
Reference in New Issue