factory/apps/mpr/views.py

174 lines
6.6 KiB
Python

from rest_framework.exceptions import ParseError
from django.db import transaction
from apps.utils.viewsets import CustomModelViewSet
from apps.wf.mixins import TicketMixin
from apps.wf.models import Ticket
from apps.mpr.models import (
PurchaseRequisition, PurchaseRequisitionItem,
WarehouseEntry, WarehouseEntryItem, WarehouseStock,
MaterialRequisition, MaterialRequisitionItem,
)
from apps.mpr.serializers import (
PurchaseRequisitionListSerializer,
PurchaseRequisitionDetailSerializer,
PurchaseRequisitionCreateSerializer,
PurchaseRequisitionItemSerializer,
WarehouseEntryListSerializer,
WarehouseEntryDetailSerializer,
WarehouseEntryCreateSerializer,
WarehouseEntryItemSerializer,
WarehouseStockSerializer,
MaterialRequisitionListSerializer,
MaterialRequisitionDetailSerializer,
MaterialRequisitionCreateSerializer,
MaterialRequisitionItemSerializer,
)
from apps.mpr.filters import (
PurchaseRequisitionFilter, WarehouseEntryFilter,
WarehouseStockFilter, MaterialRequisitionFilter,
)
class PurchaseRequisitionViewSet(TicketMixin, CustomModelViewSet):
"""
物资申购单
"""
queryset = PurchaseRequisition.objects.all()
serializer_class = PurchaseRequisitionListSerializer
retrieve_serializer_class = PurchaseRequisitionDetailSerializer
create_serializer_class = PurchaseRequisitionCreateSerializer
update_serializer_class = PurchaseRequisitionCreateSerializer
select_related_fields = ['create_by', 'belong_dept', 'ticket', 'ticket__state']
search_fields = ['number', 'create_by__name']
filterset_class = PurchaseRequisitionFilter
ordering = '-create_time'
workflow_key = 'wf_mpr'
def gen_other_ticket_data(self, instance):
dept_name = instance.belong_dept.name if instance.belong_dept else ''
return {"dept_name": dept_name}
class PurchaseRequisitionItemViewSet(CustomModelViewSet):
"""
物资申购明细
"""
queryset = PurchaseRequisitionItem.objects.all()
serializer_class = PurchaseRequisitionItemSerializer
filterset_fields = ['requisition']
ordering = 'create_time'
class WarehouseEntryViewSet(TicketMixin, CustomModelViewSet):
"""
仓库入库单
"""
queryset = WarehouseEntry.objects.all()
serializer_class = WarehouseEntryListSerializer
retrieve_serializer_class = WarehouseEntryDetailSerializer
create_serializer_class = WarehouseEntryCreateSerializer
update_serializer_class = WarehouseEntryCreateSerializer
select_related_fields = ['create_by', 'belong_dept', 'warehouse', 'ticket', 'ticket__state']
search_fields = ['number', 'create_by__name', 'warehouse__name']
filterset_class = WarehouseEntryFilter
ordering = '-create_time'
workflow_key = 'wf_warehouse_entry'
def gen_other_ticket_data(self, instance):
return {"warehouse_name": instance.warehouse.name if instance.warehouse else ''}
@staticmethod
def approve_entry(ticket: Ticket, transition, new_ticket_data: dict):
"""审批通过后,将入库明细写入物料库存"""
entry: WarehouseEntry = WarehouseEntry.objects.get(ticket=ticket)
if WarehouseStock.objects.filter(entry=entry).exists():
raise ParseError('该入库单已入库,不可重复操作')
for item in entry.items.all():
WarehouseStock.objects.create(
warehouse=entry.warehouse,
entry=entry,
entry_number=entry.number,
entry_date=entry.entry_date,
entry_type=entry.entry_type,
entry_method=entry.entry_method,
name=item.name,
spec=item.spec,
unit=item.unit,
quantity=item.quantity,
unit_price=item.unit_price,
amount=item.amount,
supplier_name=item.supplier_name,
invoice_received=item.invoice_received,
)
class WarehouseEntryItemViewSet(CustomModelViewSet):
"""
入库明细
"""
queryset = WarehouseEntryItem.objects.all()
serializer_class = WarehouseEntryItemSerializer
filterset_fields = ['entry']
ordering = 'create_time'
class WarehouseStockViewSet(CustomModelViewSet):
"""
物料库存
"""
queryset = WarehouseStock.objects.all()
serializer_class = WarehouseStockSerializer
select_related_fields = ['warehouse', 'entry']
search_fields = ['name', 'spec', 'supplier_name', 'entry_number']
filterset_class = WarehouseStockFilter
ordering = '-create_time'
perms_map = {'get': '*', 'post': 'warehouse_stock.create',
'put': 'warehouse_stock.update', 'delete': 'warehouse_stock.delete'}
class MaterialRequisitionViewSet(TicketMixin, CustomModelViewSet):
"""
物资领用单
"""
queryset = MaterialRequisition.objects.all()
serializer_class = MaterialRequisitionListSerializer
retrieve_serializer_class = MaterialRequisitionDetailSerializer
create_serializer_class = MaterialRequisitionCreateSerializer
update_serializer_class = MaterialRequisitionCreateSerializer
select_related_fields = ['create_by', 'belong_dept', 'ticket', 'ticket__state']
search_fields = ['number', 'create_by__name', 'collector']
filterset_class = MaterialRequisitionFilter
ordering = '-create_time'
workflow_key = 'wf_material_requis'
def gen_other_ticket_data(self, instance):
dept_name = instance.belong_dept.name if instance.belong_dept else ''
return {"dept_name": dept_name, "collector": instance.collector or ''}
@staticmethod
def approve_requisition(ticket: Ticket, transition, new_ticket_data: dict):
"""审批通过后,将库存物品状态改为已领用"""
req = MaterialRequisition.objects.get(ticket=ticket)
for item in req.items.filter(is_stock_item=True, stock__isnull=False):
stock = WarehouseStock.objects.select_for_update().get(id=item.stock_id)
stock.status = 'requisitioned'
stock.save(update_fields=['status'])
@staticmethod
def reject_requisition(ticket: Ticket, transition, new_ticket_data: dict):
"""审批拒绝后,恢复库存数量和状态"""
from apps.mpr.serializers import MaterialRequisitionCreateSerializer
req = MaterialRequisition.objects.get(ticket=ticket)
MaterialRequisitionCreateSerializer._restore_stock(req)
class MaterialRequisitionItemViewSet(CustomModelViewSet):
"""
物资领用明细
"""
queryset = MaterialRequisitionItem.objects.all()
serializer_class = MaterialRequisitionItemSerializer
filterset_fields = ['requisition']
ordering = 'create_time'