예제 #1
0
class OrderViewSet(CoreViewSet):
    """Order ViewSet"""

    required_scopes = (Scope.internal_front_end, )
    serializer_class = OrderSerializer
    queryset = Order.objects.select_related(
        'company',
        'contact',
        'primary_market',
    )

    @action(methods=['post'], detail=True, schema=StubSchema())
    def complete(self, request, *args, **kwargs):
        """Complete an order."""
        instance = self.get_object()
        serializer = CompleteOrderSerializer(
            instance,
            data={},
            context=self.get_serializer_context(),
        )
        serializer.is_valid(raise_exception=True)
        instance = serializer.complete()
        return Response(
            self.get_serializer(instance=instance).data,
            status=status.HTTP_200_OK,
        )

    @action(methods=['post'], detail=True, schema=StubSchema())
    def cancel(self, request, *args, **kwargs):
        """Cancel an order."""
        instance = self.get_object()
        serializer = CancelOrderSerializer(
            instance,
            data=request.data,
            context=self.get_serializer_context(),
        )
        serializer.is_valid(raise_exception=True)
        instance = serializer.cancel()
        return Response(
            self.get_serializer(instance=instance).data,
            status=status.HTTP_200_OK,
        )

    def get_serializer_context(self):
        """Extra context provided to the serializer class."""
        return {
            **super().get_serializer_context(),
            'current_user':
            self.request.user if self.request else None,
        }
예제 #2
0
class BaseEntityDocumentModelViewSet(CoreViewSet):
    """Documents ViewSet."""

    lookup_url_kwarg = 'entity_document_pk'

    def create(self, request, *args, **kwargs):
        """Create and one-time upload URL generation."""
        response = super().create(request, *args, **kwargs)
        entity_document = self.get_queryset().get(pk=response.data['id'])
        response.data['signed_upload_url'] = entity_document.document.get_signed_upload_url()

        return response

    @action(methods=['post'], detail=True, schema=StubSchema())
    def upload_complete_callback(self, request, *args, **kwargs):
        """File upload done callback."""
        entity_document = self.get_object()
        entity_document.document.schedule_av_scan()
        return self.retrieve(request)

    @action(methods=['get'], detail=True, schema=StubSchema())
    def download(self, request, *args, **kwargs):
        """Provides download information."""
        entity_document = self.get_object()

        if not entity_document.document.scanned_on:
            raise TemporarilyUnavailableException()

        if not entity_document.document.av_clean:
            raise PermissionDenied('File did not pass virus scanning.')

        url = entity_document.document.get_signed_url()

        response = super().retrieve(request)
        response.data['document_url'] = url
        return response

    def perform_destroy(self, instance):
        """
        Marks document with pending_delete status and schedules Celery task that
        performs deletion of corresponding s3 file, document and entity_document.

        Deletion of document will cascade to entity document.
        """
        instance.document.mark_deletion_pending()

        delete_document.apply_async(args=(instance.document.pk,))
예제 #3
0
class ArchivableViewSetMixin:
    """To be used with archivable models."""

    archive_validators = []
    unarchive_validators = []

    @action(methods=['post'], detail=True, schema=StubSchema())
    def archive(self, request, pk):
        """Archive the object."""
        obj = self.get_object()
        context = {
            'user': request.user,
        }
        archive_serializer = ArchiveSerializer(
            instance=obj,
            data=request.data,
            context=context,
            validators=self.archive_validators,
        )
        archive_serializer.is_valid(raise_exception=True)
        archive_serializer.save()

        obj_serializer = self.get_serializer_class()(obj)
        return Response(data=obj_serializer.data)

    @action(methods=['post'], detail=True, schema=StubSchema())
    def unarchive(self, request, pk):
        """Unarchive the object."""
        obj = self.get_object()
        unarchive_serializer = UnarchiveSerializer(
            instance=obj,
            data=request.data,
            validators=self.unarchive_validators,
        )
        unarchive_serializer.is_valid(raise_exception=True)
        unarchive_serializer.save()

        obj_serializer = self.get_serializer_class()(obj)
        return Response(data=obj_serializer.data)
