add: mtm/model serializer view 增加tkx 自动排班

This commit is contained in:
zty 2024-11-28 14:28:24 +08:00
parent c0f796f4a0
commit 4c38cee983
6 changed files with 73 additions and 13 deletions

View File

@ -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,
},
),
]

View File

@ -2,7 +2,7 @@ from django.db import models
from apps.system.models import CommonAModel, Dictionary, CommonBModel, CommonADModel, File, BaseModel
from django.db.models import Subquery, OuterRef
from rest_framework.exceptions import ValidationError, ParseError
from apps.utils.models import CommonBDModel
class Process(CommonBModel):
"""
@ -98,6 +98,12 @@ class Shift(CommonBModel):
class Meta:
verbose_name = '班次'
class Srule(CommonBDModel):
"""
班组规则
"""
rule = models.JSONField('排班规则', default=list, blank=True)
class Team(CommonBModel):
"""班组, belong_dept为所属车间

View File

@ -1,5 +1,5 @@
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 rest_framework import serializers
from rest_framework.exceptions import ValidationError, ParseError
@ -259,3 +259,10 @@ class RouteSerializer(CustomModelSerializer):
if instance.material:
self.gen_material_out(instance)
return instance
class SruleSerializer(CustomModelSerializer):
class Meta:
model = Srule
fields = '__all__'
read_only_fields = EXCLUDE_FIELDS

View File

@ -3,7 +3,7 @@ from rest_framework.routers import DefaultRouter
from apps.mtm.views import (MgroupViewSet, ShiftViewSet, TeamViewSet, MaterialViewSet,
GoalViewSet, ProcessViewSet, RouteViewSet, TeamMemberViewSet,
RoutePackViewSet)
RoutePackViewSet, SruleViewSet)
API_BASE_URL = 'api/mtm/'
HTML_BASE_URL = 'mtm/'
@ -18,6 +18,7 @@ router.register('process', ProcessViewSet, basename='process')
router.register('routepack', RoutePackViewSet, basename='routepack')
router.register('route', RouteViewSet, basename='route')
router.register('teammember', TeamMemberViewSet, basename='teammember')
router.register('srule', SruleViewSet, basename='srule')
urlpatterns = [
path(API_BASE_URL, include(router.urls)),
]

View File

@ -6,11 +6,11 @@ from rest_framework.response import Response
from rest_framework.exceptions import ParseError
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,
MgroupGoalYearSerializer, MgroupSerializer,
ShiftSerializer, TeamSerializer, ProcessSerializer,
RouteSerializer, TeamMemberSerializer, RoutePackSerializer)
RouteSerializer, TeamMemberSerializer, RoutePackSerializer, SruleSerializer)
from apps.mtm.services import get_mgroup_goals, daoru_material
from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
from apps.utils.mixins import BulkCreateModelMixin, BulkDestroyModelMixin
@ -124,7 +124,7 @@ class TeamViewSet(CustomModelViewSet):
serializer_class = TeamSerializer
select_related_fields = ['belong_dept', 'leader']
filterset_fields = ['belong_dept']
search_fields = ['name']
search_fields = ['rule']
class TeamMemberViewSet(ListModelMixin, BulkCreateModelMixin, BulkDestroyModelMixin, CustomGenericViewSet):
@ -222,4 +222,16 @@ class RouteViewSet(CustomModelViewSet):
routepack = obj.routepack
if routepack and routepack.state != RoutePack.RP_S_CREATE:
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']

View File

@ -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()
return sflog
def get_team(mgroup: Mgroup, team_ids: list):
def get_team(team_ids: list):
from apps.mtm.models import Srule
# 获取 r_list 列表
teams_ins = Srule.objects.get(mgroup=mgroup)
teams_ = Srule.objects.all().values_list('rule', flat=True)
# 提取team_id
teams = [team['team'] for team in teams_ins.r_list]
teams = [team['team'] for team in teams_[0]]
# 找到 team_ids 匹配段的结束位置
start_idx = -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)
# 如果最后一条记录的team_id为空则继续向前取三条
from itertools import islice
# 获取前三个非空值
# 获取前三个非空值并且列表反转
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.objects.get_or_create(mgroup=mgroup, shift=shift, start_time=start_time, defaults={
"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": total_sec,
"create_by": create_by,
"team": new_team
"team_id": new_team
})
current_date = current_date + datetime.timedelta(days=1)