Merge branch 'develop' of https://e.coding.net/ctcdevteam/hberp/hberp into develop
This commit is contained in:
commit
1f7251211b
|
@ -5,6 +5,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'App',
|
name: 'App',
|
||||||
provide(){
|
provide(){
|
||||||
|
@ -15,17 +16,9 @@ export default {
|
||||||
data(){
|
data(){
|
||||||
return{
|
return{
|
||||||
isRouterAlive:true,
|
isRouterAlive:true,
|
||||||
timer:null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted(){
|
mounted(){
|
||||||
this.$store.dispatch("user/getCount", {});
|
|
||||||
this.timer = window.setInterval(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.$store.dispatch("user/getCount", {})
|
|
||||||
},0)
|
|
||||||
},30000)
|
|
||||||
|
|
||||||
},
|
},
|
||||||
methods:{
|
methods:{
|
||||||
reload(){
|
reload(){
|
||||||
|
@ -34,10 +27,8 @@ export default {
|
||||||
this.isRouterAlive=true;
|
this.isRouterAlive=true;
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
},
|
|
||||||
destroyed() {
|
|
||||||
clearInterval(this.timer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
import { Navbar, Sidebar, AppMain,TagsView } from './components'
|
import { Navbar, Sidebar, AppMain,TagsView } from './components'
|
||||||
import ResizeMixin from './mixin/ResizeHandler'
|
import ResizeMixin from './mixin/ResizeHandler'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
import { getToken } from '@/utils/auth' // get token from cookie
|
||||||
export default {
|
export default {
|
||||||
name: 'Layout',
|
name: 'Layout',
|
||||||
components: {
|
components: {
|
||||||
|
@ -57,6 +57,24 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
timer:null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
let hasToken = getToken();
|
||||||
|
if (hasToken) {
|
||||||
|
this.$store.dispatch("user/getCount", {});
|
||||||
|
}
|
||||||
|
this.timer = window.setInterval(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (hasToken) {
|
||||||
|
this.$store.dispatch("user/getCount", {});
|
||||||
|
}
|
||||||
|
},0)
|
||||||
|
},5000)
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleClickOutside() {
|
handleClickOutside() {
|
||||||
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
|
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
|
||||||
|
@ -70,6 +88,10 @@ export default {
|
||||||
this.$router.push({name:'ticket',params:{}})
|
this.$router.push({name:'ticket',params:{}})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
destroyed() {
|
||||||
|
clearInterval(this.timer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
# Generated by Django 3.2.6 on 2021-11-01 07:22
|
||||||
|
|
||||||
|
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', '0025_outputmaterial_is_main'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='SubplanMaterial',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('create_time', models.DateTimeField(default=django.utils.timezone.now, help_text='创建时间', verbose_name='创建时间')),
|
||||||
|
('update_time', models.DateTimeField(auto_now=True, help_text='修改时间', verbose_name='修改时间')),
|
||||||
|
('is_deleted', models.BooleanField(default=False, help_text='删除标记', verbose_name='删除标记')),
|
||||||
|
('is_main', models.BooleanField(default=False, verbose_name='是否主产出')),
|
||||||
|
('count', models.FloatField(default=1, verbose_name='消耗量/产出量')),
|
||||||
|
('type', models.IntegerField(default=1, verbose_name='物料应用类型')),
|
||||||
|
('sort', models.IntegerField(default=1, verbose_name='排序号')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subplanmaterial_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='outputmaterial',
|
||||||
|
name='create_by',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='outputmaterial',
|
||||||
|
name='material',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='outputmaterial',
|
||||||
|
name='subproduction',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='outputmaterial',
|
||||||
|
name='update_by',
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='material',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=100, verbose_name='物料名称'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='material',
|
||||||
|
name='type',
|
||||||
|
field=models.CharField(choices=[(1, '成品'), (2, '半成品'), (3, '主要原料'), (4, '辅助材料'), (5, '加工工具'), (6, '辅助工装')], default=1, max_length=20, verbose_name='物料类型'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='material',
|
||||||
|
name='unit',
|
||||||
|
field=models.CharField(choices=[('块', '块'), ('套', '套'), ('个', '个'), ('m2', 'm2'), ('瓶', '瓶')], default='块', max_length=10, verbose_name='基准计量单位'),
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='InputMaterial',
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='OutputMaterial',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subplanmaterial',
|
||||||
|
name='material',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subplan_material', to='mtm.material', verbose_name='物料'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subplanmaterial',
|
||||||
|
name='subproduction',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='mtm.subproduction', verbose_name='关联生产分解'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='subplanmaterial',
|
||||||
|
name='update_by',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='subplanmaterial_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -16,9 +16,9 @@ class Material(CommonAModel):
|
||||||
(1, '成品'),
|
(1, '成品'),
|
||||||
(2, '半成品'),
|
(2, '半成品'),
|
||||||
(3, '主要原料'),
|
(3, '主要原料'),
|
||||||
(4, '辅助原料') ,
|
(4, '辅助材料') ,
|
||||||
(5, '加工工具'),
|
(5, '加工工具'),
|
||||||
(6, '辅助工具')
|
(6, '辅助工装')
|
||||||
)
|
)
|
||||||
unit_choices =(
|
unit_choices =(
|
||||||
('块', '块'),
|
('块', '块'),
|
||||||
|
@ -27,7 +27,7 @@ class Material(CommonAModel):
|
||||||
('m2', 'm2'),
|
('m2', 'm2'),
|
||||||
('瓶', '瓶')
|
('瓶', '瓶')
|
||||||
)
|
)
|
||||||
name = models.CharField('物料名称', max_length=100, unique=True)
|
name = models.CharField('物料名称', max_length=100)
|
||||||
number = models.CharField('编号', max_length=100, unique=True)
|
number = models.CharField('编号', max_length=100, unique=True)
|
||||||
specification = models.CharField('型号', max_length=100, null=True, blank=True)
|
specification = models.CharField('型号', max_length=100, null=True, blank=True)
|
||||||
type = models.CharField('物料类型', choices= type_choices, max_length=20, default=1)
|
type = models.CharField('物料类型', choices= type_choices, max_length=20, default=1)
|
||||||
|
@ -159,35 +159,22 @@ class SubProduction(CommonAModel):
|
||||||
verbose_name = '产品生产工序'
|
verbose_name = '产品生产工序'
|
||||||
verbose_name_plural = verbose_name
|
verbose_name_plural = verbose_name
|
||||||
|
|
||||||
|
class SubplanMaterial(CommonAModel):
|
||||||
class InputMaterial(CommonAModel):
|
|
||||||
"""
|
"""
|
||||||
输入物料
|
输入/输出物料/工具工装
|
||||||
"""
|
"""
|
||||||
material = models.ForeignKey(Material, verbose_name='输入物料', on_delete=models.CASCADE, related_name='inputmaterial')
|
type_choices=(
|
||||||
count = models.FloatField('消耗量', default=1)
|
(1, '输入物料'),
|
||||||
|
(2, '输出物料'),
|
||||||
|
(3, '工具工装')
|
||||||
|
)
|
||||||
|
material = models.ForeignKey(Material, verbose_name='物料', on_delete=models.CASCADE, related_name='subplan_material')
|
||||||
|
is_main = models.BooleanField('是否主产出', default=False) # 以该产品完成度计算进度
|
||||||
|
count = models.FloatField('消耗量/产出量', default=1)
|
||||||
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE)
|
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE)
|
||||||
|
type = models.IntegerField('物料应用类型', default=1)
|
||||||
sort = models.IntegerField('排序号', default=1)
|
sort = models.IntegerField('排序号', default=1)
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = '输入物料'
|
|
||||||
verbose_name_plural = verbose_name
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class OutputMaterial(CommonAModel):
|
|
||||||
"""
|
|
||||||
输出物料
|
|
||||||
"""
|
|
||||||
material = models.ForeignKey(Material, verbose_name='输出物料', on_delete=models.CASCADE, related_name='outputmaterial')
|
|
||||||
is_main = models.BooleanField('是否主产出', default=True) # 以该产品完成度计算进度
|
|
||||||
count = models.FloatField('产出量', default=1)
|
|
||||||
subproduction = models.ForeignKey(SubProduction, verbose_name='关联生产分解', on_delete=models.CASCADE)
|
|
||||||
sort = models.IntegerField('排序号', default=1)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
verbose_name = '输出物料'
|
|
||||||
verbose_name_plural = verbose_name
|
|
||||||
|
|
||||||
class UsedStep(CommonAModel):
|
class UsedStep(CommonAModel):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from apps.em.serializers import EquipmentSimpleSerializer
|
from apps.em.serializers import EquipmentSimpleSerializer
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.exceptions import ParseError, ValidationError
|
from rest_framework.exceptions import ParseError, ValidationError
|
||||||
from .models import InputMaterial, Material, OutputMaterial, Process, RecordForm, RecordFormField, Step, TechDoc, UsedStep, SubProduction
|
from .models import Material, Process, RecordForm, RecordFormField, Step, SubplanMaterial, TechDoc, UsedStep, SubProduction
|
||||||
from apps.system.serializers import FileSimpleSerializer, OrganizationSimpleSerializer
|
from apps.system.serializers import FileSimpleSerializer, OrganizationSimpleSerializer
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class MaterialDetailSerializer(serializers.ModelSerializer):
|
||||||
def get_processes_(self, obj):
|
def get_processes_(self, obj):
|
||||||
# steps = UsedStep.objects.filter(subproduction__product=obj).values_list('step', flat=True)
|
# steps = UsedStep.objects.filter(subproduction__product=obj).values_list('step', flat=True)
|
||||||
# objs = Process.objects.filter(step_process__id__in=steps).distinct().order_by('number')
|
# objs = Process.objects.filter(step_process__id__in=steps).distinct().order_by('number')
|
||||||
objs = Process.objects.filter(subproduction_process__product=obj, subproduction_process__is_deleted=False, is_deleted=False).order_by('number')
|
objs = Process.objects.filter(subproduction_process__product=obj, subproduction_process__is_deleted=False, is_deleted=False).distinct().order_by('number')
|
||||||
return ProcessSimpleSerializer(instance=objs, many=True).data
|
return ProcessSimpleSerializer(instance=objs, many=True).data
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ class StepSimpleSerializer(serializers.ModelSerializer):
|
||||||
fields = ['id', 'name', 'sort']
|
fields = ['id', 'name', 'sort']
|
||||||
|
|
||||||
class StepDetailSerializer(serializers.ModelSerializer):
|
class StepDetailSerializer(serializers.ModelSerializer):
|
||||||
equipments_ = EquipmentSimpleSerializer(source='equipments', many=True)
|
equipments_ = EquipmentSimpleSerializer(source='equipments', many=True, required=False)
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Step
|
model = Step
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
@ -67,51 +67,59 @@ class SubProductionSerializer(serializers.ModelSerializer):
|
||||||
model = SubProduction
|
model = SubProduction
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
class InputMaterialListSerializer(serializers.ModelSerializer):
|
class OtherMaterialSerializer(serializers.ModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = SubplanMaterial
|
||||||
|
fields = ['sort', 'material', 'subproduction']
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
if SubplanMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False, type=3).exists():
|
||||||
|
raise ValidationError('该物料已存在')
|
||||||
|
validated_data['type']=3
|
||||||
|
return super().create(validated_data)
|
||||||
|
|
||||||
|
class SubplanMaterialListSerializer(serializers.ModelSerializer):
|
||||||
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
model = InputMaterial
|
model = SubplanMaterial
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
class OutputMaterialListSerializer(serializers.ModelSerializer):
|
|
||||||
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
|
||||||
class Meta:
|
|
||||||
model = OutputMaterial
|
|
||||||
fields = '__all__'
|
|
||||||
|
|
||||||
|
|
||||||
class InputMaterialSerializer(serializers.ModelSerializer):
|
class InputMaterialSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = InputMaterial
|
model = SubplanMaterial
|
||||||
fields = ['count', 'sort', 'material', 'subproduction']
|
fields = ['count', 'sort', 'material', 'subproduction']
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
if InputMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False).exists():
|
if SubplanMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False, type=1).exists():
|
||||||
raise ValidationError('该物料已存在')
|
raise ValidationError('该物料已存在')
|
||||||
|
validated_data['type']=1
|
||||||
return super().create(validated_data)
|
return super().create(validated_data)
|
||||||
|
|
||||||
class InputMaterialUpdateSerializer(serializers.ModelSerializer):
|
class InputMaterialUpdateSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = InputMaterial
|
model = SubplanMaterial
|
||||||
fields = ['count', 'sort']
|
fields = ['count', 'sort']
|
||||||
|
|
||||||
class OutputMaterialSerializer(serializers.ModelSerializer):
|
class OutputMaterialSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = OutputMaterial
|
model = SubplanMaterial
|
||||||
fields = ['count', 'sort', 'material', 'subproduction', 'is_main']
|
fields = ['count', 'sort', 'material', 'subproduction', 'is_main']
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
if OutputMaterial.objects.filter(subproduction=validated_data['subproduction'], is_deleted=False, is_main=True).exists():
|
if SubplanMaterial.objects.filter(subproduction=validated_data['subproduction'], is_deleted=False, is_main=True, type=2).exists():
|
||||||
raise ValidationError('主产出只能有1个')
|
raise ValidationError('主产出只能有1个')
|
||||||
if OutputMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False).exists():
|
if SubplanMaterial.objects.filter(material=validated_data['material'], subproduction=validated_data['subproduction'], is_deleted=False, type=2).exists():
|
||||||
raise ValidationError('该物料已存在')
|
raise ValidationError('该物料已存在')
|
||||||
|
validated_data['type']=2
|
||||||
return super().create(validated_data)
|
return super().create(validated_data)
|
||||||
|
|
||||||
class OutputMaterialUpdateSerializer(serializers.ModelSerializer):
|
class OutputMaterialUpdateSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = OutputMaterial
|
model = SubplanMaterial
|
||||||
fields = ['count', 'sort', 'is_main']
|
fields = ['count', 'sort', 'is_main']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class UsedStepCreateSerializer(serializers.ModelSerializer):
|
class UsedStepCreateSerializer(serializers.ModelSerializer):
|
||||||
"""
|
"""
|
||||||
产品生产子工序创建
|
产品生产子工序创建
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from django.db.models import base
|
from django.db.models import base
|
||||||
from rest_framework import urlpatterns
|
from rest_framework import urlpatterns
|
||||||
from apps.mtm.views import InputMaterialViewSet, MaterialViewSet, OutputMaterialViewSet, ProcessViewSet, RecordFormFieldViewSet, RecordFormViewSet, StepViewSet, SubProductionViewSet, TechDocViewSet, UsedStepViewSet
|
from apps.mtm.views import InputMaterialViewSet, MaterialViewSet, OtherMaterialViewSet, OutputMaterialViewSet, ProcessViewSet, RecordFormFieldViewSet, RecordFormViewSet, StepViewSet, SubProductionViewSet, TechDocViewSet, UsedStepViewSet
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from rest_framework.routers import DefaultRouter
|
from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ router.register('step', StepViewSet, basename='step')
|
||||||
router.register('subproducation', SubProductionViewSet, basename='subproducation')
|
router.register('subproducation', SubProductionViewSet, basename='subproducation')
|
||||||
router.register('inputmaterial', InputMaterialViewSet, basename='inputmaterial')
|
router.register('inputmaterial', InputMaterialViewSet, basename='inputmaterial')
|
||||||
router.register('outputmaterial', OutputMaterialViewSet, basename='outputmaterial')
|
router.register('outputmaterial', OutputMaterialViewSet, basename='outputmaterial')
|
||||||
|
router.register('othermaterial', OtherMaterialViewSet, basename='othermaterial')
|
||||||
router.register('usedstep', UsedStepViewSet, basename='usedstep')
|
router.register('usedstep', UsedStepViewSet, basename='usedstep')
|
||||||
router.register('recordform', RecordFormViewSet, basename='recordform')
|
router.register('recordform', RecordFormViewSet, basename='recordform')
|
||||||
router.register('recordform-field', RecordFormFieldViewSet, basename='recordform-field')
|
router.register('recordform-field', RecordFormFieldViewSet, basename='recordform-field')
|
||||||
|
|
|
@ -2,8 +2,8 @@ from django.shortcuts import render
|
||||||
from rest_framework.viewsets import ModelViewSet, GenericViewSet
|
from rest_framework.viewsets import ModelViewSet, GenericViewSet
|
||||||
from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin
|
from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin, RetrieveModelMixin, DestroyModelMixin
|
||||||
|
|
||||||
from apps.mtm.models import InputMaterial, Material, OutputMaterial, Process, RecordForm, RecordFormField, Step, TechDoc, UsedStep, SubProduction
|
from apps.mtm.models import Material, Process, RecordForm, RecordFormField, Step, SubplanMaterial, TechDoc, UsedStep, SubProduction
|
||||||
from apps.mtm.serializers import InputMaterialListSerializer, InputMaterialSerializer, InputMaterialUpdateSerializer, MaterialDetailSerializer, MaterialSerializer, MaterialSimpleSerializer, OutputMaterialListSerializer, OutputMaterialSerializer, OutputMaterialUpdateSerializer, ProcessSerializer, RecordFormCreateSerializer, RecordFormFieldCreateSerializer, RecordFormFieldSerializer, RecordFormFieldUpdateSerializer, RecordFormSerializer, RecordFormUpdateSerializer, StepDetailSerializer, StepSerializer, SubProductionSerializer, TechDocCreateSerializer, TechDocListSerializer, TechDocUpdateSerializer, UsedStepCreateSerializer, UsedStepListSerializer, UsedStepUpdateSerializer
|
from apps.mtm.serializers import InputMaterialSerializer, InputMaterialUpdateSerializer, MaterialDetailSerializer, MaterialSerializer, MaterialSimpleSerializer, OtherMaterialSerializer, OutputMaterialSerializer, OutputMaterialUpdateSerializer, ProcessSerializer, RecordFormCreateSerializer, RecordFormFieldCreateSerializer, RecordFormFieldSerializer, RecordFormFieldUpdateSerializer, RecordFormSerializer, RecordFormUpdateSerializer, StepDetailSerializer, StepSerializer, SubProductionSerializer, SubplanMaterialListSerializer, TechDocCreateSerializer, TechDocListSerializer, TechDocUpdateSerializer, UsedStepCreateSerializer, UsedStepListSerializer, UsedStepUpdateSerializer
|
||||||
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
from apps.system.mixins import CreateUpdateModelAMixin, OptimizationMixin
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
@ -85,14 +85,14 @@ class InputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||||
输入物料-增删改查
|
输入物料-增删改查
|
||||||
"""
|
"""
|
||||||
perms_map = {'*':'*'}
|
perms_map = {'*':'*'}
|
||||||
queryset = InputMaterial.objects.select_related('material').all()
|
queryset = SubplanMaterial.objects.select_related('material').filter(type=1)
|
||||||
serializer_class = InputMaterialSerializer
|
serializer_class = InputMaterialSerializer
|
||||||
filterset_fields = ['subproduction']
|
filterset_fields = ['subproduction']
|
||||||
ordering = ['sort', '-create_time']
|
ordering = ['sort', '-create_time']
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
if self.action == 'list':
|
if self.action == 'list':
|
||||||
return InputMaterialListSerializer
|
return SubplanMaterialListSerializer
|
||||||
elif self.action == 'update':
|
elif self.action == 'update':
|
||||||
return InputMaterialUpdateSerializer
|
return InputMaterialUpdateSerializer
|
||||||
return InputMaterialSerializer
|
return InputMaterialSerializer
|
||||||
|
@ -102,18 +102,33 @@ class OutputMaterialViewSet(CreateUpdateModelAMixin, ModelViewSet):
|
||||||
输出物料-增删改查
|
输出物料-增删改查
|
||||||
"""
|
"""
|
||||||
perms_map = {'*':'*'}
|
perms_map = {'*':'*'}
|
||||||
queryset = OutputMaterial.objects.select_related('material').all()
|
queryset = SubplanMaterial.objects.select_related('material').filter(type=2)
|
||||||
serializer_class = OutputMaterialSerializer
|
serializer_class = OutputMaterialSerializer
|
||||||
filterset_fields = ['subproduction']
|
filterset_fields = ['subproduction']
|
||||||
ordering = ['sort', '-create_time']
|
ordering = ['sort', '-create_time']
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
if self.action == 'list':
|
if self.action == 'list':
|
||||||
return OutputMaterialListSerializer
|
return SubplanMaterialListSerializer
|
||||||
elif self.action == 'update':
|
elif self.action == 'update':
|
||||||
return OutputMaterialUpdateSerializer
|
return OutputMaterialUpdateSerializer
|
||||||
return OutputMaterialSerializer
|
return OutputMaterialSerializer
|
||||||
|
|
||||||
|
class OtherMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, DestroyModelMixin, CreateModelMixin, GenericViewSet):
|
||||||
|
"""
|
||||||
|
其他物料-增删改查
|
||||||
|
"""
|
||||||
|
perms_map = {'*':'*'}
|
||||||
|
queryset = SubplanMaterial.objects.select_related('material').filter(type=3)
|
||||||
|
serializer_class = OutputMaterialSerializer
|
||||||
|
filterset_fields = ['subproduction']
|
||||||
|
ordering = ['sort', '-create_time']
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
if self.action == 'list':
|
||||||
|
return SubplanMaterialListSerializer
|
||||||
|
return OtherMaterialSerializer
|
||||||
|
|
||||||
class UsedStepViewSet(OptimizationMixin, CreateModelMixin, DestroyModelMixin, ListModelMixin, UpdateModelMixin, GenericViewSet):
|
class UsedStepViewSet(OptimizationMixin, CreateModelMixin, DestroyModelMixin, ListModelMixin, UpdateModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
产品生产子工序表
|
产品生产子工序表
|
||||||
|
|
|
@ -60,7 +60,8 @@ class SubProductionProgress(BaseModel):
|
||||||
"""
|
"""
|
||||||
type_choices=(
|
type_choices=(
|
||||||
(1, '输入物料'),
|
(1, '输入物料'),
|
||||||
(2, '输出物料')
|
(2, '输出物料'),
|
||||||
|
(3, '工具工装')
|
||||||
)
|
)
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, related_name='progress_subplan')
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE, related_name='progress_subplan')
|
||||||
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE)
|
material = models.ForeignKey(Material, verbose_name='关联物料', on_delete=models.CASCADE)
|
||||||
|
|
|
@ -5,7 +5,7 @@ from apps.em.models import Equipment
|
||||||
from apps.em.serializers import EquipmentSerializer
|
from apps.em.serializers import EquipmentSerializer
|
||||||
from apps.inm.models import MaterialBatch
|
from apps.inm.models import MaterialBatch
|
||||||
from apps.inm.serializers import MaterialBatchSerializer
|
from apps.inm.serializers import MaterialBatchSerializer
|
||||||
from apps.mtm.models import InputMaterial, OutputMaterial, Step, SubProduction, UsedStep
|
from apps.mtm.models import Step, SubProduction, UsedStep
|
||||||
from apps.system.mixins import CreateUpdateModelAMixin
|
from apps.system.mixins import CreateUpdateModelAMixin
|
||||||
from apps.pm.serializers import GenSubPlanSerializer, PickNeedSerializer, PlanDestorySerializer, ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer, ResourceCalListSerializer, ResourceCalSerializer, SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer, SubProductionProgressSerializer
|
from apps.pm.serializers import GenSubPlanSerializer, PickNeedSerializer, PlanDestorySerializer, ProductionPlanCreateFromOrderSerializer, ProductionPlanSerializer, ResourceCalListSerializer, ResourceCalSerializer, SubProductionPlanListSerializer, SubProductionPlanUpdateSerializer, SubProductionProgressSerializer
|
||||||
from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin
|
from rest_framework.mixins import CreateModelMixin, ListModelMixin, UpdateModelMixin
|
||||||
|
@ -87,10 +87,8 @@ class ProductionPlanViewSet(CreateUpdateModelAMixin, ListModelMixin, CreateModel
|
||||||
start_date=production_plan.start_date, end_date=production_plan.end_date,
|
start_date=production_plan.start_date, end_date=production_plan.end_date,
|
||||||
workshop=i.process.workshop, process=i.process, create_by=request.user,
|
workshop=i.process.workshop, process=i.process, create_by=request.user,
|
||||||
steps = list(steps))
|
steps = list(steps))
|
||||||
for m in InputMaterial.objects.filter(subproduction=i, is_deleted=False).order_by('sort'):
|
for m in SubProduction.objects.filter(subproduction=i, is_deleted=False).order_by('sort'):
|
||||||
SubProductionProgress.objects.create(material=m.material, type=1, count=m.count*production_plan.count, subproduction_plan=instance)
|
SubProductionProgress.objects.create(material=m.material, type=m.type, count=m.count*production_plan.count, subproduction_plan=instance)
|
||||||
for m in OutputMaterial.objects.filter(subproduction=i, is_deleted=False).order_by('sort'):
|
|
||||||
SubProductionProgress.objects.create(material=m.material, type=2, count=m.count*production_plan.count, subproduction_plan=instance)
|
|
||||||
production_plan.is_planed=True
|
production_plan.is_planed=True
|
||||||
production_plan.save()
|
production_plan.save()
|
||||||
return Response()
|
return Response()
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from django.db.models import query
|
from django.db.models import query
|
||||||
|
from rest_framework.utils import serializer_helpers
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from apps.system.models import User
|
from apps.system.models import User
|
||||||
from apps.wf.filters import TicketFilterSet
|
from apps.wf.filters import TicketFilterSet
|
||||||
|
|
|
@ -2,7 +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.pm.models import SubProductionPlan
|
from apps.pm.models import ProductionPlan, SubProductionPlan
|
||||||
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
|
||||||
|
@ -33,7 +33,8 @@ class WProduct(CommonAModel):
|
||||||
act_state = models.IntegerField('进行状态', default=0)
|
act_state = models.IntegerField('进行状态', default=0)
|
||||||
parent = models.ForeignKey('self', verbose_name='上一级', on_delete=models.CASCADE, db_constraint=False)
|
parent = models.ForeignKey('self', verbose_name='上一级', on_delete=models.CASCADE, db_constraint=False)
|
||||||
remark = models.CharField('备注', max_length=200, null=True, blank=True)
|
remark = models.CharField('备注', max_length=200, null=True, blank=True)
|
||||||
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='关联子生产计划', on_delete=models.CASCADE)
|
subproduction_plan = models.ForeignKey(SubProductionPlan, verbose_name='当前子生产计划', on_delete=models.CASCADE)
|
||||||
|
production_plan = models.ForeignKey(ProductionPlan, verbose_name='关联主生产计划', on_delete=models.CASCADE)
|
||||||
|
|
||||||
class WProductForm(CommonAModel):
|
class WProductForm(CommonAModel):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -2,10 +2,13 @@ from rest_framework import serializers
|
||||||
from rest_framework.serializers import ModelSerializer
|
from rest_framework.serializers import ModelSerializer
|
||||||
from apps.inm.models import FIFO, FIFODetail, MaterialBatch, WareHouse
|
from apps.inm.models import FIFO, FIFODetail, MaterialBatch, WareHouse
|
||||||
from apps.mtm.models import Material
|
from apps.mtm.models import Material
|
||||||
|
from apps.mtm.serializers import MaterialSimpleSerializer
|
||||||
|
|
||||||
from apps.pm.models import SubProductionPlan
|
from apps.pm.models import SubProductionPlan, SubProductionProgress
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from apps.wpm.models import WMaterial
|
||||||
|
|
||||||
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='物料批次')
|
batch = serializers.CharField(label='物料批次')
|
||||||
|
@ -18,6 +21,9 @@ class PickSerializer(serializers.Serializer):
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
picks = validated_data.pop('picks')
|
picks = validated_data.pop('picks')
|
||||||
|
sp = validated_data['subproduction_plan']
|
||||||
|
if sp.is_picked:
|
||||||
|
raise serializers.ValidationError('该子计划已领料')
|
||||||
for i in picks:
|
for i in picks:
|
||||||
try:
|
try:
|
||||||
instance = MaterialBatch.objects.get(material=i['material'], batch=i['batch'])
|
instance = MaterialBatch.objects.get(material=i['material'], batch=i['batch'])
|
||||||
|
@ -25,6 +31,7 @@ class PickSerializer(serializers.Serializer):
|
||||||
raise serializers.ValidationError('物料不足')
|
raise serializers.ValidationError('物料不足')
|
||||||
except:
|
except:
|
||||||
raise serializers.ValidationError('物料不存在')
|
raise serializers.ValidationError('物料不存在')
|
||||||
|
# 创建出库记录
|
||||||
operator = self.context['request'].user
|
operator = self.context['request'].user
|
||||||
validated_data['create_by'] = operator
|
validated_data['create_by'] = operator
|
||||||
validated_data['operator'] = operator
|
validated_data['operator'] = operator
|
||||||
|
@ -32,6 +39,33 @@ class PickSerializer(serializers.Serializer):
|
||||||
validated_data['inout_date'] = timezone.now()
|
validated_data['inout_date'] = timezone.now()
|
||||||
fifo = FIFO.objects.create(validated_data)
|
fifo = FIFO.objects.create(validated_data)
|
||||||
for i in picks:
|
for i in picks:
|
||||||
|
# 更新出库详情
|
||||||
i['fifo'] = fifo
|
i['fifo'] = fifo
|
||||||
FIFODetail.objects.create(**i)
|
FIFODetail.objects.create(**i)
|
||||||
|
# 更新车间物料
|
||||||
|
wm = WMaterial.objects.get_or_create(material=i['material'], batch=i['batch'], \
|
||||||
|
process=validated_data['process'],defaults={
|
||||||
|
'material':i['material'],
|
||||||
|
'batch':i['batch'],
|
||||||
|
'process':validated_data['process'],
|
||||||
|
'workshop':validated_data['workshop'],
|
||||||
|
'count':0
|
||||||
|
})
|
||||||
|
wm.count = wm.count + i['pick_count']
|
||||||
|
wm.save()
|
||||||
|
# 更新子计划进度
|
||||||
|
spp = SubProductionProgress.objects.get(material=i['material'], subproduction_plan=sp, type=1)
|
||||||
|
spp.count_real = spp.count_real + i['pick_count']
|
||||||
|
spp.save()
|
||||||
|
sp.is_picked=True
|
||||||
|
sp.save()
|
||||||
return fifo
|
return fifo
|
||||||
|
|
||||||
|
class WMaterialListSerializer(serializers.ModelSerializer):
|
||||||
|
"""
|
||||||
|
车间物料
|
||||||
|
"""
|
||||||
|
material_ = MaterialSimpleSerializer(source='material', read_only=True)
|
||||||
|
class Meta:
|
||||||
|
model = Material
|
||||||
|
fields = '__all__'
|
|
@ -1,21 +1,29 @@
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from rest_framework.generics import CreateAPIView, GenericAPIView
|
from rest_framework.generics import CreateAPIView, GenericAPIView
|
||||||
|
from rest_framework.mixins import ListModelMixin
|
||||||
from rest_framework.utils.field_mapping import get_relation_kwargs
|
from rest_framework.utils.field_mapping import get_relation_kwargs
|
||||||
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||||
from apps.pm.serializers import SubProductionPlanUpdateSerializer
|
from apps.pm.serializers import SubProductionPlanUpdateSerializer
|
||||||
|
|
||||||
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.models import WMaterial
|
||||||
|
|
||||||
from apps.wpm.serializers import PickSerializer
|
from apps.wpm.serializers import PickSerializer, WMaterialListSerializer
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
class WMaterialViewSet(CreateUpdateModelAMixin, GenericViewSet):
|
class WMaterialViewSet(CreateUpdateModelAMixin, ListModelMixin, GenericViewSet):
|
||||||
"""
|
"""
|
||||||
领料
|
车间物料表
|
||||||
"""
|
"""
|
||||||
perms_map={'*':'*'}
|
perms_map={'*':'*'}
|
||||||
@action(methods=['post'], detail=True, perms_map={'post':'*'}, serializer_class=PickSerializer)
|
queryset = WMaterial.objects.select_related('material').all()
|
||||||
|
serializer_class = WMaterialListSerializer
|
||||||
|
filterset_fields = ['material', 'process', 'workshop']
|
||||||
|
ordering_fields = ['material__number']
|
||||||
|
ordering = ['material__number']
|
||||||
|
|
||||||
|
@action(methods=['post'], detail=False, perms_map={'post':'*'}, serializer_class=PickSerializer)
|
||||||
def pick(self, request, pk=None):
|
def pick(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
领料
|
领料
|
||||||
|
|
Loading…
Reference in New Issue