예제 #4
0
class CompanyViewSet(ArchivableViewSetMixin, CoreViewSet):
    """Company view set."""

    serializer_class = CompanySerializer
    unarchive_validators = (NotATransferredCompanyValidator(), )
    filter_backends = (DjangoFilterBackend, OrderingFilter)
    filterset_fields = ('global_headquarters_id',
                        'global_ultimate_duns_number')
    ordering_fields = ('name', 'created_on')
    queryset = Company.objects.select_related(
        'address_country',
        'archived_by',
        'business_type',
        'employee_range',
        'export_experience_category',
        'global_headquarters__one_list_account_owner__dit_team__country',
        'global_headquarters__one_list_account_owner__dit_team__uk_region',
        'global_headquarters__one_list_account_owner__dit_team',
        'global_headquarters__one_list_account_owner',
        'global_headquarters__one_list_tier',
        'global_headquarters',
        'headquarter_type',
        'one_list_account_owner__dit_team__country',
        'one_list_account_owner__dit_team__uk_region',
        'one_list_account_owner__dit_team',
        'one_list_account_owner',
        'one_list_tier',
        'registered_address_country',
        'transferred_to',
        'turnover_range',
        'uk_region',
    ).prefetch_related(
        Prefetch('contacts', queryset=get_contact_queryset()),
        Prefetch('investor_investment_projects',
                 queryset=get_slim_investment_project_queryset()),
        'export_to_countries',
        'future_interest_countries',
        'sector__parent__parent',
        'sector__parent',
        'sector',
        Prefetch('export_countries', queryset=get_export_country_queryset()),
    )

    @action(
        methods=['post'],
        detail=True,
        permission_classes=[
            HasPermissions(
                f'company.{CompanyPermission.change_company}',
                f'company.{CompanyPermission.change_regional_account_manager}',
            ),
        ],
        schema=StubSchema(),
    )
    def assign_regional_account_manager(self, request, *args, **kwargs):
        """
        Sets the company to be an international trade adviser-managed One List company, and
        assigns the requested user as the account manager.

        This means:

        - setting the One List tier to 'Tier D - Interaction Trade Adviser Accounts' (using the
        tier ID, not the name)
        - setting the requested user as the One List account manager (overwriting the
        existing value)

        The operation is not allowed if:

        - the company is a subsidiary of a One List company
        - the company is already a One List company on a different tier (i.e. not 'Tier D -
        Interaction Trade Adviser Accounts')
        """
        instance = self.get_object()
        serializer = AssignRegionalAccountManagerSerializer(instance=instance,
                                                            data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save(request.user)
        return Response(None, status=status.HTTP_204_NO_CONTENT)

    @action(
        methods=['post'],
        detail=True,
        permission_classes=[
            HasPermissions(
                f'company.{CompanyPermission.change_company}',
                f'company.{CompanyPermission.change_regional_account_manager}',
            ),
        ],
        schema=StubSchema(),
    )
    def self_assign_account_manager(self, request, *args, **kwargs):
        """
        Sets the company to be an international trade adviser-managed One List company, and
        assigns the authenticated user as the account manager.

        This means:

        - setting the One List tier to 'Tier D - Interaction Trade Adviser Accounts' (using the
        tier ID, not the name)
        - setting the authenticated user as the One List account manager (overwriting the
        existing value)

        The operation is not allowed if:

        - the company is a subsidiary of a One List company
        - the company is already a One List company on a different tier (i.e. not 'Tier D -
        Interaction Trade Adviser Accounts')
        """
        instance = self.get_object()
        serializer = SelfAssignAccountManagerSerializer(instance=instance,
                                                        data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save(request.user)
        return Response(None, status=status.HTTP_204_NO_CONTENT)

    @action(
        methods=['post'],
        detail=True,
        permission_classes=[
            HasPermissions(
                f'company.{CompanyPermission.change_company}',
                f'company.{CompanyPermission.change_regional_account_manager}',
            ),
        ],
        schema=StubSchema(),
    )
    def remove_account_manager(self, request, *args, **kwargs):
        """
        Remove the One List account manager and tier from a company if it is an international
        trade adviser-managed One List company.

        The operation is not allowed if the company is a One List company that isn't on
        'Tier D - Interaction Trade Adviser Accounts'.
        """
        instance = self.get_object()
        serializer = RemoveAccountManagerSerializer(instance=instance,
                                                    data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save(request.user)
        return Response(None, status=status.HTTP_204_NO_CONTENT)

    @action(
        methods=['post'],
        detail=True,
        permission_classes=[
            HasPermissions(
                f'company.{CompanyPermission.change_company}',
                f'company.{CompanyPermission.change_one_list_tier_and_global_account_manager}',
            ),
        ],
        schema=StubSchema(),
    )
    def assign_one_list_tier_and_global_account_manager(
            self, request, *args, **kwargs):
        """
        Assign One List tier and Global Account Manager.

        This endpoint enables a user with correct permissions to assign company one list tier
        and global account manager except when company is on
        'Tier D - Interaction Trade Adviser Accounts'.

        One List tier and Global Account Manager cannot be assigned to a subsidiary.
        """
        instance = self.get_object()
        serializer = AssignOneListTierAndGlobalAccountManagerSerializer(
            instance=instance,
            data=request.data,
        )
        serializer.is_valid(raise_exception=True)
        serializer.save(request.user)
        return Response(None, status=status.HTTP_204_NO_CONTENT)

    @action(
        methods=['post'],
        detail=True,
        permission_classes=[
            HasPermissions(
                f'company.{CompanyPermission.change_company}',
                f'company.{CompanyPermission.change_one_list_tier_and_global_account_manager}',
            ),
        ],
        schema=StubSchema(),
    )
    def remove_from_one_list(self, request, *args, **kwargs):
        """
        Remove company from One List.

        The operation is not allowed if the company is on
        'Tier D - Interaction Trade Adviser Accounts'.
        """
        instance = self.get_object()
        serializer = RemoveCompanyFromOneListSerializer(instance=instance,
                                                        data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save(request.user)
        return Response(None, status=status.HTTP_204_NO_CONTENT)

    @action(
        methods=['patch'],
        detail=True,
        permission_classes=[
            HasPermissions(
                f'company.{CompanyPermission.change_company}',
                f'company.{CompanyPermission.change_one_list_core_team_member}',
            ),
        ],
        schema=StubSchema(),
    )
    def update_one_list_core_team(self, request, *args, **kwargs):
        """Updates core team for the company."""
        instance = self.get_object()
        serializer = UpdateOneListCoreTeamMembersSerializer(
            instance=instance,
            data=request.data,
            partial=True,
        )
        serializer.is_valid(raise_exception=True)
        serializer.save(request.user)
        return Response(None, status=status.HTTP_204_NO_CONTENT)

    @action(
        methods=['patch'],
        permission_classes=[
            HasPermissions(
                f'company.{CompanyPermission.change_company}',
                'company.change_companyexportcountry',
            ),
        ],
        detail=True,
    )
    def update_export_detail(self, request, *args, **kwargs):
        """
        Update export related information for the company.
        """
        instance = self.get_object()
        serializer = UpdateExportDetailsSerializer(
            instance=instance,
            data=request.data,
            partial=True,
        )
        serializer.is_valid(raise_exception=True)
        serializer.save(request.user)
        return Response(None, status=status.HTTP_204_NO_CONTENT)
예제 #5
0
class CompanyReferralViewSet(CoreViewSet):
    """Company referral view set."""

    serializer_class = CompanyReferralSerializer
    queryset = CompanyReferral.objects.select_related(
        'company',
        'contact',
        'completed_by__dit_team',
        'created_by__dit_team',
        'interaction',
        'recipient__dit_team',
    )

    def get_queryset(self):
        """
        Get a queryset for list action that is filtered to the authenticated user's sent and
        received referrals, otherwise return original queryset.
        """
        if self.action == 'list':
            return super().get_queryset().filter(
                Q(created_by=self.request.user) | Q(recipient=self.request.user),
            )

        return super().get_queryset()

    @action(
        methods=['post'],
        detail=True,
        schema=StubSchema(),
        permission_classes=[
            HasPermissions('company_referral.change_companyreferral'),
        ],
    )
    def complete(self, request, **kwargs):
        """
        View for completing a referral.

        Completing a referral involves creating an interaction and linking the referral and
        interaction together. Hence, this view creates an interaction and updates the referral
        object accordingly.
        """
        referral = self.get_object()
        context = {
            **self.get_serializer_context(),
            # Used by HasAssociatedInvestmentProjectValidator
            'check_association_permissions': False,
            'referral': referral,
            'user': request.user,
        }
        data = {
            **request.data,
            'company': {
                'id': referral.company.pk,
            },
        }
        serializer = CompleteCompanyReferralSerializer(
            data=data,
            context=context,
        )
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
예제 #6
0
class IProjectViewSet(ArchivableViewSetMixin, CoreViewSet):
    """Unified investment project views.

    This replaces the previous project, value, team and requirements endpoints.
    """

    permission_classes = (
        InvestmentProjectModelPermissions,
        IsAssociatedToInvestmentProjectPermission,
    )
    serializer_class = IProjectSerializer
    queryset = InvestmentProject.objects.select_related(
        'archived_by',
        'average_salary',
        'client_relationship_manager__dit_team',
        'client_relationship_manager',
        'country_lost_to',
        'country_investment_originates_from',
        'fdi_type',
        'intermediate_company',
        'investment_type',
        'investmentprojectcode',
        'investor_company',
        'investor_type',
        'level_of_involvement',
        'project_assurance_adviser__dit_team',
        'project_assurance_adviser',
        'project_manager__dit_team',
        'project_manager',
        'referral_source_activity_marketing',
        'referral_source_activity_website',
        'referral_source_activity',
        'referral_source_adviser',
        'specific_programme',
        'stage',
        'uk_company__address_country',
        'uk_company',
    ).prefetch_related(
        'actual_uk_regions',
        'business_activities',
        'client_contacts',
        'competitor_countries',
        'delivery_partners',
        'sector__parent__parent',
        'sector__parent',
        'sector',
        'strategic_drivers',
        'uk_region_locations',
        Prefetch('team_members', queryset=_team_member_queryset),
    )
    filter_backends = (
        DjangoFilterBackend,
        OrderingFilter,
        IsAssociatedToInvestmentProjectFilter,
    )
    filterset_fields = ('investor_company_id', )
    ordering = ('-created_on', )

    def get_view_name(self):
        """Returns the view set name for the DRF UI."""
        return 'Investment projects'

    def get_serializer_context(self):
        """Extra context provided to the serializer class."""
        return {
            **super().get_serializer_context(),
            'current_user':
            self.request.user if self.request else None,
        }

    @action(
        methods=['post'],
        detail=True,
        permission_classes=[
            HasPermissions(
                f'investment.{InvestmentProjectPermission.change_to_any_stage}'
            ),
        ],
        filter_backends=[],
        schema=StubSchema(),
    )
    def change_stage(self, request, *args, **kwargs):
        """Change the stage of an investment project"""
        instance = self.get_object()
        serializer = IProjectChangeStageSerializer(
            instance,
            data=request.data,
            context=self.get_serializer_context(),
        )
        serializer.is_valid(raise_exception=True)
        instance = serializer.change_stage(user=self.request.user)
        return Response(
            self.get_serializer(instance=instance).data,
            status=status.HTTP_200_OK,
        )