diff --git a/Inventory/models/entry.py b/Inventory/models/entry.py index a1ce9a5..9bd5e03 100644 --- a/Inventory/models/entry.py +++ b/Inventory/models/entry.py @@ -97,7 +97,7 @@ def create_entry(cls, bidding_sheet, inspections): """ entry = cls( bidding_sheet=bidding_sheet, - source=bidding_sheet.biddingacceptance.accept_supplier.name) + source=bidding_sheet.bidding_acceptance.accept_supplier.name) entry.save() details = [] for inspection in inspections: diff --git a/Procurement/api/bidding.py b/Procurement/api/bidding.py index fbf19d1..0dfa00f 100644 --- a/Procurement/api/bidding.py +++ b/Procurement/api/bidding.py @@ -14,8 +14,9 @@ class BiddingSheetViewSet(viewsets.ModelViewSet): def get_serializer_class(self): if self.action == 'list': return serializers.BiddingSheetListSerializer - else: - return serializers.BaseBiddingSheetSerializer + elif self.action == 'retrieve': + return serializers.BiddingSheetReadSerializer + return serializers.BaseBiddingSheetSerializer # 招标申请 @@ -38,6 +39,7 @@ class BiddingAcceptanceViewSet(viewsets.ModelViewSet): pagination_class = SmallResultsSetPagination queryset = models.BiddingAcceptance.objects.all().order_by('-pk') serializer_class = serializers.BaseBiddingAcceptanceSerializer + filter_class = filters.BiddingAcceptanceFilter # 比质比价卡 diff --git a/Procurement/filters/__init__.py b/Procurement/filters/__init__.py index 523e3dd..d877619 100644 --- a/Procurement/filters/__init__.py +++ b/Procurement/filters/__init__.py @@ -1,6 +1,7 @@ from .procurement import (PurchaseOrderFilter, ProcurementMaterialFilter) -from .bidding import (BiddingSheetFilter, BiddingApplicationFilter) +from .bidding import (BiddingSheetFilter, BiddingApplicationFilter, + BiddingAcceptanceFilter) from .supplier import (SupplyRelationshipFilter, SupplyDocumentFilter, SupplyQuotationFilter, SupplierFilter) @@ -20,4 +21,4 @@ 'MaterialSubApplyFilter', 'MaterialExcutionFilter', 'SupplyDocumentFilter', 'SupplyQuotationFilter', 'ContractDetailFilter', 'MaterialExecutionDetailFilter', - 'SupplierFilter'] + 'BiddingAcceptanceFilter', 'SupplierFilter'] diff --git a/Procurement/filters/bidding.py b/Procurement/filters/bidding.py index 46ab768..42adc4a 100644 --- a/Procurement/filters/bidding.py +++ b/Procurement/filters/bidding.py @@ -1,11 +1,13 @@ from django_filters import rest_framework as filters from Procurement import models +from Procurement import BIDDING_SHEET_STATUS_CHOICES # 根据标单编号模糊查询 class BiddingSheetFilter(filters.FilterSet): uid = filters.CharFilter(name='uid', lookup_expr='icontains') - status = filters.ChoiceFilter(name='status', lookup_expr='exact') + status = filters.MultipleChoiceFilter( + name='status', choices=BIDDING_SHEET_STATUS_CHOICES) class Meta: model = models.BiddingSheet @@ -19,3 +21,12 @@ class BiddingApplicationFilter(filters.FilterSet): class Meta: model = models.BiddingApplication fields = ('uid', 'status') + + +class BiddingAcceptanceFilter(filters.FilterSet): + bidding_sheet = filters.CharFilter(name='bidding_sheet', + lookup_expr='exact') + + class Meta: + model = models.BiddingAcceptance + fields = ('bidding_sheet',) diff --git a/Procurement/filters/procurement.py b/Procurement/filters/procurement.py index 05fcd52..4ffc28e 100644 --- a/Procurement/filters/procurement.py +++ b/Procurement/filters/procurement.py @@ -3,7 +3,7 @@ from Procurement.models import (PurchaseOrder, ProcurementMaterial) from Procurement import PURCHASE_ORDER_STATUS_CHOICES from Process.models import (ProcessMaterial) -from Procurement import (PROCUREMENT_MATERIAL_STATUS, ) +from Procurement import (PROCUREMENT_MATERIAL_STATUS, INVENTORY_TYPE) class PurchaseOrderFilter(filters.FilterSet): @@ -19,25 +19,29 @@ class Meta: class ProcurementMaterialFilter(filters.FilterSet): - - purchase_order = filters.CharFilter(name='purchase_order', - lookup_expr='exact') - inventory_type = filters.CharFilter(name='inventory_type', - lookup_expr='exact') purchase_order_uid = filters.CharFilter(method='filter_purchase_order') process_material_name = filters.CharFilter( method='filter_process_material_name') + sub_work_order_uid = filters.CharFilter(method='filter_sub_work_order_uid') + status = filters.MultipleChoiceFilter(name='status', choices=PROCUREMENT_MATERIAL_STATUS) finished = filters.BooleanFilter(name='finished', lookup_expr='exact') + purchase_order = filters.CharFilter(name='purchase_order', + lookup_expr='exact') + + inventory_type = filters.ChoiceFilter(name='inventory_type', + choices=INVENTORY_TYPE) + class Meta: model = ProcurementMaterial - fields = ('purchase_order', 'inventory_type', 'purchase_order_uid', - 'process_material_name', 'status', 'finished') + fields = ('purchase_order_uid', 'process_material_name', + 'sub_work_order_uid', 'purchase_order', 'status', 'finished', + 'inventory_type') def filter_purchase_order(self, query_set, name, value): purchase_order = PurchaseOrder.objects.filter(uid=value) @@ -56,3 +60,13 @@ def filter_process_material_name(self, query_set, name, value): procurement_materials = self.Meta.model.objects.filter( process_material__in=process_materials) return procurement_materials + + def filter_sub_work_order_uid(self, query_set, name, value): + value = value.split('-') # 参见SubWorkOrder模型定义 + if not value or len(value) != 2 or '' in value: + return self.Meta.model.objects.none() + procurement_materials = self.Meta.model.objects.filter( + sub_order__work_order__uid=value[0], sub_order__index=value[1]) + if not procurement_materials: + return self.Meta.model.objects.none() + return procurement_materials diff --git a/Procurement/migrations/0013_auto_20180124_1648.py b/Procurement/migrations/0013_auto_20180124_1648.py new file mode 100644 index 0000000..6bad9a1 --- /dev/null +++ b/Procurement/migrations/0013_auto_20180124_1648.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2018-01-24 08:48 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('Procurement', '0012_auto_20180122_2046'), + ] + + operations = [ + migrations.AlterField( + model_name='biddingacceptance', + name='bidding_sheet', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='bidding_acceptance', to='Procurement.BiddingSheet', verbose_name='标单'), + ), + migrations.AlterField( + model_name='biddingapplication', + name='bidding_sheet', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='bidding_application', to='Procurement.BiddingSheet', verbose_name='标单'), + ), + migrations.AlterField( + model_name='parityratiocard', + name='bidding_sheet', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='parity_ratio_card', to='Procurement.BiddingSheet', verbose_name='标单'), + ), + ] diff --git a/Procurement/migrations/0014_merge_20180125_1059.py b/Procurement/migrations/0014_merge_20180125_1059.py new file mode 100644 index 0000000..e5499bd --- /dev/null +++ b/Procurement/migrations/0014_merge_20180125_1059.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.6 on 2018-01-25 02:59 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('Procurement', '0013_auto_20180125_0023'), + ('Procurement', '0013_auto_20180124_1648'), + ] + + operations = [ + ] diff --git a/Procurement/models/bidding.py b/Procurement/models/bidding.py index 89420e6..22cb6dd 100644 --- a/Procurement/models/bidding.py +++ b/Procurement/models/bidding.py @@ -73,130 +73,130 @@ def payable_amount(self): @transition(field='status', source=BIDDING_SHEET_STATUS_CREATE, target=BIDDING_SHEET_STATUS_SELECT_SUPPLLER_APPROVED) - def select_supplier_approved(): + def select_supplier_approved(self, request): # TODO pass @transition( field='status', source=BIDDING_SHEET_STATUS_SELECT_SUPPLLER_APPROVED, target=BIDDING_SHEET_STATUS_INVITE_BID_APPLY_SELECT) - def invite_bid_apply_selected(): + def invite_bid_apply_selected(self, request): # TODO pass @transition( field='status', source=BIDDING_SHEET_STATUS_INVITE_BID_APPLY_SELECT, target=BIDDING_SHEET_STATUS_INVITE_BID_FILL) - def invite_bid_filled(): + def invite_bid_filled(self, request): # TODO pass @transition(field='status', source=BIDDING_SHEET_STATUS_INVITE_BID_FILL, target=BIDDING_SHEET_STATUS_INVITE_BID_CARRY) - def invite_bid_carried(): + def invite_bid_carried(self, request): # TODO pass @transition(field='status', source=BIDDING_SHEET_STATUS_INVITE_BID_CARRY, target=BIDDING_SHEET_STATUS_INVITE_BID_COMPLETE) - def invite_bid_completed(): + def invite_bid_completed(self, request): # TODO pass @transition( field='status', source=BIDDING_SHEET_STATUS_INVITE_BID_COMPLETE, target=BIDDING_SHEET_STATUS_PROCESS_FOLLOW) - def process_followed(): + def process_followed(self, request): # TODO pass @transition(field='status', source=BIDDING_SHEET_STATUS_PROCESS_FOLLOW, target=BIDDING_SHEET_STATUS_CHECK) - def checked(): + def checked(self, request): # TODO pass @transition(field='status', source=BIDDING_SHEET_STATUS_CHECK, target=BIDDING_SHEET_STATUS_STORE) - def stored(): + def stored(self, request): # TODO pass @transition(field='status', source=BIDDING_SHEET_STATUS_STORE, target=BIDDING_SHEET_STATUS_COMPLETE) - def completed(): + def completed(self, request): # TODO pass @transition(field='status', source=BIDDING_SHEET_STATUS_COMPLETE, target=BIDDING_SHEET_STATUS_STOP) - def stopped(): + def stopped(self, request): # TODO pass # 状态回溯 @transition(field='status', source=BIDDING_SHEET_STATUS_STOP, target=BIDDING_SHEET_STATUS_COMPLETE) - def completed_rollback(): + def completed_rollback(self, request): # TODO pass @transition( field='status', source=BIDDING_SHEET_STATUS_COMPLETE, target=BIDDING_SHEET_STATUS_STORE) - def stored_rollback(): + def stored_rollback(self, request): # TODO pass @transition( field='status', source=BIDDING_SHEET_STATUS_STORE, target=BIDDING_SHEET_STATUS_CHECK) - def checked_rollback(): + def checked_rollback(self, request): # TODO pass @transition(field='status', source=BIDDING_SHEET_STATUS_CHECK, target=BIDDING_SHEET_STATUS_PROCESS_FOLLOW) - def process_follow_rollbacked(): + def process_follow_rollbacked(self, request): # TODO pass @transition(field='status', source=BIDDING_SHEET_STATUS_PROCESS_FOLLOW, target=BIDDING_SHEET_STATUS_INVITE_BID_COMPLETE) - def invite_bid_completed_rollback(): + def invite_bid_completed_rollback(self, request): # TODO pass @transition( field='status', source=BIDDING_SHEET_STATUS_INVITE_BID_COMPLETE, target=BIDDING_SHEET_STATUS_INVITE_BID_CARRY) - def invite_bid_carried_rollback(): + def invite_bid_carried_rollback(self, request): # TODO pass @transition(field='status', source=BIDDING_SHEET_STATUS_INVITE_BID_CARRY, target=BIDDING_SHEET_STATUS_INVITE_BID_FILL) - def invite_bid_filled_rollback(): + def invite_bid_filled_rollback(self, request): # TODO pass @transition(field='status', source=BIDDING_SHEET_STATUS_INVITE_BID_FILL, target=BIDDING_SHEET_STATUS_INVITE_BID_APPLY_SELECT) - def invite_bid_apply_selected_rollback(): + def invite_bid_apply_selected_rollback(self, request): # TODO pass @transition( field='status', source=BIDDING_SHEET_STATUS_INVITE_BID_APPLY_SELECT, target=BIDDING_SHEET_STATUS_SELECT_SUPPLLER_APPROVED) - def select_supplier_approved_rollback(): + def select_supplier_approved_rollback(self, request): # TODO pass @transition( field='status', source=BIDDING_SHEET_STATUS_SELECT_SUPPLLER_APPROVED, target=BIDDING_SHEET_STATUS_CREATE) - def created_rollback(): + def created_rollback(self, request): # TODO pass @@ -207,6 +207,7 @@ class BiddingApplication(models.Model, metaclass=TransitionMeta): 标单申请表 """ bidding_sheet = models.OneToOneField(BiddingSheet, verbose_name='标单', + related_name='bidding_application', on_delete=models.CASCADE) uid = models.CharField(verbose_name='标单申请编号', max_length=50, unique=True) @@ -247,49 +248,49 @@ def __str__(self): @transition( field='status', source=COMMENT_STATUS_APPLY_FILL, target=COMMENT_STATUS_APPLY_OPERATOR_COMMENT) - def operator_comment(): + def operator_comment(self, request): # TODO pass @transition( field='status', source=COMMENT_STATUS_APPLY_OPERATOR_COMMENT, target=COMMENT_STATUS_APPLY_LEAD_COMMENT) - def lead_comment(): + def lead_comment(self, request): # TODO pass @transition( field='status', source=COMMENT_STATUS_APPLY_LEAD_COMMENT, target=COMMENT_STATUS_APPLY_NEED_COMMENT) - def need_comment(): + def need_comment(self, request): # TODO pass @transition( field='status', source=COMMENT_STATUS_APPLY_NEED_COMMENT, target=COMMENT_STATUS_APPLY_CENTRALIZE_COMMENT) - def centralize_comment(): + def centralize_comment(self, request): # TODO pass @transition( field='status', source=COMMENT_STATUS_APPLY_CENTRALIZE_COMMENT, target=COMMENT_STATUS_APPLY_LOGISTICAL_COMMENT) - def logistical_comment(): + def logistical_comment(self, request): # TODO pass @transition( field='status', source=COMMENT_STATUS_APPLY_LOGISTICAL_COMMENT, target=COMMENT_STATUS_APPLY_COMPANY_COMMENT) - def company_comment(): + def company_comment(self, request): # TODO pass @transition( field='status', source=COMMENT_STATUS_APPLY_COMPANY_COMMENT, target=COMMENT_STATUS_APPLY_FINISH) - def finish(): + def finish(self, request): # TODO pass @@ -299,6 +300,7 @@ class ParityRatioCard(models.Model, metaclass=TransitionMeta): 比质比价卡 """ bidding_sheet = models.OneToOneField(BiddingSheet, verbose_name='标单', + related_name='parity_ratio_card', on_delete=models.CASCADE) apply_id = models.CharField(verbose_name='标单申请编号', max_length=20) applicant = models.CharField(verbose_name='申请单位', max_length=40) @@ -328,35 +330,35 @@ def __str__(self): @transition( field='status', source=COMMENT_STATUS_QUALITY_FILL, target=COMMENT_STATUS_QUALITY_OPERATOR_COMMENT) - def operator_comment(): + def operator_comment(self, request): # TODO pass @transition( field='status', source=COMMENT_STATUS_QUALITY_OPERATOR_COMMENT, target=COMMENT_STATUS_QUALITY_NEED_TECH_COMMENT) - def need_tech_comment(): + def need_tech_comment(self, request): # TODO pass @transition( field='status', source=COMMENT_STATUS_QUALITY_NEED_TECH_COMMENT, target=COMMENT_STATUS_QUALITY_NEED_LEAD_COMMENT) - def need_lead_comment(): + def need_lead_comment(self, request): # TODO pass @transition( field='status', source=COMMENT_STATUS_QUALITY_NEED_LEAD_COMMENT, target=COMMENT_STATUS_QUALITY_COMPREHENSIVE_COMMENT) - def comprehensive_comment(): + def comprehensive_comment(self, request): # TODO pass @transition( field='status', source=COMMENT_STATUS_QUALITY_COMPREHENSIVE_COMMENT, target=COMMENT_STATUS_QUALITY_COMPANY_COMMENT) - def company_comment(): + def company_comment(self, request): # TODO pass @@ -366,6 +368,7 @@ class BiddingAcceptance(models.Model): 中标通知书 """ bidding_sheet = models.OneToOneField(BiddingSheet, verbose_name='标单', + related_name='bidding_acceptance', on_delete=models.CASCADE) uid = models.CharField(verbose_name='标书编号', max_length=50, unique=True) # TODO: auto relate? diff --git a/Procurement/models/supplier.py b/Procurement/models/supplier.py index 479ce7d..9af3e34 100644 --- a/Procurement/models/supplier.py +++ b/Procurement/models/supplier.py @@ -59,35 +59,35 @@ def __str__(self): @transition( field='status', source=COMMENT_STATUS_CHECK_FILL, target=COMMENT_STATUS_CHECK_OPERATOR_COMMENT) - def operator_comment(): + def operator_comment(self, request): # TODO pass @transition( field='status', source=COMMENT_STATUS_CHECK_OPERATOR_COMMENT, target=COMMENT_STATUS_CHECK_LEAD_COMMENT) - def lead_comment(): + def lead_comment(self, request): # TODO pass @transition( field='status', source=COMMENT_STATUS_CHECK_LEAD_COMMENT, target=COMMENT_STATUS_CHECK_QUALITY_COMMENT) - def quality_comment(): + def quality_comment(self, request): # TODO pass @transition( field='status', source=COMMENT_STATUS_CHECK_QUALITY_COMMENT, target=COMMENT_STATUS_CHECK_ECONOMIC_COMMENT) - def economic_comment(): + def economic_comment(self, request): # TODO pass @transition( field='status', source=COMMENT_STATUS_CHECK_ECONOMIC_COMMENT, target=COMMENT_STATUS_CHECK_COMPREHENSIVE_COMMENT) - def comprehensive_comment(): + def comprehensive_comment(self, request): # TODO pass diff --git a/Procurement/serializers/__init__.py b/Procurement/serializers/__init__.py index e885ab8..ec81294 100644 --- a/Procurement/serializers/__init__.py +++ b/Procurement/serializers/__init__.py @@ -24,9 +24,9 @@ from .bidding import ( BaseBiddingSheetSerializer, BiddingSheetListSerializer, - BaseBiddingApplicationSerializer, BiddingApplicationListSerializer, - BiddingApplicationCreateSerializer, BaseBiddingAcceptanceSerializer, - BaseParityRatioCardSerializer, + BiddingSheetReadSerializer, BaseBiddingApplicationSerializer, + BiddingApplicationListSerializer, BiddingApplicationCreateSerializer, + BaseBiddingAcceptanceSerializer, BaseParityRatioCardSerializer ) from .other import ( diff --git a/Procurement/serializers/bidding.py b/Procurement/serializers/bidding.py index a2012d8..55d30b9 100644 --- a/Procurement/serializers/bidding.py +++ b/Procurement/serializers/bidding.py @@ -1,28 +1,7 @@ from rest_framework import serializers from Procurement import models -from Procurement.serializers import (BaseTransitionSerializer, - BaseDynamicFieldSerializer) - - -# 标单 -class BaseBiddingSheetSerializer(BaseTransitionSerializer): - purchase_order_uid = serializers.CharField(source='purchase_order.uid', - read_only=True) - - class Meta: - model = models.BiddingSheet - fields = ('id', 'uid', 'purchase_order', 'purchase_order_uid', - 'create_dt', 'status', 'contract_amount', 'billing_amount', - 'category') - - -class BiddingSheetListSerializer(BaseBiddingSheetSerializer): - - pretty_status = serializers.CharField(source='get_status_display') - - class Meta(BaseBiddingSheetSerializer.Meta): - fields = ('id', 'uid', 'purchase_order', 'purchase_order_uid', - 'create_dt', 'status', 'category', 'pretty_status') +from Procurement.serializers import ( + BaseTransitionSerializer, BaseDynamicFieldSerializer) # 标单申请表 @@ -60,8 +39,8 @@ class BaseBiddingAcceptanceSerializer(BaseDynamicFieldSerializer): class Meta: model = models.BiddingAcceptance fields = ('id', 'uid', 'bidding_sheet', 'requestor', 'content', - 'amount', 'accept_dt', 'accept_money', 'contact', - 'contact_phone') + 'amount', 'accept_dt', 'accept_money', 'accept_supplier', + 'contact', 'contact_phone') # 比质比价卡 @@ -71,3 +50,37 @@ class Meta: fields = ('id', 'bidding_sheet', 'apply_id', 'applicant', 'requestor', 'work_order', 'amount', 'unit', 'content', 'material', 'delivery_period', 'status') + + +# 标单 +class BaseBiddingSheetSerializer(BaseTransitionSerializer): + purchase_order_uid = serializers.CharField(source='purchase_order.uid', + read_only=True) + + class Meta: + model = models.BiddingSheet + fields = ('id', 'uid', 'purchase_order', 'purchase_order_uid', + 'create_dt', 'status', 'contract_amount', 'billing_amount', + 'category') + + +class BiddingSheetListSerializer(BaseBiddingSheetSerializer): + + pretty_status = serializers.CharField(source='get_status_display') + + class Meta(BaseBiddingSheetSerializer.Meta): + fields = ('id', 'uid', 'purchase_order', 'purchase_order_uid', + 'create_dt', 'status', 'category', 'pretty_status') + + +class BiddingSheetReadSerializer(BaseBiddingSheetSerializer): + pretty_status = serializers.CharField(source='get_status_display') + bidding_application = BaseBiddingApplicationSerializer(read_only=True) + bidding_acceptance = BaseBiddingAcceptanceSerializer(read_only=True) + parity_ratio_card = BaseParityRatioCardSerializer(read_only=True) + + class Meta(BaseBiddingSheetSerializer.Meta): + fields = ('id', 'uid', 'purchase_order', 'purchase_order_uid', + 'create_dt', 'status', 'category', 'pretty_status', + 'bidding_application', 'bidding_acceptance', + 'parity_ratio_card')