feat: wpm中增加到岗记录

This commit is contained in:
caoqianming 2023-11-20 16:26:14 +08:00
parent cbce572350
commit fddadfe30c
8 changed files with 134 additions and 18 deletions

View File

@ -57,6 +57,7 @@ class PmService:
"""
从大任务自动排产出小任务
"""
from apps.wpm.services import make_sflogs
if utask.state != Utask.UTASK_CREATED:
raise ParseError('任务状态异常')
utask.state = Utask.UTASK_DECOMPOSE
@ -82,6 +83,8 @@ class PmService:
'update_by': user,
'is_count_utask': True
})
make_sflogs(mgroup=utask.mgroup,
start_date=task_date, end_date=task_date, create_by=user)
else:
# 获取产品的加工路线
rqs = Route.get_routes(product)
@ -131,6 +134,8 @@ class PmService:
'update_by': user,
'is_count_utask': val.is_count_utask
})
make_sflogs(mgroup=mgroup,
start_date=task_date, end_date=task_date, create_by=user)
@classmethod
def check_orderitems(cls, orderitems: QuerySet[OrderItem]):

View File

@ -0,0 +1,42 @@
# Generated by Django 3.2.12 on 2023-11-20 08:23
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', '0002_myschedule'),
('wpm', '0031_alter_mlog_mtask'),
]
operations = [
migrations.AddField(
model_name='sflog',
name='work_date',
field=models.DateField(blank=True, null=True, verbose_name='值班日期'),
),
migrations.CreateModel(
name='AttLog',
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='删除标记')),
('state', models.CharField(choices=[('pending', '待定'), ('normal', '正常'), ('late', '迟到'), ('early_leave', '早退'), ('absent', '未到岗'), ('leave', '请假')], default='pending', help_text="[('pending', '待定'), ('normal', '正常'), ('late', '迟到'), ('early_leave', '早退'), ('absent', '未到岗'), ('leave', '请假')]", max_length=20, verbose_name='状态')),
('note', models.TextField(blank=True, default='', verbose_name='备注信息')),
('create_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='attlog_create_by', to=settings.AUTH_USER_MODEL, verbose_name='创建人')),
('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='system.post', verbose_name='岗位')),
('sflog', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='wpm.sflog', verbose_name='关联值班记录')),
('update_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='attlog_update_by', to=settings.AUTH_USER_MODEL, verbose_name='最后编辑人')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='到岗人')),
],
options={
'abstract': False,
},
),
]

View File

@ -32,6 +32,7 @@ class SfLog(CommonADModel):
Shift, verbose_name='当班班次', on_delete=models.CASCADE)
leader = models.ForeignKey(
'system.user', verbose_name='班长', on_delete=models.CASCADE, null=True, blank=True)
work_date = models.DateField('值班日期', null=True, blank=True)
start_time = models.DateTimeField('值班开始')
end_time = models.DateTimeField('值班结束')
note = models.TextField('其他备注', null=True, blank=True)
@ -179,3 +180,27 @@ class Handover(CommonADModel):
submit_time = models.DateTimeField('提交时间', null=True, blank=True)
submit_user = models.ForeignKey(
User, verbose_name='提交人', on_delete=models.CASCADE, null=True, blank=True, related_name='handover_submit_user')
class AttLog(CommonADModel):
"""
到岗记录
"""
ATT_STATE_CHOICES = [
('pending', '待定'),
('normal', '正常'),
('late', '迟到'),
('early_leave', '早退'),
('absent', '未到岗'),
('leave', '请假'),
# 可以根据需要添加更多状态
]
sflog = models.ForeignKey(
SfLog, verbose_name='关联值班记录', on_delete=models.CASCADE)
user = models.ForeignKey(
'system.user', verbose_name='到岗人', on_delete=models.CASCADE)
post = models.ForeignKey(
'system.post', verbose_name='岗位', on_delete=models.CASCADE)
state = models.CharField('状态', max_length=20,
choices=ATT_STATE_CHOICES, default='pending', help_text=str(ATT_STATE_CHOICES))
note = models.TextField('备注信息', default='', blank=True)

