serializers.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. from rest_framework import serializers
  2. from .models import InboundBill, MaterialDetail ,OutboundBill, OutMaterialDetail
  3. from utils import datasolve
  4. class InboundApplySerializer(serializers.ModelSerializer):
  5. """
  6. 生产入库申请序列化器
  7. """
  8. class Meta:
  9. model = InboundBill
  10. fields = '__all__'
  11. ordering_fields = ['update_time', 'create_time']
  12. read_only_fields = ['billId', 'number', 'type', 'date', 'department', 'warehouse', 'creater', 'note', 'totalCount']
  13. class OutboundApplySerializer(serializers.ModelSerializer):
  14. """
  15. 生产出库申请序列化器
  16. """
  17. class Meta:
  18. model = OutboundBill
  19. fields = '__all__'
  20. ordering_fields = ['update_time', 'create_time']
  21. read_only_fields = ['billId', 'number', 'type', 'date', 'department', 'warehouse', 'creater', 'note', 'totalCount']
  22. class boundPostSerializer(serializers.Serializer):
  23. """
  24. 生产入库申请序列化器
  25. """
  26. billId = serializers.IntegerField(required=True, label='原始单据ID')
  27. number = serializers.CharField(required=True, label='单据编号')
  28. type = serializers.IntegerField(required=True, label='绑定类型')
  29. date = serializers.CharField(required=True, label='入库时间')
  30. department = serializers.CharField(required=True, label='部门')
  31. warehouse = serializers.CharField(required=True, label='仓库')
  32. creater = serializers.CharField(required=True, label='创建人')
  33. note = serializers.CharField(required=False, label='备注说明')
  34. totalCount = serializers.IntegerField(required=True, label='总条目数')
  35. materials = serializers.ListField(required=True, label='物料明细')
  36. class Meta:
  37. fields = ['billId', 'number', 'type', 'date', 'department', 'warehouse', 'creater', 'note', 'totalCount','materials']
  38. def validate_materials(self, value):
  39. """
  40. 增强版物料明细验证
  41. 返回带具体缺失字段的错误信息
  42. """
  43. required_fields = [
  44. 'entryIds', 'production_batch',
  45. 'goods_code', 'goods_name', 'goods_std',
  46. 'plan_qty',
  47. 'goods_unit'
  48. ]
  49. errors = []
  50. for index, item in enumerate(value):
  51. # 识别缺失字段
  52. missing_fields = [field for field in required_fields if field not in item]
  53. if missing_fields:
  54. errors.append({
  55. "index": index,
  56. "entryIds": item.get('entryIds'), # 保留原始标识
  57. "production_batch": item.get('production_batch'),
  58. "missing_fields": missing_fields,
  59. "message": f"第{index+1}条物料缺少必填字段: {', '.join(missing_fields)}"
  60. })
  61. if errors:
  62. # 抛出结构化错误
  63. raise serializers.ValidationError([
  64. {
  65. "detail": error["message"],
  66. "metadata": {
  67. "entryIds": error["entryIds"],
  68. "production_batch": error["production_batch"],
  69. "missing_fields": error["missing_fields"]
  70. }
  71. } for error in errors
  72. ])
  73. return value
  74. class MaterialDetailSerializer(serializers.ModelSerializer):
  75. """
  76. 物料明细序列化器
  77. """
  78. class Meta:
  79. model = MaterialDetail
  80. exclude = ['id', 'note']
  81. read_only_fields = ['entryIds', 'production_batch', 'goods_code', 'goods_name', 'goods_std', 'goods_weight', 'plan_qty', 'goods_total_weight', 'goods_unit', 'note']
  82. class OutMaterialDetailSerializer(serializers.ModelSerializer):
  83. """
  84. 物料明细序列化器
  85. """
  86. class Meta:
  87. model = OutMaterialDetail
  88. exclude = ['id', 'note']
  89. read_only_fields = ['entryIds', 'production_batch', 'goods_code', 'goods_name', 'goods_weight', 'goods_out_qty', 'goods_total_weight', 'goods_unit', 'note']
  90. class outboundPostSerializer(serializers.Serializer):
  91. """
  92. 生产入库申请序列化器
  93. """
  94. billId = serializers.IntegerField(required=True, label='原始单据ID')
  95. number = serializers.CharField(required=True, label='单据编号')
  96. type = serializers.IntegerField(required=True, label='绑定类型')
  97. date = serializers.CharField(required=True, label='出库时间')
  98. department = serializers.CharField(required=True, label='部门')
  99. warehouse = serializers.CharField(required=True, label='仓库')
  100. creater = serializers.CharField(required=True, label='创建人')
  101. note = serializers.CharField(required=False, label='备注说明')
  102. totalCount = serializers.IntegerField(required=True, label='总条目数')
  103. materials = serializers.ListField(required=True, label='物料明细')
  104. class Meta:
  105. fields = ['billId', 'number', 'type', 'date', 'department', 'warehouse', 'creater', 'note', 'totalCount','materials']
  106. def validate_materials(self, value):
  107. """
  108. 增强版物料明细验证
  109. 返回带具体缺失字段的错误信息
  110. """
  111. required_fields = [
  112. 'entryIds', 'production_batch',
  113. 'goods_code', 'goods_name',
  114. 'goods_out_qty',
  115. 'goods_unit'
  116. ]
  117. errors = []
  118. for index, item in enumerate(value):
  119. # 识别缺失字段
  120. missing_fields = [field for field in required_fields if field not in item]
  121. if missing_fields:
  122. errors.append({
  123. "index": index,
  124. "entryIds": item.get('entryIds'), # 保留原始标识
  125. "production_batch": item.get('production_batch'),
  126. "missing_fields": missing_fields,
  127. "message": f"第{index+1}条物料缺少必填字段: {', '.join(missing_fields)}"
  128. })
  129. if errors:
  130. # 抛出结构化错误
  131. raise serializers.ValidationError([
  132. {
  133. "detail": error["message"],
  134. "metadata": {
  135. "entryIds": error["entryIds"],
  136. "production_batch": error["production_batch"],
  137. "missing_fields": error["missing_fields"]
  138. }
  139. } for error in errors
  140. ])
  141. return value