diff --git a/seed/views/v3/import_files.py b/seed/views/v3/import_files.py index 4d263fb33d..06c8fafe3a 100644 --- a/seed/views/v3/import_files.py +++ b/seed/views/v3/import_files.py @@ -82,39 +82,6 @@ class MappingResultsResponseSerializer(serializers.Serializer): tax_lots = MappingResultsTaxLotSerializer(many=True) -class MappingSerializer(serializers.Serializer): - from_field = serializers.CharField() - from_units = serializers.CharField() - to_field = serializers.CharField() - to_field_display_name = serializers.CharField() - to_table_name = serializers.CharField() - - -class SaveColumnMappingsRequestPayloadSerializer(serializers.Serializer): - """ - Example: - { - "mappings": [ - { - 'from_field': 'eui', # raw field in import file - 'from_units': 'kBtu/ft**2/year', # pint-parsable units, optional - 'to_field': 'energy_use_intensity', - 'to_field_display_name': 'Energy Use Intensity', - 'to_table_name': 'PropertyState', - }, - { - 'from_field': 'gfa', - 'from_units': 'ft**2', # pint-parsable units, optional - 'to_field': 'gross_floor_area', - 'to_field_display_name': 'Gross Floor Area', - 'to_table_name': 'PropertyState', - } - ] - } - """ - mappings = serializers.ListField(child=MappingSerializer()) - - def convert_first_five_rows_to_list(header, first_five_rows): """ Return the first five rows. This is a complicated method because it handles converting the @@ -556,35 +523,6 @@ def mapping_done(self, request, pk=None): } ) - @swagger_auto_schema( - request_body=SaveColumnMappingsRequestPayloadSerializer, - responses={ - 200: 'success response' - } - ) - @api_endpoint_class - @ajax_request_class - @has_perm_class('requires_member') - @action(detail=True, methods=['POST']) - def save_column_mappings(self, request, pk=None): - """ - Saves the mappings between the raw headers of an ImportFile and the - destination fields in the `to_table_name` model which should be either - PropertyState or TaxLotState - - Valid source_type values are found in ``seed.models.SEED_DATA_SOURCES`` - """ - body = request.data - import_file = ImportFile.objects.get(pk=pk) - organization = import_file.import_record.super_organization - mappings = body.get('mappings', []) - result = Column.create_mappings(mappings, organization, request.user, import_file.id) - - if result: - return JsonResponse({'status': 'success'}) - else: - return JsonResponse({'status': 'error'}) - @api_endpoint_class @ajax_request_class @has_perm_class('requires_member') diff --git a/seed/views/v3/organizations.py b/seed/views/v3/organizations.py index 9e28669998..7caa71b97a 100644 --- a/seed/views/v3/organizations.py +++ b/seed/views/v3/organizations.py @@ -7,6 +7,9 @@ import logging from django.http import JsonResponse +from drf_yasg import openapi +from drf_yasg.utils import swagger_auto_schema +from rest_framework import serializers from rest_framework import status from rest_framework import viewsets from rest_framework.decorators import action @@ -15,10 +18,46 @@ from seed.lib.superperms.orgs.decorators import has_perm_class from seed.lib.superperms.orgs.models import Organization from seed.models.columns import Column +from seed.models import ImportFile +from seed.utils.api import api_endpoint_class +from seed.utils.api_schema import AutoSchemaHelper _log = logging.getLogger(__name__) +class MappingSerializer(serializers.Serializer): + from_field = serializers.CharField() + from_units = serializers.CharField() + to_field = serializers.CharField() + to_field_display_name = serializers.CharField() + to_table_name = serializers.CharField() + + +class SaveColumnMappingsRequestPayloadSerializer(serializers.Serializer): + """ + Example: + { + "mappings": [ + { + 'from_field': 'eui', # raw field in import file + 'from_units': 'kBtu/ft**2/year', # pint-parsable units, optional + 'to_field': 'energy_use_intensity', + 'to_field_display_name': 'Energy Use Intensity', + 'to_table_name': 'PropertyState', + }, + { + 'from_field': 'gfa', + 'from_units': 'ft**2', # pint-parsable units, optional + 'to_field': 'gross_floor_area', + 'to_field_display_name': 'Gross Floor Area', + 'to_table_name': 'PropertyState', + } + ] + } + """ + mappings = serializers.ListField(child=MappingSerializer()) + + class OrganizationViewSet(viewsets.ViewSet): model = Column @@ -67,3 +106,59 @@ def columns(self, request, pk=None): 'status': 'error', 'message': 'organization with with id {} does not exist'.format(pk) }, status=status.HTTP_404_NOT_FOUND) + + @swagger_auto_schema( + manual_parameters=[ + AutoSchemaHelper.query_integer_field( + 'import_file_id', required=True, description='Import file id'), + openapi.Parameter( + 'id', openapi.IN_PATH, type=openapi.TYPE_INTEGER, description='Organization id'), + ], + request_body=SaveColumnMappingsRequestPayloadSerializer, + responses={ + 200: 'success response' + } + ) + @api_endpoint_class + @ajax_request_class + @has_perm_class('requires_member') + @action(detail=True, methods=['POST']) + def column_mappings(self, request, pk=None): + """ + Saves the mappings between the raw headers of an ImportFile and the + destination fields in the `to_table_name` model which should be either + PropertyState or TaxLotState + + Valid source_type values are found in ``seed.models.SEED_DATA_SOURCES`` + """ + import_file_id = request.query_params.get('import_file_id') + if import_file_id is None: + return JsonResponse({ + 'status': 'error', + 'message': 'Query param `import_file_id` is required' + }, status=status.HTTP_400_BAD_REQUEST) + try: + _ = ImportFile.objects.get(pk=import_file_id) + organization = Organization.objects.get(pk=pk) + except ImportFile.DoesNotExist: + return JsonResponse({ + 'status': 'error', + 'message': 'No import file found' + }, status=status.HTTP_404_NOT_FOUND) + except Organization.DoesNotExist: + return JsonResponse({ + 'status': 'error', + 'message': 'No organization found' + }, status=status.HTTP_404_NOT_FOUND) + + result = Column.create_mappings( + request.data.get('mappings', []), + organization, + request.user, + import_file_id + ) + + if result: + return JsonResponse({'status': 'success'}) + else: + return JsonResponse({'status': 'error'})