View File

@ -3,13 +3,15 @@ from apps.utils.serializers import CustomModelSerializer
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from .models import SfLog, StLog, SfLogExp, WMaterial, Mlog, Handover, Mlogb
from .models import SfLog, StLog, SfLogExp, WMaterial, Mlog, Handover, Mlogb, AttLog
from apps.system.models import Dept, User
from apps.system.serializers import UserSimpleSerializer
from apps.pm.models import Mtask
from apps.wpm.tasks import cal_enstat_when_pcoal_heat_change, cal_enstat_when_team_change
from apps.mtm.models import Mgroup, TeamMember, Shift
from apps.mtm.serializers import MaterialSimpleSerializer
from django.db import transaction
from django.utils import timezone
class StLogSerializer(CustomModelSerializer):
@ -37,16 +39,26 @@ class SfLogSerializer(CustomModelSerializer):
}
def update(self, instance, validated_data):
old_pcoal_heat = instance.pcoal_heat
old_team = instance.team
instance = super().update(instance, validated_data)
new_pcoal_heat = instance.pcoal_heat
new_team = instance.team
if new_pcoal_heat != old_pcoal_heat:
cal_enstat_when_pcoal_heat_change.delay(instance.id)
if new_team != old_team:
cal_enstat_when_team_change.delay(instance.id)
return instance
with transaction.atomic():
old_pcoal_heat = instance.pcoal_heat
old_team = instance.team
instance: SfLog = super().update(instance, validated_data)
new_pcoal_heat = instance.pcoal_heat
new_team = instance.team
mgroup: Mgroup = instance.mgroup
if new_pcoal_heat != old_pcoal_heat and mgroup.need_enm:
cal_enstat_when_pcoal_heat_change.delay(instance.id)
if new_team != old_team:
default_state = 'pending'
if timezone.now() > instance.end_time:
default_state = 'normal'
# 分配班组时创建人员到岗情况
for item in TeamMember.objects.filter(team=new_team, mgroup=instance.mgroup):
AttLog.objects.get_or_create(sflog=instance, user=item.user, defaults={
'sflog': instance, 'user': item.user, 'post': item.post, 'state': default_state, 'create_by': self.context['request'].user})
if mgroup.need_enm:
cal_enstat_when_team_change.delay(instance.id)
return instance
# def to_internal_value(self, data):
# if hasattr(self.Meta, 'update_fields') and self.context['request'].method in ['PUT', 'PATCH']:
# u_fields = self.Meta.update_fields
@ -111,6 +123,8 @@ class MlogSerializer(CustomModelSerializer):
source='equipment.name', read_only=True)
equipment_2_name = serializers.CharField(
source='equipment_2.name', read_only=True)
shift = serializers.PrimaryKeyRelatedField(
label='班次ID', queryset=Shift.objects.all(), required=True)
shift_name = serializers.CharField(source='shift.name', read_only=True)
mlogb = MlogbSerializer(
label='多产出件信息', many=True, required=False)
@ -251,3 +265,16 @@ class MlogAnaSerializer(serializers.Serializer):
start_date = serializers.DateField(label='开始日期', required=True)
end_date = serializers.DateField(label='结束日期', required=True)
material_cate = serializers.CharField(label='物料系列', required=False)
class AttLogSerializer(CustomModelSerializer):
mgroup_name = serializers.CharField(
source='sflog.mgroup.name', read_only=True)
user_name = serializers.CharField(source='user.name', read_only=True)
post_name = serializers.CharField(source='post.name', read_only=True)
belong_dept_name = serializers.CharField(
source='sflog.mgroup.belong_dept.name', read_only=True)
class Meta:
model = AttLog
fields = '__all__'

View File

