139 lines
5.5 KiB
Python
139 lines
5.5 KiB
Python
|
|
from rest_framework import serializers
|
||
|
|
from django.db import transaction
|
||
|
|
from .models import (
|
||
|
|
Device, DeviceSerial, DeviceIP, MaintenanceRecord, DeviceAttachment
|
||
|
|
)
|
||
|
|
from loguru import logger
|
||
|
|
|
||
|
|
|
||
|
|
class DeviceSerialSerializer(serializers.ModelSerializer):
|
||
|
|
class Meta:
|
||
|
|
model = DeviceSerial
|
||
|
|
fields = ['id', 'serial_number', 'serial_type', 'is_primary', 'remark']
|
||
|
|
|
||
|
|
|
||
|
|
class DeviceIPSerializer(serializers.ModelSerializer):
|
||
|
|
class Meta:
|
||
|
|
model = DeviceIP
|
||
|
|
fields = ['id', 'ip_address', 'ip_type', 'is_primary', 'subnet_mask', 'gateway', 'vlan_id']
|
||
|
|
|
||
|
|
|
||
|
|
class MaintenanceRecordSerializer(serializers.ModelSerializer):
|
||
|
|
class Meta:
|
||
|
|
model = MaintenanceRecord
|
||
|
|
fields = ['id', 'maintenance_date', 'fault_description', 'repair_content',
|
||
|
|
'replaced_parts', 'maintenance_by', 'cost', 'remark']
|
||
|
|
|
||
|
|
|
||
|
|
class DeviceAttachmentSerializer(serializers.ModelSerializer):
|
||
|
|
class Meta:
|
||
|
|
model = DeviceAttachment
|
||
|
|
fields = ['id', 'file', 'file_name', 'file_type', 'uploaded_at']
|
||
|
|
read_only_fields = ['uploaded_at']
|
||
|
|
|
||
|
|
|
||
|
|
class DeviceSerializer(serializers.ModelSerializer):
|
||
|
|
serials = DeviceSerialSerializer(many=True, required=False)
|
||
|
|
ips = DeviceIPSerializer(many=True, required=False)
|
||
|
|
maintenance_records = MaintenanceRecordSerializer(many=True, read_only=True)
|
||
|
|
attachments = DeviceAttachmentSerializer(many=True, read_only=True)
|
||
|
|
service_duration_days = serializers.IntegerField(read_only=True)
|
||
|
|
is_warranty_expired = serializers.BooleanField(read_only=True)
|
||
|
|
primary_serial = serializers.SerializerMethodField()
|
||
|
|
primary_ip = serializers.SerializerMethodField()
|
||
|
|
latest_maintenance = serializers.SerializerMethodField()
|
||
|
|
|
||
|
|
class Meta:
|
||
|
|
model = Device
|
||
|
|
fields = ['id', 'location', 'building', 'floor', 'cabinet', 'device_name',
|
||
|
|
'model', 'brand', 'mac_address', 'enable_date', 'last_inspection_date',
|
||
|
|
'thumbnail', 'status', 'responsible_person', 'warranty_expire',
|
||
|
|
'service_duration_days', 'is_warranty_expired', 'primary_serial',
|
||
|
|
'primary_ip', 'latest_maintenance', 'serials', 'ips',
|
||
|
|
'maintenance_records', 'attachments', 'created_at', 'updated_at']
|
||
|
|
read_only_fields = ['created_at', 'updated_at']
|
||
|
|
|
||
|
|
def get_primary_serial(self, obj):
|
||
|
|
primary = obj.serials.filter(is_primary=True).first()
|
||
|
|
if primary:
|
||
|
|
return DeviceSerialSerializer(primary).data
|
||
|
|
return None
|
||
|
|
|
||
|
|
def get_primary_ip(self, obj):
|
||
|
|
primary = obj.ips.filter(is_primary=True).first()
|
||
|
|
if primary:
|
||
|
|
return DeviceIPSerializer(primary).data
|
||
|
|
return None
|
||
|
|
|
||
|
|
def get_latest_maintenance(self, obj):
|
||
|
|
latest = obj.maintenance_records.first()
|
||
|
|
if latest:
|
||
|
|
return MaintenanceRecordSerializer(latest).data
|
||
|
|
return None
|
||
|
|
|
||
|
|
@transaction.atomic
|
||
|
|
def create(self, validated_data):
|
||
|
|
serials_data = validated_data.pop('serials', [])
|
||
|
|
ips_data = validated_data.pop('ips', [])
|
||
|
|
|
||
|
|
device = Device.objects.create(**validated_data)
|
||
|
|
|
||
|
|
for serial_data in serials_data:
|
||
|
|
DeviceSerial.objects.create(device=device, **serial_data)
|
||
|
|
|
||
|
|
for ip_data in ips_data:
|
||
|
|
DeviceIP.objects.create(device=device, **ip_data)
|
||
|
|
|
||
|
|
logger.info(f'Created device: {device.id} - {device.device_name}')
|
||
|
|
return device
|
||
|
|
|
||
|
|
@transaction.atomic
|
||
|
|
def update(self, instance, validated_data):
|
||
|
|
serials_data = validated_data.pop('serials', None)
|
||
|
|
ips_data = validated_data.pop('ips', None)
|
||
|
|
|
||
|
|
for attr, value in validated_data.items():
|
||
|
|
setattr(instance, attr, value)
|
||
|
|
instance.save()
|
||
|
|
|
||
|
|
if serials_data is not None:
|
||
|
|
instance.serials.all().delete()
|
||
|
|
for serial_data in serials_data:
|
||
|
|
DeviceSerial.objects.create(device=instance, **serial_data)
|
||
|
|
|
||
|
|
if ips_data is not None:
|
||
|
|
instance.ips.all().delete()
|
||
|
|
for ip_data in ips_data:
|
||
|
|
DeviceIP.objects.create(device=instance, **ip_data)
|
||
|
|
|
||
|
|
logger.info(f'Updated device: {instance.id}')
|
||
|
|
return instance
|
||
|
|
|
||
|
|
|
||
|
|
class DeviceListSerializer(serializers.ModelSerializer):
|
||
|
|
primary_serial_number = serializers.SerializerMethodField()
|
||
|
|
primary_ip_address = serializers.SerializerMethodField()
|
||
|
|
latest_maintenance_summary = serializers.SerializerMethodField()
|
||
|
|
service_duration_days = serializers.IntegerField(read_only=True)
|
||
|
|
|
||
|
|
class Meta:
|
||
|
|
model = Device
|
||
|
|
fields = ['id', 'location', 'building', 'device_name', 'model', 'brand',
|
||
|
|
'status', 'responsible_person', 'enable_date', 'thumbnail',
|
||
|
|
'primary_serial_number', 'primary_ip_address',
|
||
|
|
'latest_maintenance_summary', 'service_duration_days']
|
||
|
|
|
||
|
|
def get_primary_serial_number(self, obj):
|
||
|
|
primary = obj.serials.filter(is_primary=True).first()
|
||
|
|
return primary.serial_number if primary else None
|
||
|
|
|
||
|
|
def get_primary_ip_address(self, obj):
|
||
|
|
primary = obj.ips.filter(is_primary=True).first()
|
||
|
|
return primary.ip_address if primary else None
|
||
|
|
|
||
|
|
def get_latest_maintenance_summary(self, obj):
|
||
|
|
latest = obj.maintenance_records.first()
|
||
|
|
if latest:
|
||
|
|
return f"{latest.maintenance_date}: {latest.fault_description[:50]}..." if latest.fault_description else str(latest.maintenance_date)
|
||
|
|
return None
|