Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
d6915a9f19
|
@ -15,3 +15,12 @@ export function getProcessYield(data) {
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
//到岗统计
|
||||||
|
export function getatwork(data) {
|
||||||
|
return request({
|
||||||
|
url: '/srm/at_work/',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -418,12 +418,12 @@ export const asyncRoutes = [
|
||||||
meta: { title: '人员列表', icon: 'example', perms: ['user_manage'] }
|
meta: { title: '人员列表', icon: 'example', perms: ['user_manage'] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'personnel',
|
path: 'attendance',
|
||||||
name: 'personnel',
|
name: 'attendance',
|
||||||
component: () => import('@/views/personnel/user'),
|
component: () => import('@/views/personnel/attendance'),
|
||||||
meta: { title: '考勤列表', icon: 'example', perms: ['user_manage'] }
|
meta: { title: '考勤列表', icon: 'example', perms: ['attendance_manage'] }
|
||||||
} ,{
|
} ,{
|
||||||
path: 'userupdate',
|
path: 'userupdate/:id',
|
||||||
name: 'userupdate',
|
name: 'userupdate',
|
||||||
component: () => import('@/views/personnel/userupdate'),
|
component: () => import('@/views/personnel/userupdate'),
|
||||||
meta: { title: '人员信息详情', icon: 'employee', perms: ['employee_detail'] },
|
meta: { title: '人员信息详情', icon: 'employee', perms: ['employee_detail'] },
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
<el-card>
|
||||||
|
<el-tabs type="border-card">
|
||||||
|
<el-tab-pane label="今日到岗">
|
||||||
|
<el-table
|
||||||
|
|
||||||
|
:data="userList.results"
|
||||||
|
style="width: 100%; margin-top: 6px"
|
||||||
|
highlight-current-row
|
||||||
|
row-key="id"
|
||||||
|
height="100"
|
||||||
|
stripe
|
||||||
|
border
|
||||||
|
v-el-height-adaptive-table="{ bottomOffset: 41 }"
|
||||||
|
>
|
||||||
|
<el-table-column type="index" width="50" label="序号" />
|
||||||
|
<el-table-column align="center" label="工号">
|
||||||
|
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="姓名">
|
||||||
|
<template slot-scope="scope">{{ scope.row.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="到岗情况">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tag type="success" v-if="scope.row.is_atwork">在岗</el-tag>
|
||||||
|
|
||||||
|
<el-tag type="danger" v-else>离岗</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column align="header-center" label="部门">
|
||||||
|
<template v-if="scope.row.dept_" slot-scope="scope">{{
|
||||||
|
scope.row.dept_.name
|
||||||
|
}}</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-show="userList.count > 0"
|
||||||
|
:total="userList.count"
|
||||||
|
:page.sync="listQuery.page"
|
||||||
|
:limit.sync="listQuery.page_size"
|
||||||
|
@pagination="getList"
|
||||||
|
/></el-tab-pane>
|
||||||
|
<el-tab-pane label="到岗统计">
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
|
||||||
|
<span class="demonstration">年、月</span>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="value2"
|
||||||
|
type="month"
|
||||||
|
placeholder="选择年月">
|
||||||
|
</el-date-picker>
|
||||||
|
<el-button type="primary" @click="submit">主要按钮</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
|
||||||
|
:data="atworkList"
|
||||||
|
style="width: 100%; margin-top: 6px"
|
||||||
|
highlight-current-row
|
||||||
|
row-key="id"
|
||||||
|
height="680"
|
||||||
|
stripe
|
||||||
|
border
|
||||||
|
v-el-height-adaptive-table="{ bottomOffset: 41 }"
|
||||||
|
>
|
||||||
|
<el-table-column type="index" width="50" label="序号" />
|
||||||
|
<el-table-column align="center" label="工号">
|
||||||
|
<template slot-scope="scope">{{ scope.row.number }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="姓名">
|
||||||
|
<template slot-scope="scope">{{ scope.row.name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column align="header-center" label="部门">
|
||||||
|
<template slot-scope="scope">{{ scope.row.dept_name }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column align="center" label="出勤天数">
|
||||||
|
<template slot-scope="scope">{{ scope.row.count }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
</el-tab-pane>
|
||||||
|
|
||||||
|
</el-tabs>
|
||||||
|
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<style>
|
||||||
|
.avatar-uploader .el-upload {
|
||||||
|
border: 1px dashed #d9d9d9;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.avatar-uploader .el-upload:hover {
|
||||||
|
border-color: #409eff;
|
||||||
|
}
|
||||||
|
.avatar-uploader-icon {
|
||||||
|
font-size: 28px;
|
||||||
|
color: #8c939d;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
line-height: 100px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.avatar {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
import { getEmployeeList } from "@/api/employee";
|
||||||
|
import checkPermission from "@/utils/permission";
|
||||||
|
|
||||||
|
import {getatwork } from "@/api/srm";
|
||||||
|
import { upUrl, upHeaders } from "@/api/file";
|
||||||
|
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
|
||||||
|
import Treeselect from "@riophae/vue-treeselect";
|
||||||
|
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { Pagination, Treeselect },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
userList: { count: 0 },
|
||||||
|
atworkList: "",
|
||||||
|
value3:null,
|
||||||
|
value2:null,
|
||||||
|
listLoading: true,
|
||||||
|
listQuery: {
|
||||||
|
page: 1,
|
||||||
|
page_size: 20,
|
||||||
|
},
|
||||||
|
|
||||||
|
atworkDate:{year:null,month:null},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
checkPermission,
|
||||||
|
//今日到岗
|
||||||
|
getList() {
|
||||||
|
this.listQuery.fields='number,name,is_atwork,dept_';
|
||||||
|
getEmployeeList(this.listQuery).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.userList = response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//到岗统计
|
||||||
|
|
||||||
|
submit()
|
||||||
|
{
|
||||||
|
|
||||||
|
this.atworkDate.year=this.value2.getFullYear();
|
||||||
|
this.atworkDate.month=this.value2.getMonth()+1;
|
||||||
|
|
||||||
|
getatwork(this.atworkDate).then((response) => {
|
||||||
|
if (response.data) {
|
||||||
|
this.atworkList = response.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -2,9 +2,7 @@
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
|
|
||||||
<el-card>
|
<el-card>
|
||||||
<div slot="header" class="clearfix">
|
|
||||||
<span>用户</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
<el-input
|
<el-input
|
||||||
|
@ -39,7 +37,7 @@
|
||||||
height="100"
|
height="100"
|
||||||
stripe
|
stripe
|
||||||
border
|
border
|
||||||
v-el-height-adaptive-table="{bottomOffset: 50}"
|
v-el-height-adaptive-table="{bottomOffset: 41}"
|
||||||
>
|
>
|
||||||
<el-table-column type="index" width="50" />
|
<el-table-column type="index" width="50" />
|
||||||
<el-table-column align="center" label="工号">
|
<el-table-column align="center" label="工号">
|
||||||
|
@ -179,8 +177,7 @@ export default {
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getList();
|
this.getList();
|
||||||
this.getOrgAll();
|
|
||||||
this.getRoleAll();
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
checkPermission,
|
checkPermission,
|
||||||
|
@ -212,18 +209,7 @@ export default {
|
||||||
this.listLoading = false;
|
this.listLoading = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getOrgAll() {
|
|
||||||
this.treeLoding = true;
|
|
||||||
getOrgAll().then(response => {
|
|
||||||
this.orgData = genTree(response.data);
|
|
||||||
this.treeLoding = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
getRoleAll() {
|
|
||||||
getRoleAll().then(response => {
|
|
||||||
this.roles = genTree(response.data);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
resetFilter() {
|
resetFilter() {
|
||||||
this.listQuery = {
|
this.listQuery = {
|
||||||
page: 1,
|
page: 1,
|
||||||
|
|
|
@ -1,24 +1,56 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<el-card>
|
<el-row :gutter="2">
|
||||||
<el-row>
|
<el-col :span="9" >
|
||||||
<el-col :span="4">
|
<el-card style="height:655px" >
|
||||||
<div>基础信息</div>
|
|
||||||
<el-form label-width="60px">
|
|
||||||
<el-form-item label="姓名">{{userDate.name}}</el-form-item>
|
|
||||||
<el-form-item label="账户">{{userDate.username}}</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item label="角色">
|
<div>基础信息</div>
|
||||||
<el-tag
|
<el-form ref="Form" :model="user" label-width="80px" label-position="right" :rules="rule1">
|
||||||
v-for="(item, index) in userDate.roles_name"
|
<el-form-item label="姓名" prop="name">
|
||||||
:key="index"
|
<el-input v-model="user.name" placeholder="姓名" />
|
||||||
style="margin:2px"
|
</el-form-item>
|
||||||
>{{item}}</el-tag>
|
<el-form-item label="账户" prop="username">
|
||||||
|
<el-input v-model="user.username" placeholder="账户" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="所属部门" prop="dept">
|
||||||
|
<el-cascader ref="cascader" :options="orgData" v-model="user.dept" :show-all-levels="false"></el-cascader>
|
||||||
|
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="角色" prop="roles">
|
||||||
|
<el-select v-model="user.roles" multiple placeholder="请选择" style="width:100%">
|
||||||
|
<el-option
|
||||||
|
v-for="item in roles"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="头像" prop="dept">
|
||||||
|
<el-upload
|
||||||
|
class="avatar-uploader"
|
||||||
|
:action="upUrl"
|
||||||
|
accept="image/jpeg, image/gif, image/png, image/bmp"
|
||||||
|
:show-file-list="false"
|
||||||
|
:on-success="handleAvatarSuccess"
|
||||||
|
:before-upload="beforeAvatarUpload"
|
||||||
|
:headers="upHeaders"
|
||||||
|
>
|
||||||
|
<img v-if="user.avatar" :src="user.avatar" class="avatar" />
|
||||||
|
<i v-else class="el-icon-plus avatar-uploader-icon" />
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item size="large">
|
||||||
|
<el-button type="primary" @click="submitFormuser" >保存</el-button>
|
||||||
|
<el-button @click="goBack">返回</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="手机">{{userDate.phone}}</el-form-item>
|
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
|
||||||
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="20">
|
<el-col :span="15" >
|
||||||
|
<el-card style="height:655px" >
|
||||||
<div>详细信息</div>
|
<div>详细信息</div>
|
||||||
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="100px">
|
<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="100px">
|
||||||
<el-row>
|
<el-row>
|
||||||
|
@ -31,6 +63,8 @@
|
||||||
:style="{width: '100%'}"
|
:style="{width: '100%'}"
|
||||||
></el-input>
|
></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
<el-form-item label="学历" prop="qualification">
|
<el-form-item label="学历" prop="qualification">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.qualification"
|
v-model="formData.qualification"
|
||||||
|
@ -61,7 +95,8 @@
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8">
|
||||||
<el-form-item label="在职状态" prop="job_state">
|
<el-form-item label="在职状态" prop="job_state">
|
||||||
<el-select
|
<el-select
|
||||||
v-model="formData.job_state"
|
v-model="formData.job_state"
|
||||||
|
@ -77,6 +112,12 @@
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
|
||||||
|
</el-row>
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="8">
|
||||||
<el-form-item label="出生年月" prop="birthday">
|
<el-form-item label="出生年月" prop="birthday">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="formData.birthday"
|
v-model="formData.birthday"
|
||||||
|
@ -88,11 +129,8 @@
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
</el-row>
|
|
||||||
<el-row>
|
|
||||||
|
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
|
|
||||||
<el-form-item label="身份证号" prop="id_number">
|
<el-form-item label="身份证号" prop="id_number">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="formData.id_number"
|
v-model="formData.id_number"
|
||||||
|
@ -107,7 +145,7 @@
|
||||||
|
|
||||||
|
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="6">
|
<el-col :span="8">
|
||||||
<el-form-item label="证件照" prop="photo">
|
<el-form-item label="证件照" prop="photo">
|
||||||
<el-upload
|
<el-upload
|
||||||
:action="upUrl"
|
:action="upUrl"
|
||||||
|
@ -123,9 +161,8 @@
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
|
||||||
<el-row>
|
<el-col :span="8">
|
||||||
<el-col :span="6">
|
|
||||||
<el-form-item label="签名图片" prop="signature">
|
<el-form-item label="签名图片" prop="signature">
|
||||||
<el-upload :action="upUrl" :headers="upHeaders" accept=".png, .jpeg, .jpg" :before-upload="beforeUpload" class="avatar-uploader"
|
<el-upload :action="upUrl" :headers="upHeaders" accept=".png, .jpeg, .jpg" :before-upload="beforeUpload" class="avatar-uploader"
|
||||||
:show-file-list="false"
|
:show-file-list="false"
|
||||||
|
@ -139,9 +176,10 @@
|
||||||
<el-button @click="goBack">返回</el-button>
|
<el-button @click="goBack">返回</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-card>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style>
|
<style>
|
||||||
|
@ -186,21 +224,27 @@
|
||||||
|
|
||||||
import { upUrl, upHeaders } from "@/api/file"
|
import { upUrl, upHeaders } from "@/api/file"
|
||||||
import { genSignature } from "@/api/util"
|
import { genSignature } from "@/api/util"
|
||||||
import { getUser } from "@/api/user";
|
import { getUser,updateUser } from "@/api/user";
|
||||||
|
import { genTree } from "@/utils"
|
||||||
|
import { getOrgAll } from "@/api/org"
|
||||||
|
import { getRoleAll } from "@/api/role"
|
||||||
|
import Treeselect from '@riophae/vue-treeselect'
|
||||||
import { getEmployee, updateEmployee } from "@/api/employee";
|
import { getEmployee, updateEmployee } from "@/api/employee";
|
||||||
const defaultForm = {
|
const defaultForm = {
|
||||||
user:{},
|
user:{},
|
||||||
};
|
};
|
||||||
export default {
|
export default {
|
||||||
name: "Employeedetail",
|
name: "Employeedetail",
|
||||||
components: {},
|
components: { Treeselect },
|
||||||
props: ["id"],
|
props: ["id"],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
upHeaders: upHeaders(),
|
upHeaders: upHeaders(),
|
||||||
upUrl: upUrl(),
|
upUrl: upUrl(),
|
||||||
formData: Object.assign({}, defaultForm),
|
formData: Object.assign({}, defaultForm),
|
||||||
userDate:[],
|
user:[],
|
||||||
|
orgData: [],
|
||||||
|
roles: [],
|
||||||
genderOptions: [
|
genderOptions: [
|
||||||
{ value: "男", label: "男" },
|
{ value: "男", label: "男" },
|
||||||
{ value: "女", label: "女" }
|
{ value: "女", label: "女" }
|
||||||
|
@ -209,6 +253,7 @@ export default {
|
||||||
{ value: 1, label: "在职" },
|
{ value: 1, label: "在职" },
|
||||||
{ value: 2, label: "离职" }
|
{ value: 2, label: "离职" }
|
||||||
],
|
],
|
||||||
|
deptvalue:null,
|
||||||
rules: {
|
rules: {
|
||||||
|
|
||||||
ID_number: [
|
ID_number: [
|
||||||
|
@ -226,7 +271,8 @@ export default {
|
||||||
created() {
|
created() {
|
||||||
this.formData.id = this.$route.params.id;
|
this.formData.id = this.$route.params.id;
|
||||||
this.getDetail();
|
this.getDetail();
|
||||||
|
this.getOrgAll();
|
||||||
|
this.getRoleAll();
|
||||||
},
|
},
|
||||||
mounted() {},
|
mounted() {},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -235,13 +281,38 @@ export default {
|
||||||
this.formData = res.data;
|
this.formData = res.data;
|
||||||
getUser(res.data.user).then(Response => {
|
getUser(res.data.user).then(Response => {
|
||||||
|
|
||||||
this.userDate=Response.data;
|
this.user=Response.data;
|
||||||
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
getOrgAll() {
|
||||||
|
|
||||||
|
getOrgAll().then(response => {
|
||||||
|
this.orgData = genTree(response.data);
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getRoleAll() {
|
||||||
|
getRoleAll({page:0}).then(response => {
|
||||||
|
this.roles =response.data;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
handleAvatarSuccess(res, file) {
|
||||||
|
this.user.avatar = res.data.path
|
||||||
|
},
|
||||||
|
beforeAvatarUpload(file) {
|
||||||
|
const isLt2M = file.size / 1024 / 1024 < 2;
|
||||||
|
if (!isLt2M) {
|
||||||
|
this.$message.error("上传头像图片大小不能超过 2MB!");
|
||||||
|
}
|
||||||
|
return isLt2M;
|
||||||
|
},
|
||||||
|
filterNode(value, data) {
|
||||||
|
if (!value) return true;
|
||||||
|
return data.label.indexOf(value) !== -1;
|
||||||
|
},
|
||||||
beforeUpload(file) {
|
beforeUpload(file) {
|
||||||
const isLt1M = file.size / 1024 / 1024 < 1;
|
const isLt1M = file.size / 1024 / 1024 < 1;
|
||||||
if (!isLt1M) {
|
if (!isLt1M) {
|
||||||
|
@ -277,6 +348,26 @@ export default {
|
||||||
},
|
},
|
||||||
goBack() {
|
goBack() {
|
||||||
this.$router.go(-1);
|
this.$router.go(-1);
|
||||||
|
},
|
||||||
|
submitFormuser() {
|
||||||
|
this.$refs["Form"].validate(valid => {
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
|
||||||
|
this.deptvalue= this.$refs['cascader'].getCheckedNodes();
|
||||||
|
if( this.deptvalue!="")
|
||||||
|
{
|
||||||
|
this.user.dept=this.deptvalue[0].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateUser(this.user.id, this.user).then(res => {
|
||||||
|
|
||||||
|
this.$message({
|
||||||
|
message: "编辑成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -88,9 +88,9 @@
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="header-center" label="部门">
|
<el-table-column align="header-center" label="部门">
|
||||||
<template
|
<template
|
||||||
v-if="scope.row.dept_name != null"
|
v-if="scope.row.dept"
|
||||||
slot-scope="scope"
|
slot-scope="scope"
|
||||||
>{{ scope.row.dept_name }}</template>
|
>{{ scope.row.dept_.name }}</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="创建日期">
|
<el-table-column label="创建日期">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
|
|
|
@ -2,7 +2,7 @@ from django.db.models import base
|
||||||
from rest_framework import urlpatterns
|
from rest_framework import urlpatterns
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
from apps.develop.views import CleanDataView, UpdateCuttingView, UpdateEquipState, UpdateFIFOItem, UpdateLastTestResult, UpdateNeedToOrder, UpdateSpg
|
from apps.develop.views import CleanDataView, UpdateCuttingView, UpdateEquipState, UpdateFIFOItem, UpdateFIFONumber, UpdateLastTestResult, UpdateNeedToOrder, UpdateSpg
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('cleandata/', CleanDataView.as_view()),
|
path('cleandata/', CleanDataView.as_view()),
|
||||||
|
@ -12,6 +12,7 @@ urlpatterns = [
|
||||||
path('update_fifoitem/', UpdateFIFOItem.as_view()),
|
path('update_fifoitem/', UpdateFIFOItem.as_view()),
|
||||||
path('update_spg/', UpdateSpg.as_view()),
|
path('update_spg/', UpdateSpg.as_view()),
|
||||||
path('update_equip_state/', UpdateEquipState.as_view()),
|
path('update_equip_state/', UpdateEquipState.as_view()),
|
||||||
path('update_need_to_order/', UpdateNeedToOrder.as_view())
|
path('update_need_to_order/', UpdateNeedToOrder.as_view()),
|
||||||
|
path('update_fifo_number/', UpdateFIFONumber.as_view())
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -106,3 +106,15 @@ class UpdateNeedToOrder(APIView):
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
WProduct.objects.exclude(to_order=None).update(need_to_order=True)
|
WProduct.objects.exclude(to_order=None).update(need_to_order=True)
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
class UpdateFIFONumber(APIView):
|
||||||
|
permission_classes = [IsAdminUser]
|
||||||
|
def post(self, request):
|
||||||
|
from utils.tools import ranstr
|
||||||
|
for i in FIFO.objects.all():
|
||||||
|
if i.type in [FIFO.FIFO_TYPE_DO_IN, FIFO.FIFO_TYPE_PUR_IN]:
|
||||||
|
i.number = 'RK'+ ranstr(7)
|
||||||
|
else:
|
||||||
|
i.number = 'CK' + ranstr(7)
|
||||||
|
i.save()
|
||||||
|
return Response()
|
|
@ -10,6 +10,8 @@ from django.db.models.query import Prefetch
|
||||||
class EmployeeSerializer(DynamicFieldsSerializerMixin, ModelSerializer):
|
class EmployeeSerializer(DynamicFieldsSerializerMixin, ModelSerializer):
|
||||||
name = serializers.CharField(source='user.name', read_only=True)
|
name = serializers.CharField(source='user.name', read_only=True)
|
||||||
dept_ = OrganizationSimpleSerializer(source='user.dept', read_only=True)
|
dept_ = OrganizationSimpleSerializer(source='user.dept', read_only=True)
|
||||||
|
is_atwork = serializers.BooleanField(source='user.is_atwork', read_only=True)
|
||||||
|
last_check_time = serializers.DateTimeField(source='user.last_check_time', read_only=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Employee
|
model = Employee
|
||||||
exclude = ['face_data']
|
exclude = ['face_data']
|
||||||
|
|
|
@ -3,6 +3,3 @@ from django.apps import AppConfig
|
||||||
class InmConfig(AppConfig):
|
class InmConfig(AppConfig):
|
||||||
name = 'apps.inm'
|
name = 'apps.inm'
|
||||||
verbose_name = '库存管理'
|
verbose_name = '库存管理'
|
||||||
|
|
||||||
def ready(self):
|
|
||||||
import apps.inm.signals
|
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Generated by Django 3.2.9 on 2022-01-27 07:47
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pum', '0004_puorder_puorderitem'),
|
||||||
|
('inm', '0028_alter_fifoitem_files'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='fifo',
|
||||||
|
name='pu_order',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='pum.puorder', verbose_name='关联采购订单'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,31 @@
|
||||||
|
# Generated by Django 3.2.9 on 2022-01-28 01:43
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pum', '0004_puorder_puorderitem'),
|
||||||
|
('inm', '0029_fifo_pu_order'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='fifo',
|
||||||
|
name='number',
|
||||||
|
field=models.CharField(default=1, max_length=100, verbose_name='记录编号'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='fifo',
|
||||||
|
name='vendor',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='pum.vendor', verbose_name='供应商'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='fifoitemproduct',
|
||||||
|
name='fifoitem',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='inm.fifoitem', verbose_name='关联出入库条目'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Generated by Django 3.2.9 on 2022-01-28 06:32
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('pum', '0004_puorder_puorderitem'),
|
||||||
|
('inm', '0030_auto_20220128_0943'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='fifoitem',
|
||||||
|
name='pu_order_item',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='pum.puorderitem', verbose_name='关联采购订单条目'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -2,6 +2,7 @@ from django.db import models
|
||||||
from django.db.models.base import Model
|
from django.db.models.base import Model
|
||||||
import django.utils.timezone as timezone
|
import django.utils.timezone as timezone
|
||||||
from django.db.models.query import QuerySet
|
from django.db.models.query import QuerySet
|
||||||
|
from apps.pum.models import PuOrder, PuOrderItem, Vendor
|
||||||
from apps.system.models import CommonADModel, CommonAModel, CommonBModel, Organization, User, Dict, File
|
from apps.system.models import CommonADModel, CommonAModel, CommonBModel, Organization, User, Dict, File
|
||||||
from utils.model import SoftModel, BaseModel
|
from utils.model import SoftModel, BaseModel
|
||||||
from simple_history.models import HistoricalRecords
|
from simple_history.models import HistoricalRecords
|
||||||
|
@ -72,12 +73,17 @@ class FIFO(CommonADModel):
|
||||||
(FIFO_TYPE_PUR_IN, '采购入库'),
|
(FIFO_TYPE_PUR_IN, '采购入库'),
|
||||||
(FIFO_TYPE_DO_IN, '生产入库')
|
(FIFO_TYPE_DO_IN, '生产入库')
|
||||||
)
|
)
|
||||||
|
number = models.CharField('记录编号', max_length=100)
|
||||||
type = models.IntegerField('出入库类型', default=1)
|
type = models.IntegerField('出入库类型', default=1)
|
||||||
is_audited = models.BooleanField('是否审核', default=False)
|
is_audited = models.BooleanField('是否审核', default=False)
|
||||||
auditor = models.ForeignKey(
|
auditor = models.ForeignKey(
|
||||||
User, verbose_name='审核人', on_delete=models.CASCADE, null=True, blank=True)
|
User, verbose_name='审核人', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
inout_date = models.DateField('出入库日期', null=True, blank=True)
|
inout_date = models.DateField('出入库日期', null=True, blank=True)
|
||||||
remark = models.CharField('备注', max_length=1000, default='')
|
remark = models.CharField('备注', max_length=1000, default='')
|
||||||
|
vendor = models.ForeignKey(Vendor, verbose_name='供应商',
|
||||||
|
on_delete=models.CASCADE, null=True, blank=True)
|
||||||
|
pu_order = models.ForeignKey(PuOrder, verbose_name='关联采购订单',
|
||||||
|
null=True, blank=True, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
|
||||||
class FIFOItem(BaseModel):
|
class FIFOItem(BaseModel):
|
||||||
|
@ -97,6 +103,8 @@ class FIFOItem(BaseModel):
|
||||||
subproduction_plan = models.ForeignKey(
|
subproduction_plan = models.ForeignKey(
|
||||||
SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True)
|
SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, null=True, blank=True)
|
||||||
files = models.ManyToManyField(File, verbose_name='上传材料', blank=True)
|
files = models.ManyToManyField(File, verbose_name='上传材料', blank=True)
|
||||||
|
pu_order_item = models.ForeignKey(PuOrderItem,
|
||||||
|
verbose_name='关联采购订单条目', null=True, blank=True, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
|
||||||
class IProduct(BaseModel):
|
class IProduct(BaseModel):
|
||||||
|
@ -116,14 +124,17 @@ class IProduct(BaseModel):
|
||||||
|
|
||||||
class FIFOItemProduct(BaseModel):
|
class FIFOItemProduct(BaseModel):
|
||||||
"""
|
"""
|
||||||
出入库产品
|
出入库记录具体产品
|
||||||
"""
|
"""
|
||||||
fifoitem = models.ForeignKey(
|
fifoitem = models.ForeignKey(
|
||||||
FIFOItem, verbose_name='关联出入库具体产品', on_delete=models.CASCADE)
|
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,
|
wproduct = models.ForeignKey('wpm.wproduct',
|
||||||
|
on_delete=models.CASCADE, verbose_name='关联的动态产品',
|
||||||
|
db_constraint=False, null=True, blank=True,
|
||||||
related_name='fifoitem_wproduct')
|
related_name='fifoitem_wproduct')
|
||||||
number = models.CharField('物品编号', max_length=50)
|
number = models.CharField('物品编号', max_length=50)
|
||||||
material = models.ForeignKey(
|
material = models.ForeignKey(
|
||||||
Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
Material, verbose_name='物料类型', on_delete=models.CASCADE)
|
||||||
iproduct = models.ForeignKey(
|
iproduct = models.ForeignKey(
|
||||||
IProduct, verbose_name='关联库存产品', null=True, blank=True, on_delete=models.SET_NULL)
|
IProduct, verbose_name='关联库存产品',
|
||||||
|
null=True, blank=True, on_delete=models.SET_NULL)
|
||||||
|
|
|
@ -2,6 +2,7 @@ from rest_framework import exceptions
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse, Inventory
|
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse, Inventory
|
||||||
|
from apps.pum.models import PuOrder, Vendor
|
||||||
from apps.qm.models import TestRecord, TestRecordItem
|
from apps.qm.models import TestRecord, TestRecordItem
|
||||||
from apps.sam.serializers import OrderSimpleSerializer
|
from apps.sam.serializers import OrderSimpleSerializer
|
||||||
|
|
||||||
|
@ -10,6 +11,8 @@ from apps.system.serializers import FileSimpleSerializer, UserSimpleSerializer
|
||||||
from apps.mtm.serializers import MaterialSimpleSerializer
|
from apps.mtm.serializers import MaterialSimpleSerializer
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from utils.mixins import DynamicFieldsSerializerMixin
|
from utils.mixins import DynamicFieldsSerializerMixin
|
||||||
|
from utils.tools import ranstr
|
||||||
|
from rest_framework.exceptions import ValidationError
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,6 +76,28 @@ class FIFOListSerializer(serializers.ModelSerializer):
|
||||||
model = FIFO
|
model = FIFO
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
class FIFOItemCreateSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = FIFOItem
|
||||||
|
fields = ['warehouse',
|
||||||
|
'material', 'batch', 'fifo', 'files', 'pu_order_item']
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
fifo = validated_data['fifo']
|
||||||
|
pu_order_item = validated_data.get('pu_order_item', None)
|
||||||
|
if pu_order_item:
|
||||||
|
if fifo.pu_order != pu_order_item.pu_order:
|
||||||
|
raise ValidationError('项目与采购订单不一致')
|
||||||
|
validated_data['material']=pu_order_item.material
|
||||||
|
else:
|
||||||
|
if fifo.pu_order is not None:
|
||||||
|
raise ValidationError('非采购订单')
|
||||||
|
return super().create(validated_data)
|
||||||
|
|
||||||
|
class FIFOItemUpdateSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = FIFOItem
|
||||||
|
fields = ['warehouse', 'batch', 'files']
|
||||||
|
|
||||||
class FIFOItemSerializer(serializers.ModelSerializer):
|
class FIFOItemSerializer(serializers.ModelSerializer):
|
||||||
warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True)
|
warehouse_ = WareHouseSimpleSerializer(source='warehouse', read_only=True)
|
||||||
|
@ -83,14 +108,14 @@ class FIFOItemSerializer(serializers.ModelSerializer):
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
class IProductInPurSerializer(serializers.ModelSerializer):
|
class FIFOItemProductCreateSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = IProduct
|
model = IProduct
|
||||||
fields = ['number']
|
fields = ['number']
|
||||||
|
|
||||||
|
|
||||||
class FIFODetailInPurSerializer(serializers.ModelSerializer):
|
class FIFODetailInPurSerializer(serializers.ModelSerializer):
|
||||||
details = IProductInPurSerializer(many=True, required=False)
|
details = FIFOItemProductCreateSerializer(many=True, required=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = FIFOItem
|
model = FIFOItem
|
||||||
|
@ -101,41 +126,26 @@ class MaterialBatchQuerySerializer(serializers.Serializer):
|
||||||
warehouse = serializers.IntegerField(label="仓库ID", required=False)
|
warehouse = serializers.IntegerField(label="仓库ID", required=False)
|
||||||
materials = serializers.ListField(child=serializers.IntegerField(label="物料ID"), required=False)
|
materials = serializers.ListField(child=serializers.IntegerField(label="物料ID"), required=False)
|
||||||
|
|
||||||
|
class FIFOInOtherSerializer(serializers.ModelSerializer):
|
||||||
class FIFOInPurSerializer(serializers.ModelSerializer):
|
|
||||||
"""
|
"""
|
||||||
采购入库序列化
|
其他入库序列化
|
||||||
"""
|
"""
|
||||||
details = FIFODetailInPurSerializer(many=True)
|
details = FIFODetailInPurSerializer(many=True, required=False)
|
||||||
|
vendor = serializers.PrimaryKeyRelatedField(label='供应商ID',
|
||||||
|
queryset=Vendor.objects.all())
|
||||||
class Meta:
|
class Meta:
|
||||||
model = FIFO
|
model = FIFO
|
||||||
fields = ['details']
|
fields = ['details', 'vendor']
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
details = validated_data.pop('details')
|
details = validated_data.pop('details')
|
||||||
if len(details) > 0:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
raise serializers.ValidationError('没有入库内容')
|
|
||||||
|
|
||||||
# for i in details:
|
|
||||||
# # 校验批次
|
|
||||||
# try:
|
|
||||||
# if i['batch']:
|
|
||||||
# obj = MaterialBatch.objects.get(batch=i['batch'], material=i['material'])
|
|
||||||
# if obj.warehouse != validated_data['warehouse']:
|
|
||||||
# raise serializers.ValidationError('批次号{}在其他仓库已存在'.format(i['batch']))
|
|
||||||
# except:
|
|
||||||
# pass
|
|
||||||
|
|
||||||
# 创建采购入库
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
validated_data['type'] = FIFO.FIFO_TYPE_PUR_IN
|
validated_data['type'] = FIFO.FIFO_TYPE_PUR_IN
|
||||||
obj = FIFO(**validated_data)
|
obj = FIFO(**validated_data)
|
||||||
obj.save()
|
obj.save()
|
||||||
for i in details:
|
for i in details:
|
||||||
if 'details' in i:
|
if 'details' in i:
|
||||||
|
i['number'] = 'RK' + ranstr(7)
|
||||||
p_details = i.pop('details')
|
p_details = i.pop('details')
|
||||||
if len(p_details) != i['count']:
|
if len(p_details) != i['count']:
|
||||||
raise serializers.ValidationError('数目对不上')
|
raise serializers.ValidationError('数目对不上')
|
||||||
|
@ -148,19 +158,30 @@ class FIFOInPurSerializer(serializers.ModelSerializer):
|
||||||
x['fifoitem'] = fifoitem
|
x['fifoitem'] = fifoitem
|
||||||
p_list0.append(FIFOItemProduct(**x))
|
p_list0.append(FIFOItemProduct(**x))
|
||||||
FIFOItemProduct.objects.bulk_create(p_list0)
|
FIFOItemProduct.objects.bulk_create(p_list0)
|
||||||
|
|
||||||
p_list = []
|
|
||||||
for x in p_details:
|
|
||||||
x['material'] = i['material']
|
|
||||||
x['warehouse'] = validated_data['warehouse']
|
|
||||||
x['batch'] = i['batch']
|
|
||||||
p_list.append(IProduct(**x))
|
|
||||||
IProduct.objects.bulk_create(p_list)
|
|
||||||
else:
|
else:
|
||||||
i['fifo'] = obj
|
i['fifo'] = obj
|
||||||
|
i['number'] = 'RK' + ranstr(7)
|
||||||
FIFOItem.objects.create(**i)
|
FIFOItem.objects.create(**i)
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
class FIFOInPurSerializer(serializers.ModelSerializer):
|
||||||
|
"""
|
||||||
|
采购入库序列化
|
||||||
|
"""
|
||||||
|
pu_order = serializers.PrimaryKeyRelatedField(label='采购订单ID',
|
||||||
|
queryset = PuOrder.objects.filter(is_audited=True))
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = FIFO
|
||||||
|
fields = ['pu_order']
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
pu_order = validated_data['pu_order']
|
||||||
|
validated_data['vendor'] = pu_order.vendor
|
||||||
|
validated_data['number'] = 'RK' + ranstr(7)
|
||||||
|
obj = FIFO.objects.create(**validated_data)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
class InmTestRecordItemCreateSerializer(serializers.ModelSerializer):
|
class InmTestRecordItemCreateSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
from rest_framework.exceptions import ValidationError
|
||||||
|
from apps.inm.models import FIFOItemProduct, IProduct, Inventory, MaterialBatch, FIFO, FIFOItem
|
||||||
|
|
||||||
|
class InmService:
|
||||||
|
@classmethod
|
||||||
|
def update_inm(cls, instance:FIFO, type:int=1):
|
||||||
|
"""
|
||||||
|
更新库存(正反)
|
||||||
|
"""
|
||||||
|
if instance.type in [FIFO.FIFO_TYPE_PUR_IN, FIFO.FIFO_TYPE_DO_IN]: # 采购入库, 生产入库
|
||||||
|
# 更新相关表
|
||||||
|
for i in FIFOItem.objects.filter(fifo=instance):
|
||||||
|
material = i.material
|
||||||
|
warehouse = i.warehouse
|
||||||
|
o1, _ = Inventory.objects.get_or_create(material=material, warehouse=warehouse, \
|
||||||
|
defaults={'material':material, 'warehouse':warehouse, 'count':0})
|
||||||
|
o1.count = o1.count + i.count
|
||||||
|
o1.save()
|
||||||
|
o2, _ = MaterialBatch.objects.get_or_create(material=material, warehouse=warehouse, batch=i.batch,\
|
||||||
|
defaults={'material':material, 'warehouse':warehouse, 'count':0, 'batch':i.batch})
|
||||||
|
o2.count = o2.count + i.count
|
||||||
|
o2.save()
|
||||||
|
material.count = material.count + i.count
|
||||||
|
material.save()
|
||||||
|
|
||||||
|
# 创建IProduct
|
||||||
|
ips2 = []
|
||||||
|
for m in FIFOItemProduct.objects.filter(fifoitem=i):
|
||||||
|
ip = {}
|
||||||
|
ip['warehouse'] = warehouse
|
||||||
|
ip['batch'] = i.batch
|
||||||
|
wp = m.wproduct
|
||||||
|
ip['wproduct'] = wp
|
||||||
|
ip['number'] = m.number
|
||||||
|
ip['material'] = m.material
|
||||||
|
ips2.append(IProduct(**ip))
|
||||||
|
IProduct.objects.bulk_create(ips2)
|
||||||
|
|
||||||
|
# 如果是采购入库更新采购订单表
|
||||||
|
if instance.type == FIFO.FIFO_TYPE_PUR_IN:
|
||||||
|
pur_order_item = i.pur_order_item
|
||||||
|
delivered_count = pur_order_item.delivered_count + i.count
|
||||||
|
if delivered_count > pur_order_item.count:
|
||||||
|
raise ValidationError('超出采购订单所需量')
|
||||||
|
pur_order_item.delivered_count = delivered_count
|
||||||
|
pur_order_item.save()
|
||||||
|
|
||||||
|
elif instance.type in [FIFO.FIFO_TYPE_DO_OUT, FIFO.FIFO_TYPE_SALE_OUT]: # 生产领料 销售出库
|
||||||
|
# 更新相关表
|
||||||
|
for i in FIFOItem.objects.filter(fifo=instance):
|
||||||
|
material = i.material
|
||||||
|
warehouse = i.warehouse
|
||||||
|
o1 = Inventory.objects.get(material=material, warehouse=warehouse)
|
||||||
|
temp_count = o1.count - i.count
|
||||||
|
if temp_count < 0:
|
||||||
|
raise ValidationError('库存不足,操作失败')
|
||||||
|
o1.count = temp_count
|
||||||
|
o1.save()
|
||||||
|
o2 = MaterialBatch.objects.get(material=material, warehouse=warehouse, batch=i.batch)
|
||||||
|
temp_count = o2.count - i.count
|
||||||
|
if temp_count < 0:
|
||||||
|
raise ValidationError('库存不足,操作失败')
|
||||||
|
o2.count = temp_count
|
||||||
|
o2.save()
|
||||||
|
temp_count = material.count - i.count
|
||||||
|
if temp_count < 0:
|
||||||
|
raise ValidationError('库存不足,操作失败')
|
||||||
|
material.count = temp_count
|
||||||
|
material.save()
|
||||||
|
|
||||||
|
# 删除IProduct
|
||||||
|
if instance.type == FIFO.FIFO_TYPE_DO_OUT:
|
||||||
|
# 生产领料的情况直接从IProduct中删除
|
||||||
|
numbers = FIFOItemProduct.objects.filter(fifoitem=i).values_list('number', flat=True)
|
||||||
|
IProduct.objects.filter(number__in=numbers).delete()
|
|
@ -1,58 +0,0 @@
|
||||||
from django.db.models.signals import post_save
|
|
||||||
from django.dispatch import receiver
|
|
||||||
|
|
||||||
from apps.inm.models import FIFOItemProduct, IProduct, Inventory, MaterialBatch, FIFO, FIFOItem
|
|
||||||
|
|
||||||
|
|
||||||
def update_inm(instance:FIFO, type:int=1):
|
|
||||||
"""
|
|
||||||
更新库存(正反)
|
|
||||||
"""
|
|
||||||
if instance.type in [FIFO.FIFO_TYPE_PUR_IN, FIFO.FIFO_TYPE_DO_IN]: # 采购入库, 生产入库
|
|
||||||
# 更新相关表
|
|
||||||
for i in FIFOItem.objects.filter(fifo=instance):
|
|
||||||
material = i.material
|
|
||||||
warehouse = i.warehouse
|
|
||||||
o1, _ = Inventory.objects.get_or_create(material=material, warehouse=warehouse, \
|
|
||||||
defaults={'material':material, 'warehouse':warehouse, 'count':0})
|
|
||||||
o1.count = o1.count + i.count
|
|
||||||
o1.save()
|
|
||||||
o2, _ = MaterialBatch.objects.get_or_create(material=material, warehouse=warehouse, batch=i.batch,\
|
|
||||||
defaults={'material':material, 'warehouse':warehouse, 'count':0, 'batch':i.batch})
|
|
||||||
o2.count = o2.count + i.count
|
|
||||||
o2.save()
|
|
||||||
material.count = material.count + i.count
|
|
||||||
material.save()
|
|
||||||
|
|
||||||
# 创建IProduct
|
|
||||||
ips2 = []
|
|
||||||
for m in FIFOItemProduct.objects.filter(fifoitem=i):
|
|
||||||
ip = {}
|
|
||||||
ip['warehouse'] = warehouse
|
|
||||||
ip['batch'] = i.batch
|
|
||||||
wp = m.wproduct
|
|
||||||
ip['wproduct'] = wp
|
|
||||||
ip['number'] = m.number
|
|
||||||
ip['material'] = m.material
|
|
||||||
ips2.append(IProduct(**ip))
|
|
||||||
IProduct.objects.bulk_create(ips2)
|
|
||||||
|
|
||||||
elif instance.type in [FIFO.FIFO_TYPE_DO_OUT, FIFO.FIFO_TYPE_SALE_OUT]: # 生产领料 销售出库
|
|
||||||
# 更新相关表
|
|
||||||
for i in FIFOItem.objects.filter(fifo=instance):
|
|
||||||
material = i.material
|
|
||||||
warehouse = i.warehouse
|
|
||||||
o1 = Inventory.objects.get(material=material, warehouse=warehouse)
|
|
||||||
o1.count = o1.count - i.count
|
|
||||||
o1.save()
|
|
||||||
o2 = MaterialBatch.objects.get(material=material, warehouse=warehouse, batch=i.batch)
|
|
||||||
o2.count = o2.count - i.count
|
|
||||||
o2.save()
|
|
||||||
material.count = material.count - i.count
|
|
||||||
material.save()
|
|
||||||
|
|
||||||
# 删除IProduct
|
|
||||||
if instance.type == FIFO.FIFO_TYPE_DO_OUT:
|
|
||||||
numbers = FIFOItemProduct.objects.filter(fifoitem=i).values_list('number', flat=True)
|
|
||||||
IProduct.objects.filter(number__in=numbers).delete()
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework import exceptions
|
from rest_framework import exceptions
|
||||||
from rest_framework.exceptions import APIException
|
from rest_framework.exceptions import APIException, ValidationError
|
||||||
from rest_framework.mixins import DestroyModelMixin, ListModelMixin, UpdateModelMixin
|
from rest_framework.mixins import DestroyModelMixin, ListModelMixin, UpdateModelMixin, CreateModelMixin
|
||||||
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, FIFOItemUpdateSerializer, FIFOListSerializer, IProductListSerializer, \
|
from apps.inm.serializers import FIFOInOtherSerializer, FIFOItemCreateSerializer, FIFOItemSerializer, FIFOInPurSerializer, FIFOItemUpdateSerializer, FIFOListSerializer, IProductListSerializer, \
|
||||||
InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, \
|
InmTestRecordCreateSerializer, MaterialBatchQuerySerializer, MaterialBatchSerializer, WareHouseSerializer, \
|
||||||
WareHouseCreateUpdateSerializer, InventorySerializer
|
WareHouseCreateUpdateSerializer, InventorySerializer
|
||||||
from apps.inm.signals import update_inm
|
from apps.inm.services import InmService
|
||||||
from apps.qm.models import TestRecordItem
|
from apps.qm.models import TestRecordItem
|
||||||
from apps.system.mixins import CreateUpdateModelAMixin
|
from apps.system.mixins import CreateUpdateModelAMixin
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
|
@ -77,7 +77,7 @@ class MaterialBatchViewSet(ListModelMixin, GenericViewSet):
|
||||||
return Response(MaterialBatchSerializer(instance=queryset, many=True).data)
|
return Response(MaterialBatchSerializer(instance=queryset, many=True).data)
|
||||||
|
|
||||||
|
|
||||||
class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin, GenericViewSet):
|
class FIFOItemViewSet(ListModelMixin, CreateModelMixin, DestroyModelMixin, UpdateModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
出入库记录详情表
|
出入库记录详情表
|
||||||
"""
|
"""
|
||||||
|
@ -93,12 +93,27 @@ class FIFOItemViewSet(ListModelMixin, DestroyModelMixin, UpdateModelMixin, Gener
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
if self.action == 'update':
|
if self.action == 'update':
|
||||||
return FIFOItemUpdateSerializer
|
return FIFOItemUpdateSerializer
|
||||||
|
elif self.action == 'create':
|
||||||
|
return FIFOItemCreateSerializer
|
||||||
return super().get_serializer_class()
|
return super().get_serializer_class()
|
||||||
|
|
||||||
def perform_destroy(self, instance):
|
def create(self, request, *args, **kwargs):
|
||||||
if instance.fifo.is_audited:
|
obj = self.get_object()
|
||||||
raise APIException('该出入库记录已通过审核, 无法删除')
|
if obj.fifo.is_audited:
|
||||||
return super().perform_destroy(instance)
|
raise ValidationError('该出入库记录已审核')
|
||||||
|
return super().create(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def update(self, request, *args, **kwargs):
|
||||||
|
obj = self.get_object()
|
||||||
|
if obj.fifo.is_audited:
|
||||||
|
raise ValidationError('该出入库记录已审核')
|
||||||
|
return super().update(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def destroy(self, request, *args, **kwargs):
|
||||||
|
obj = self.get_object()
|
||||||
|
if obj.fifo.is_audited:
|
||||||
|
raise ValidationError('该出入库记录已审核')
|
||||||
|
return super().destroy(request, *args, **kwargs)
|
||||||
|
|
||||||
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=InmTestRecordCreateSerializer)
|
@action(methods=['post'], detail=False, perms_map={'post': '*'}, serializer_class=InmTestRecordCreateSerializer)
|
||||||
def test(self, request, pk=None):
|
def test(self, request, pk=None):
|
||||||
|
@ -161,12 +176,25 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
serializer.save(create_by=request.user)
|
serializer.save(create_by=request.user)
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False, perms_map={'post': '*'},
|
||||||
|
serializer_class=FIFOInOtherSerializer)
|
||||||
|
def in_other(self, request, pk=None):
|
||||||
|
"""
|
||||||
|
其他入库
|
||||||
|
"""
|
||||||
|
serializer = self.get_serializer(data=request.data)
|
||||||
|
serializer.is_valid(raise_exception=True)
|
||||||
|
serializer.save(create_by=request.user)
|
||||||
|
return Response()
|
||||||
|
|
||||||
@action(methods=['post'], detail=True, perms_map={'post': '*'}, serializer_class=serializers.Serializer)
|
@action(methods=['post'], detail=True, perms_map={'post': '*'}, serializer_class=serializers.Serializer)
|
||||||
def audit(self, request, pk=None):
|
def audit(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
审核通过
|
审核通过
|
||||||
"""
|
"""
|
||||||
obj = self.get_object()
|
obj = self.get_object()
|
||||||
|
if not FIFOItem.objects.filter(fifo=obj).exists():
|
||||||
|
raise ValidationError('出入库条目为空')
|
||||||
for i in FIFOItem.objects.filter(fifo=obj, need_test=True):
|
for i in FIFOItem.objects.filter(fifo=obj, need_test=True):
|
||||||
if not i.is_testok:
|
if not i.is_testok:
|
||||||
raise APIException('未检验通过, 不可审核')
|
raise APIException('未检验通过, 不可审核')
|
||||||
|
@ -177,7 +205,7 @@ class FIFOViewSet(ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
obj.auditor = request.user
|
obj.auditor = request.user
|
||||||
obj.inout_date = timezone.now() # 也是审核日期
|
obj.inout_date = timezone.now() # 也是审核日期
|
||||||
obj.save()
|
obj.save()
|
||||||
update_inm(obj) # 更新库存
|
InmService.update_inm(obj) # 更新库存
|
||||||
return Response()
|
return Response()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
# Generated by Django 3.2.9 on 2022-01-27 07:47
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('mtm', '0044_subproduction_need_combtest'),
|
||||||
|
('pum', '0003_remove_vendor_material'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='PuOrder',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||||
|
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||||
|
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||||
|
('number', models.CharField(max_length=100, unique=True, verbose_name='订单编号')),
|
||||||
|
('is_audited', models.BooleanField(default=False, verbose_name='是否审核')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='puorder_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='puorder_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
('vendor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pum.vendor', verbose_name='供应商')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': '采购订单',
|
||||||
|
'verbose_name_plural': '采购订单',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='PuOrderItem',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||||
|
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||||
|
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||||
|
('count', models.PositiveIntegerField(default=0, verbose_name='所需数量')),
|
||||||
|
('delivered_count', models.PositiveIntegerField(default=0, verbose_name='已到货数量')),
|
||||||
|
('delivery_date', models.DateField(verbose_name='截止到货日期')),
|
||||||
|
('material', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.material', verbose_name='采购材料')),
|
||||||
|
('pu_order', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='item_pu_order', to='pum.puorder', verbose_name='关联采购订单')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -5,7 +5,7 @@ from django.db.models.query import QuerySet
|
||||||
from apps.system.models import CommonAModel, CommonBModel, Organization, User, Dict, File
|
from apps.system.models import CommonAModel, CommonBModel, Organization, User, Dict, File
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
class Vendor(CommonAModel):
|
class Vendor(CommonAModel):
|
||||||
|
@ -24,3 +24,25 @@ class Vendor(CommonAModel):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
class PuOrder(CommonAModel):
|
||||||
|
"""
|
||||||
|
采购订单信息
|
||||||
|
"""
|
||||||
|
number = models.CharField('订单编号', max_length=100, unique=True)
|
||||||
|
vendor = models.ForeignKey(Vendor, verbose_name='供应商', on_delete=models.CASCADE)
|
||||||
|
is_audited = models.BooleanField('是否审核', default=False)
|
||||||
|
class Meta:
|
||||||
|
verbose_name = '采购订单'
|
||||||
|
verbose_name_plural = verbose_name
|
||||||
|
|
||||||
|
class PuOrderItem(BaseModel):
|
||||||
|
"""
|
||||||
|
采购具体项目
|
||||||
|
"""
|
||||||
|
material = models.ForeignKey(Material, verbose_name='采购材料', on_delete=models.CASCADE)
|
||||||
|
count = models.PositiveIntegerField('所需数量', default=0)
|
||||||
|
delivered_count = models.PositiveIntegerField('已到货数量', default=0)
|
||||||
|
delivery_date = models.DateField('截止到货日期')
|
||||||
|
pu_order = models.ForeignKey(PuOrder, verbose_name='关联采购订单',
|
||||||
|
on_delete=models.CASCADE, null=True, blank=True, related_name='item_pu_order')
|
|
@ -1,9 +1,47 @@
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework.serializers import ModelSerializer, ValidationError
|
||||||
|
from apps.mtm.serializers import MaterialSimpleSerializer
|
||||||
from .models import Vendor
|
from .models import PuOrder, PuOrderItem, Vendor
|
||||||
|
|
||||||
|
|
||||||
class VendorSerializer(ModelSerializer):
|
class VendorSerializer(ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Vendor
|
model = Vendor
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
class VendorSimpleSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Vendor
|
||||||
|
fields = ['id', 'name']
|
||||||
|
|
||||||
|
class PuOrderItemSerializer(ModelSerializer):
|
||||||
|
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = PuOrderItem
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
class PuOrderItemCreateSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = PuOrderItem
|
||||||
|
fields = ['count', 'delivery_date', 'pu_order', 'material']
|
||||||
|
|
||||||
|
def validate(self, attrs):
|
||||||
|
pu_order = attrs['pu_order']
|
||||||
|
if pu_order.is_audited:
|
||||||
|
raise ValidationError('采购订单已审核')
|
||||||
|
return super().validate(attrs)
|
||||||
|
|
||||||
|
class PuOrderItemUpdateSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = PuOrderItem
|
||||||
|
fields = ['count', 'delivery_date']
|
||||||
|
|
||||||
|
class PuOrderSerializer(ModelSerializer):
|
||||||
|
vendor_ = VendorSimpleSerializer(source='vendor', read_only=True)
|
||||||
|
items = PuOrderItemSerializer(source='item_pu_order', many=True, read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = PuOrder
|
||||||
|
fields = '__all__'
|
||||||
|
|
||||||
|
class PuOrderCreateUpdateSerializer(ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = PuOrder
|
||||||
|
fields = ['number', 'vendor']
|
|
@ -1,11 +1,13 @@
|
||||||
from django.db.models import base
|
from django.db.models import base
|
||||||
from rest_framework import urlpatterns
|
from rest_framework import urlpatterns
|
||||||
from apps.pum.views import VendorViewSet
|
from apps.pum.views import PuOrderItemViewSet, PuOrderViewSet, VendorViewSet
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
router = DefaultRouter()
|
router = DefaultRouter()
|
||||||
router.register('vendor', VendorViewSet, basename='vendor')
|
router.register('vendor', VendorViewSet, basename='vendor')
|
||||||
|
router.register('pu_order', PuOrderViewSet, basename='pu_order')
|
||||||
|
router.register('pu_order_item', PuOrderItemViewSet, basename='pu_order_item')
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', include(router.urls)),
|
path('', include(router.urls)),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,11 +1,17 @@
|
||||||
|
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
from numpy import delete
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin
|
||||||
from apps.pum.models import Vendor
|
from rest_framework.viewsets import GenericViewSet
|
||||||
from apps.pum.serializers import VendorSerializer
|
from apps.pum.models import PuOrder, PuOrderItem, Vendor
|
||||||
|
from apps.pum.serializers import PuOrderCreateUpdateSerializer, PuOrderItemCreateSerializer, PuOrderItemSerializer, PuOrderItemUpdateSerializer, PuOrderSerializer, VendorSerializer
|
||||||
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
||||||
|
from rest_framework.exceptions import APIException, ValidationError
|
||||||
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework import serializers
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework import status
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
class VendorViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
class VendorViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||||
"""
|
"""
|
||||||
|
@ -19,3 +25,69 @@ class VendorViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||||
filterset_fields = []
|
filterset_fields = []
|
||||||
ordering_fields = ['create_time']
|
ordering_fields = ['create_time']
|
||||||
ordering = ['-create_time']
|
ordering = ['-create_time']
|
||||||
|
|
||||||
|
|
||||||
|
class PuOrderViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||||
|
"""
|
||||||
|
采购订单-增删改查
|
||||||
|
"""
|
||||||
|
perms_map = {'get': '*', 'post': '*',
|
||||||
|
'put': '*', 'delete': '*'}
|
||||||
|
queryset = PuOrder.objects.select_related('vendor').\
|
||||||
|
prefetch_related('item_pu_order').all()
|
||||||
|
serializer_class = PuOrderSerializer
|
||||||
|
search_fields = ['number', 'vendor__name']
|
||||||
|
filterset_fields = ['vendor']
|
||||||
|
ordering = ['-create_time']
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
if self.action in ['create', 'update']:
|
||||||
|
return PuOrderCreateUpdateSerializer
|
||||||
|
return super().get_serializer_class()
|
||||||
|
|
||||||
|
def update(self, request, *args, **kwargs):
|
||||||
|
obj = self.get_object()
|
||||||
|
if obj.is_audited:
|
||||||
|
raise ValidationError('该采购订单已审核')
|
||||||
|
return super().update(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def destroy(self, request, *args, **kwargs):
|
||||||
|
obj = self.get_object()
|
||||||
|
if obj.is_audited:
|
||||||
|
raise ValidationError('该采购订单已审核')
|
||||||
|
return super().destroy(request, *args, **kwargs)
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=True, perms_map={'post':'*'},
|
||||||
|
serializer_class=serializers.Serializer)
|
||||||
|
def audit(self, request, pk=None):
|
||||||
|
obj = self.get_object()
|
||||||
|
if obj.item_pu_order.exists() and not obj.is_audited:
|
||||||
|
obj.is_audited = True
|
||||||
|
obj.update_by = request.user
|
||||||
|
obj.save()
|
||||||
|
return Response()
|
||||||
|
return Response('订单状态有误', status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
class PuOrderItemViewSet(CreateModelMixin, ListModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
|
"""
|
||||||
|
采购订单条目
|
||||||
|
"""
|
||||||
|
perms_map = {'get': '*', 'post': '*',
|
||||||
|
'put': '*', 'delete': '*'}
|
||||||
|
queryset = PuOrderItem.objects.select_related('material').all()
|
||||||
|
serializer_class = PuOrderItemSerializer
|
||||||
|
filterset_fields = ['pu_order', 'material']
|
||||||
|
ordering = ['-create_time']
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
if self.action == 'create':
|
||||||
|
return PuOrderItemCreateSerializer
|
||||||
|
elif self.action == 'update':
|
||||||
|
return PuOrderItemUpdateSerializer
|
||||||
|
return super().get_serializer_class()
|
||||||
|
|
||||||
|
def destroy(self, request, *args, **kwargs):
|
||||||
|
obj = self.get_object()
|
||||||
|
if obj.pu_order.is_audited:
|
||||||
|
raise ValidationError('所属采购已审核')
|
||||||
|
return super().destroy(request, *args, **kwargs)
|
|
@ -73,7 +73,7 @@ class TestRecord(CommonADModel):
|
||||||
remark = models.TextField('备注', default='')
|
remark = models.TextField('备注', default='')
|
||||||
|
|
||||||
|
|
||||||
class TestRecordItem(BaseModel):
|
class TestRecordItem(CommonADModel):
|
||||||
"""
|
"""
|
||||||
记录表格字段值
|
记录表格字段值
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -124,13 +124,17 @@ class TestRecordUpdateSerializer(serializers.ModelSerializer):
|
||||||
fields = ['is_testok', 'record_data']
|
fields = ['is_testok', 'record_data']
|
||||||
|
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data):
|
||||||
|
# 获取更新人
|
||||||
|
update_by = self.context['request'].user
|
||||||
record_data = validated_data.pop('record_data')
|
record_data = validated_data.pop('record_data')
|
||||||
for attr, value in validated_data.items():
|
for attr, value in validated_data.items():
|
||||||
setattr(instance, attr, value)
|
setattr(instance, attr, value)
|
||||||
instance.save()
|
instance.save(update_by=update_by)
|
||||||
for i in record_data:
|
for i in record_data:
|
||||||
tri = i['id']
|
tri = i['id']
|
||||||
|
if i['field_value'] != tri.field_value:
|
||||||
tri.field_value = i['field_value']
|
tri.field_value = i['field_value']
|
||||||
|
tri.update_by = update_by
|
||||||
tri.is_testok = i['is_testok']
|
tri.is_testok = i['is_testok']
|
||||||
tri.is_hidden = i['is_hidden']
|
tri.is_hidden = i['is_hidden']
|
||||||
tri.save()
|
tri.save()
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 3.2.9 on 2022-01-27 07:47
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('sam', '0011_order_need_mtest'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='order',
|
||||||
|
name='delivery_date',
|
||||||
|
field=models.DateField(verbose_name='截止交货日期'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -58,7 +58,7 @@ class Order(CommonAModel):
|
||||||
count = models.PositiveIntegerField('所需数量', default=0)
|
count = models.PositiveIntegerField('所需数量', default=0)
|
||||||
planed_count = models.PositiveIntegerField('已排数量', default=0)
|
planed_count = models.PositiveIntegerField('已排数量', default=0)
|
||||||
delivered_count = models.PositiveIntegerField('已交货数量', default=0)
|
delivered_count = models.PositiveIntegerField('已交货数量', default=0)
|
||||||
delivery_date = models.DateField('交货日期')
|
delivery_date = models.DateField('截止交货日期')
|
||||||
need_mtest = models.BooleanField('是否需要军检', default=False)
|
need_mtest = models.BooleanField('是否需要军检', default=False)
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '订单信息'
|
verbose_name = '订单信息'
|
||||||
|
|
|
@ -2,6 +2,7 @@ from rest_framework.mixins import ListModelMixin, DestroyModelMixin, CreateModel
|
||||||
from rest_framework.viewsets import GenericViewSet
|
from rest_framework.viewsets import GenericViewSet
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, WareHouse
|
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, WareHouse
|
||||||
|
from apps.inm.services import InmService
|
||||||
from apps.mtm.models import Material
|
from apps.mtm.models import Material
|
||||||
from apps.sam.models import Sale, SaleProduct
|
from apps.sam.models import Sale, SaleProduct
|
||||||
from apps.sam.serializers_sale import SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer
|
from apps.sam.serializers_sale import SaleCreateSerializer, SaleListSerializer, SaleProductCreateSerializer, SaleProductListSerializer
|
||||||
|
@ -11,10 +12,11 @@ from rest_framework.decorators import action
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from apps.system.mixins import CreateUpdateModelAMixin
|
from apps.system.mixins import CreateUpdateModelAMixin
|
||||||
from apps.inm.signals import update_inm
|
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
|
|
||||||
|
from utils.tools import ranstr
|
||||||
|
|
||||||
class SaleViewSet(CreateUpdateModelAMixin, ListModelMixin, RetrieveModelMixin, CreateModelMixin, DestroyModelMixin, GenericViewSet):
|
class SaleViewSet(CreateUpdateModelAMixin, ListModelMixin, RetrieveModelMixin, CreateModelMixin, DestroyModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
销售记录
|
销售记录
|
||||||
|
@ -71,6 +73,7 @@ class SaleViewSet(CreateUpdateModelAMixin, ListModelMixin, RetrieveModelMixin, C
|
||||||
fifo.auditor = request.user
|
fifo.auditor = request.user
|
||||||
fifo.inout_date = timezone.now()
|
fifo.inout_date = timezone.now()
|
||||||
fifo.create_by = request.user
|
fifo.create_by = request.user
|
||||||
|
fifo.number = 'CK' + ranstr(7)
|
||||||
fifo.save()
|
fifo.save()
|
||||||
# 创建出库条目
|
# 创建出库条目
|
||||||
ips = IProduct.objects.filter(sale_iproduct__sale=obj)
|
ips = IProduct.objects.filter(sale_iproduct__sale=obj)
|
||||||
|
@ -104,7 +107,7 @@ class SaleViewSet(CreateUpdateModelAMixin, ListModelMixin, RetrieveModelMixin, C
|
||||||
WProduct.objects.filter(iproduct_wproduct__sale_iproduct__sale=obj).update(
|
WProduct.objects.filter(iproduct_wproduct__sale_iproduct__sale=obj).update(
|
||||||
act_state=WProduct.WPR_ACT_STATE_SELLED)
|
act_state=WProduct.WPR_ACT_STATE_SELLED)
|
||||||
# 更新库存
|
# 更新库存
|
||||||
update_inm(fifo)
|
InmService.update_inm(fifo)
|
||||||
# 变更审核状态
|
# 变更审核状态
|
||||||
obj.is_audited = True
|
obj.is_audited = True
|
||||||
obj.save()
|
obj.save()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
from numpy import number
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.generics import ListAPIView, CreateAPIView
|
from rest_framework.generics import ListAPIView, CreateAPIView
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
@ -78,10 +79,11 @@ class AtWorkCountView(CreateAPIView):
|
||||||
serializer.is_valid(raise_exception=True)
|
serializer.is_valid(raise_exception=True)
|
||||||
vdata = serializer.validated_data
|
vdata = serializer.validated_data
|
||||||
ret = ClockRecord.objects.filter(
|
ret = ClockRecord.objects.filter(
|
||||||
create_time__year = vdata['year'],
|
update_time__year = vdata['year'],
|
||||||
create_time__month = vdata['month']
|
update_time__month = vdata['month']
|
||||||
).values(
|
).values(
|
||||||
user_id = F('create_by'),
|
user_id = F('create_by'),
|
||||||
|
number = F('create_by__employee_user__number'),
|
||||||
username = F('create_by__username'),
|
username = F('create_by__username'),
|
||||||
name = F('create_by__name'),
|
name = F('create_by__name'),
|
||||||
dept_name = F('create_by__dept__name')).annotate(
|
dept_name = F('create_by__dept__name')).annotate(
|
||||||
|
|
|
@ -4,8 +4,8 @@ from rest_framework.serializers import ModelSerializer
|
||||||
from apps.em.models import Equipment
|
from apps.em.models import Equipment
|
||||||
from apps.em.serializers import EquipmentSimpleSerializer
|
from apps.em.serializers import EquipmentSimpleSerializer
|
||||||
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse
|
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct, IProduct, MaterialBatch, WareHouse
|
||||||
from apps.inm.signals import update_inm
|
|
||||||
from apps.inm.serializers import WareHouseSimpleSerializer
|
from apps.inm.serializers import WareHouseSimpleSerializer
|
||||||
|
from apps.inm.services import InmService
|
||||||
from apps.mtm.models import Material, RecordForm, RecordFormField, Step, SubprodctionMaterial
|
from apps.mtm.models import Material, RecordForm, RecordFormField, Step, SubprodctionMaterial
|
||||||
from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer, RecordFormSimpleSerializer, StepSimpleSerializer
|
from apps.mtm.serializers import MaterialSimpleSerializer, ProcessSimpleSerializer, RecordFormSimpleSerializer, StepSimpleSerializer
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ from apps.wpm.models import Operation, OperationEquip, OperationMaterial, Operat
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from apps.sam.models import Order
|
from apps.sam.models import Order
|
||||||
from utils.mixins import DynamicFieldsSerializerMixin
|
from utils.mixins import DynamicFieldsSerializerMixin
|
||||||
|
from utils.tools import ranstr
|
||||||
|
|
||||||
class PickHalfSerializer(serializers.Serializer):
|
class PickHalfSerializer(serializers.Serializer):
|
||||||
id = serializers.PrimaryKeyRelatedField(queryset=SubProductionProgress.objects.all(), label='子计划进度ID')
|
id = serializers.PrimaryKeyRelatedField(queryset=SubProductionProgress.objects.all(), label='子计划进度ID')
|
||||||
|
@ -29,12 +30,14 @@ class PickHalfSerializer(serializers.Serializer):
|
||||||
|
|
||||||
class PickHalfsSerializer(serializers.ListSerializer):
|
class PickHalfsSerializer(serializers.ListSerializer):
|
||||||
child = PickHalfSerializer()
|
child = PickHalfSerializer()
|
||||||
|
|
||||||
class PickDetailSerializer(serializers.Serializer):
|
class PickDetailSerializer(serializers.Serializer):
|
||||||
material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label="物料ID")
|
material = serializers.PrimaryKeyRelatedField(queryset=Material.objects.all(), label="物料ID")
|
||||||
batch = serializers.CharField(label='物料批次', allow_blank=True)
|
batch = serializers.CharField(label='物料批次', allow_blank=True)
|
||||||
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
|
warehouse = serializers.PrimaryKeyRelatedField(queryset=WareHouse.objects.all(), label="仓库ID")
|
||||||
pick_count = serializers.IntegerField(label="领料数量", required=False)
|
pick_count = serializers.IntegerField(label="领料数量", required=False)
|
||||||
iproducts = serializers.PrimaryKeyRelatedField(queryset=IProduct.objects.all(), label='库存半成品ID',required=False, many=True)
|
iproducts = serializers.PrimaryKeyRelatedField(queryset=IProduct.objects.all(), label='库存半成品ID',
|
||||||
|
required=False, many=True)
|
||||||
|
|
||||||
class PickSerializer(serializers.Serializer):
|
class PickSerializer(serializers.Serializer):
|
||||||
subproduction_plan=serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID")
|
subproduction_plan=serializers.PrimaryKeyRelatedField(queryset=SubProductionPlan.objects.all(), label="子计划ID")
|
||||||
|
@ -58,7 +61,9 @@ class PickSerializer(serializers.Serializer):
|
||||||
# 创建出库记录
|
# 创建出库记录
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
fifo = FIFO.objects.create(type=FIFO.FIFO_TYPE_DO_OUT, inout_date=timezone.now(), create_by=self.context['request'].user)
|
fifo = FIFO.objects.create(type=FIFO.FIFO_TYPE_DO_OUT,
|
||||||
|
inout_date=timezone.now(), create_by=self.context['request'].user,
|
||||||
|
number = 'CK' + ranstr(7))
|
||||||
for i in picks:
|
for i in picks:
|
||||||
isLowLevel = False
|
isLowLevel = False
|
||||||
# 更新出库详情
|
# 更新出库详情
|
||||||
|
@ -123,7 +128,7 @@ class PickSerializer(serializers.Serializer):
|
||||||
# 更新库存
|
# 更新库存
|
||||||
fifo.is_audited = True
|
fifo.is_audited = True
|
||||||
fifo.save()
|
fifo.save()
|
||||||
update_inm(fifo)
|
InmService.update_inm(fifo)
|
||||||
return fifo
|
return fifo
|
||||||
|
|
||||||
class WMaterialListSerializer(serializers.ModelSerializer):
|
class WMaterialListSerializer(serializers.ModelSerializer):
|
||||||
|
|
|
@ -3,7 +3,7 @@ from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, \
|
||||||
ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
ListModelMixin, RetrieveModelMixin, UpdateModelMixin
|
||||||
from rest_framework.viewsets import GenericViewSet
|
from rest_framework.viewsets import GenericViewSet
|
||||||
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct
|
from apps.inm.models import FIFO, FIFOItem, FIFOItemProduct
|
||||||
from apps.inm.signals import update_inm
|
from apps.inm.services import InmService
|
||||||
from apps.mtm.models import Material, RecordForm, RecordFormField, Step, SubprodctionMaterial, TechDoc
|
from apps.mtm.models import Material, RecordForm, RecordFormField, Step, SubprodctionMaterial, TechDoc
|
||||||
from apps.mtm.serializers import RecordFormDetailSerializer, SubprodctionMaterialListSerializer, TechDocListSerializer
|
from apps.mtm.serializers import RecordFormDetailSerializer, SubprodctionMaterialListSerializer, TechDocListSerializer
|
||||||
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
||||||
|
@ -37,6 +37,8 @@ from django.utils import timezone
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
|
|
||||||
|
from utils.tools import ranstr
|
||||||
|
|
||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
|
@ -188,7 +190,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||||
raise exceptions.APIException('该产品当前状态不可检验')
|
raise exceptions.APIException('该产品当前状态不可检验')
|
||||||
|
|
||||||
savedict = dict(
|
savedict = dict(
|
||||||
create_by=self.request.user,
|
create_by=request.user,
|
||||||
wproduct=wproduct,
|
wproduct=wproduct,
|
||||||
material=wproduct.material,
|
material=wproduct.material,
|
||||||
number=wproduct.number,
|
number=wproduct.number,
|
||||||
|
@ -219,6 +221,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||||
tri.test_record = tr
|
tri.test_record = tr
|
||||||
tri.form_field = i
|
tri.form_field = i
|
||||||
tri.is_hidden = i.is_hidden
|
tri.is_hidden = i.is_hidden
|
||||||
|
tri.create_by = request.user
|
||||||
tri.save()
|
tri.save()
|
||||||
return Response(TestRecordDetailSerializer(instance=tr).data)
|
return Response(TestRecordDetailSerializer(instance=tr).data)
|
||||||
|
|
||||||
|
@ -242,9 +245,10 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||||
'subproduction_plan', 'material', 'subproduction_plan__number').annotate(total=Count('id'))
|
'subproduction_plan', 'material', 'subproduction_plan__number').annotate(total=Count('id'))
|
||||||
# 创建入库记录
|
# 创建入库记录
|
||||||
remark = vdata.get('remark', '')
|
remark = vdata.get('remark', '')
|
||||||
fifo = FIFO.objects.create(type=FIFO.FIFO_TYPE_DO_IN,
|
fifo = FIFO.objects.create(
|
||||||
|
type=FIFO.FIFO_TYPE_DO_IN,
|
||||||
is_audited=True, auditor=request.user, inout_date=timezone.now(),
|
is_audited=True, auditor=request.user, inout_date=timezone.now(),
|
||||||
create_by=request.user, remark=remark)
|
create_by=request.user, remark=remark, number='RK'+ranstr(7))
|
||||||
# 创建入库明细
|
# 创建入库明细
|
||||||
for i in wproducts_a:
|
for i in wproducts_a:
|
||||||
spi = SubProductionPlan.objects.get(pk=i['subproduction_plan'])
|
spi = SubProductionPlan.objects.get(pk=i['subproduction_plan'])
|
||||||
|
@ -270,7 +274,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||||
ips.append(FIFOItemProduct(**ip))
|
ips.append(FIFOItemProduct(**ip))
|
||||||
FIFOItemProduct.objects.bulk_create(ips)
|
FIFOItemProduct.objects.bulk_create(ips)
|
||||||
# 更新库存并修改半成品进行状态
|
# 更新库存并修改半成品进行状态
|
||||||
update_inm(fifo)
|
InmService.update_inm(fifo)
|
||||||
for i in wproducts:
|
for i in wproducts:
|
||||||
i.act_state = WProduct.WPR_ACT_STATE_INM
|
i.act_state = WProduct.WPR_ACT_STATE_INM
|
||||||
i.warehouse = warehouse
|
i.warehouse = warehouse
|
||||||
|
@ -320,7 +324,7 @@ class WProductViewSet(ListModelMixin, RetrieveModelMixin, GenericViewSet):
|
||||||
ips.append(FIFOItemProduct(**ip))
|
ips.append(FIFOItemProduct(**ip))
|
||||||
FIFOItemProduct.objects.bulk_create(ips)
|
FIFOItemProduct.objects.bulk_create(ips)
|
||||||
# 更新库存并修改半成品进行状态
|
# 更新库存并修改半成品进行状态
|
||||||
update_inm(fifo)
|
InmService.update_inm(fifo)
|
||||||
wproduct.act_state = WProduct.WPR_ACT_STATE_INM
|
wproduct.act_state = WProduct.WPR_ACT_STATE_INM
|
||||||
wproduct.warehouse = warehouse
|
wproduct.warehouse = warehouse
|
||||||
wproduct.save()
|
wproduct.save()
|
||||||
|
|
|
@ -11,3 +11,4 @@ psutil==5.8.0
|
||||||
pillow==8.3.1
|
pillow==8.3.1
|
||||||
opencv-python==4.5.3.56
|
opencv-python==4.5.3.56
|
||||||
django-celery-results==2.2.0
|
django-celery-results==2.2.0
|
||||||
|
numpy==1.21.2
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import os
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from rest_framework.parsers import MultiPartParser
|
from rest_framework.parsers import MultiPartParser
|
||||||
|
@ -6,10 +7,9 @@ from PIL import Image
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import os
|
|
||||||
import uuid
|
|
||||||
import cv2
|
import cv2
|
||||||
from server.settings import BASE_DIR
|
from server.settings import BASE_DIR
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
# class UploadFileView(APIView):
|
# class UploadFileView(APIView):
|
||||||
# permission_classes = [IsAuthenticated]
|
# permission_classes = [IsAuthenticated]
|
||||||
|
@ -39,16 +39,33 @@ class GenSignature(APIView):
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
path = (BASE_DIR + request.data['path']).replace('\\', '/')
|
path = (BASE_DIR + request.data['path']).replace('\\', '/')
|
||||||
|
try:
|
||||||
image = cv2.imread(path, cv2.IMREAD_UNCHANGED)
|
image = cv2.imread(path, cv2.IMREAD_UNCHANGED)
|
||||||
size = image.shape
|
size = image.shape
|
||||||
|
width = size[0] # 宽度
|
||||||
|
height = size[1] # 高度
|
||||||
|
if size[2] != 4: # 判断
|
||||||
|
background = np.zeros((size[0], size[1], 4))
|
||||||
|
for yh in range(height):
|
||||||
|
for xw in range(width):
|
||||||
|
background[xw, yh, :3] = image[xw, yh]
|
||||||
|
background[xw, yh, 3] = 255
|
||||||
|
image = background
|
||||||
|
size = image.shape
|
||||||
for i in range(size[0]):
|
for i in range(size[0]):
|
||||||
for j in range(size[1]):
|
for j in range(size[1]):
|
||||||
if image[i][j][0]>100 and image[i][j][1]>100 and image[i][j][2]>100:
|
if image[i][j][0]>100 and image[i][j][1]>100 and image[i][j][2]>100:
|
||||||
image[i][j][3] = 0
|
image[i][j][3] = 0
|
||||||
else:
|
else:
|
||||||
image[i][j][0],image[i][j][1],image[i][j][2] = 0,0,0
|
image[i][j][0],image[i][j][1],image[i][j][2] = 0,0,0
|
||||||
cv2.imwrite(path,image)
|
ext = os.path.splitext(path)
|
||||||
return Response(request.data, status=status.HTTP_200_OK)
|
new_path = ext[0] + '.png'
|
||||||
|
cv2.imwrite(new_path, image)
|
||||||
|
return Response({'path':new_path.replace(BASE_DIR, '')}, status=status.HTTP_200_OK)
|
||||||
|
except:
|
||||||
|
return Response('签名照处理失败,请重新上传',
|
||||||
|
status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
|
||||||
import time
|
import time
|
||||||
class UpdateDevelop(APIView):
|
class UpdateDevelop(APIView):
|
||||||
|
|
Loading…
Reference in New Issue