@ -16,8 +16,10 @@ from apps.mtm.models import Mgroup, Shift, Material, Route
from .models import SfLog, SfLogExp, WMaterial, Mlog, Mlogb, Handover
def make_sflogs(mgroup: Mgroup, start_date: datetime.date, end_date: datetime.date):
for shift in Shift.objects.all():
def make_sflogs(mgroup: Mgroup, start_date: datetime.date, end_date: datetime.date, create_by=None):
shift_rule = mgroup.shift_rule
shifts = Shift.objects.filter(rule=shift_rule) # 根据排班规则制定排班记录
for shift in shifts:
start_time_o = shift.start_time_o
end_time_o = shift.end_time_o
current_date = start_date
@ -26,12 +28,16 @@ def make_sflogs(mgroup: Mgroup, start_date: datetime.date, end_date: datetime.da
end_time = datetime.datetime.combine(current_date, end_time_o)
if start_time > end_time:
start_time -= datetime.timedelta(days=1)
duration = end_time - start_time
total_hours_now = duration.total_seconds() / 3600
SfLog.objects.get_or_create(mgroup=mgroup, shift=shift, start_time=start_time, defaults={
"mgroup": mgroup,
"shift": shift,
"work_date": current_date,
"start_time": start_time,
"end_time": end_time,
"total_hour_now": 12
"total_hour_now": total_hours_now,
"create_by": create_by
})
current_date = current_date + datetime.timedelta(days=1)

View File

@ -41,7 +41,8 @@ def get_total_hour_now(sflogId: str):
if sflogId:
sflog = SfLog.objects.get(id=sflogId)
if sflog.end_time <= now:
sflog.total_hour_now = 12 # 写死的数据不是很好
sflog.total_hour_now = (
sflog.end_time-sflog.start_time).total_seconds()/3600 # 写死的数据不是很好
else:
total_hour_now = (now-sflog.start_time).total_seconds()/3600
sflog.total_hour_now = total_hour_now if total_hour_now > 0 else 0

View File

@ -1,7 +1,7 @@
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from apps.wpm.views import SfLogViewSet, StLogViewSet, SfLogExpViewSet, WMaterialViewSet, MlogViewSet, HandoverViewSet
from apps.wpm.views import SfLogViewSet, StLogViewSet, SfLogExpViewSet, WMaterialViewSet, MlogViewSet, HandoverViewSet, AttlogViewSet
API_BASE_URL = 'api/wpm/'
@ -14,6 +14,7 @@ router.register('sflogexp', SfLogExpViewSet, basename='sflogexp')
router.register('wmaterial', WMaterialViewSet, basename='wmaterial')
router.register('mlog', MlogViewSet, basename='mlog')
router.register('handover', HandoverViewSet, basename='handover')
router.register('attlog', AttlogViewSet, basename='attlog')
urlpatterns = [
path(API_BASE_URL, include(router.urls)),
]

View File

@ -14,10 +14,10 @@ from apps.utils.viewsets import CustomGenericViewSet, CustomModelViewSet
from apps.utils.mixins import BulkCreateModelMixin
from .filters import SfLogExpFilter, SfLogFilter, WMaterialFilter, MlogFilter, HandoverFilter
from .models import SfLog, SfLogExp, StLog, WMaterial, Mlog, Handover, Mlogb
from .models import SfLog, SfLogExp, StLog, WMaterial, Mlog, Handover, Mlogb, AttLog
from .serializers import (SflogExpSerializer, SfLogSerializer, StLogSerializer, WMaterialSerializer,
MlogSerializer, MlogRelatedSerializer, DeptBatchSerializer, HandoverSerializer,
GenHandoverSerializer, GenHandoverWmSerializer, MlogAnaSerializer)
GenHandoverSerializer, GenHandoverWmSerializer, MlogAnaSerializer, AttLogSerializer)
from .services import mlog_submit, update_mtask, handover_submit
# Create your views here.
@ -304,3 +304,12 @@ class HandoverViewSet(CustomModelViewSet):
create_by=user
)
return Response()
class AttlogViewSet(CustomModelViewSet):
queryset = AttLog.objects.all()
serializer_class = AttLogSerializer
select_related_fields = ['user', 'post', 'sflog']
filterset_fields = ['sflog__mgroup',
'sflog__mgroup__belong_dept__name', 'sflog__work_date', 'sflog__mgroup__cate', 'sflog__mgroup__need_enm']
ordering = ['-sflog__work_date', 'create_time']