174 lines
6.6 KiB
Python
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'
|