add: mtm/model serializer view 增加tkx 自动排班
This commit is contained in:
parent
c0f796f4a0
commit
4c38cee983
|
@ -0,0 +1,34 @@
|
||||||
|
# Generated by Django 3.2.12 on 2024-11-27 07:52
|
||||||
|
|
||||||
|
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),
|
||||||
|
('system', '0005_alter_permission_type'),
|
||||||
|
('mtm', '0042_auto_20241010_1140'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Srule',
|
||||||
|
fields=[
|
||||||
|
('id', models.CharField(editable=False, help_text='主键ID', max_length=20, 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='删除标记')),
|
||||||
|
('rule', models.JSONField(blank=True, default=list, verbose_name='排班规则')),
|
||||||
|
('belong_dept', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='srule_belong_dept', to='system.dept', verbose_name='所属部门')),
|
||||||
|
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='srule_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='srule_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'abstract': False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -2,7 +2,7 @@ from django.db import models
|
||||||
from apps.system.models import CommonAModel, Dictionary, CommonBModel, CommonADModel, File, BaseModel
|
from apps.system.models import CommonAModel, Dictionary, CommonBModel, CommonADModel, File, BaseModel
|
||||||
from django.db.models import Subquery, OuterRef
|
from django.db.models import Subquery, OuterRef
|
||||||
from rest_framework.exceptions import ValidationError, ParseError
|
from rest_framework.exceptions import ValidationError, ParseError
|
||||||
|
from apps.utils.models import CommonBDModel
|
||||||
|
|
||||||
class Process(CommonBModel):
|
class Process(CommonBModel):
|
||||||
"""
|
"""
|
||||||
|
@ -98,6 +98,12 @@ class Shift(CommonBModel):
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = '班次'
|
verbose_name = '班次'
|
||||||
|
|
||||||
|
class Srule(CommonBDModel):
|
||||||
|
"""
|
||||||
|
班组规则
|
||||||
|
"""
|
||||||
|
rule = models.JSONField('排班规则', default=list, blank=True)
|
||||||
|
|
||||||
|
|
||||||
class Team(CommonBModel):
|
class Team(CommonBModel):
|
||||||
"""班组, belong_dept为所属车间
|
"""班组, belong_dept为所属车间
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from apps.utils.serializers import CustomModelSerializer
|
from apps.utils.serializers import CustomModelSerializer
|
||||||
from apps.mtm.models import Shift, Material, Mgroup, Team, Goal, Process, Route, TeamMember, RoutePack
|
from apps.mtm.models import Shift, Material, Mgroup, Team, Goal, Process, Route, TeamMember, RoutePack, Srule
|
||||||
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE, EXCLUDE_FIELDS_DEPT
|
from apps.utils.constants import EXCLUDE_FIELDS, EXCLUDE_FIELDS_BASE, EXCLUDE_FIELDS_DEPT
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.exceptions import ValidationError, ParseError
|
from rest_framework.exceptions import ValidationError, ParseError
|
||||||
|
@ -259,3 +259,10 @@ class RouteSerializer(CustomModelSerializer):
|
||||||
if instance.material:
|
if instance.material:
|
||||||
self.gen_material_out(instance)
|
self.gen_material_out(instance)
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
class SruleSerializer(CustomModelSerializer):
|
||||||
|
class Meta:
|
||||||
|
model = Srule
|
||||||
|
fields = '__all__'
|
||||||
|
read_only_fields = EXCLUDE_FIELDS
|
|
@ -3,7 +3,7 @@ from rest_framework.routers import DefaultRouter
|
||||||
|
|
||||||
from apps.mtm.views import (MgroupViewSet, ShiftViewSet, TeamViewSet, MaterialViewSet,
|
from apps.mtm.views import (MgroupViewSet, ShiftViewSet, TeamViewSet, MaterialViewSet,
|
||||||
GoalViewSet, ProcessViewSet, RouteViewSet, TeamMemberViewSet,
|
GoalViewSet, ProcessViewSet, RouteViewSet, TeamMemberViewSet,
|
||||||
RoutePackViewSet)
|
RoutePackViewSet, SruleViewSet)
|
||||||
|
|
||||||
API_BASE_URL = 'api/mtm/'
|
API_BASE_URL = 'api/mtm/'
|
||||||
HTML_BASE_URL = 'mtm/'
|
HTML_BASE_URL = 'mtm/'
|
||||||
|
@ -18,6 +18,7 @@ router.register('process', ProcessViewSet, basename='process')
|
||||||
router.register('routepack', RoutePackViewSet, basename='routepack')
|
router.register('routepack', RoutePackViewSet, basename='routepack')
|
||||||
router.register('route', RouteViewSet, basename='route')
|
router.register('route', RouteViewSet, basename='route')
|
||||||
router.register('teammember', TeamMemberViewSet, basename='teammember')
|
router.register('teammember', TeamMemberViewSet, basename='teammember')
|
||||||
|
router.register('srule', SruleViewSet, basename='srule')
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path(API_BASE_URL, include(router.urls)),
|
path(API_BASE_URL, include(router.urls)),
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,11 +6,11 @@ from rest_framework.response import Response
|
||||||
from rest_framework.exceptions import ParseError
|
from rest_framework.exceptions import ParseError
|
||||||
|
|
||||||
from apps.mtm.filters import GoalFilter, MaterialFilter, RouteFilter
|
from apps.mtm.filters import GoalFilter, MaterialFilter, RouteFilter
|
||||||
from apps.mtm.models import Goal, Material, Mgroup, Shift, Team, Process, Route, TeamMember, RoutePack
|
from apps.mtm.models import Goal, Material, Mgroup, Shift, Team, Process, Route, TeamMember, RoutePack, Srule
|
||||||
from apps.mtm.serializers import (GoalSerializer, MaterialSerializer,
|
from apps.mtm.serializers import (GoalSerializer, MaterialSerializer,
|
||||||
MgroupGoalYearSerializer, MgroupSerializer,
|
MgroupGoalYearSerializer, MgroupSerializer,
|
||||||
ShiftSerializer, TeamSerializer, ProcessSerializer,
|
ShiftSerializer, TeamSerializer, ProcessSerializer,
|
||||||
RouteSerializer, TeamMemberSerializer, RoutePackSerializer)
|
RouteSerializer, TeamMemberSerializer, RoutePackSerializer, SruleSerializer)
|
||||||
from apps.mtm.services import get_mgroup_goals, daoru_material
|
from apps.mtm.services import get_mgroup_goals, daoru_material
|
||||||
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
|
||||||
from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin
|
from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin
|
||||||
|
@ -124,7 +124,7 @@ class TeamViewSet(CustomModelViewSet):
|
||||||
serializer_class = TeamSerializer
|
serializer_class = TeamSerializer
|
||||||
select_related_fields = ['belong_dept', 'leader']
|
select_related_fields = ['belong_dept', 'leader']
|
||||||
filterset_fields = ['belong_dept']
|
filterset_fields = ['belong_dept']
|
||||||
search_fields = ['name']
|
search_fields = ['rule']
|
||||||
|
|
||||||
|
|
||||||
class TeamMemberViewSet(ListModelMixin, BulkCreateModelMixin, BulkDestroyModelMixin, CustomGenericViewSet):
|
class TeamMemberViewSet(ListModelMixin, BulkCreateModelMixin, BulkDestroyModelMixin, CustomGenericViewSet):
|
||||||
|
@ -223,3 +223,15 @@ class RouteViewSet(CustomModelViewSet):
|
||||||
if routepack and routepack.state != RoutePack.RP_S_CREATE:
|
if routepack and routepack.state != RoutePack.RP_S_CREATE:
|
||||||
raise ParseError('该状态下不可编辑')
|
raise ParseError('该状态下不可编辑')
|
||||||
return super().update(request, *args, **kwargs)
|
return super().update(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class SruleViewSet(CustomModelViewSet):
|
||||||
|
"""
|
||||||
|
list: 排班规则
|
||||||
|
"""
|
||||||
|
queryset = Srule.objects.all()
|
||||||
|
serializer_class = SruleSerializer
|
||||||
|
select_related_fields = ['belong_dept']
|
||||||
|
filterset_fields = ['belong_dept']
|
||||||
|
search_fields = ['rule']
|
||||||
|
|
|
@ -52,12 +52,12 @@ def get_sflog(mgroup: Mgroup, happen_time: datetime):
|
||||||
start_time__lte=happen_time, end_time__gt=happen_time, mgroup=mgroup).order_by('-start_time').first()
|
start_time__lte=happen_time, end_time__gt=happen_time, mgroup=mgroup).order_by('-start_time').first()
|
||||||
return sflog
|
return sflog
|
||||||
|
|
||||||
def get_team(mgroup: Mgroup, team_ids: list):
|
def get_team(team_ids: list):
|
||||||
from apps.mtm.models import Srule
|
from apps.mtm.models import Srule
|
||||||
# 获取 r_list 列表
|
# 获取 r_list 列表
|
||||||
teams_ins = Srule.objects.get(mgroup=mgroup)
|
teams_ = Srule.objects.all().values_list('rule', flat=True)
|
||||||
# 提取team_id
|
# 提取team_id
|
||||||
teams = [team['team'] for team in teams_ins.r_list]
|
teams = [team['team'] for team in teams_[0]]
|
||||||
# 找到 team_ids 匹配段的结束位置
|
# 找到 team_ids 匹配段的结束位置
|
||||||
start_idx = -1
|
start_idx = -1
|
||||||
for i in range(len(teams)-len(team_ids)+1):
|
for i in range(len(teams)-len(team_ids)+1):
|
||||||
|
@ -91,9 +91,9 @@ def make_sflogs(mgroup: Mgroup, start_date: datetime.date, end_date: datetime.da
|
||||||
all_teams = SfLog.objects.filter(mgroup=mgroup, start_time__lt=start_time).order_by('-start_time').values_list('team', flat=True)
|
all_teams = SfLog.objects.filter(mgroup=mgroup, start_time__lt=start_time).order_by('-start_time').values_list('team', flat=True)
|
||||||
# 如果最后一条记录的team_id为空,则继续向前取三条
|
# 如果最后一条记录的team_id为空,则继续向前取三条
|
||||||
from itertools import islice
|
from itertools import islice
|
||||||
# 获取前三个非空值
|
# 获取前三个非空值并且列表反转
|
||||||
last_teams = list(islice(all_teams, 3))
|
last_teams = list(islice(all_teams, 3))
|
||||||
new_team = get_team(mgroup=mgroup, team_ids=last_teams)
|
new_team = get_team(team_ids=last_teams[::-1])
|
||||||
# 创建SfLog记录
|
# 创建SfLog记录
|
||||||
SfLog.objects.get_or_create(mgroup=mgroup, shift=shift, start_time=start_time, defaults={
|
SfLog.objects.get_or_create(mgroup=mgroup, shift=shift, start_time=start_time, defaults={
|
||||||
"mgroup": mgroup,
|
"mgroup": mgroup,
|
||||||
|
@ -104,7 +104,7 @@ def make_sflogs(mgroup: Mgroup, start_date: datetime.date, end_date: datetime.da
|
||||||
"total_sec_now": total_sec,
|
"total_sec_now": total_sec,
|
||||||
"total_sec": total_sec,
|
"total_sec": total_sec,
|
||||||
"create_by": create_by,
|
"create_by": create_by,
|
||||||
"team": new_team
|
"team_id": new_team
|
||||||
})
|
})
|
||||||
current_date = current_date + datetime.timedelta(days=1)
|
current_date = current_date + datetime.timedelta(days=1)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue