description
This commit is contained in:
commit
b4a03a1feb
|
|
@ -103,4 +103,14 @@ export function getiproductList(query) {
|
||||||
method: 'get',
|
method: 'get',
|
||||||
params: query
|
params: query
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//军检
|
||||||
|
//军检
|
||||||
|
export function saleMtest(id, data) {
|
||||||
|
return request({
|
||||||
|
url: `/inm/iproduct/${id}/mtest/`,
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -368,4 +368,5 @@ export function deletetechdoc(id, data) {
|
||||||
method: 'delete',
|
method: 'delete',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,13 @@ export function createOrder(data) {
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
export function getOrder(id) {
|
||||||
|
return request({
|
||||||
|
url: `/sam/order/${id}/`,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export function updateOrder(id, data) {
|
export function updateOrder(id, data) {
|
||||||
return request({
|
return request({
|
||||||
url: `/sam/order/${id}/`,
|
url: `/sam/order/${id}/`,
|
||||||
|
|
@ -93,4 +100,68 @@ export function getordertoplan() {
|
||||||
url: '/sam/order/toplan/',
|
url: '/sam/order/toplan/',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
//销售记录列表
|
||||||
|
export function getSaleList(query) {
|
||||||
|
return request({
|
||||||
|
url: '/sam/sale/',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//销售记录创建
|
||||||
|
export function createSale(data) {
|
||||||
|
return request({
|
||||||
|
url: '/sam/sale/',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function deleteSale(id, data) {
|
||||||
|
return request({
|
||||||
|
url: `/sam/sale/${id}/`,
|
||||||
|
method: 'delete',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getSale(id) {
|
||||||
|
return request({
|
||||||
|
url: `/sam/sale/${id}/`,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//销售记录列表
|
||||||
|
export function getSaleproductList(query) {
|
||||||
|
return request({
|
||||||
|
url: '/sam/sale_product/',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除销售记录关联产品
|
||||||
|
export function deleteSaleproduct(id, data) {
|
||||||
|
return request({
|
||||||
|
url: `/sam/sale_product/${id}/`,
|
||||||
|
method: 'delete',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//审核
|
||||||
|
export function saleAudit(id) {
|
||||||
|
return request({
|
||||||
|
url: `/sam/sale/${id}/audit/`,
|
||||||
|
method: 'POST',
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -261,6 +261,32 @@ export function createputins(data) {
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
//车间领料批量提交
|
||||||
|
export function createInputs(data) {
|
||||||
|
return request({
|
||||||
|
url: '/wpm/operation_input/creates/',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//产出批量提交
|
||||||
|
export function createOutputs(data) {
|
||||||
|
return request({
|
||||||
|
url: '/wpm/operation_output/creates/',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//表格初始化
|
||||||
|
|
||||||
|
export function recordInit(id) {
|
||||||
|
return request({
|
||||||
|
url: `/wpm/operation_record/${id}/init/`,
|
||||||
|
method: 'GET',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
//半产品复检
|
//半产品复检
|
||||||
export function wproductReview(data) {
|
export function wproductReview(data) {
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ export const asyncRoutes = [
|
||||||
component: Layout,
|
component: Layout,
|
||||||
redirect: '/sam/customer',
|
redirect: '/sam/customer',
|
||||||
name: 'sam',
|
name: 'sam',
|
||||||
meta: { title: '合同管理', icon: 'example', perms: ['equipment_set'] },
|
meta: { title: '销售管理', icon: 'example', perms: ['equipment_set'] },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'customer',
|
path: 'customer',
|
||||||
|
|
@ -284,6 +284,21 @@ export const asyncRoutes = [
|
||||||
component: () => import('@/views/sam/order'),
|
component: () => import('@/views/sam/order'),
|
||||||
meta: { title: '订单信息', icon: 'example', perms: ['index_manage'] }
|
meta: { title: '订单信息', icon: 'example', perms: ['index_manage'] }
|
||||||
}
|
}
|
||||||
|
,
|
||||||
|
{
|
||||||
|
path: 'sales',
|
||||||
|
name: 'sales',
|
||||||
|
component: () => import('@/views/sam/sales'),
|
||||||
|
meta: { title: '销售信息', icon: 'example', perms: ['index_manage'] }
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{
|
||||||
|
path: 'salesdetail/:id',
|
||||||
|
name: 'salesdetail',
|
||||||
|
component: () => import('@/views/sam/salesdetail'),
|
||||||
|
meta: { title: '销售详情', perms: ['vendor_manage'] },
|
||||||
|
hidden: true
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column label="操作人员">
|
<el-table-column label="操作人员">
|
||||||
<template slot-scope="scope">{{
|
<template slot-scope="scope" v-if="scope.row.create_by">{{
|
||||||
scope.row.create_by_.name
|
scope.row.create_by_.name
|
||||||
}}</template>
|
}}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,38 @@
|
||||||
<el-table-column label="所在仓库">
|
<el-table-column label="所在仓库">
|
||||||
<template slot-scope="scope">{{ scope.row.warehouse_.name }}</template>
|
<template slot-scope="scope">{{ scope.row.warehouse_.name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="是否已军检">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
|
||||||
|
|
||||||
|
<el-tag v-if="scope.row.is_mtested == false">未军检</el-tag>
|
||||||
|
<el-tag v-else>已军检</el-tag></template>
|
||||||
|
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="军检">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
|
||||||
|
|
||||||
|
<el-tag v-if="scope.row.is_mtestok == false">不合格</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.is_mtestok == true">合格</el-tag></template>
|
||||||
|
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
align="center"
|
||||||
|
label="操作"
|
||||||
|
width="220px"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
|
||||||
|
<el-link
|
||||||
|
v-if="scope.row.is_mtested == false"
|
||||||
|
@click="handleMtest(scope)"
|
||||||
|
>军检</el-link
|
||||||
|
>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<pagination
|
<pagination
|
||||||
v-show="iproductData.count > 0"
|
v-show="iproductData.count > 0"
|
||||||
|
|
@ -38,14 +68,40 @@
|
||||||
:limit.sync="listQuery.page_size"
|
:limit.sync="listQuery.page_size"
|
||||||
@pagination="getList"
|
@pagination="getList"
|
||||||
/>
|
/>
|
||||||
|
<el-dialog
|
||||||
|
:visible.sync="dialogVisible"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
title="军检"
|
||||||
|
>
|
||||||
|
<el-form
|
||||||
|
ref="Form"
|
||||||
|
:model="mtest"
|
||||||
|
label-width="150px"
|
||||||
|
label-position="right"
|
||||||
|
|
||||||
|
>
|
||||||
|
<el-form-item label="军检是否合格">
|
||||||
|
|
||||||
|
<el-radio v-model="mtest.is_mtestok" label=True >合格</el-radio>
|
||||||
|
<el-radio v-model="mtest.is_mtestok" label=False >不合格</el-radio>
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注" prop="remark">
|
||||||
|
<el-input v-model="mtest.remark" placeholder="备注" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
<div style="text-align: right">
|
||||||
|
<el-button type="danger" @click="dialogVisible = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="smtconfirm('Form')">确认</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import {
|
import { getiproductList,saleMtest} from "@/api/inm";
|
||||||
getiproductList,
|
|
||||||
} from "@/api/inm";
|
|
||||||
import checkPermission from "@/utils/permission";
|
import checkPermission from "@/utils/permission";
|
||||||
|
|
||||||
import { genTree } from "@/utils";
|
import { genTree } from "@/utils";
|
||||||
|
|
@ -63,6 +119,10 @@ export default {
|
||||||
page: 1,
|
page: 1,
|
||||||
page_size: 20,
|
page_size: 20,
|
||||||
},
|
},
|
||||||
|
mtest: {},
|
||||||
|
salesdetail:"",
|
||||||
|
saleproduct:"",
|
||||||
|
dialogVisible:false,
|
||||||
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
@ -83,7 +143,22 @@ export default {
|
||||||
this.listLoading = false;
|
this.listLoading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
handleMtest(scope){
|
||||||
|
this.saleproduct=scope.row.id;
|
||||||
|
this.dialogVisible=true;
|
||||||
|
},
|
||||||
|
smtconfirm(){
|
||||||
|
|
||||||
|
saleMtest(this.saleproduct,this.mtest).then((res) => {
|
||||||
|
|
||||||
|
if (res.code >= 200) {
|
||||||
|
this.getList();
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$message.success("成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,6 @@
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:visible.sync="dialogVisible"
|
:visible.sync="dialogVisible"
|
||||||
:close-on-click-modal="false"
|
|
||||||
:title="dialogType === 'edit' ? '编辑合同' : '新增合同'"
|
:title="dialogType === 'edit' ? '编辑合同' : '新增合同'"
|
||||||
>
|
>
|
||||||
<el-form
|
<el-form
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,10 @@
|
||||||
<el-table-column label="交货日期" width="150" >
|
<el-table-column label="交货日期" width="150" >
|
||||||
<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="已交货数量" width="150" >
|
||||||
|
<template slot-scope="scope">{{ scope.row.delivered_count }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column label="创建时间" width="160" >
|
<el-table-column label="创建时间" width="160" >
|
||||||
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
<template slot-scope="scope">{{ scope.row.create_time }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,410 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-card>
|
||||||
|
<div>
|
||||||
|
<el-button type="primary" icon="el-icon-plus" @click="handleCreate"
|
||||||
|
>新增销售记录</el-button
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
v-model="listQuery.search"
|
||||||
|
placeholder="客户名称"
|
||||||
|
style="width: 300px"
|
||||||
|
class="filter-item"
|
||||||
|
@keyup.enter.native="handleFilter"
|
||||||
|
/>
|
||||||
|
<el-button
|
||||||
|
class="filter-item"
|
||||||
|
type="primary"
|
||||||
|
icon="el-icon-search"
|
||||||
|
@click="handleFilter"
|
||||||
|
>搜索</el-button
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
class="filter-item"
|
||||||
|
type="primary"
|
||||||
|
icon="el-icon-refresh-left"
|
||||||
|
@click="resetFilter"
|
||||||
|
>重置</el-button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</el-card>
|
||||||
|
<el-card style="margin-top: 2px">
|
||||||
|
<el-table
|
||||||
|
v-loading="listLoading"
|
||||||
|
:data="saleList.results"
|
||||||
|
border
|
||||||
|
fit
|
||||||
|
stripe
|
||||||
|
highlight-current-row
|
||||||
|
|
||||||
|
>
|
||||||
|
<el-table-column type="index" width="50" />
|
||||||
|
<el-table-column label="产品名称" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope" v-if="scope.row.product">{{ scope.row.product_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="产品型号" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope" v-if="scope.row.product">{{ scope.row.product_.specification }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="客户名称" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope" v-if="scope.row.customer">{{ scope.row.customer_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="订单编号" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope" v-if="scope.row.order">{{ scope.row.order_.number }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="合同名称" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope" v-if="scope.row.order&&scope.row.order_.contract">{{ scope.row.order_.contract_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="是否审核" >
|
||||||
|
<template slot-scope="scope" > <el-tag v-if="scope.row.is_audited == false">否</el-tag>
|
||||||
|
<el-tag v-else>是</el-tag></template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-link
|
||||||
|
v-if="checkPermission(['warehouse_delete'])"
|
||||||
|
|
||||||
|
@click="handleDetail(scope)"
|
||||||
|
>详情</el-link
|
||||||
|
>
|
||||||
|
|
||||||
|
<el-link
|
||||||
|
v-if="scope.row.is_audited==false"
|
||||||
|
|
||||||
|
@click="handleAudit(scope)"
|
||||||
|
>审核</el-link
|
||||||
|
>
|
||||||
|
|
||||||
|
<el-link
|
||||||
|
v-if="scope.row.is_audited==false"
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(scope)"
|
||||||
|
>删除</el-link
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<pagination
|
||||||
|
v-show="saleList.count > 0"
|
||||||
|
:total="saleList.count"
|
||||||
|
:page.sync="listQuery.page"
|
||||||
|
:limit.sync="listQuery.page_size"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
<el-dialog
|
||||||
|
:visible.sync="dialogVisible"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
width="60%"
|
||||||
|
:title="dialogType === 'edit' ? '编辑销售信息' : '新增销售信息'"
|
||||||
|
>
|
||||||
|
<el-form
|
||||||
|
ref="Form"
|
||||||
|
:model="sale"
|
||||||
|
label-width="80px"
|
||||||
|
label-position="right"
|
||||||
|
|
||||||
|
:rules="rule1"
|
||||||
|
>
|
||||||
|
<el-form-item label="关联订单" prop="name">
|
||||||
|
<el-select style="width: 100%" v-model="sale.order" @change="selectorder" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item in orderoptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.number"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="关联客户" prop="customer">
|
||||||
|
<el-select style="width: 100%" v-model="sale.customer" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item in customeroptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
|
||||||
|
<el-form-item label="所需产品" prop="product">
|
||||||
|
<el-select style="width: 100%" v-model="sale.product" @change="selectproduct" placeholder="请选择">
|
||||||
|
<el-option
|
||||||
|
v-for="item in materialoptions"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="选择产品" prop="iproducts">
|
||||||
|
<div class="trdiv">
|
||||||
|
<el-transfer v-model="sale.iproducts" :data="iproductoptions" :titles="['未选产品', '已选产品']" right-check-change="change"></el-transfer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</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 { createSale,getOrderList,getCustomerList,getSaleList,getOrder,deleteSale,getSale,saleAudit} from "@/api/sam";
|
||||||
|
import checkPermission from "@/utils/permission";
|
||||||
|
import { getMaterialList } from "@/api/mtm";
|
||||||
|
import { getiproductList,} from "@/api/inm";
|
||||||
|
import { genTree } from "@/utils";
|
||||||
|
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||||
|
const defaulteSale = {
|
||||||
|
order:null,
|
||||||
|
customer:null,
|
||||||
|
product:null
|
||||||
|
};
|
||||||
|
export default {
|
||||||
|
components: { Pagination },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
sale: defaulteSale,
|
||||||
|
saleList: {
|
||||||
|
count: 0,
|
||||||
|
},
|
||||||
|
listQuery: {
|
||||||
|
page: 1,
|
||||||
|
page_size: 20,
|
||||||
|
},
|
||||||
|
orderoptions:[],
|
||||||
|
customeroptions:[],
|
||||||
|
materialoptions:[],
|
||||||
|
iproductoptions:[],
|
||||||
|
dialogVisible: false,
|
||||||
|
dialogType: "new",
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
this.getCustomerLists();
|
||||||
|
this.getproductList();
|
||||||
|
this.getOrderLists();
|
||||||
|
this.getMaterialList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
checkPermission,
|
||||||
|
//关联订单
|
||||||
|
getOrderLists() {
|
||||||
|
|
||||||
|
getOrderList({page:0}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.orderoptions = response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//选择订单变化
|
||||||
|
|
||||||
|
selectorder(selval)
|
||||||
|
{
|
||||||
|
getOrder(selval).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.sale.customer = response.data.customer;
|
||||||
|
this.sale.product = response.data.product;
|
||||||
|
this.iproductoptions=[];
|
||||||
|
getiproductList({material: this.sale.product,page:0}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
response.data.forEach((item) => {
|
||||||
|
this.iproductoptions.push({
|
||||||
|
label: item.number+"__"+item.material_.name+"__"+(item.is_mtested==true?"已军检":"未军检") ,
|
||||||
|
key: item.id
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
getList() {
|
||||||
|
|
||||||
|
getSaleList(this.listQuery).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.saleList = response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//关联客户
|
||||||
|
getCustomerLists() {
|
||||||
|
|
||||||
|
getCustomerList({page:0,}).then((response) => {
|
||||||
|
|
||||||
|
this.customeroptions = response.data;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
//选择产品
|
||||||
|
getMaterialList()
|
||||||
|
{
|
||||||
|
getMaterialList({type:1,page:0}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.materialoptions = response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
selectproduct(selval)
|
||||||
|
{
|
||||||
|
this.iproductoptions=[];
|
||||||
|
getiproductList({material:selval,page:0}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
response.data.forEach((item) => {
|
||||||
|
this.iproductoptions.push({
|
||||||
|
label: item.number+"__"+item.material_.name+"__"+(item.is_mtested==true?"已军检":"未军检") ,
|
||||||
|
key: item.id
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
//成品
|
||||||
|
getproductList() {
|
||||||
|
this.iproductoptions=[],
|
||||||
|
getiproductList({page:0}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
response.data.forEach((item) => {
|
||||||
|
this.iproductoptions.push({
|
||||||
|
label: item.number+"__"+item.material_.name+"__"+(item.is_mtested==true?"已军检":"未军检") ,
|
||||||
|
key: item.id
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
handleFilter() {
|
||||||
|
this.listQuery.page = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
resetFilter() {
|
||||||
|
this.listQuery = {
|
||||||
|
page: 1,
|
||||||
|
page_size: 20,
|
||||||
|
}
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
handleCreate() {
|
||||||
|
this.sale = Object.assign({}, defaulteSale);
|
||||||
|
this.dialogType = "new";
|
||||||
|
this.dialogVisible = true;
|
||||||
|
this.iproductoptions=[];
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs["Form"].clearValidate();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
handleEdit(scope) {
|
||||||
|
this.sale = Object.assign({}, scope.row); // copy obj
|
||||||
|
console.log(this.sale);
|
||||||
|
this.dialogType = "edit";
|
||||||
|
this.dialogVisible = true;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs["Form"].clearValidate();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleDelete(scope) {
|
||||||
|
this.$confirm("确认删除?", "警告", {
|
||||||
|
confirmButtonText: "确认",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
await deleteSale(scope.row.id);
|
||||||
|
this.getList();
|
||||||
|
this.$message.success("成功");
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async confirm(form) {
|
||||||
|
this.$refs[form].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
const isEdit = this.dialogType === "edit";
|
||||||
|
if (isEdit) {
|
||||||
|
updateContract(this.sale.id, this.sale).then((res) => {
|
||||||
|
if (res.code >= 200) {
|
||||||
|
this.getList();
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$message.success("成功");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
createSale(this.sale).then((res) => {
|
||||||
|
if (res.code >= 200) {
|
||||||
|
this.getList();
|
||||||
|
this.dialogVisible = false;
|
||||||
|
this.$message.success("成功");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
//销售详情
|
||||||
|
handleDetail(scope){
|
||||||
|
|
||||||
|
this.$router.push({name: "salesdetail", params: { id: scope.row.id }, })
|
||||||
|
},
|
||||||
|
|
||||||
|
//审核
|
||||||
|
handleAudit(scope){
|
||||||
|
saleAudit(scope.row.id).then((res) => {
|
||||||
|
|
||||||
|
if (res.code >= 200) {
|
||||||
|
|
||||||
|
this.$message.success("审核成功成功");
|
||||||
|
this.getList();
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style scoped>
|
||||||
|
.trdiv >>> .el-transfer-panel{
|
||||||
|
width:350px;
|
||||||
|
}
|
||||||
|
.trdiv >>> .el-transfer__buttons{
|
||||||
|
width:110px
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,146 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
|
||||||
|
<el-card style="margin-top: 2px">
|
||||||
|
<el-descriptions title="基本信息" direction="vertical" :column="8" border>
|
||||||
|
<el-descriptions-item label="客户名称" v-if="salesdetail.customer"> {{salesdetail.customer_.name}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="产品名称" v-if="salesdetail.product"> {{salesdetail.product_.name}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="产品型号" :span="2" v-if="salesdetail.product"> {{salesdetail.product_.specification}}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="订单编号" v-if="salesdetail.order"> {{salesdetail.order_.number}} </el-descriptions-item>
|
||||||
|
<el-descriptions-item label="合同名称" v-if="salesdetail.order"> {{salesdetail.order_.contract_.name}}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
<el-card class="box-card">
|
||||||
|
<div slot="header" class="clearfix">
|
||||||
|
<span>关联产品信息</span>
|
||||||
|
</div>
|
||||||
|
<el-table
|
||||||
|
ref="singleTable"
|
||||||
|
:data="saleproduct"
|
||||||
|
highlight-current-row
|
||||||
|
style="width: 100%">
|
||||||
|
|
||||||
|
|
||||||
|
<el-table-column type="index" width="50" />
|
||||||
|
<el-table-column label="产品编号" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="产品名称" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope" >{{ scope.row.iproduct_.material_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="批次" >
|
||||||
|
<template slot-scope="scope" >{{ scope.row.iproduct_.batch }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="仓库">
|
||||||
|
<template slot-scope="scope">{{ scope.row.iproduct_.warehouse_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否已军检">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
|
||||||
|
|
||||||
|
<el-tag v-if="scope.row.is_mtested == false">未军检</el-tag>
|
||||||
|
<el-tag v-else>已军检</el-tag></template>
|
||||||
|
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="军检">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
|
||||||
|
|
||||||
|
<el-tag v-if="scope.row.is_mtestok == false">不合格</el-tag>
|
||||||
|
<el-tag v-else>合格</el-tag></template>
|
||||||
|
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
|
||||||
|
<el-table-column
|
||||||
|
align="center"
|
||||||
|
label="操作"
|
||||||
|
width="220px"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
|
||||||
|
|
||||||
|
<el-link
|
||||||
|
v-if="checkPermission(['warehouse_delete'])"
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(scope)"
|
||||||
|
>删除</el-link
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import {getSale,getSaleproductList,deleteSaleproduct} 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 {
|
||||||
|
|
||||||
|
salesdetail:"",
|
||||||
|
saleproduct:"",
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
created() {
|
||||||
|
this.id = this.$route.params.id;
|
||||||
|
this.getList();
|
||||||
|
this.getSaleproductLists();
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
checkPermission,
|
||||||
|
//详情
|
||||||
|
getList() {
|
||||||
|
|
||||||
|
getSale(this.id).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.salesdetail = response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getSaleproductLists()
|
||||||
|
{
|
||||||
|
getSaleproductList({sale:this.id,page:0}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.saleproduct = response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleDelete(scope) {
|
||||||
|
this.$confirm("确认删除?", "警告", {
|
||||||
|
confirmButtonText: "确认",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "error",
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
await deleteSaleproduct(scope.row.id);
|
||||||
|
this.getSaleproductLists();
|
||||||
|
this.$message.success("成功");
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
@ -156,6 +156,54 @@
|
||||||
/>
|
/>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
<el-tab-pane label="夹层半成品">
|
||||||
|
<el-card style="margin-top: 2px">
|
||||||
|
<el-table
|
||||||
|
v-loading="listLoading"
|
||||||
|
:data="wproductList3.results"
|
||||||
|
border
|
||||||
|
fit
|
||||||
|
stripe
|
||||||
|
highlight-current-row
|
||||||
|
max-height="600"
|
||||||
|
>
|
||||||
|
<el-table-column type="index" width="50"/>
|
||||||
|
<el-table-column label="半成品名称">
|
||||||
|
<template slot-scope="scope">{{ scope.row.material_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="半成品编号">
|
||||||
|
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="检测状态">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ actstate_[scope.row.act_state] }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="所在子工序">
|
||||||
|
<template slot-scope="scope">{{ scope.row.step_.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="操作" width="220px">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-link
|
||||||
|
v-if="checkPermission(['warehouse_update'])"
|
||||||
|
@click="handleInspection(scope)"
|
||||||
|
>检验
|
||||||
|
</el-link
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<pagination
|
||||||
|
v-show="wproductList3.count > 0"
|
||||||
|
:total="wproductList3.count"
|
||||||
|
:page.sync="listQuery3.page"
|
||||||
|
:limit.sync="listQuery3.page_size"
|
||||||
|
@pagination="getList3"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
|
|
||||||
<el-dialog title="物料检查表" :close-on-click-modal="false" :visible.sync="outerVisible">
|
<el-dialog title="物料检查表" :close-on-click-modal="false" :visible.sync="outerVisible">
|
||||||
|
|
@ -269,6 +317,9 @@
|
||||||
},
|
},
|
||||||
wproductList2: {
|
wproductList2: {
|
||||||
count: 0,
|
count: 0,
|
||||||
|
},
|
||||||
|
wproductList3: {
|
||||||
|
count: 0,
|
||||||
},
|
},
|
||||||
listQuery: {
|
listQuery: {
|
||||||
page: 1,
|
page: 1,
|
||||||
|
|
@ -282,8 +333,12 @@
|
||||||
page: 1,
|
page: 1,
|
||||||
page_size: 20,
|
page_size: 20,
|
||||||
},
|
},
|
||||||
formLabelWidth: '',
|
listQuery3: {
|
||||||
formLabelWidthL: '',
|
page: 1,
|
||||||
|
page_size: 20,
|
||||||
|
},
|
||||||
|
formLabelWidth:'',
|
||||||
|
formLabelWidthL:'',
|
||||||
actstate_: {
|
actstate_: {
|
||||||
6: "待复检",
|
6: "待复检",
|
||||||
10: "生产中",
|
10: "生产中",
|
||||||
|
|
@ -292,6 +347,7 @@
|
||||||
40: "库存中",
|
40: "库存中",
|
||||||
50: "不合格",
|
50: "不合格",
|
||||||
60: "待成品检验",
|
60: "待成品检验",
|
||||||
|
26:"待夹层检验",
|
||||||
},
|
},
|
||||||
choice: [
|
choice: [
|
||||||
{
|
{
|
||||||
|
|
@ -333,6 +389,7 @@
|
||||||
this.getList();
|
this.getList();
|
||||||
this.getList2();
|
this.getList2();
|
||||||
this.getList1();
|
this.getList1();
|
||||||
|
this.getList3();
|
||||||
// this.getLists();
|
// this.getLists();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -363,7 +420,7 @@
|
||||||
getList1() {
|
getList1() {
|
||||||
|
|
||||||
this.listQuery1.act_state = 30;
|
this.listQuery1.act_state = 30;
|
||||||
this.listQuery1.material__type = 1;
|
this.listQuery1.material__type = 2;
|
||||||
getwproductList(this.listQuery1).then((response) => {
|
getwproductList(this.listQuery1).then((response) => {
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
this.wproductList1 = response.data;
|
this.wproductList1 = response.data;
|
||||||
|
|
@ -371,7 +428,17 @@
|
||||||
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
//夹层半成品列表
|
||||||
|
getList3() {
|
||||||
|
|
||||||
|
this.listQuery3.act_state = 26;
|
||||||
|
getwproductList(this.listQuery3).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.wproductList3 = response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
//半成品批量入库
|
//半成品批量入库
|
||||||
handleCreate() {
|
handleCreate() {
|
||||||
this.dialogFormVisibles = true;
|
this.dialogFormVisibles = true;
|
||||||
|
|
@ -385,7 +452,7 @@
|
||||||
_this.mutipID = []
|
_this.mutipID = []
|
||||||
this.$refs.multipleTable.selection.forEach((item) => {
|
this.$refs.multipleTable.selection.forEach((item) => {
|
||||||
_this.mutipID.push(item.id);
|
_this.mutipID.push(item.id);
|
||||||
alert(_this.mutipID);
|
|
||||||
});
|
});
|
||||||
console.log(_this.mutipID);
|
console.log(_this.mutipID);
|
||||||
|
|
||||||
|
|
@ -497,6 +564,7 @@
|
||||||
this.getList();
|
this.getList();
|
||||||
this.getList1();
|
this.getList1();
|
||||||
this.getList2();
|
this.getList2();
|
||||||
|
this.getList3();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
<el-card>
|
<el-card>
|
||||||
<div slot="header" class="clearfix">
|
<div slot="header" class="clearfix">
|
||||||
<span>基本信息</span>
|
<span>基本信息</span>
|
||||||
|
<el-button style="float: right; padding: 3px 0" @click="readbook()" type="text">查看作业指导书</el-button>
|
||||||
</div>
|
</div>
|
||||||
<el-form
|
<el-form
|
||||||
ref="form"
|
ref="form"
|
||||||
|
|
@ -49,6 +50,20 @@
|
||||||
<el-button>取消</el-button>
|
<el-button>取消</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
<el-drawer
|
||||||
|
title="作业指导书点击下载查看!"
|
||||||
|
:visible.sync="drawer"
|
||||||
|
direction="rtl"
|
||||||
|
size="10%">
|
||||||
|
<el-table :data="techdocList">
|
||||||
|
<el-table-column label="表名称" width="150">
|
||||||
|
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-link type="primary" :href="scope.row.file_.file" target="_blank">{{ scope.row.file_.name }}</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-drawer>
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-row gutter="2">
|
<el-row gutter="2">
|
||||||
<el-col span="8">
|
<el-col span="8">
|
||||||
|
|
@ -160,10 +175,10 @@
|
||||||
:model="tableForm"
|
:model="tableForm"
|
||||||
:visible.sync="dialogVisibleForm"
|
:visible.sync="dialogVisibleForm"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
:title="tableForm.name"
|
:title="fieldList.name"
|
||||||
>
|
>
|
||||||
<el-form label-width="80px" label-position="right">
|
<el-form label-width="80px" label-position="right">
|
||||||
<el-row v-for="(item, $index) in fieldList" :key="$index">
|
<el-row v-for="(item, $index) in fieldList.form_fields" :key="$index">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
v-if="item.field_type === 'string'"
|
v-if="item.field_type === 'string'"
|
||||||
:label="item.field_name"
|
:label="item.field_name"
|
||||||
|
|
@ -312,9 +327,21 @@
|
||||||
stripe
|
stripe
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
max-height="400"
|
max-height="400"
|
||||||
|
ref="multipleTable"
|
||||||
>
|
>
|
||||||
|
<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="子计划编号"
|
||||||
|
>
|
||||||
|
<template slot-scope="scope">{{
|
||||||
|
scope.row.subproduction_plan_.number
|
||||||
|
}}</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="物料名称">
|
<el-table-column label="物料名称">
|
||||||
<template slot-scope="scope">{{
|
<template slot-scope="scope">{{
|
||||||
scope.row.material_.name
|
scope.row.material_.name
|
||||||
|
|
@ -349,7 +376,7 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" label="操作" width="100px">
|
<!-- <el-table-column align="center" label="操作" width="100px">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-link
|
<el-link
|
||||||
v-if="checkPermission(['warehouse_update'])"
|
v-if="checkPermission(['warehouse_update'])"
|
||||||
|
|
@ -357,8 +384,13 @@
|
||||||
>提交</el-link
|
>提交</el-link
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>!-->
|
||||||
</el-table>
|
</el-table>
|
||||||
|
<div style="text-align: right">
|
||||||
|
<el-button type="danger" @click="dialogTablepick = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handlepicks()">提交</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
@ -403,7 +435,12 @@
|
||||||
stripe
|
stripe
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
max-height="400"
|
max-height="400"
|
||||||
>
|
ref="multipleTables"
|
||||||
|
>
|
||||||
|
<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="生产计划编号">
|
||||||
|
|
@ -439,7 +476,7 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" label="操作" width="100px">
|
<!-- <el-table-column align="center" label="操作" width="100px">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-link
|
<el-link
|
||||||
v-if="checkPermission(['warehouse_update'])"
|
v-if="checkPermission(['warehouse_update'])"
|
||||||
|
|
@ -447,8 +484,12 @@
|
||||||
>提交</el-link
|
>提交</el-link
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>!-->
|
||||||
</el-table>
|
</el-table>
|
||||||
|
<div style="text-align: right">
|
||||||
|
<el-button type="danger" @click="dialogTableoutput = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleoutputs()">提交</el-button>
|
||||||
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
@ -492,9 +533,12 @@ import {
|
||||||
deleteOperationwproduct,
|
deleteOperationwproduct,
|
||||||
gettoolList,
|
gettoolList,
|
||||||
createTool,
|
createTool,
|
||||||
|
createInputs,
|
||||||
|
recordInit,
|
||||||
|
createOutputs
|
||||||
} from "@/api/wpm";
|
} from "@/api/wpm";
|
||||||
|
|
||||||
import { getrffieldList } from "@/api/mtm";
|
import { getrffieldList,gettechdocList } from "@/api/mtm";
|
||||||
import checkPermission from "@/utils/permission";
|
import checkPermission from "@/utils/permission";
|
||||||
import { getprogressList } from "@/api/pm";
|
import { getprogressList } from "@/api/pm";
|
||||||
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||||
|
|
@ -504,9 +548,11 @@ export default {
|
||||||
inject: ["reload"],
|
inject: ["reload"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
techdocList:"",
|
||||||
operationList: {
|
operationList: {
|
||||||
count: 0,
|
count: 0,
|
||||||
},
|
},
|
||||||
|
drawer:false,
|
||||||
listQuery: {
|
listQuery: {
|
||||||
page: 1,
|
page: 1,
|
||||||
page_size: 20,
|
page_size: 20,
|
||||||
|
|
@ -629,6 +675,17 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
checkPermission,
|
checkPermission,
|
||||||
|
|
||||||
|
//作业指导书
|
||||||
|
readbook(){
|
||||||
|
this.drawer=true;
|
||||||
|
gettechdocList({operation:this.id,page:0}).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.techdocList= response.data;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
//是否使用边角料
|
//是否使用边角料
|
||||||
getList() {
|
getList() {
|
||||||
getoperation(this.id).then((response) => {
|
getoperation(this.id).then((response) => {
|
||||||
|
|
@ -712,9 +769,7 @@ export default {
|
||||||
handlerecord(scope) {
|
handlerecord(scope) {
|
||||||
this.tableForm = Object.assign({}, scope.row); // copy obj
|
this.tableForm = Object.assign({}, scope.row); // copy obj
|
||||||
this.formID = scope.row.id;
|
this.formID = scope.row.id;
|
||||||
this.listQueryfield.form = scope.row.form_.id;
|
recordInit( this.formID).then((response) => {
|
||||||
this.listQueryfield.page = 0;
|
|
||||||
getrffieldList(this.listQueryfield).then((response) => {
|
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
this.fieldList = response.data;
|
this.fieldList = response.data;
|
||||||
}
|
}
|
||||||
|
|
@ -777,6 +832,40 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
//车间领料批量提交
|
||||||
|
handlepicks() {
|
||||||
|
|
||||||
|
|
||||||
|
let _this = this;
|
||||||
|
|
||||||
|
this.pickDatas=[],
|
||||||
|
this.$refs.multipleTable.selection.forEach((item) => {
|
||||||
|
if(item.pick_count>0)
|
||||||
|
{
|
||||||
|
this.pickDatas.push({
|
||||||
|
"operation" :this.id,
|
||||||
|
"wmaterial":item.id,
|
||||||
|
"count": item.pick_count,
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
createInputs(this.pickDatas).then((res) => {
|
||||||
|
if (res.code >= 200) {
|
||||||
|
this.dialogTablepick = false;
|
||||||
|
this.$message.success("提交成功!");
|
||||||
|
_this.getinputLists();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
//操作产出物料列表
|
//操作产出物料列表
|
||||||
getoutputLists() {
|
getoutputLists() {
|
||||||
getoutputList({ operation: this.id, page: 0 }).then((response) => {
|
getoutputList({ operation: this.id, page: 0 }).then((response) => {
|
||||||
|
|
@ -809,6 +898,38 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
//车间产出物料批量提交
|
||||||
|
handleoutputs() {
|
||||||
|
|
||||||
|
|
||||||
|
this.outputDatas=[],
|
||||||
|
this.$refs.multipleTables.selection.forEach((item) => {
|
||||||
|
if(item.output_count>0)
|
||||||
|
{
|
||||||
|
this.outputDatas.push({
|
||||||
|
"operation" :this.id,
|
||||||
|
"subproduction_progress":item.id,
|
||||||
|
"count": item.output_count,
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
createOutputs(this.outputDatas).then((res) => {
|
||||||
|
if (res.code >= 200) {
|
||||||
|
this.dialogTableoutput = false;
|
||||||
|
|
||||||
|
this.$message.success("提交成功!");
|
||||||
|
this.getoutputLists();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
//提交本次操作
|
//提交本次操作
|
||||||
handlesubmit() {
|
handlesubmit() {
|
||||||
submitOperation(this.id).then((res) => {
|
submitOperation(this.id).then((res) => {
|
||||||
|
|
|
||||||
|
|
@ -440,7 +440,7 @@ export default {
|
||||||
_this.mutipID=[]
|
_this.mutipID=[]
|
||||||
this.$refs.multipleTable.selection.forEach((item) => {
|
this.$refs.multipleTable.selection.forEach((item) => {
|
||||||
_this.mutipID.push( item.id );
|
_this.mutipID.push( item.id );
|
||||||
alert(_this.mutipID);
|
|
||||||
});
|
});
|
||||||
console.log(_this.mutipID);
|
console.log(_this.mutipID);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -703,6 +703,7 @@ export default {
|
||||||
50: "不合格",
|
50: "不合格",
|
||||||
60: "待成品检验",
|
60: "待成品检验",
|
||||||
8:"操作准备中",
|
8:"操作准备中",
|
||||||
|
26:"待夹层检验",
|
||||||
},
|
},
|
||||||
state_: {
|
state_: {
|
||||||
0: "制定中",
|
0: "制定中",
|
||||||
|
|
|
||||||
|
|
@ -14,4 +14,4 @@ class IProductFilterSet(filters.FilterSet):
|
||||||
order = filters.NumberFilter(field_name="wproduct__subproduction_plan__production_plan__order")
|
order = filters.NumberFilter(field_name="wproduct__subproduction_plan__production_plan__order")
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IProduct
|
model = IProduct
|
||||||
fields = ['material', 'warehouse', 'batch', 'order']
|
fields = ['material', 'warehouse', 'batch', 'order', 'is_mtested', 'is_mtestok']
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-07 00:42
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('inm', '0020_iproduct_is_saled'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='fifoitemproduct',
|
||||||
|
name='iproduct',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='inm.iproduct', verbose_name='关联库存产品'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-08 06:08
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('inm', '0021_fifoitemproduct_iproduct'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='iproduct',
|
||||||
|
name='is_mtested',
|
||||||
|
field=models.BooleanField(default=False, verbose_name='是否军检'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='iproduct',
|
||||||
|
name='is_mtestok',
|
||||||
|
field=models.BooleanField(blank=True, null=True, verbose_name='是否军检合格'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='iproduct',
|
||||||
|
name='remark_mtest',
|
||||||
|
field=models.TextField(blank=True, null=True, verbose_name='军检备注'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -84,15 +84,6 @@ class FIFOItem(BaseModel):
|
||||||
fifo = models.ForeignKey(FIFO, verbose_name='关联出入库', on_delete=models.CASCADE)
|
fifo = models.ForeignKey(FIFO, verbose_name='关联出入库', on_delete=models.CASCADE)
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True)
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
|
|
||||||
class FIFOItemProduct(BaseModel):
|
|
||||||
"""
|
|
||||||
出入库产品
|
|
||||||
"""
|
|
||||||
fifoitem = models.ForeignKey(FIFOItem, verbose_name='关联出入库具体产品', on_delete=models.CASCADE)
|
|
||||||
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True)
|
|
||||||
number = models.CharField('物品编号', max_length=50)
|
|
||||||
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
|
||||||
|
|
||||||
class IProduct(BaseModel):
|
class IProduct(BaseModel):
|
||||||
"""
|
"""
|
||||||
具体产品条目
|
具体产品条目
|
||||||
|
|
@ -102,6 +93,21 @@ class IProduct(BaseModel):
|
||||||
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
warehouse = models.ForeignKey(WareHouse, on_delete=models.CASCADE, verbose_name='所在仓库')
|
||||||
batch = models.CharField('所属批次号', max_length=100, default='')
|
batch = models.CharField('所属批次号', max_length=100, default='')
|
||||||
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True)
|
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True)
|
||||||
|
is_mtested = models.BooleanField('是否军检', default=False)
|
||||||
|
is_mtestok = models.BooleanField('是否军检合格', null=True, blank=True)
|
||||||
|
remark_mtest = models.TextField('军检备注', null=True, blank=True)
|
||||||
is_saled = models.BooleanField('是否售出', default=False)
|
is_saled = models.BooleanField('是否售出', default=False)
|
||||||
|
|
||||||
|
class FIFOItemProduct(BaseModel):
|
||||||
|
"""
|
||||||
|
出入库产品
|
||||||
|
"""
|
||||||
|
fifoitem = models.ForeignKey(FIFOItem, verbose_name='关联出入库具体产品', on_delete=models.CASCADE)
|
||||||
|
wproduct = models.ForeignKey('wpm.wproduct', on_delete=models.CASCADE, verbose_name='关联的动态产品', db_constraint=False, null=True, blank=True)
|
||||||
|
number = models.CharField('物品编号', max_length=50)
|
||||||
|
material = models.ForeignKey(Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||||
|
iproduct = models.ForeignKey(IProduct, verbose_name='关联库存产品', null=True, blank=True, on_delete=models.SET_NULL)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -146,4 +146,10 @@ class InmTestRecordCreateSerializer(serializers.ModelSerializer):
|
||||||
is_testok = serializers.BooleanField()
|
is_testok = serializers.BooleanField()
|
||||||
class Meta:
|
class Meta:
|
||||||
model = TestRecord
|
model = TestRecord
|
||||||
fields = ['form', 'record_data', 'is_testok', 'fifo_item']
|
fields = ['form', 'record_data', 'is_testok', 'fifo_item']
|
||||||
|
|
||||||
|
|
||||||
|
class IProductMtestSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = IProduct
|
||||||
|
fields = ['remark_mtest', 'is_mtestok']
|
||||||
|
|
@ -36,7 +36,7 @@ def update_inm(instance:FIFO, type:int=1):
|
||||||
ips2.append(IProduct(**ip))
|
ips2.append(IProduct(**ip))
|
||||||
IProduct.objects.bulk_create(ips2)
|
IProduct.objects.bulk_create(ips2)
|
||||||
|
|
||||||
elif instance.type in [FIFO.FIFO_TYPE_DO_OUT]: # 生产领料
|
elif instance.type in [FIFO.FIFO_TYPE_DO_OUT, FIFO.FIFO_TYPE_SALE_OUT]: # 生产领料 销售出库
|
||||||
# 更新相关表
|
# 更新相关表
|
||||||
for i in FIFOItem.objects.filter(fifo=instance):
|
for i in FIFOItem.objects.filter(fifo=instance):
|
||||||
material = i.material
|
material = i.material
|
||||||
|
|
@ -49,8 +49,9 @@ def update_inm(instance:FIFO, type:int=1):
|
||||||
o2.save()
|
o2.save()
|
||||||
material.count = material.count - i.count
|
material.count = material.count - i.count
|
||||||
material.save()
|
material.save()
|
||||||
|
|
||||||
# 删除IProduct
|
# 删除IProduct
|
||||||
numbers = FIFOItemProduct.objects.filter(fifoitem=i).values_list('number', flat=True)
|
if instance.type == FIFO.FIFO_TYPE_DO_OUT:
|
||||||
IProduct.objects.filter(number__in=numbers).delete()
|
numbers = FIFOItemProduct.objects.filter(fifoitem=i).values_list('number', flat=True)
|
||||||
|
IProduct.objects.filter(number__in=numbers).delete()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
from rest_framework import exceptions
|
||||||
from rest_framework.exceptions import APIException
|
from rest_framework.exceptions import APIException
|
||||||
from rest_framework.mixins import DestroyModelMixin, ListModelMixin, RetrieveModelMixin
|
from rest_framework.mixins import DestroyModelMixin, ListModelMixin, RetrieveModelMixin
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||||
from apps.inm.filters import IProductFilterSet, MbFilterSet
|
from apps.inm.filters import IProductFilterSet, MbFilterSet
|
||||||
|
|
||||||
from apps.inm.models import FIFO, FIFOItem, IProduct, MaterialBatch, WareHouse,Inventory
|
from apps.inm.models import FIFO, FIFOItem, IProduct, MaterialBatch, WareHouse,Inventory
|
||||||
from apps.inm.serializers import FIFOItemSerializer, FIFOInPurSerializer, FIFOListSerializer, IProductListSerializer, InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer,InventorySerializer
|
from apps.inm.serializers import FIFOItemSerializer, FIFOInPurSerializer, FIFOListSerializer, IProductListSerializer, IProductMtestSerializer, InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, WareHouseCreateUpdateSerializer,InventorySerializer
|
||||||
from apps.inm.signals import update_inm
|
from apps.inm.signals import update_inm
|
||||||
|
from apps.mtm.models import Material
|
||||||
from apps.qm.models import TestRecordItem
|
from apps.qm.models import TestRecordItem
|
||||||
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
|
|
@ -172,4 +174,21 @@ class IProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
filterset_class = IProductFilterSet
|
filterset_class = IProductFilterSet
|
||||||
search_fields = []
|
search_fields = []
|
||||||
ordering_fields = ['create_time']
|
ordering_fields = ['create_time']
|
||||||
ordering = ['-create_time']
|
ordering = ['-create_time']
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=IProductMtestSerializer)
|
||||||
|
def mtest(self, request, pk=None):
|
||||||
|
"""
|
||||||
|
军检
|
||||||
|
"""
|
||||||
|
obj = self.get_object()
|
||||||
|
if obj.is_mtested:
|
||||||
|
raise exceptions.APIException('已进行军检')
|
||||||
|
if obj.wproduct:
|
||||||
|
if obj.wproduct.material.type != Material.MA_TYPE_GOOD:
|
||||||
|
raise exceptions.APIException('军检必须是成品')
|
||||||
|
obj.remark_mtest = request.data.get('remark_mtest', None)
|
||||||
|
obj.is_mtested = True
|
||||||
|
obj.is_mtestok = request.data.get('is_mtestok')
|
||||||
|
obj.save()
|
||||||
|
return Response()
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
from django_filters import rest_framework as filters
|
||||||
|
from apps.mtm.models import TechDoc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class TechDocFilterset(filters.FilterSet):
|
||||||
|
# operation = filters.NumberFilter(method='filter_operation')
|
||||||
|
operation = filters.CharFilter(field_name="subproduction__subplan_subprod__ow_subplan__operation")
|
||||||
|
class Meta:
|
||||||
|
model = TechDoc
|
||||||
|
fields = ['subproduction', 'operation']
|
||||||
|
|
||||||
|
# def filter_operation(self, queryset, name, value):
|
||||||
|
# return queryset.filter(subproduction__subplan_subprod__ow_subplan__operation=value)
|
||||||
|
|
@ -130,6 +130,20 @@ class RecordFormField(CommonAModel):
|
||||||
"""
|
"""
|
||||||
记录字段表
|
记录字段表
|
||||||
"""
|
"""
|
||||||
|
FIELD_STRING = 'string'
|
||||||
|
FIELD_INT = 'int'
|
||||||
|
FIELD_FLOAT = 'float'
|
||||||
|
FIELD_BOOL = 'boolean'
|
||||||
|
FIELD_DATE = 'date'
|
||||||
|
FIELD_TIME = 'time'
|
||||||
|
FIELD_DATETIME = 'datetime'
|
||||||
|
FIELD_RADIO = 'radio'
|
||||||
|
FIELD_CHECKBOX = 'checkbox'
|
||||||
|
FIELD_SELECT = 'select'
|
||||||
|
FIELD_SELECTS = 'selects'
|
||||||
|
FIELD_TEXTAREA = 'textarea'
|
||||||
|
FIELD_DRAW = 'draw'
|
||||||
|
FIELD_FROMSYSTEM = 'fromsystem'
|
||||||
field_type_choices = (
|
field_type_choices = (
|
||||||
('string', '字符串'),
|
('string', '字符串'),
|
||||||
('int', '整型'),
|
('int', '整型'),
|
||||||
|
|
@ -143,7 +157,7 @@ class RecordFormField(CommonAModel):
|
||||||
('select', '单选下拉'),
|
('select', '单选下拉'),
|
||||||
('selects', '多选下拉'),
|
('selects', '多选下拉'),
|
||||||
('textarea', '文本域'),
|
('textarea', '文本域'),
|
||||||
('draw', '绘图')
|
('draw', '绘图'),
|
||||||
)
|
)
|
||||||
high_rule_choices = (
|
high_rule_choices = (
|
||||||
(1, '小于'),
|
(1, '小于'),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from rest_framework.viewsets import ModelViewSet, GenericViewSet
|
from rest_framework.viewsets import ModelViewSet, GenericViewSet
|
||||||
from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin
|
from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin
|
||||||
|
from apps.mtm.filters import TechDocFilterset
|
||||||
|
|
||||||
from apps.mtm.models import Material, Process, RecordForm, RecordFormField, Step, SubprodctionMaterial, TechDoc, UsedStep, SubProduction
|
from apps.mtm.models import Material, Process, RecordForm, RecordFormField, Step, SubprodctionMaterial, TechDoc, UsedStep, SubProduction
|
||||||
from apps.mtm.serializers import InputMaterialSerializer, InputMaterialUpdateSerializer, MaterialDetailSerializer, MaterialSerializer, MaterialSimpleSerializer, OtherMaterialSerializer, OutputMaterialSerializer, OutputMaterialUpdateSerializer, ProcessSerializer, RecordFormCreateSerializer, RecordFormDetailSerializer, RecordFormFieldCreateSerializer, RecordFormFieldSerializer, RecordFormFieldUpdateSerializer, RecordFormSerializer, RecordFormUpdateSerializer, StepDetailSerializer, StepSerializer, SubProductionSerializer, SubprodctionMaterialListSerializer, TechDocCreateSerializer, TechDocListSerializer, TechDocUpdateSerializer, UsedStepCreateSerializer, UsedStepListSerializer, UsedStepUpdateSerializer
|
from apps.mtm.serializers import InputMaterialSerializer, InputMaterialUpdateSerializer, MaterialDetailSerializer, MaterialSerializer, MaterialSimpleSerializer, OtherMaterialSerializer, OutputMaterialSerializer, OutputMaterialUpdateSerializer, ProcessSerializer, RecordFormCreateSerializer, RecordFormDetailSerializer, RecordFormFieldCreateSerializer, RecordFormFieldSerializer, RecordFormFieldUpdateSerializer, RecordFormSerializer, RecordFormUpdateSerializer, StepDetailSerializer, StepSerializer, SubProductionSerializer, SubprodctionMaterialListSerializer, TechDocCreateSerializer, TechDocListSerializer, TechDocUpdateSerializer, UsedStepCreateSerializer, UsedStepListSerializer, UsedStepUpdateSerializer
|
||||||
|
|
@ -201,7 +202,7 @@ class TechDocViewSet(OptimizationMixin, CreateUpdateModelAMixin, ModelViewSet):
|
||||||
"""
|
"""
|
||||||
perms_map = {'*':'*'}
|
perms_map = {'*':'*'}
|
||||||
queryset = TechDoc.objects.select_related('file').all()
|
queryset = TechDoc.objects.select_related('file').all()
|
||||||
filterset_fields = ['subproduction']
|
filterset_class = TechDocFilterset
|
||||||
search_fields = ['name']
|
search_fields = ['name']
|
||||||
ordering = ['-id']
|
ordering = ['-id']
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-09 08:38
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pm', '0015_auto_20211122_1556'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='productionplan',
|
||||||
|
name='count_ok',
|
||||||
|
field=models.IntegerField(default=0, verbose_name='合格数'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='productionplan',
|
||||||
|
name='count_real',
|
||||||
|
field=models.IntegerField(default=0, verbose_name='实际产出数'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -18,6 +18,8 @@ class ProductionPlan(CommonAModel):
|
||||||
order = models.ForeignKey(Order, verbose_name='关联订单', null=True, blank=True, on_delete=models.SET_NULL)
|
order = models.ForeignKey(Order, verbose_name='关联订单', null=True, blank=True, on_delete=models.SET_NULL)
|
||||||
product = models.ForeignKey(Material, verbose_name='生产产品', on_delete=models.CASCADE)
|
product = models.ForeignKey(Material, verbose_name='生产产品', on_delete=models.CASCADE)
|
||||||
count = models.IntegerField('生产数量', default=1)
|
count = models.IntegerField('生产数量', default=1)
|
||||||
|
count_real = models.IntegerField('实际产出数', default=0)
|
||||||
|
count_ok = models.IntegerField('合格数', default=0)
|
||||||
start_date = models.DateField('计划开工日期')
|
start_date = models.DateField('计划开工日期')
|
||||||
end_date = models.DateField('计划完工日期')
|
end_date = models.DateField('计划完工日期')
|
||||||
is_planed = models.BooleanField('是否已排产', default=False)
|
is_planed = models.BooleanField('是否已排产', default=False)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
from django.db.models.signals import post_save
|
from django.db.models.signals import post_save
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
from apps.mtm.models import Material
|
||||||
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
||||||
|
|
||||||
@receiver(post_save, sender=SubProductionProgress)
|
@receiver(post_save, sender=SubProductionProgress)
|
||||||
|
|
@ -18,6 +19,13 @@ def update_subplan_main(sender, instance, created, **kwargs):
|
||||||
subplan.state = SubProductionPlan.SUBPLAN_STATE_DONE
|
subplan.state = SubProductionPlan.SUBPLAN_STATE_DONE
|
||||||
elif instance.count_ok < instance.count and instance.count_ok > 0:
|
elif instance.count_ok < instance.count and instance.count_ok > 0:
|
||||||
subplan.state = SubProductionPlan.SUBPLAN_STATE_WORKING
|
subplan.state = SubProductionPlan.SUBPLAN_STATE_WORKING
|
||||||
subplan.save()
|
subplan.save()
|
||||||
|
if subplan.main_product.type == Material.MA_TYPE_GOOD:
|
||||||
|
# 如果是产品,更新主计划进度
|
||||||
|
plan = subplan.production_plan
|
||||||
|
plan.count_real = subplan.count_real
|
||||||
|
plan.count_ok = subplan.count_ok
|
||||||
|
plan.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-08 06:08
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('qm', '0013_auto_20211202_1620'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='testrecord',
|
||||||
|
name='type',
|
||||||
|
field=models.PositiveSmallIntegerField(choices=[(10, '子工序检验'), (20, '工序检验'), (30, '工序复检'), (36, '夹层检验'), (40, '成品检验')], default=20),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-09 08:38
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('qm', '0014_alter_testrecord_type'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='testrecord',
|
||||||
|
name='test_record',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='qm.testrecord', verbose_name='关联的检验记录'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -50,11 +50,13 @@ class TestRecord(CommonAModel):
|
||||||
TEST_STEP = 10
|
TEST_STEP = 10
|
||||||
TEST_PROCESS = 20
|
TEST_PROCESS = 20
|
||||||
TEST_PROCESS_RE = 30
|
TEST_PROCESS_RE = 30
|
||||||
|
TEST_COMB = 36
|
||||||
TEST_FINAL = 40
|
TEST_FINAL = 40
|
||||||
type_choice = (
|
type_choice = (
|
||||||
(TEST_STEP, '子工序检验'),
|
(TEST_STEP, '子工序检验'),
|
||||||
(TEST_PROCESS, '工序检验'),
|
(TEST_PROCESS, '工序检验'),
|
||||||
(TEST_PROCESS_RE, '工序复检'),
|
(TEST_PROCESS_RE, '工序复检'),
|
||||||
|
(TEST_COMB, '夹层检验'),
|
||||||
(TEST_FINAL, '成品检验')
|
(TEST_FINAL, '成品检验')
|
||||||
)
|
)
|
||||||
form = models.ForeignKey('mtm.recordform', verbose_name='所用表格', on_delete=models.CASCADE)
|
form = models.ForeignKey('mtm.recordform', verbose_name='所用表格', on_delete=models.CASCADE)
|
||||||
|
|
@ -67,7 +69,7 @@ class TestRecord(CommonAModel):
|
||||||
step = models.ForeignKey('mtm.step', verbose_name='关联的工序步骤', on_delete=models.CASCADE, null=True, blank=True)
|
step = models.ForeignKey('mtm.step', verbose_name='关联的工序步骤', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
subproduction_plan = models.ForeignKey('pm.subproductionplan', verbose_name='关联的生产子计划', on_delete=models.CASCADE, null=True, blank=True)
|
subproduction_plan = models.ForeignKey('pm.subproductionplan', verbose_name='关联的生产子计划', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
fifo_item = models.ForeignKey('inm.fifoitem', verbose_name='关联的出入库批次', on_delete=models.CASCADE, null=True, blank=True)
|
fifo_item = models.ForeignKey('inm.fifoitem', verbose_name='关联的出入库批次', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
test_record = models.ForeignKey('self', verbose_name='关联检验记录', on_delete=models.CASCADE, null=True, blank=True)
|
test_record = models.ForeignKey('self', verbose_name='关联的检验记录', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
remark = models.TextField('备注', default='')
|
remark = models.TextField('备注', default='')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-07 00:42
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('sam', '0008_alter_saleproduct_number'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='saleproduct',
|
||||||
|
name='is_mtestok',
|
||||||
|
field=models.BooleanField(blank=True, null=True, verbose_name='是否军检合格'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-08 06:08
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('sam', '0009_alter_saleproduct_is_mtestok'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='saleproduct',
|
||||||
|
name='is_mtested',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='saleproduct',
|
||||||
|
name='is_mtestok',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -89,8 +89,6 @@ class SaleProduct(BaseModel):
|
||||||
sale = models.ForeignKey(Sale, verbose_name='关联销售记录', on_delete=models.CASCADE)
|
sale = models.ForeignKey(Sale, verbose_name='关联销售记录', on_delete=models.CASCADE)
|
||||||
number = models.CharField('物品编号', max_length=50)
|
number = models.CharField('物品编号', max_length=50)
|
||||||
iproduct = models.ForeignKey('inm.iproduct', verbose_name='关联库存产品', on_delete=models.CASCADE, related_name='sale_iproduct')
|
iproduct = models.ForeignKey('inm.iproduct', verbose_name='关联库存产品', on_delete=models.CASCADE, related_name='sale_iproduct')
|
||||||
is_mtested = models.BooleanField('是否军检', default=False)
|
|
||||||
is_mtestok = models.BooleanField('是否军检合格', default=True)
|
|
||||||
remark = models.TextField('备注', null=True, blank=True)
|
remark = models.TextField('备注', null=True, blank=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ class SaleCreateSerializer(serializers.ModelSerializer):
|
||||||
attrs['customer'] = order.customer
|
attrs['customer'] = order.customer
|
||||||
attrs['product'] = order.product
|
attrs['product'] = order.product
|
||||||
for i in attrs['iproducts']:
|
for i in attrs['iproducts']:
|
||||||
if i.material is not attrs['product']:
|
if i.material != attrs['product']:
|
||||||
raise exceptions.APIException('产品选取错误')
|
raise exceptions.APIException('产品选取错误')
|
||||||
return super().validate(attrs)
|
return super().validate(attrs)
|
||||||
|
|
||||||
|
|
@ -101,9 +101,4 @@ class SaleProductCreateSerializer(serializers.ModelSerializer):
|
||||||
instance = SaleProduct.objects.create(**validated_data)
|
instance = SaleProduct.objects.create(**validated_data)
|
||||||
instance.sale.count = SaleProduct.objects.filter(sale=instance.sale).count()
|
instance.sale.count = SaleProduct.objects.filter(sale=instance.sale).count()
|
||||||
instance.sale.save()
|
instance.sale.save()
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
class SaleProductMtestSerializer(serializers.ModelSerializer):
|
|
||||||
class Meta:
|
|
||||||
model = SaleProduct
|
|
||||||
fields = ['remark', 'is_mtestok']
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
|
from django.db.models.aggregates import Count
|
||||||
from rest_framework import exceptions, serializers
|
from rest_framework import exceptions, serializers
|
||||||
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin
|
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin
|
||||||
from apps.inm.models import FIFO
|
from apps.mtm.models import Material
|
||||||
from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer, SaleProductMtestSerializer
|
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, WareHouse
|
||||||
|
from apps.inm.signals import update_inm
|
||||||
|
from apps.sam.serializers import ContractCreateUpdateSerializer, ContractSerializer, CustomerCreateUpdateSerializer, CustomerSerializer, OrderCreateUpdateSerializer, OrderSerializer, SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer
|
||||||
from apps.sam.models import Contract, Customer, Order, Sale, SaleProduct
|
from apps.sam.models import Contract, Customer, Order, Sale, SaleProduct
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||||
from apps.system.mixins import CreateUpdateCustomMixin
|
from apps.system.mixins import CreateUpdateCustomMixin
|
||||||
|
|
@ -75,7 +78,7 @@ class OrderViewSet(CreateUpdateCustomMixin, ModelViewSet):
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
|
||||||
class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, CreateModelMixin, GenericViewSet):
|
class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, CreateModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
销售记录
|
销售记录
|
||||||
"""
|
"""
|
||||||
|
|
@ -128,15 +131,53 @@ class SaleViewSet(CreateUpdateCustomMixin, ListModelMixin, RetrieveModelMixin, C
|
||||||
fifo.is_audited = True
|
fifo.is_audited = True
|
||||||
fifo.auditor = request.user
|
fifo.auditor = request.user
|
||||||
fifo.inout_date = timezone.now()
|
fifo.inout_date = timezone.now()
|
||||||
|
fifo.create_by = request.user
|
||||||
fifo.save()
|
fifo.save()
|
||||||
# 出库条目
|
# 出库条目 暂时不校验是否军检
|
||||||
spds = SaleProduct.objects.filter(sale=obj)
|
# spds = SaleProduct.objects.filter(sale=obj)
|
||||||
for i in spds:
|
# for i in spds:
|
||||||
if i.is_mtested and i.is_mtestok:
|
# if i.is_mtested and i.is_mtestok:
|
||||||
pass
|
# pass
|
||||||
else:
|
# else:
|
||||||
raise exceptions.APIException('存在未军检产品')
|
# raise exceptions.APIException('存在未军检产品')
|
||||||
|
# 创建出库条目
|
||||||
|
ips = IProduct.objects.filter(sale_iproduct__sale=obj)
|
||||||
|
items = ips.values('warehouse', 'material', 'batch').annotate(total=Count('id'))
|
||||||
|
for i in items:
|
||||||
|
warehouse = WareHouse.objects.get(id=i['warehouse'])
|
||||||
|
material = Material.objects.get(id=i['material'])
|
||||||
|
fifoitem = FIFOItem()
|
||||||
|
fifoitem.is_tested = True
|
||||||
|
fifoitem.is_testok = True
|
||||||
|
fifoitem.warehouse = warehouse
|
||||||
|
fifoitem.material = material
|
||||||
|
fifoitem.count = i['total']
|
||||||
|
fifoitem.batch = i['batch']
|
||||||
|
fifoitem.fifo = fifo
|
||||||
|
fifoitem.save()
|
||||||
|
items_p = ips.filter(warehouse=warehouse, batch=i['batch'])
|
||||||
|
ipxs = []
|
||||||
|
for i in items_p:
|
||||||
|
# 创建出库明细半成品
|
||||||
|
ip = {}
|
||||||
|
ip['fifoitem'] = fifoitem
|
||||||
|
ip['number'] = i.number
|
||||||
|
ip['material'] = i.material
|
||||||
|
ip['iproduct'] = i
|
||||||
|
ipxs.append(FIFOItemProduct(**ip))
|
||||||
|
FIFOItemProduct.objects.bulk_create(ipxs)
|
||||||
|
# 更新成品库情况
|
||||||
|
ips.update(is_saled=True)
|
||||||
# 更新库存
|
# 更新库存
|
||||||
|
update_inm(fifo)
|
||||||
|
# 变更审核状态
|
||||||
|
obj.is_audited = True
|
||||||
|
obj.save()
|
||||||
|
# 变更订单状态
|
||||||
|
if obj.order:
|
||||||
|
order = obj.order
|
||||||
|
order.delivered_count = order.delivered_count + obj.count
|
||||||
|
order.save()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, GenericViewSet):
|
class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, GenericViewSet):
|
||||||
|
|
@ -158,20 +199,12 @@ class SaleProductViewSet(ListModelMixin, DestroyModelMixin, CreateModelMixin, Ge
|
||||||
|
|
||||||
def destroy(self, request, *args, **kwargs):
|
def destroy(self, request, *args, **kwargs):
|
||||||
obj = self.get_object()
|
obj = self.get_object()
|
||||||
obj.sale.count = SaleProduct.objects.filter(sale=obj.sale).count()
|
sale = obj.sale
|
||||||
obj.sale.save()
|
if sale.is_audited:
|
||||||
|
raise exceptions.APIException('该销售记录已审核,不可删除产品')
|
||||||
|
sale.count = SaleProduct.objects.filter(sale=obj.sale).count()
|
||||||
|
sale.save()
|
||||||
obj.delete()
|
obj.delete()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=SaleProductMtestSerializer)
|
|
||||||
def mtest(self, request, pk=None):
|
|
||||||
"""
|
|
||||||
军检
|
|
||||||
"""
|
|
||||||
obj = self.get_object()
|
|
||||||
if obj.is_mtested:
|
|
||||||
raise exceptions.APIException('已进行军检')
|
|
||||||
obj.remark = request.data.get('remark', None)
|
|
||||||
obj.is_mtestok = request.data.get('is_mtestok')
|
|
||||||
obj.save()
|
|
||||||
return Response()
|
|
||||||
|
|
@ -210,7 +210,7 @@ class Ticket(CommonBModel):
|
||||||
participant = models.JSONField('当前处理人', default=list, blank=True, help_text='可以为空(无处理人的情况,如结束状态)、userid、userid列表')
|
participant = models.JSONField('当前处理人', default=list, blank=True, help_text='可以为空(无处理人的情况,如结束状态)、userid、userid列表')
|
||||||
act_state = models.IntegerField('进行状态', default=1, help_text='当前工单的进行状态', choices=act_state_choices)
|
act_state = models.IntegerField('进行状态', default=1, help_text='当前工单的进行状态', choices=act_state_choices)
|
||||||
multi_all_person = models.JSONField('全部处理的结果', default=dict, blank=True, help_text='需要当前状态处理人全部处理时实际的处理结果,json格式')
|
multi_all_person = models.JSONField('全部处理的结果', default=dict, blank=True, help_text='需要当前状态处理人全部处理时实际的处理结果,json格式')
|
||||||
|
|
||||||
|
|
||||||
# class TicketCustomField(BaseModel):
|
# class TicketCustomField(BaseModel):
|
||||||
# """
|
# """
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-08 06:08
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('wpm', '0029_auto_20211202_1630'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='wproduct',
|
||||||
|
name='act_state',
|
||||||
|
field=models.IntegerField(choices=[(6, '待复检'), (8, '操作准备中'), (10, '操作进行中'), (20, '待检验'), (26, '待夹层检验'), (30, '已合格'), (40, '库存中'), (50, '不合格'), (60, '待成品检验')], default=0, verbose_name='进行状态'),
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
# Generated by Django 3.2.9 on 2021-12-09 08:38
|
||||||
|
|
||||||
|
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 = [
|
||||||
|
('wf', '0017_auto_20211203_1501'),
|
||||||
|
('pm', '0016_auto_20211209_1638'),
|
||||||
|
('mtm', '0041_alter_material_type'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('wpm', '0030_alter_wproduct_act_state'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='operationmaterial',
|
||||||
|
name='count',
|
||||||
|
field=models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='消耗或产出数量'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='operationwproduct',
|
||||||
|
name='subproduction_plan',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ow_subplan', to='pm.subproductionplan', verbose_name='当前子生产计划'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='wproduct',
|
||||||
|
name='act_state',
|
||||||
|
field=models.IntegerField(choices=[(6, '待复检'), (8, '操作准备中'), (10, '操作进行中'), (20, '待检验'), (26, '待夹层检验'), (30, '已合格'), (40, '已入库'), (50, '不合格'), (60, '待成品检验')], default=0, verbose_name='进行状态'),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='WprouctTicket',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||||
|
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||||
|
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||||
|
('number', models.CharField(blank=True, max_length=50, null=True, verbose_name='物品编号')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wprouctticket_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='所在物料状态')),
|
||||||
|
('step', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.step', verbose_name='所在步骤')),
|
||||||
|
('subproduction_plan', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pm.subproductionplan', verbose_name='所在子生产计划')),
|
||||||
|
('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wf.ticket', verbose_name='关联工单')),
|
||||||
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='wprouctticket_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
('wproduct', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wpm.wproduct', verbose_name='关联产品')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -9,7 +9,6 @@ from apps.system.models import CommonADModel, CommonAModel, CommonBModel, Organi
|
||||||
from utils.model import SoftModel, BaseModel
|
from utils.model import SoftModel, BaseModel
|
||||||
from simple_history.models import HistoricalRecords
|
from simple_history.models import HistoricalRecords
|
||||||
from apps.mtm.models import Material, Process, RecordFormField, Step, RecordForm, SubprodctionMaterial
|
from apps.mtm.models import Material, Process, RecordFormField, Step, RecordForm, SubprodctionMaterial
|
||||||
from django.core.validators import MinValueValidator
|
|
||||||
from apps.em.models import Equipment
|
from apps.em.models import Equipment
|
||||||
class WMaterial(BaseModel):
|
class WMaterial(BaseModel):
|
||||||
"""
|
"""
|
||||||
|
|
@ -28,6 +27,7 @@ class WProduct(CommonAModel):
|
||||||
WPR_ACT_STATE_DOWAIT = 8
|
WPR_ACT_STATE_DOWAIT = 8
|
||||||
WPR_ACT_STATE_DOING = 10
|
WPR_ACT_STATE_DOING = 10
|
||||||
WPR_ACT_STATE_TOTEST = 20
|
WPR_ACT_STATE_TOTEST = 20
|
||||||
|
WPR_ACT_STATE_TOCOMBTEST = 26
|
||||||
WPR_ACT_STATE_OK = 30
|
WPR_ACT_STATE_OK = 30
|
||||||
WPR_ACT_STATE_INM = 40
|
WPR_ACT_STATE_INM = 40
|
||||||
WPR_ACT_STATE_NOTOK = 50
|
WPR_ACT_STATE_NOTOK = 50
|
||||||
|
|
@ -37,8 +37,9 @@ class WProduct(CommonAModel):
|
||||||
(WPR_ACT_STATE_DOWAIT, '操作准备中'),
|
(WPR_ACT_STATE_DOWAIT, '操作准备中'),
|
||||||
(WPR_ACT_STATE_DOING, '操作进行中'),
|
(WPR_ACT_STATE_DOING, '操作进行中'),
|
||||||
(WPR_ACT_STATE_TOTEST, '待检验'),
|
(WPR_ACT_STATE_TOTEST, '待检验'),
|
||||||
|
(WPR_ACT_STATE_TOCOMBTEST, '待夹层检验'),
|
||||||
(WPR_ACT_STATE_OK, '已合格'),
|
(WPR_ACT_STATE_OK, '已合格'),
|
||||||
(WPR_ACT_STATE_INM, '库存中'),
|
(WPR_ACT_STATE_INM, '已入库'),
|
||||||
(WPR_ACT_STATE_NOTOK, '不合格'),
|
(WPR_ACT_STATE_NOTOK, '不合格'),
|
||||||
(WPR_ACT_STATE_TOFINALTEST, '待成品检验')
|
(WPR_ACT_STATE_TOFINALTEST, '待成品检验')
|
||||||
)
|
)
|
||||||
|
|
@ -55,6 +56,16 @@ class WProduct(CommonAModel):
|
||||||
operation = models.ForeignKey('wpm.operation', verbose_name='关联操作',
|
operation = models.ForeignKey('wpm.operation', verbose_name='关联操作',
|
||||||
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_operation')
|
on_delete=models.SET_NULL, null=True, blank=True, related_name='wp_operation')
|
||||||
|
|
||||||
|
class WprouctTicket(CommonAModel):
|
||||||
|
"""
|
||||||
|
玻璃审批工单
|
||||||
|
"""
|
||||||
|
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
||||||
|
wproduct = models.ForeignKey(WProduct, verbose_name='关联产品', on_delete=models.CASCADE)
|
||||||
|
material = models.ForeignKey(Material, verbose_name='所在物料状态', on_delete=models.CASCADE)
|
||||||
|
step = models.ForeignKey(Step, verbose_name='所在步骤', on_delete=models.CASCADE)
|
||||||
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='所在子生产计划', on_delete=models.CASCADE)
|
||||||
|
ticket = models.ForeignKey('wf.ticket', verbose_name='关联工单', on_delete=models.CASCADE)
|
||||||
|
|
||||||
class Pick(CommonADModel):
|
class Pick(CommonADModel):
|
||||||
"""
|
"""
|
||||||
|
|
@ -97,7 +108,7 @@ class OperationWproduct(BaseModel):
|
||||||
wproduct = models.ForeignKey(WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='ow_wproduct')
|
wproduct = models.ForeignKey(WProduct, verbose_name='关联半成品', on_delete=models.CASCADE, related_name='ow_wproduct')
|
||||||
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
number = models.CharField('物品编号', null=True, blank=True, max_length=50)
|
||||||
material = models.ForeignKey(Material, verbose_name='操作时的物料状态', on_delete=models.CASCADE)
|
material = models.ForeignKey(Material, verbose_name='操作时的物料状态', on_delete=models.CASCADE)
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE)
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE, related_name='ow_subplan')
|
||||||
|
|
||||||
|
|
||||||
class OperationMaterial(BaseModel):
|
class OperationMaterial(BaseModel):
|
||||||
|
|
@ -108,7 +119,7 @@ class OperationMaterial(BaseModel):
|
||||||
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE)
|
operation = models.ForeignKey(Operation, verbose_name='关联的生产操作', on_delete=models.CASCADE)
|
||||||
|
|
||||||
material = models.ForeignKey(Material, verbose_name='可能产出的产品', on_delete=models.CASCADE, null=True, blank=True)
|
material = models.ForeignKey(Material, verbose_name='可能产出的产品', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
count = models.IntegerField('消耗或产出数量', validators=[MinValueValidator(0)], null=True, blank=True)
|
count = models.PositiveSmallIntegerField('消耗或产出数量', null=True, blank=True)
|
||||||
|
|
||||||
wmaterial = models.ForeignKey(WMaterial, verbose_name='关联的车间物料', on_delete=models.CASCADE, null=True, blank=True)
|
wmaterial = models.ForeignKey(WMaterial, verbose_name='关联的车间物料', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
subproduction_progress = models.ForeignKey(SubProductionProgress, verbose_name='关联的生产进度', on_delete=models.CASCADE, null=True, blank=True)
|
subproduction_progress = models.ForeignKey(SubProductionProgress, verbose_name='关联的生产进度', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
|
|
|
||||||
|
|
@ -292,6 +292,11 @@ class WpmTestRecordCreateSerializer(serializers.ModelSerializer):
|
||||||
model = TestRecord
|
model = TestRecord
|
||||||
fields = ['form', 'record_data', 'is_testok', 'wproduct']
|
fields = ['form', 'record_data', 'is_testok', 'wproduct']
|
||||||
|
|
||||||
|
class WpmTestFormInitSerializer(serializers.Serializer):
|
||||||
|
wproduct = serializers.PrimaryKeyRelatedField(queryset=WProduct.objects.all(), required=True)
|
||||||
|
form = serializers.PrimaryKeyRelatedField(queryset=RecordForm.objects.all(), required=True)
|
||||||
|
|
||||||
|
|
||||||
class WplanPutInSerializer(serializers.Serializer):
|
class WplanPutInSerializer(serializers.Serializer):
|
||||||
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
|
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
|
||||||
remark = serializers.CharField(label="入库备注", required =False)
|
remark = serializers.CharField(label="入库备注", required =False)
|
||||||
|
|
@ -335,6 +340,11 @@ class OperationMaterialCreate1Serailizer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = OperationMaterial
|
model = OperationMaterial
|
||||||
fields = ['operation', 'wmaterial', 'count']
|
fields = ['operation', 'wmaterial', 'count']
|
||||||
|
|
||||||
|
def validate(self, attrs):
|
||||||
|
if attrs['count'] <=0:
|
||||||
|
raise exceptions.APIException('消耗物料数量错误')
|
||||||
|
return super().validate(attrs)
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
wmaterial = validated_data['wmaterial']
|
wmaterial = validated_data['wmaterial']
|
||||||
|
|
@ -343,7 +353,10 @@ class OperationMaterialCreate1Serailizer(serializers.ModelSerializer):
|
||||||
validated_data['batch'] = wmaterial.batch
|
validated_data['batch'] = wmaterial.batch
|
||||||
validated_data['type'] = SubprodctionMaterial.SUB_MA_TYPE_IN
|
validated_data['type'] = SubprodctionMaterial.SUB_MA_TYPE_IN
|
||||||
return super().create(validated_data)
|
return super().create(validated_data)
|
||||||
|
|
||||||
|
class OperationMaterialCreate1ListSerailizer(serializers.ListSerializer):
|
||||||
|
child=OperationMaterialCreate1Serailizer()
|
||||||
|
|
||||||
class OperationMaterialCreate2Serailizer(serializers.ModelSerializer):
|
class OperationMaterialCreate2Serailizer(serializers.ModelSerializer):
|
||||||
subproduction_progress = serializers.PrimaryKeyRelatedField(required=True, queryset=SubProductionProgress.objects.all())
|
subproduction_progress = serializers.PrimaryKeyRelatedField(required=True, queryset=SubProductionProgress.objects.all())
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
@ -357,6 +370,9 @@ class OperationMaterialCreate2Serailizer(serializers.ModelSerializer):
|
||||||
validated_data['type'] = SubprodctionMaterial.SUB_MA_TYPE_OUT
|
validated_data['type'] = SubprodctionMaterial.SUB_MA_TYPE_OUT
|
||||||
return super().create(validated_data)
|
return super().create(validated_data)
|
||||||
|
|
||||||
|
|
||||||
|
class OperationMaterialCreate2ListSerailizer(serializers.ListSerializer):
|
||||||
|
child=OperationMaterialCreate2Serailizer()
|
||||||
class OperationMaterialCreate3Serializer(serializers.ModelSerializer):
|
class OperationMaterialCreate3Serializer(serializers.ModelSerializer):
|
||||||
material = serializers.PrimaryKeyRelatedField(required=True, queryset=Material.objects.all())
|
material = serializers.PrimaryKeyRelatedField(required=True, queryset=Material.objects.all())
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,14 @@ from apps.mtm.serializers import RecordFormDetailSerializer, SubprodctionMateria
|
||||||
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
||||||
from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer, SubProductionProgressSerializer
|
from apps.pm.serializers import SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer, SubProductionProgressSerializer
|
||||||
from apps.qm.models import TestRecord, TestRecordItem
|
from apps.qm.models import TestRecord, TestRecordItem
|
||||||
|
from apps.qm.serializers import TestRecordDetailSerializer
|
||||||
|
|
||||||
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from apps.wpm.filters import WMaterialFilterSet
|
from apps.wpm.filters import WMaterialFilterSet
|
||||||
from apps.wpm.models import OperationEquip, OperationWproduct, Pick, PickWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem
|
from apps.wpm.models import OperationEquip, OperationWproduct, Pick, PickWproduct, WMaterial, WProduct, Operation, OperationMaterial, OperationRecord, OperationRecordItem
|
||||||
|
|
||||||
from apps.wpm.serializers import OperationEquipListSerializer, OperationEquipUpdateSerializer, OperationMaterialCreate1Serailizer, OperationMaterialCreate2Serailizer, OperationMaterialCreate3Serializer, OperationMaterialListSerializer, OperationRecordListSerializer, OperationRecordSubmitSerializer, OperationUpdateSerializer, OperationWproductListSerializer, OperationCreateSerializer, OperationDetailSerializer, OperationListSerializer, PickHalfSerializer, PickHalfsSerializer, PickSerializer, OperationInitSerializer, OperationSubmitSerializer, WMaterialListSerializer, WProductListSerializer, WplanPutInSerializer, WpmTestRecordCreateSerializer, WproductPutInSerializer, WproductPutInsSerializer
|
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 rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from rest_framework import exceptions, serializers
|
from rest_framework import exceptions, serializers
|
||||||
|
|
@ -183,6 +184,39 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
ordering_fields = ['id']
|
ordering_fields = ['id']
|
||||||
ordering = ['id']
|
ordering = ['id']
|
||||||
|
|
||||||
|
@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)
|
||||||
|
vdata = serializer.validated_data
|
||||||
|
wproduct = vdata['wproduct']
|
||||||
|
form = vdata['form']
|
||||||
|
|
||||||
|
|
||||||
|
# 如果是复检记录, 需要带入原数据
|
||||||
|
if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST:
|
||||||
|
# 查找最近一条检验记录
|
||||||
|
trs = TestRecord.objects.filter(wproduct=wproduct, type=TestRecord.TEST_PROCESS).order_by('-id').first()
|
||||||
|
if trs:
|
||||||
|
origin_data = TestRecordDetailSerializer(instance=trs).data
|
||||||
|
data = RecordFormDetailSerializer(instance=form).data
|
||||||
|
data['origin_data'] = origin_data
|
||||||
|
o_dict = {}
|
||||||
|
for i in origin_data['record_data_']:
|
||||||
|
o_dict[i['field_key']] = i['field_value']
|
||||||
|
for i in data['form_fields']:
|
||||||
|
i['origin_value'] = o_dict[i['field_key']]
|
||||||
|
else:
|
||||||
|
raise exceptions.APIException('原工序检验记录不存在')
|
||||||
|
else:
|
||||||
|
data = RecordFormDetailSerializer(instance=form).data
|
||||||
|
|
||||||
|
# 后续加入系统自带数据
|
||||||
|
return Response(data)
|
||||||
|
|
||||||
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WpmTestRecordCreateSerializer)
|
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WpmTestRecordCreateSerializer)
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def test(self, request, pk=None):
|
def test(self, request, pk=None):
|
||||||
|
|
@ -195,7 +229,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
record_data = vdata.pop('record_data')
|
record_data = vdata.pop('record_data')
|
||||||
wproduct = vdata['wproduct']
|
wproduct = vdata['wproduct']
|
||||||
if wproduct.act_state not in [WProduct.WPR_ACT_STATE_TOTEST,
|
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_TORETEST, WProduct.WPR_ACT_STATE_TOFINALTEST, WProduct.WPR_ACT_STATE_TOCOMBTEST]:
|
||||||
raise exceptions.APIException('该产品当前状态不可检验')
|
raise exceptions.APIException('该产品当前状态不可检验')
|
||||||
if 'is_testok' not in vdata:
|
if 'is_testok' not in vdata:
|
||||||
raise exceptions.APIException('未填写检测结论')
|
raise exceptions.APIException('未填写检测结论')
|
||||||
|
|
@ -206,6 +240,8 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
savedict['type'] = TestRecord.TEST_PROCESS_RE
|
savedict['type'] = TestRecord.TEST_PROCESS_RE
|
||||||
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOFINALTEST:
|
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOFINALTEST:
|
||||||
savedict['type'] = TestRecord.TEST_FINAL
|
savedict['type'] = TestRecord.TEST_FINAL
|
||||||
|
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOCOMBTEST:
|
||||||
|
savedict['type'] = TestRecord.TEST_COMB
|
||||||
obj = serializer.save(**savedict)
|
obj = serializer.save(**savedict)
|
||||||
tris = []
|
tris = []
|
||||||
for m in record_data: # 保存记录详情
|
for m in record_data: # 保存记录详情
|
||||||
|
|
@ -224,15 +260,14 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
# 如果检测合格, 变更动态产品进行状态
|
# 如果检测合格, 变更动态产品进行状态
|
||||||
|
|
||||||
if obj.is_testok:
|
if obj.is_testok:
|
||||||
if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST:
|
if wproduct.act_state == WProduct.WPR_ACT_STATE_TORETEST: # 复检
|
||||||
wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT # 复检
|
wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
|
||||||
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and wproduct.material.type == Material.MA_TYPE_GOOD:
|
elif wproduct.act_state == WProduct.WPR_ACT_STATE_TOTEST and wproduct.material.type == Material.MA_TYPE_GOOD: # 成品检验
|
||||||
wproduct.act_state = WProduct.WPR_ACT_STATE_TOFINALTEST # 成品检验
|
wproduct.act_state = WProduct.WPR_ACT_STATE_TOFINALTEST
|
||||||
else:
|
else:
|
||||||
wproduct.act_state = WProduct.WPR_ACT_STATE_OK
|
wproduct.act_state = WProduct.WPR_ACT_STATE_OK
|
||||||
if wproduct.number is None: # 产生半成品编号
|
if wproduct.number is None: # 产生半成品编号
|
||||||
wproduct.number = 'WP'+ranstr(7)
|
wproduct.number = 'WP'+ranstr(7)
|
||||||
wproduct.save()
|
|
||||||
# 更新子计划状态
|
# 更新子计划状态
|
||||||
# 更新子计划主产品数
|
# 更新子计划主产品数
|
||||||
instance = SubProductionProgress.objects.get(subproduction_plan=wproduct.subproduction_plan,
|
instance = SubProductionProgress.objects.get(subproduction_plan=wproduct.subproduction_plan,
|
||||||
|
|
@ -241,8 +276,9 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
instance.save()
|
instance.save()
|
||||||
else:# 如果不合格
|
else:# 如果不合格
|
||||||
wproduct.act_state = WProduct.WPR_ACT_STATE_NOTOK
|
wproduct.act_state = WProduct.WPR_ACT_STATE_NOTOK
|
||||||
wproduct.save()
|
# 需要走不合格品审理单
|
||||||
|
wproduct.update_by = request.user
|
||||||
|
wproduct.save()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WproductPutInsSerializer)
|
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=WproductPutInsSerializer)
|
||||||
|
|
@ -267,12 +303,12 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
is_audited=True, auditor=request.user, inout_date=timezone.now(), create_by=request.user, remark=remark)
|
is_audited=True, auditor=request.user, inout_date=timezone.now(), create_by=request.user, remark=remark)
|
||||||
# 创建入库明细
|
# 创建入库明细
|
||||||
for i in wproducts_a:
|
for i in wproducts_a:
|
||||||
spi = i['subproduction_plan']
|
spi = SubProductionPlan.objects.get(pk=i['subproduction_plan'])
|
||||||
fifoitem = FIFOItem()
|
fifoitem = FIFOItem()
|
||||||
fifoitem.is_tested = True
|
fifoitem.is_tested = True
|
||||||
fifoitem.is_testok = True
|
fifoitem.is_testok = True
|
||||||
fifoitem.warehouse = warehouse
|
fifoitem.warehouse = warehouse
|
||||||
fifoitem.material = i['material']
|
fifoitem.material = Material.objects.get(pk=i['material'])
|
||||||
fifoitem.count = i['total']
|
fifoitem.count = i['total']
|
||||||
fifoitem.batch = spi.number
|
fifoitem.batch = spi.number
|
||||||
fifoitem.fifo = fifo
|
fifoitem.fifo = fifo
|
||||||
|
|
@ -292,7 +328,7 @@ class WProductViewSet(ListModelMixin, GenericViewSet):
|
||||||
FIFOItemProduct.objects.bulk_create(ips)
|
FIFOItemProduct.objects.bulk_create(ips)
|
||||||
# 更新库存并修改半成品进行状态
|
# 更新库存并修改半成品进行状态
|
||||||
update_inm(fifo)
|
update_inm(fifo)
|
||||||
wproducts.update(act_state=WProduct.WPR_ACT_STATE_INM, warehouse=warehouse, update_by=request.user)
|
wproducts.update(act_state=WProduct.WPR_ACT_STATE_INM, warehouse=warehouse, update_by=request.user, update_time=timezone.now())
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WproductPutInSerializer)
|
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=WproductPutInSerializer)
|
||||||
|
|
@ -486,6 +522,7 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
||||||
instance.count_real = instance.count_real + 1 # 这个地方可能会有问题,不够严谨
|
instance.count_real = instance.count_real + 1 # 这个地方可能会有问题,不够严谨
|
||||||
instance.save()
|
instance.save()
|
||||||
wp.operation = None
|
wp.operation = None
|
||||||
|
wp.update_by = request.user
|
||||||
wp.save()
|
wp.save()
|
||||||
elif step.type == Step.STEP_TYPE_DIV:
|
elif step.type == Step.STEP_TYPE_DIV:
|
||||||
# 更新物料产出情况
|
# 更新物料产出情况
|
||||||
|
|
@ -498,25 +535,31 @@ class OperationViewSet(ListModelMixin, RetrieveModelMixin, CreateModelMixin, Upd
|
||||||
for x in range(i.count):
|
for x in range(i.count):
|
||||||
WProduct.objects.create(**wpr)
|
WProduct.objects.create(**wpr)
|
||||||
elif step.type == Step.STEP_TYPE_COMB:
|
elif step.type == Step.STEP_TYPE_COMB:
|
||||||
if i.subproduction_progress.is_main:
|
oms_w = OperationMaterial.objects.filter(operation=op, type=SubprodctionMaterial.SUB_MA_TYPE_OUT,
|
||||||
newstep, hasNext = WpmServies.get_next_step(i.subproduction_plan, step)
|
subproduction_progress__ismain=True)
|
||||||
|
if len(oms_w) == 1:
|
||||||
|
oms_w = oms_w[0]
|
||||||
|
# 校验单片数量是否正确, 暂时未写
|
||||||
|
newstep, hasNext = WpmServies.get_next_step(oms_w.subproduction_plan, step)
|
||||||
wproduct = WProduct()
|
wproduct = WProduct()
|
||||||
wproduct.material = i.material
|
wproduct.material = oms_w.material
|
||||||
wproduct.step = newstep
|
wproduct.step = newstep
|
||||||
wproduct.subproduction_plan = i.subproduction_plan
|
wproduct.subproduction_plan = oms_w.subproduction_plan
|
||||||
if hasNext:
|
if hasNext:
|
||||||
wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
|
wproduct.act_state = WProduct.WPR_ACT_STATE_DOWAIT
|
||||||
else:
|
else:
|
||||||
wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST
|
wproduct.act_state = WProduct.WPR_ACT_STATE_TOTEST
|
||||||
# 更新子计划进度
|
# 更新子计划进度
|
||||||
instance = SubProductionProgress.objects.get(subproduction_plan=i.subproduction_plan,
|
instance = oms_w.subproduction_progress
|
||||||
is_main=True, type=SubprodctionMaterial.SUB_MA_TYPE_OUT)
|
|
||||||
instance.count_real = instance.count_real + 1 # 这个地方可能会有问题,不够严谨
|
instance.count_real = instance.count_real + 1 # 这个地方可能会有问题,不够严谨
|
||||||
instance.save()
|
instance.save()
|
||||||
|
wproduct.create_by = request.user
|
||||||
wproduct.save()
|
wproduct.save()
|
||||||
# 隐藏原半成品
|
# 隐藏原半成品
|
||||||
wps = WProduct.objects.filter(ow_wproduct__operation = op)
|
wps = WProduct.objects.filter(ow_wproduct__operation = op)
|
||||||
wps.update(is_hidden=True, child=wproduct)
|
wps.update(is_hidden=True, child=wproduct, update_by=request.user, update_time=timezone.now())
|
||||||
|
else:
|
||||||
|
raise exceptions.APIException('产出物料错误')
|
||||||
op.is_submited = True
|
op.is_submited = True
|
||||||
op.save()
|
op.save()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
@ -594,6 +637,16 @@ class OperationRecordViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
instance.delete()
|
instance.delete()
|
||||||
return Response()
|
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)
|
||||||
|
|
||||||
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=OperationRecordSubmitSerializer)
|
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=OperationRecordSubmitSerializer)
|
||||||
def submit(self, request, pk=None):
|
def submit(self, request, pk=None):
|
||||||
serializer = OperationRecordSubmitSerializer(data=request.data, context={'request':self.request})
|
serializer = OperationRecordSubmitSerializer(data=request.data, context={'request':self.request})
|
||||||
|
|
@ -632,7 +685,18 @@ class OperationMaterialInputViewSet(ListModelMixin, CreateModelMixin, DestroyMod
|
||||||
if self.action == 'create':
|
if self.action == 'create':
|
||||||
return OperationMaterialCreate1Serailizer
|
return OperationMaterialCreate1Serailizer
|
||||||
return super().get_serializer_class()
|
return super().get_serializer_class()
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=OperationMaterialCreate1ListSerailizer)
|
||||||
|
def creates(self, request, pk=None):
|
||||||
|
"""
|
||||||
|
批量创建消耗物料
|
||||||
|
"""
|
||||||
|
serializer = OperationMaterialCreate1ListSerailizer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
serializer.save()
|
||||||
|
return Response()
|
||||||
|
|
||||||
|
|
||||||
@transaction.atomic()
|
@transaction.atomic()
|
||||||
def destroy(self, request, *args, **kwargs):
|
def destroy(self, request, *args, **kwargs):
|
||||||
instance = self.get_object()
|
instance = self.get_object()
|
||||||
|
|
@ -656,7 +720,17 @@ class OperationMaterialOutputViewSet(ListModelMixin, CreateModelMixin, DestroyMo
|
||||||
if self.action == 'create':
|
if self.action == 'create':
|
||||||
return OperationMaterialCreate2Serailizer
|
return OperationMaterialCreate2Serailizer
|
||||||
return super().get_serializer_class()
|
return super().get_serializer_class()
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=OperationMaterialCreate2ListSerailizer)
|
||||||
|
def creates(self, request, pk=None):
|
||||||
|
"""
|
||||||
|
批量创建产出物料
|
||||||
|
"""
|
||||||
|
serializer = OperationMaterialCreate2ListSerailizer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
serializer.save()
|
||||||
|
return Response()
|
||||||
|
|
||||||
@transaction.atomic()
|
@transaction.atomic()
|
||||||
def destroy(self, request, *args, **kwargs):
|
def destroy(self, request, *args, **kwargs):
|
||||||
instance = self.get_object()
|
instance = self.get_object()
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ class UpdateDevelop(APIView):
|
||||||
import os
|
import os
|
||||||
# 更新后端
|
# 更新后端
|
||||||
os.chdir('/home/hberp')
|
os.chdir('/home/hberp')
|
||||||
ret = os.popen('git pull https://caoqianming%40ctc.ac.cn:9093qqww@e.coding.net/ctcdevteam/hberp/hberp.git develop')
|
ret = os.popen('git pull https://caoqianming%40foxmail.com:9093qqww@e.coding.net/ctcdevteam/hberp/hberp.git develop')
|
||||||
# 打包前端
|
# 打包前端
|
||||||
# os.chdir('/home/hberp/hb_client')
|
# os.chdir('/home/hberp/hb_client')
|
||||||
# os.system('npm run build:prod')
|
# os.system('npm run build:prod')
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue