From d7c859276f6bf8298496e4c46797b38eaf1646de Mon Sep 17 00:00:00 2001 From: tim738745 <98717409+tim738745@users.noreply.github.com> Date: Wed, 10 Apr 2024 16:13:47 -0700 Subject: [PATCH] chore: 217 - install formatters and do initial format (#277) * add formatters * format python code with black * format js code with prettier --- django/api/apps.py | 2 +- django/api/asgi.py | 2 +- django/api/constants.py | 207 ++++++---- django/api/decorators/permission.py | 16 +- django/api/filters/icbc_data.py | 11 +- django/api/filters/order_by.py | 51 ++- django/api/keycloak_authentication.py | 44 +- django/api/management/commands/decode_vin.py | 8 +- .../commands/import_arc_project_tracking.py | 27 +- .../commands/import_charger_rebates.py | 23 +- .../management/commands/import_data_fleets.py | 23 +- .../commands/import_hydrogen_fleets.py | 23 +- .../commands/import_hydrogen_fueling.py | 23 +- .../management/commands/import_ldv_rebates.py | 23 +- .../commands/import_public_charging.py | 23 +- .../management/commands/import_scrap_it.py | 23 +- django/api/management/commands/import_suvi.py | 23 +- django/api/migrations/0001_initial.py | 383 +++++++++++++----- django/api/migrations/0002_ldvrebates.py | 132 ++++-- .../migrations/0003_vindecodedinformation.py | 43 +- .../api/migrations/0004_auto_20211116_1813.py | 42 +- .../0005_vindecodedinformation_vin.py | 6 +- .../0006_specialityusevehicleincentives.py | 59 ++- django/api/migrations/0007_datasets.py | 29 +- django/api/migrations/0008_chargerrebates.py | 66 ++- django/api/migrations/0009_publiccharging.py | 90 ++-- .../0010_chargerrebates_fix_columns.py | 14 +- .../api/migrations/0011_auto_20211216_1944.py | 6 +- .../api/migrations/0012_hydrogrenfueling.py | 92 +++-- django/api/migrations/0013_hydrogenfleets.py | 75 ++-- django/api/migrations/0014_datafleets.py | 136 +++++-- .../api/migrations/0015_arcprojecttracking.py | 78 ++-- django/api/migrations/0016_scrapit.py | 77 +++- .../api/migrations/0017_whitelistedusers.py | 29 +- .../api/migrations/0018_auto_20231201_2301.py | 8 +- .../api/migrations/0019_auto_20240223_1820.py | 101 +++-- .../api/migrations/0020_auto_20240311_2136.py | 26 +- .../api/migrations/0021_auto_20240326_2152.py | 6 +- django/api/models/__init__.py | 2 +- django/api/models/arc_project_tracking.py | 86 +--- django/api/models/charger_rebates.py | 69 +--- django/api/models/credit_class.py | 9 +- django/api/models/data_fleets.py | 135 ++---- django/api/models/datasets.py | 2 +- django/api/models/hydrogen_fleets.py | 91 +---- django/api/models/hydrogen_fueling.py | 101 +---- django/api/models/icbc_registration_data.py | 14 +- django/api/models/icbc_upload_date.py | 8 +- django/api/models/icbc_vehicle.py | 29 +- django/api/models/ldv_rebates.py | 123 ++---- django/api/models/mixins/effective_dates.py | 10 +- django/api/models/mixins/named.py | 16 +- django/api/models/organization.py | 20 +- django/api/models/permission.py | 10 +- django/api/models/public_charging.py | 87 +--- django/api/models/scrap_it.py | 67 +-- .../speciality_use_vehicle_incentives.py | 44 +- django/api/models/user.py | 6 +- django/api/models/user_permission.py | 16 +- django/api/models/vehicle.py | 68 +--- django/api/models/vehicle_class.py | 7 +- django/api/models/vehicle_zev_type.py | 7 +- django/api/models/vin_decoded_information.py | 32 +- django/api/pagination.py | 4 +- django/api/serializers/datasets.py | 3 +- .../api/serializers/icbc_registration_data.py | 4 +- django/api/serializers/icbc_vehicle.py | 9 +- django/api/serializers/permission.py | 6 +- django/api/serializers/user.py | 22 +- .../services/datasheet_template_generator.py | 45 +- django/api/services/ldv_rebates.py | 44 +- django/api/services/minio.py | 8 +- django/api/services/permissions.py | 7 +- django/api/services/spreadsheet_uploader.py | 107 +++-- .../api/services/spreadsheet_uploader_prep.py | 79 ++-- django/api/services/user.py | 4 +- django/api/services/vin_decoder.py | 69 ++-- django/api/services/vin_decoder_old.py | 28 +- django/api/settings.py | 196 ++++----- django/api/tests/base_test.py | 5 +- django/api/urls.py | 21 +- django/api/viewsets/icbc_data.py | 17 +- django/api/viewsets/minio.py | 10 +- django/api/viewsets/upload.py | 80 ++-- django/api/viewsets/user.py | 33 +- django/api/wsgi.py | 2 +- django/requirements.txt | 1 + frontend/package.json | 1 + frontend/src/app/components/AlertDialog.js | 44 +- frontend/src/app/components/App.js | 30 +- frontend/src/app/components/Footer.js | 80 ++-- frontend/src/app/components/Header.js | 40 +- .../src/app/components/KeycloakProvider.js | 33 +- frontend/src/app/components/Layout.js | 14 +- frontend/src/app/components/Loading.js | 10 +- frontend/src/app/components/Login.js | 23 +- frontend/src/app/components/Logout.js | 20 +- frontend/src/app/components/ReactTable.js | 214 +++++----- .../app/components/ReactTablePagination.js | 33 +- frontend/src/app/styles/App.scss | 24 +- frontend/src/app/styles/FileUpload.scss | 9 +- frontend/src/app/styles/Footer.scss | 115 +++--- frontend/src/app/styles/Header.scss | 166 ++++---- frontend/src/app/styles/Login.scss | 23 +- frontend/src/app/styles/ReactTable.scss | 6 +- frontend/src/app/styles/Roboto.scss | 14 +- frontend/src/app/styles/Users.scss | 18 +- frontend/src/app/styles/index.scss | 18 +- frontend/src/app/styles/variables.scss | 2 +- frontend/src/app/utilities/getFileSize.js | 7 +- frontend/src/app/utilities/props.js | 2 +- frontend/src/app/utilities/reactTable.js | 12 +- frontend/src/app/utilities/useAxios.js | 32 +- frontend/src/app/utilities/useKeycloak.js | 12 +- frontend/src/contexts.js | 4 +- frontend/src/dashboard/DashboardContainer.js | 4 +- frontend/src/dashboard/router.js | 11 +- frontend/src/icbc_data/IcbcDataContainer.js | 14 +- .../src/icbc_data/components/IcbcDataTable.js | 77 ++-- frontend/src/icbc_data/router.js | 16 +- frontend/src/icbc_data/routes.js | 2 +- frontend/src/index.js | 30 +- frontend/src/uploads/UploadContainer.js | 197 +++++---- frontend/src/uploads/components/FileDrop.js | 36 +- .../src/uploads/components/FileDropArea.js | 47 +-- frontend/src/uploads/components/UploadPage.js | 60 ++- frontend/src/uploads/router.js | 16 +- frontend/src/uploads/routes.js | 6 +- frontend/src/users/UsersContainer.js | 102 ++--- frontend/src/users/components/UsersPage.js | 132 ++++-- frontend/src/users/routes.js | 2 +- 131 files changed, 2924 insertions(+), 2747 deletions(-) diff --git a/django/api/apps.py b/django/api/apps.py index d87006dd..14b89a82 100644 --- a/django/api/apps.py +++ b/django/api/apps.py @@ -2,4 +2,4 @@ class ApiConfig(AppConfig): - name = 'api' + name = "api" diff --git a/django/api/asgi.py b/django/api/asgi.py index 82cb1c14..1bc5b37e 100644 --- a/django/api/asgi.py +++ b/django/api/asgi.py @@ -11,6 +11,6 @@ from django.core.asgi import get_asgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'api.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "api.settings") application = get_asgi_application() diff --git a/django/api/constants.py b/django/api/constants.py index d461598c..ce0ddef6 100644 --- a/django/api/constants.py +++ b/django/api/constants.py @@ -13,8 +13,15 @@ from api.models.public_charging import PublicCharging from api.models.scrap_it import ScrapIt from api.models.speciality_use_vehicle_incentives import SpecialityUseVehicleIncentives -from api.services.spreadsheet_uploader_prep import prepare_arc_project_tracking, prepare_hydrogen_fleets, prepare_hydrogen_fueling, prepare_ldv_rebates, prepare_public_charging, prepare_scrap_it, prepare_speciality_use_vehicle_incentives - +from api.services.spreadsheet_uploader_prep import ( + prepare_arc_project_tracking, + prepare_hydrogen_fleets, + prepare_hydrogen_fueling, + prepare_ldv_rebates, + prepare_public_charging, + prepare_scrap_it, + prepare_speciality_use_vehicle_incentives, +) class ARCProjectTrackingColumns(Enum): @@ -34,6 +41,7 @@ class ARCProjectTrackingColumns(Enum): FUEL_TYPE = "Fuel Type" PUBLICLY_ANNOUNCED = "Publicly Announced" + class ArcProjectTrackingColumnMapping(Enum): funding_call = "Funding Call" proponent = "Proponent" @@ -51,6 +59,7 @@ class ArcProjectTrackingColumnMapping(Enum): fuel_type = "Fuel Type" publicly_announced = "Publicly Announced" + class EVChargingRebatesColumns(Enum): ORGANIZATION = "Organization" REGION = "Region" @@ -63,6 +72,7 @@ class EVChargingRebatesColumns(Enum): BC_EMPR_FUNDING_ANTICIPATED = "B.C. (EMPR) Funding Anticipated (Max $25,000 per station, excludes MOTI stations) (Not all funding paid out yet as depends on station completion)" NOTES = "Notes" + class EVChargingRebatesColumnMapping(Enum): organization = "Organization" region = "Region" @@ -95,15 +105,24 @@ class DataFleetsColumns(Enum): AVERAGE_DAILY_TRAVEL_DISTANCE = "Average daily travel distance?" WHICH_COMPONENT_ARE_YOU_APPLYING_FOR = "Which component are you applying for?*" ESTIMATED_COST = "Estimated cost" - WHICH_TYPE_OF_CHARGER_ARE_YOU_INSTALLING = "Which type of charger are you installing?" - HOW_MANY_LEVEL_2_CHARGING_STATIONS = "How many Level 2 Charging Stations are you applying for" - HOW_MANY_LEVEL_3_DC_FAST_CHARGING_STATIONS = "How many Level 3/DC Fast Charging Stations are you applying for" - APPLICATION_FORM_FLEETS_COMPLETION_DATE_TIME = '"Application Form Fleets" completion date/time' + WHICH_TYPE_OF_CHARGER_ARE_YOU_INSTALLING = ( + "Which type of charger are you installing?" + ) + HOW_MANY_LEVEL_2_CHARGING_STATIONS = ( + "How many Level 2 Charging Stations are you applying for" + ) + HOW_MANY_LEVEL_3_DC_FAST_CHARGING_STATIONS = ( + "How many Level 3/DC Fast Charging Stations are you applying for" + ) + APPLICATION_FORM_FLEETS_COMPLETION_DATE_TIME = ( + '"Application Form Fleets" completion date/time' + ) PRE_APPROVAL_DATE = "Pre-Approval Date" DEADLINE = "Deadline" APPLICATION_NUMBER = "Application Number" POTENTIAL_REBATE = "Potential Rebate" + class DataFleetsColumnMapping(Enum): current_stage = "Current Stage" rebate_value = "Rebate Value" @@ -124,14 +143,21 @@ class DataFleetsColumnMapping(Enum): component_being_applied_for = "Which component are you applying for?*" estimated_cost = "Estimated cost" type_of_charger_being_installed = "Which type of charger are you installing?" - number_of_level_2_charging_stations_being_applied_for = "How many Level 2 Charging Stations are you applying for" - number_of_level_3_dc_fast_charging_stations_being_applied_for = "How many Level 3/DC Fast Charging Stations are you applying for" - application_form_fleets_completion_date_time = '"Application Form Fleets" completion date/time' + number_of_level_2_charging_stations_being_applied_for = ( + "How many Level 2 Charging Stations are you applying for" + ) + number_of_level_3_dc_fast_charging_stations_being_applied_for = ( + "How many Level 3/DC Fast Charging Stations are you applying for" + ) + application_form_fleets_completion_date_time = ( + '"Application Form Fleets" completion date/time' + ) pre_approval_date = "Pre-Approval Date" deadline = "Deadline" application_number = "Application Number" potential_rebate = "Potential Rebate" + class HydrogenFleetsColumns(Enum): APPLICATION_NUMBER = "Application #" FLEET_NUMBER = "Fleet #" @@ -149,6 +175,7 @@ class HydrogenFleetsColumns(Enum): DEALER_NAME = "Dealer Name" REBATE_AMOUNT = "Rebate Amount" + class HydrogenFleetsColumnMapping(Enum): application_number = "Application #" fleet_number = "Fleet #" @@ -166,6 +193,7 @@ class HydrogenFleetsColumnMapping(Enum): dealer_name = "Dealer Name" rebate_amount = "Rebate Amount" + class HydrogenFuelingColumns(Enum): STATION_NUMBER = "Station Number" RFP_CLOSE_DATE = "RFP Close Date" @@ -186,6 +214,7 @@ class HydrogenFuelingColumns(Enum): OPENING_DATE = "Opening Date" TOTAL_CAPITAL_COST = "Total Capital Cost" + class HydrogenFuelingColumnMapping(Enum): station_number = "Station Number" rfp_close_date = "RFP Close Date" @@ -206,6 +235,7 @@ class HydrogenFuelingColumnMapping(Enum): opening_date = "Opening Date" total_capital_cost = "Total Capital Cost" + class LDVRebatesColumns(Enum): CASL_CONSENT = "CASL Consent" DATE_APPROVED = "DATE APPROVED" @@ -235,6 +265,7 @@ class LDVRebatesColumns(Enum): DELIVERED = "Delivered" CONSENT_TO_CONTACT = "Consent to Contact" + class LdvRebatesColumnMapping(Enum): casl_consent = "CASL Consent" date_approved = "DATE APPROVED" @@ -284,6 +315,7 @@ class PublicChargingColumns(Enum): REVIEW_NUMBER = "Review Number" PAID_OUT_REBATE_AMOUNT = "Paid out rebate amount" + class PublicChargingColumnMapping(Enum): applicant_name = "Applicant Name" address = "Address" @@ -303,6 +335,7 @@ class PublicChargingColumnMapping(Enum): review_number = "Review Number" rebate_paid = "Paid out rebate amount" + class ScrapItColumns(Enum): APPROVAL_NUM = "Approval Num" APP_RECVD_DATE = "App Recv'd Date" @@ -316,6 +349,7 @@ class ScrapItColumns(Enum): BUDGET_CODE = "Budget Code" SCRAP_DATE = "Scrap Date" + class ScrapItColumnMapping(Enum): approval_number = "Approval Num" application_received_date = "App Recv'd Date" @@ -329,6 +363,7 @@ class ScrapItColumnMapping(Enum): budget_code = "Budget Code" scrap_date = "Scrap Date" + class SpecialityUseVehicleIncentiveProgramColumns(Enum): APPROVALS = "Approvals" DATE = "Date" @@ -342,6 +377,7 @@ class SpecialityUseVehicleIncentiveProgramColumns(Enum): MANUFACTURER = "Manufacturer" MODEL = "Model" + class SpecialityUseVehicleIncentivesColumnMapping(Enum): approvals = "Approvals" date = "Date" @@ -354,8 +390,9 @@ class SpecialityUseVehicleIncentivesColumnMapping(Enum): manufacturer = "Manufacturer" model = "Model" + FIELD_TYPES = { - 'ARC Project Tracking': { + "ARC Project Tracking": { "funding_call": str, "proponent": str, "reference_number": str, @@ -372,7 +409,7 @@ class SpecialityUseVehicleIncentivesColumnMapping(Enum): "fuel_type": str, "publicly_announced": bool, }, - 'EV Charging Rebates': { + "EV Charging Rebates": { "organization": str, "region": str, "city": str, @@ -384,7 +421,7 @@ class SpecialityUseVehicleIncentivesColumnMapping(Enum): "rebate_paid": float, "notes": str, }, - 'Data Fleets': { + "Data Fleets": { "current_stage": str, "rebate_value": str, "legal_name_of_organization_fleet": str, @@ -412,7 +449,7 @@ class SpecialityUseVehicleIncentivesColumnMapping(Enum): "application_number": str, "potential_rebate": str, }, - 'Hydrogen Fleets': { + "Hydrogen Fleets": { "application_number": int, "fleet_number": int, "application_date": str, @@ -427,9 +464,9 @@ class SpecialityUseVehicleIncentivesColumnMapping(Enum): "year": str, "purchase_date": str, "dealer_name": str, - "rebate_amount": str + "rebate_amount": str, }, - 'Hydrogen Fueling': { + "Hydrogen Fueling": { "station_number": int, "rfp_close_date": datetime.date, "station_name": str, @@ -447,9 +484,9 @@ class SpecialityUseVehicleIncentivesColumnMapping(Enum): "number_of_fueling_positions": int, "operational_date": datetime.date, "opening_date": datetime.date, - "total_capital_cost": Decimal + "total_capital_cost": Decimal, }, - 'LDV Rebates': { + "LDV Rebates": { "casl_consent": bool, "date_approved": str, "submission_id": int, @@ -478,7 +515,7 @@ class SpecialityUseVehicleIncentivesColumnMapping(Enum): "delivered": bool, "consent_to_contact": bool, }, - 'Public Charging': { + "Public Charging": { "applicant_name": str, "address": str, "charging_station_info": str, @@ -497,7 +534,7 @@ class SpecialityUseVehicleIncentivesColumnMapping(Enum): "review_number": int, "rebate_paid": float, }, - 'Scrap It': { + "Scrap It": { "approval_number": int, "application_received_date": str, "completion_date": str, @@ -510,7 +547,7 @@ class SpecialityUseVehicleIncentivesColumnMapping(Enum): "budget_code": str, "scrap_date": str, }, - 'Specialty Use Vehicle Incentive Program': { + "Specialty Use Vehicle Incentive Program": { "approvals": str, "date": str, "applicant_name": str, @@ -521,71 +558,71 @@ class SpecialityUseVehicleIncentivesColumnMapping(Enum): "total_purchase_price": int, "manufacturer": str, "model": str, - } + }, } DATASET_CONFIG = { - 'ARC Project Tracking': { - 'model': ARCProjectTracking, - 'columns': ARCProjectTrackingColumns, - 'column_mapping': ArcProjectTrackingColumnMapping, - 'sheet_name': 'Project_Tracking', - 'preparation_functions': [prepare_arc_project_tracking] - }, - 'EV Charging Rebates': { - 'model': ChargerRebates, - 'columns': EVChargingRebatesColumns, - 'column_mapping': EVChargingRebatesColumnMapping, - 'sheet_name': 'Updated', - 'header_row': 2 - }, - 'Data Fleets': { - 'model': DataFleets, - 'columns': DataFleetsColumns, - 'column_mapping': DataFleetsColumnMapping, - 'sheet_name': 'Data Fleets' - }, - 'Hydrogen Fleets': { - 'model': HydrogenFleets, - 'columns': HydrogenFleetsColumnMapping, - 'column_mapping': HydrogenFleetsColumnMapping, - 'sheet_name': 'Fleets', - 'preparation_functions': [prepare_hydrogen_fleets] - }, - 'Hydrogen Fueling': { - 'model': HydrogrenFueling, - 'columns': HydrogenFuelingColumnMapping, - 'column_mapping': HydrogenFuelingColumnMapping, - 'sheet_name': 'Station_Tracking', - 'preparation_functions': [prepare_hydrogen_fueling] - }, - 'LDV Rebates': { - 'model': LdvRebates, - 'columns': LdvRebatesColumnMapping, - 'sheet_name': 'Raw Data', - 'preparation_functions': [prepare_ldv_rebates] - }, - 'Public Charging': { - 'model': PublicCharging, - 'columns': PublicChargingColumns, - 'column_mapping': PublicChargingColumnMapping, - 'sheet_name': 'Project_applications', - 'header_row': 2, - 'preparation_functions': [prepare_public_charging] - }, - 'Scrap It': { - 'model': ScrapIt, - 'columns': ScrapItColumns, - 'column_mapping': ScrapItColumnMapping, - 'sheet_name': 'TOP OTHER TRANSACTIONS', - 'header_row': 5, - 'preparation_functions': [prepare_scrap_it] - }, - 'Specialty Use Vehicle Incentive Program': { - 'model': SpecialityUseVehicleIncentives, - 'columns': SpecialityUseVehicleIncentiveProgramColumns, - 'column_mapping': SpecialityUseVehicleIncentivesColumnMapping, - 'sheet_name': 'Sheet1', - 'preparation_functions': [prepare_speciality_use_vehicle_incentives] - }, - } \ No newline at end of file + "ARC Project Tracking": { + "model": ARCProjectTracking, + "columns": ARCProjectTrackingColumns, + "column_mapping": ArcProjectTrackingColumnMapping, + "sheet_name": "Project_Tracking", + "preparation_functions": [prepare_arc_project_tracking], + }, + "EV Charging Rebates": { + "model": ChargerRebates, + "columns": EVChargingRebatesColumns, + "column_mapping": EVChargingRebatesColumnMapping, + "sheet_name": "Updated", + "header_row": 2, + }, + "Data Fleets": { + "model": DataFleets, + "columns": DataFleetsColumns, + "column_mapping": DataFleetsColumnMapping, + "sheet_name": "Data Fleets", + }, + "Hydrogen Fleets": { + "model": HydrogenFleets, + "columns": HydrogenFleetsColumnMapping, + "column_mapping": HydrogenFleetsColumnMapping, + "sheet_name": "Fleets", + "preparation_functions": [prepare_hydrogen_fleets], + }, + "Hydrogen Fueling": { + "model": HydrogrenFueling, + "columns": HydrogenFuelingColumnMapping, + "column_mapping": HydrogenFuelingColumnMapping, + "sheet_name": "Station_Tracking", + "preparation_functions": [prepare_hydrogen_fueling], + }, + "LDV Rebates": { + "model": LdvRebates, + "columns": LdvRebatesColumnMapping, + "sheet_name": "Raw Data", + "preparation_functions": [prepare_ldv_rebates], + }, + "Public Charging": { + "model": PublicCharging, + "columns": PublicChargingColumns, + "column_mapping": PublicChargingColumnMapping, + "sheet_name": "Project_applications", + "header_row": 2, + "preparation_functions": [prepare_public_charging], + }, + "Scrap It": { + "model": ScrapIt, + "columns": ScrapItColumns, + "column_mapping": ScrapItColumnMapping, + "sheet_name": "TOP OTHER TRANSACTIONS", + "header_row": 5, + "preparation_functions": [prepare_scrap_it], + }, + "Specialty Use Vehicle Incentive Program": { + "model": SpecialityUseVehicleIncentives, + "columns": SpecialityUseVehicleIncentiveProgramColumns, + "column_mapping": SpecialityUseVehicleIncentivesColumnMapping, + "sheet_name": "Sheet1", + "preparation_functions": [prepare_speciality_use_vehicle_incentives], + }, +} diff --git a/django/api/decorators/permission.py b/django/api/decorators/permission.py index beb030bc..a2836c97 100644 --- a/django/api/decorators/permission.py +++ b/django/api/decorators/permission.py @@ -5,6 +5,7 @@ from api.models.user import User from api.models.user_permission import UserPermission + def check_upload_permission(): def wrapper(func): def wrapped(request, *args, **kwargs): @@ -15,22 +16,29 @@ def wrapped(request, *args, **kwargs): for each in user_permission: permission = Permission.objects.get(id=each.permission_id) permissions.append(permission.description) - if 'uploader' not in permissions: + if "uploader" not in permissions: return Response( - 'You do not have permission to upload data.', status=status.HTTP_403_FORBIDDEN + "You do not have permission to upload data.", + status=status.HTTP_403_FORBIDDEN, ) return func(request, *args, **kwargs) + return wrapped + return wrapper + def check_admin_permission(): def wrapper(func): def wrapped(request, *args, **kwargs): permissions = create_permission_list(request.user) - if 'admin' not in permissions: + if "admin" not in permissions: return Response( - "You do not have permission to make changes to other users' permissions.", status=status.HTTP_403_FORBIDDEN + "You do not have permission to make changes to other users' permissions.", + status=status.HTTP_403_FORBIDDEN, ) return func(request, *args, **kwargs) + return wrapped + return wrapper diff --git a/django/api/filters/icbc_data.py b/django/api/filters/icbc_data.py index 87db8c36..722f9b43 100644 --- a/django/api/filters/icbc_data.py +++ b/django/api/filters/icbc_data.py @@ -7,6 +7,7 @@ Further reading: https://django-filter.readthedocs.io/en/master/ref/filters.html """ + from django.db.models import Q from django_filters import FilterSet, CharFilter @@ -14,13 +15,13 @@ class IcbcDataFilter(FilterSet): - icbc_vehicle__make = CharFilter(lookup_expr='icontains') - icbc_vehicle__model_name = CharFilter(lookup_expr='icontains') - icbc_vehicle__model_year__name = CharFilter(lookup_expr='icontains') - vin = CharFilter(lookup_expr='icontains') + icbc_vehicle__make = CharFilter(lookup_expr="icontains") + icbc_vehicle__model_name = CharFilter(lookup_expr="icontains") + icbc_vehicle__model_year__name = CharFilter(lookup_expr="icontains") + vin = CharFilter(lookup_expr="icontains") class Meta: model = IcbcRegistrationData fields = [ - 'vin', + "vin", ] diff --git a/django/api/filters/order_by.py b/django/api/filters/order_by.py index c84e33de..1f4e8a07 100644 --- a/django/api/filters/order_by.py +++ b/django/api/filters/order_by.py @@ -3,6 +3,7 @@ This is to support ordering by nested fields without needing to add custom coding per Model """ + from typing import List, Tuple from rest_framework.filters import OrderingFilter from django.db.models import Field, Model, QuerySet @@ -13,15 +14,14 @@ class RelatedOrderingFilter(OrderingFilter): @staticmethod def _get_verbose_name(field: Field, non_verbose_name: str) -> str: - return field.verbose_name \ - if hasattr(field, 'verbose_name') \ - else non_verbose_name.replace('_', ' ') + return ( + field.verbose_name + if hasattr(field, "verbose_name") + else non_verbose_name.replace("_", " ") + ) def _retrieve_all_related_fields( - self, - fields: Tuple[Field], - model: Model, - depth: int = 0 + self, fields: Tuple[Field], model: Model, depth: int = 0 ) -> List[tuple]: valid_fields = [] if depth > self._max_related_depth: @@ -31,38 +31,37 @@ def _retrieve_all_related_fields( rel_fields = self._retrieve_all_related_fields( field.related_model._meta.get_fields(), field.related_model, - depth + 1 + depth + 1, ) for rel_field in rel_fields: - valid_fields.append(( - f'{field.name}__{rel_field[0]}', - self._get_verbose_name(field, rel_field[1]) - )) + valid_fields.append( + ( + f"{field.name}__{rel_field[0]}", + self._get_verbose_name(field, rel_field[1]), + ) + ) else: - valid_fields.append(( - field.name, - self._get_verbose_name(field, field.name), - )) + valid_fields.append( + ( + field.name, + self._get_verbose_name(field, field.name), + ) + ) return valid_fields def get_valid_fields( - self, - queryset: QuerySet, - view, - context: dict = None + self, queryset: QuerySet, view, context: dict = None ) -> List[tuple]: - valid_fields = getattr(view, 'ordering_fields', self.ordering_fields) - if not valid_fields == '__all_related__': + valid_fields = getattr(view, "ordering_fields", self.ordering_fields) + if not valid_fields == "__all_related__": if not context: context = {} valid_fields = super().get_valid_fields(queryset, view, context) else: valid_fields = [ *self._retrieve_all_related_fields( - queryset.model._meta.get_fields(), - queryset.model + queryset.model._meta.get_fields(), queryset.model ), - *[(key, key.title().split('__')) - for key in queryset.query.annotations] + *[(key, key.title().split("__")) for key in queryset.query.annotations], ] return valid_fields diff --git a/django/api/keycloak_authentication.py b/django/api/keycloak_authentication.py index d44f7a03..7abd1d86 100644 --- a/django/api/keycloak_authentication.py +++ b/django/api/keycloak_authentication.py @@ -6,57 +6,45 @@ class KeycloakAuthentication(authentication.BaseAuthentication): def authenticate(self, request): - auth = request.headers.get('Authorization', None) + auth = request.headers.get("Authorization", None) if not auth: - raise exceptions.AuthenticationFailed( - 'Authorization token required' - ) + raise exceptions.AuthenticationFailed("Authorization token required") try: scheme, token = auth.split() except ValueError: - raise exceptions.AuthenticationFailed( - 'Authorization token required' - ) + raise exceptions.AuthenticationFailed("Authorization token required") if not token: - raise exceptions.AuthenticationFailed( - 'Authorization token required' - ) + raise exceptions.AuthenticationFailed("Authorization token required") keycloak_openid = KeycloakOpenID( server_url=settings.KEYCLOAK_URL, client_id=settings.KEYCLOAK_CLIENT_ID, - realm_name=settings.KEYCLOAK_REALM + realm_name=settings.KEYCLOAK_REALM, ) # Decode the token from the front-end - KEYCLOAK_PUBLIC_KEY = \ - "-----BEGIN PUBLIC KEY-----\n" + \ - keycloak_openid.public_key() + \ - "\n-----END PUBLIC KEY-----" + KEYCLOAK_PUBLIC_KEY = ( + "-----BEGIN PUBLIC KEY-----\n" + + keycloak_openid.public_key() + + "\n-----END PUBLIC KEY-----" + ) - options = { - 'verify_signature': True, - 'verify_aud': True, - 'verify_exp': True - } + options = {"verify_signature": True, "verify_aud": True, "verify_exp": True} token_info = keycloak_openid.decode_token( - token, - key=KEYCLOAK_PUBLIC_KEY, - options=options + token, key=KEYCLOAK_PUBLIC_KEY, options=options ) user_info = keycloak_openid.userinfo(token) - if user_info.get('user_id') != token_info.get('user_id'): - raise exceptions.AuthenticationFailed( - 'Invalid Token' - ) - return user_info.get('idir_username'), None + if user_info.get("user_id") != token_info.get("user_id"): + raise exceptions.AuthenticationFailed("Invalid Token") + return user_info.get("idir_username"), None # user = None + # if 'user_id' not in user_info: # # try email # if 'email' in user_info: diff --git a/django/api/management/commands/decode_vin.py b/django/api/management/commands/decode_vin.py index 7b2b224e..327a2a41 100644 --- a/django/api/management/commands/decode_vin.py +++ b/django/api/management/commands/decode_vin.py @@ -3,12 +3,8 @@ class Command(BaseCommand): - help = 'Loads operational data' + help = "Loads operational data" def handle(self, *args, **options): decoder() - self.stdout.write( - self.style.SUCCESS( - 'Decoding Completed!' - ) - ) + self.stdout.write(self.style.SUCCESS("Decoding Completed!")) diff --git a/django/api/management/commands/import_arc_project_tracking.py b/django/api/management/commands/import_arc_project_tracking.py index 5c937cb5..e5159b53 100644 --- a/django/api/management/commands/import_arc_project_tracking.py +++ b/django/api/management/commands/import_arc_project_tracking.py @@ -2,39 +2,36 @@ from os import path from django.core.management import BaseCommand -#from django.api.services.spreadsheet_uploader_prep import import_from_xls +# from django.api.services.spreadsheet_uploader_prep import import_from_xls class Command(BaseCommand): """ This command takes in an excel file and will parse and create records """ - help = 'Loads file into the data fleets table' + + help = "Loads file into the data fleets table" def add_arguments(self, parser): """ Currently only takes in an excel file as a required argument """ - parser.add_argument( - 'xls_file', help='Filename of the xls being imported' - ) + parser.add_argument("xls_file", help="Filename of the xls being imported") def handle(self, *args, **options): """ Function to parse the file and pass it to the import service """ - xls_file = options.get('xls_file') + xls_file = options.get("xls_file") if not path.exists(xls_file): - self.stdout.write(self.style.ERROR( - 'Cannot find {file}. ' - 'Please make sure the filename is correct.'.format( - file=xls_file + self.stdout.write( + self.style.ERROR( + "Cannot find {file}. " + "Please make sure the filename is correct.".format(file=xls_file) ) - )) + ) return False - #import_from_xls(xls_file) - self.stdout.write(self.style.SUCCESS( - 'Import complete' - )) + # import_from_xls(xls_file) + self.stdout.write(self.style.SUCCESS("Import complete")) diff --git a/django/api/management/commands/import_charger_rebates.py b/django/api/management/commands/import_charger_rebates.py index 395e6ab6..366c1685 100644 --- a/django/api/management/commands/import_charger_rebates.py +++ b/django/api/management/commands/import_charger_rebates.py @@ -11,32 +11,29 @@ class Command(BaseCommand): TODO: Allow users to put in a directory as an argument so that the function can parse multiple files """ - help = 'Loads file into the ldv rebates table' + + help = "Loads file into the ldv rebates table" def add_arguments(self, parser): """ Currently only takes in an excel file as a required argument """ - parser.add_argument( - 'xls_file', help='Filename of the xls being imported' - ) + parser.add_argument("xls_file", help="Filename of the xls being imported") def handle(self, *args, **options): """ Function to parse the file and pass it to the import service """ - xls_file = options.get('xls_file') + xls_file = options.get("xls_file") if not path.exists(xls_file): - self.stdout.write(self.style.ERROR( - 'Cannot find {file}. ' - 'Please make sure the filename is correct.'.format( - file=xls_file + self.stdout.write( + self.style.ERROR( + "Cannot find {file}. " + "Please make sure the filename is correct.".format(file=xls_file) ) - )) + ) return False import_from_xls(xls_file) - self.stdout.write(self.style.SUCCESS( - 'Import complete' - )) + self.stdout.write(self.style.SUCCESS("Import complete")) diff --git a/django/api/management/commands/import_data_fleets.py b/django/api/management/commands/import_data_fleets.py index 33306804..3ce9fe09 100644 --- a/django/api/management/commands/import_data_fleets.py +++ b/django/api/management/commands/import_data_fleets.py @@ -9,32 +9,29 @@ class Command(BaseCommand): """ This command takes in an excel file and will parse and create records """ - help = 'Loads file into the data fleets table' + + help = "Loads file into the data fleets table" def add_arguments(self, parser): """ Currently only takes in an excel file as a required argument """ - parser.add_argument( - 'xls_file', help='Filename of the xls being imported' - ) + parser.add_argument("xls_file", help="Filename of the xls being imported") def handle(self, *args, **options): """ Function to parse the file and pass it to the import service """ - xls_file = options.get('xls_file') + xls_file = options.get("xls_file") if not path.exists(xls_file): - self.stdout.write(self.style.ERROR( - 'Cannot find {file}. ' - 'Please make sure the filename is correct.'.format( - file=xls_file + self.stdout.write( + self.style.ERROR( + "Cannot find {file}. " + "Please make sure the filename is correct.".format(file=xls_file) ) - )) + ) return False import_from_xls(xls_file) - self.stdout.write(self.style.SUCCESS( - 'Import complete' - )) + self.stdout.write(self.style.SUCCESS("Import complete")) diff --git a/django/api/management/commands/import_hydrogen_fleets.py b/django/api/management/commands/import_hydrogen_fleets.py index 67a8df28..c715a69f 100644 --- a/django/api/management/commands/import_hydrogen_fleets.py +++ b/django/api/management/commands/import_hydrogen_fleets.py @@ -9,32 +9,29 @@ class Command(BaseCommand): """ This command takes in an excel file and will parse and create records """ - help = 'Loads file into the hydrogen fleets table' + + help = "Loads file into the hydrogen fleets table" def add_arguments(self, parser): """ Currently only takes in an excel file as a required argument """ - parser.add_argument( - 'xls_file', help='Filename of the xls being imported' - ) + parser.add_argument("xls_file", help="Filename of the xls being imported") def handle(self, *args, **options): """ Function to parse the file and pass it to the import service """ - xls_file = options.get('xls_file') + xls_file = options.get("xls_file") if not path.exists(xls_file): - self.stdout.write(self.style.ERROR( - 'Cannot find {file}. ' - 'Please make sure the filename is correct.'.format( - file=xls_file + self.stdout.write( + self.style.ERROR( + "Cannot find {file}. " + "Please make sure the filename is correct.".format(file=xls_file) ) - )) + ) return False import_from_xls(xls_file) - self.stdout.write(self.style.SUCCESS( - 'Import complete' - )) + self.stdout.write(self.style.SUCCESS("Import complete")) diff --git a/django/api/management/commands/import_hydrogen_fueling.py b/django/api/management/commands/import_hydrogen_fueling.py index 38c84b1f..3db1e30a 100644 --- a/django/api/management/commands/import_hydrogen_fueling.py +++ b/django/api/management/commands/import_hydrogen_fueling.py @@ -10,32 +10,29 @@ class Command(BaseCommand): TODO: Allow users to put in a directory as an argument so that the function can parse multiple files """ - help = 'Loads file into the hydrogen fueling table' + + help = "Loads file into the hydrogen fueling table" def add_arguments(self, parser): """ Currently only takes in an excel file as a required argument """ - parser.add_argument( - 'xls_file', help='Filename of the xls being imported' - ) + parser.add_argument("xls_file", help="Filename of the xls being imported") def handle(self, *args, **options): """ Function to parse the file and pass it to the import service """ - xls_file = options.get('xls_file') + xls_file = options.get("xls_file") if not path.exists(xls_file): - self.stdout.write(self.style.ERROR( - 'Cannot find {file}. ' - 'Please make sure the filename is correct.'.format( - file=xls_file + self.stdout.write( + self.style.ERROR( + "Cannot find {file}. " + "Please make sure the filename is correct.".format(file=xls_file) ) - )) + ) return False import_from_xls(xls_file) - self.stdout.write(self.style.SUCCESS( - 'Import complete' - )) + self.stdout.write(self.style.SUCCESS("Import complete")) diff --git a/django/api/management/commands/import_ldv_rebates.py b/django/api/management/commands/import_ldv_rebates.py index 35101d95..27a34f12 100644 --- a/django/api/management/commands/import_ldv_rebates.py +++ b/django/api/management/commands/import_ldv_rebates.py @@ -11,32 +11,29 @@ class Command(BaseCommand): TODO: Allow users to put in a directory as an argument so that the function can parse multiple files """ - help = 'Loads file into the ldv rebates table' + + help = "Loads file into the ldv rebates table" def add_arguments(self, parser): """ Currently only takes in an excel file as a required argument """ - parser.add_argument( - 'xls_file', help='Filename of the xls being imported' - ) + parser.add_argument("xls_file", help="Filename of the xls being imported") def handle(self, *args, **options): """ Function to parse the file and pass it to the import service """ - xls_file = options.get('xls_file') + xls_file = options.get("xls_file") if not path.exists(xls_file): - self.stdout.write(self.style.ERROR( - 'Cannot find {file}. ' - 'Please make sure the filename is correct.'.format( - file=xls_file + self.stdout.write( + self.style.ERROR( + "Cannot find {file}. " + "Please make sure the filename is correct.".format(file=xls_file) ) - )) + ) return False import_from_xls(xls_file) - self.stdout.write(self.style.SUCCESS( - 'Import complete' - )) + self.stdout.write(self.style.SUCCESS("Import complete")) diff --git a/django/api/management/commands/import_public_charging.py b/django/api/management/commands/import_public_charging.py index 721d4ce5..88a8b9b3 100644 --- a/django/api/management/commands/import_public_charging.py +++ b/django/api/management/commands/import_public_charging.py @@ -10,32 +10,29 @@ class Command(BaseCommand): TODO: Allow users to put in a directory as an argument so that the function can parse multiple files """ - help = 'Loads file into the public charging table' + + help = "Loads file into the public charging table" def add_arguments(self, parser): """ Currently only takes in an excel file as a required argument """ - parser.add_argument( - 'xls_file', help='Filename of the xls being imported' - ) + parser.add_argument("xls_file", help="Filename of the xls being imported") def handle(self, *args, **options): """ Function to parse the file and pass it to the import service """ - xls_file = options.get('xls_file') + xls_file = options.get("xls_file") if not path.exists(xls_file): - self.stdout.write(self.style.ERROR( - 'Cannot find {file}. ' - 'Please make sure the filename is correct.'.format( - file=xls_file + self.stdout.write( + self.style.ERROR( + "Cannot find {file}. " + "Please make sure the filename is correct.".format(file=xls_file) ) - )) + ) return False import_from_xls(xls_file) - self.stdout.write(self.style.SUCCESS( - 'Import complete' - )) + self.stdout.write(self.style.SUCCESS("Import complete")) diff --git a/django/api/management/commands/import_scrap_it.py b/django/api/management/commands/import_scrap_it.py index 56e424dc..b16a537c 100644 --- a/django/api/management/commands/import_scrap_it.py +++ b/django/api/management/commands/import_scrap_it.py @@ -9,32 +9,29 @@ class Command(BaseCommand): """ This command takes in an excel file and will parse and create records """ - help = 'Loads file into the data fleets table' + + help = "Loads file into the data fleets table" def add_arguments(self, parser): """ Currently only takes in an excel file as a required argument """ - parser.add_argument( - 'xls_file', help='Filename of the xls being imported' - ) + parser.add_argument("xls_file", help="Filename of the xls being imported") def handle(self, *args, **options): """ Function to parse the file and pass it to the import service """ - xls_file = options.get('xls_file') + xls_file = options.get("xls_file") if not path.exists(xls_file): - self.stdout.write(self.style.ERROR( - 'Cannot find {file}. ' - 'Please make sure the filename is correct.'.format( - file=xls_file + self.stdout.write( + self.style.ERROR( + "Cannot find {file}. " + "Please make sure the filename is correct.".format(file=xls_file) ) - )) + ) return False import_from_xls(xls_file) - self.stdout.write(self.style.SUCCESS( - 'Import complete' - )) + self.stdout.write(self.style.SUCCESS("Import complete")) diff --git a/django/api/management/commands/import_suvi.py b/django/api/management/commands/import_suvi.py index a7b76636..897c0b8c 100644 --- a/django/api/management/commands/import_suvi.py +++ b/django/api/management/commands/import_suvi.py @@ -10,32 +10,29 @@ class Command(BaseCommand): TODO: Allow users to put in a directory as an argument so that the function can parse multiple files """ - help = 'Loads file into the speciality use vehicle incentives table' + + help = "Loads file into the speciality use vehicle incentives table" def add_arguments(self, parser): """ Currently only takes in an excel file as a required argument """ - parser.add_argument( - 'xls_file', help='Filename of the xls being imported' - ) + parser.add_argument("xls_file", help="Filename of the xls being imported") def handle(self, *args, **options): """ Function to parse the file and pass it to the import service """ - xls_file = options.get('xls_file') + xls_file = options.get("xls_file") if not path.exists(xls_file): - self.stdout.write(self.style.ERROR( - 'Cannot find {file}. ' - 'Please make sure the filename is correct.'.format( - file=xls_file + self.stdout.write( + self.style.ERROR( + "Cannot find {file}. " + "Please make sure the filename is correct.".format(file=xls_file) ) - )) + ) return False import_from_xls(xls_file) - self.stdout.write(self.style.SUCCESS( - 'Import complete' - )) + self.stdout.write(self.style.SUCCESS("Import complete")) diff --git a/django/api/migrations/0001_initial.py b/django/api/migrations/0001_initial.py index 52e319a0..3f96b76d 100644 --- a/django/api/migrations/0001_initial.py +++ b/django/api/migrations/0001_initial.py @@ -8,166 +8,337 @@ class Migration(migrations.Migration): initial = True - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( - name='CreditClass', + name="CreditClass", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('credit_class', models.CharField(max_length=3, unique=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("credit_class", models.CharField(max_length=3, unique=True)), ], options={ - 'db_table': 'credit_class_code', + "db_table": "credit_class_code", }, ), migrations.CreateModel( - name='IcbcUploadDate', + name="IcbcUploadDate", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('upload_date', models.DateField()), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("upload_date", models.DateField()), ], options={ - 'db_table': 'icbc_upload_date', + "db_table": "icbc_upload_date", }, ), migrations.CreateModel( - name='ModelYear', + name="ModelYear", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('name', models.CharField(db_column='description', max_length=250, unique=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ( + "name", + models.CharField( + db_column="description", max_length=250, unique=True + ), + ), ], options={ - 'db_table': 'model_year', + "db_table": "model_year", }, ), migrations.CreateModel( - name='Organization', + name="Organization", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('name', models.CharField(db_column='organization_name', max_length=500, unique=True)), - ('short_name', models.CharField(db_column='short_name', max_length=64, null=True, unique=True)), - ('is_active', models.BooleanField(default=False)), - ('is_government', models.BooleanField(default=False)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ( + "name", + models.CharField( + db_column="organization_name", max_length=500, unique=True + ), + ), + ( + "short_name", + models.CharField( + db_column="short_name", max_length=64, null=True, unique=True + ), + ), + ("is_active", models.BooleanField(default=False)), + ("is_government", models.BooleanField(default=False)), ], options={ - 'db_table': 'organization', + "db_table": "organization", }, ), migrations.CreateModel( - name='VehicleClass', + name="VehicleClass", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('description', models.CharField(db_column='description', max_length=250)), - ('vehicle_class_code', models.CharField(max_length=3, unique=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ( + "description", + models.CharField(db_column="description", max_length=250), + ), + ("vehicle_class_code", models.CharField(max_length=3, unique=True)), ], options={ - 'db_table': 'vehicle_class_code', + "db_table": "vehicle_class_code", }, ), migrations.CreateModel( - name='ZevType', + name="ZevType", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('description', models.CharField(db_column='description', max_length=250)), - ('vehicle_zev_code', models.CharField(max_length=4, unique=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ( + "description", + models.CharField(db_column="description", max_length=250), + ), + ("vehicle_zev_code", models.CharField(max_length=4, unique=True)), ], options={ - 'db_table': 'vehicle_zev_type', + "db_table": "vehicle_zev_type", }, ), migrations.CreateModel( - name='IcbcVehicle', + name="IcbcVehicle", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('make', models.CharField(db_index=True, max_length=250)), - ('model_name', models.CharField(db_index=True, max_length=250)), - ('model_year', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='api.modelyear')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("make", models.CharField(db_index=True, max_length=250)), + ("model_name", models.CharField(db_index=True, max_length=250)), + ( + "model_year", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="api.modelyear" + ), + ), ], options={ - 'db_table': 'icbc_vehicle', - 'unique_together': {('make', 'model_name', 'model_year')}, - 'index_together': {('make', 'model_name', 'model_year')}, + "db_table": "icbc_vehicle", + "unique_together": {("make", "model_name", "model_year")}, + "index_together": {("make", "model_name", "model_year")}, }, ), migrations.CreateModel( - name='IcbcRegistrationData', + name="IcbcRegistrationData", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('vin', models.CharField(db_index=True, max_length=20, unique=True)), - ('icbc_upload_date', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.icbcuploaddate')), - ('icbc_vehicle', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.icbcvehicle')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("vin", models.CharField(db_index=True, max_length=20, unique=True)), + ( + "icbc_upload_date", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="api.icbcuploaddate", + ), + ), + ( + "icbc_vehicle", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="api.icbcvehicle", + ), + ), ], options={ - 'db_table': 'icbc_registration_data', + "db_table": "icbc_registration_data", }, ), migrations.CreateModel( - name='Vehicle', + name="Vehicle", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('make', models.CharField(max_length=250)), - ('range', models.IntegerField()), - ('model_name', models.CharField(max_length=250)), - ('validation_status', models.CharField(default='DRAFT', max_length=20)), - ('weight_kg', models.DecimalField(decimal_places=0, max_digits=6)), - ('has_passed_us_06_test', models.BooleanField(default=False)), - ('credit_value', models.DecimalField(decimal_places=2, max_digits=20, null=True)), - ('is_active', models.BooleanField(default=True)), - ('credit_class', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='api.creditclass')), - ('model_year', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='api.modelyear')), - ('organization', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='api.organization')), - ('vehicle_class_code', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='api.vehicleclass')), - ('vehicle_zev_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='api.zevtype')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("make", models.CharField(max_length=250)), + ("range", models.IntegerField()), + ("model_name", models.CharField(max_length=250)), + ("validation_status", models.CharField(default="DRAFT", max_length=20)), + ("weight_kg", models.DecimalField(decimal_places=0, max_digits=6)), + ("has_passed_us_06_test", models.BooleanField(default=False)), + ( + "credit_value", + models.DecimalField(decimal_places=2, max_digits=20, null=True), + ), + ("is_active", models.BooleanField(default=True)), + ( + "credit_class", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="+", + to="api.creditclass", + ), + ), + ( + "model_year", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="api.modelyear" + ), + ), + ( + "organization", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="api.organization", + ), + ), + ( + "vehicle_class_code", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="api.vehicleclass", + ), + ), + ( + "vehicle_zev_type", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="api.zevtype" + ), + ), ], options={ - 'db_table': 'vehicle', - 'unique_together': {('make', 'model_name', 'vehicle_zev_type', 'model_year')}, + "db_table": "vehicle", + "unique_together": { + ("make", "model_name", "vehicle_zev_type", "model_year") + }, }, ), ] diff --git a/django/api/migrations/0002_ldvrebates.py b/django/api/migrations/0002_ldvrebates.py index 8471b9ac..cab9f1e5 100644 --- a/django/api/migrations/0002_ldvrebates.py +++ b/django/api/migrations/0002_ldvrebates.py @@ -6,48 +6,110 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0001_initial'), + ("api", "0001_initial"), ] operations = [ migrations.CreateModel( - name='LdvRebates', + name="LdvRebates", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('submission_id', models.IntegerField(unique=True)), - ('casl_consent', models.BooleanField(default=False)), - ('date_approved', models.DateField(blank=True, null=True)), - ('submission_date', models.DateField(blank=True, null=True)), - ('company_name', models.CharField(blank=True, max_length=200, null=True)), - ('company_city', models.CharField(blank=True, max_length=200, null=True)), - ('applicant_name', models.CharField(blank=True, max_length=200, null=True)), - ('applicant_address_1', models.CharField(blank=True, max_length=200, null=True)), - ('applicant_address_2', models.CharField(blank=True, max_length=200, null=True)), - ('applicant_city', models.CharField(blank=True, max_length=100, null=True)), - ('applicant_postal_code', models.CharField(blank=True, max_length=10, null=True)), - ('applicant_phone', models.CharField(blank=True, max_length=15, null=True)), - ('applicant_email', models.CharField(blank=True, max_length=50, null=True)), - ('applicant_use', models.CharField(blank=True, max_length=20, null=True)), - ('applicant_type', models.CharField(blank=True, max_length=100, null=True)), - ('business_name', models.CharField(blank=True, max_length=100, null=True)), - ('business_number', models.CharField(blank=True, max_length=30, null=True)), - ('drivers_license', models.CharField(blank=True, max_length=30, null=True)), - ('province', models.CharField(blank=True, max_length=50, null=True)), - ('msrp', models.DecimalField(decimal_places=2, max_digits=20)), - ('other_incentives', models.DecimalField(decimal_places=2, max_digits=20)), - ('document_type', models.CharField(blank=True, max_length=40, null=True)), - ('vehicle', models.CharField(blank=True, max_length=200, null=True)), - ('incentive_amount', models.DecimalField(decimal_places=2, max_digits=20)), - ('vin', models.CharField(blank=True, max_length=255, null=True)), - ('delivered', models.BooleanField(default=False)), - ('consent_to_contact', models.BooleanField(default=False)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("submission_id", models.IntegerField(unique=True)), + ("casl_consent", models.BooleanField(default=False)), + ("date_approved", models.DateField(blank=True, null=True)), + ("submission_date", models.DateField(blank=True, null=True)), + ( + "company_name", + models.CharField(blank=True, max_length=200, null=True), + ), + ( + "company_city", + models.CharField(blank=True, max_length=200, null=True), + ), + ( + "applicant_name", + models.CharField(blank=True, max_length=200, null=True), + ), + ( + "applicant_address_1", + models.CharField(blank=True, max_length=200, null=True), + ), + ( + "applicant_address_2", + models.CharField(blank=True, max_length=200, null=True), + ), + ( + "applicant_city", + models.CharField(blank=True, max_length=100, null=True), + ), + ( + "applicant_postal_code", + models.CharField(blank=True, max_length=10, null=True), + ), + ( + "applicant_phone", + models.CharField(blank=True, max_length=15, null=True), + ), + ( + "applicant_email", + models.CharField(blank=True, max_length=50, null=True), + ), + ( + "applicant_use", + models.CharField(blank=True, max_length=20, null=True), + ), + ( + "applicant_type", + models.CharField(blank=True, max_length=100, null=True), + ), + ( + "business_name", + models.CharField(blank=True, max_length=100, null=True), + ), + ( + "business_number", + models.CharField(blank=True, max_length=30, null=True), + ), + ( + "drivers_license", + models.CharField(blank=True, max_length=30, null=True), + ), + ("province", models.CharField(blank=True, max_length=50, null=True)), + ("msrp", models.DecimalField(decimal_places=2, max_digits=20)), + ( + "other_incentives", + models.DecimalField(decimal_places=2, max_digits=20), + ), + ( + "document_type", + models.CharField(blank=True, max_length=40, null=True), + ), + ("vehicle", models.CharField(blank=True, max_length=200, null=True)), + ( + "incentive_amount", + models.DecimalField(decimal_places=2, max_digits=20), + ), + ("vin", models.CharField(blank=True, max_length=255, null=True)), + ("delivered", models.BooleanField(default=False)), + ("consent_to_contact", models.BooleanField(default=False)), ], options={ - 'db_table': 'ldv_rebates', + "db_table": "ldv_rebates", }, ), ] diff --git a/django/api/migrations/0003_vindecodedinformation.py b/django/api/migrations/0003_vindecodedinformation.py index 300aab92..46fff5ad 100644 --- a/django/api/migrations/0003_vindecodedinformation.py +++ b/django/api/migrations/0003_vindecodedinformation.py @@ -6,26 +6,43 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0002_ldvrebates'), + ("api", "0002_ldvrebates"), ] operations = [ migrations.CreateModel( - name='VINDecodedInformation', + name="VINDecodedInformation", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('manufacturer', models.CharField(blank=True, max_length=500, null=True)), - ('make', models.CharField(blank=True, max_length=250, null=True)), - ('model', models.CharField(blank=True, max_length=250, null=True)), - ('model_year', models.IntegerField(blank=True, null=True)), - ('fuel_type_primary', models.CharField(blank=True, max_length=250, null=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ( + "manufacturer", + models.CharField(blank=True, max_length=500, null=True), + ), + ("make", models.CharField(blank=True, max_length=250, null=True)), + ("model", models.CharField(blank=True, max_length=250, null=True)), + ("model_year", models.IntegerField(blank=True, null=True)), + ( + "fuel_type_primary", + models.CharField(blank=True, max_length=250, null=True), + ), ], options={ - 'db_table': 'vin_decoded_information', + "db_table": "vin_decoded_information", }, ), ] diff --git a/django/api/migrations/0004_auto_20211116_1813.py b/django/api/migrations/0004_auto_20211116_1813.py index bd46ee19..84812e6f 100644 --- a/django/api/migrations/0004_auto_20211116_1813.py +++ b/django/api/migrations/0004_auto_20211116_1813.py @@ -6,58 +6,58 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0003_vindecodedinformation'), + ("api", "0003_vindecodedinformation"), ] operations = [ migrations.AlterField( - model_name='ldvrebates', - name='applicant_email', + model_name="ldvrebates", + name="applicant_email", field=models.CharField(blank=True, max_length=200, null=True), ), migrations.AlterField( - model_name='ldvrebates', - name='applicant_phone', + model_name="ldvrebates", + name="applicant_phone", field=models.CharField(blank=True, max_length=25, null=True), ), migrations.AlterField( - model_name='ldvrebates', - name='applicant_postal_code', + model_name="ldvrebates", + name="applicant_postal_code", field=models.CharField(blank=True, max_length=50, null=True), ), migrations.AlterField( - model_name='ldvrebates', - name='applicant_use', + model_name="ldvrebates", + name="applicant_use", field=models.CharField(blank=True, max_length=50, null=True), ), migrations.AlterField( - model_name='ldvrebates', - name='business_number', + model_name="ldvrebates", + name="business_number", field=models.CharField(blank=True, max_length=50, null=True), ), migrations.AlterField( - model_name='ldvrebates', - name='date_approved', + model_name="ldvrebates", + name="date_approved", field=models.CharField(blank=True, max_length=100, null=True), ), migrations.AlterField( - model_name='ldvrebates', - name='document_type', + model_name="ldvrebates", + name="document_type", field=models.CharField(blank=True, max_length=50, null=True), ), migrations.AlterField( - model_name='ldvrebates', - name='drivers_license', + model_name="ldvrebates", + name="drivers_license", field=models.CharField(blank=True, max_length=50, null=True), ), migrations.AlterField( - model_name='ldvrebates', - name='submission_date', + model_name="ldvrebates", + name="submission_date", field=models.CharField(blank=True, max_length=100, null=True), ), migrations.AlterField( - model_name='ldvrebates', - name='submission_id', + model_name="ldvrebates", + name="submission_id", field=models.IntegerField(), ), ] diff --git a/django/api/migrations/0005_vindecodedinformation_vin.py b/django/api/migrations/0005_vindecodedinformation_vin.py index 6e828dc6..ed268227 100644 --- a/django/api/migrations/0005_vindecodedinformation_vin.py +++ b/django/api/migrations/0005_vindecodedinformation_vin.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0004_auto_20211116_1813'), + ("api", "0004_auto_20211116_1813"), ] operations = [ migrations.AddField( - model_name='vindecodedinformation', - name='vin', + model_name="vindecodedinformation", + name="vin", field=models.CharField(default=0, max_length=20), preserve_default=False, ), diff --git a/django/api/migrations/0006_specialityusevehicleincentives.py b/django/api/migrations/0006_specialityusevehicleincentives.py index 937764bd..12e0cc60 100644 --- a/django/api/migrations/0006_specialityusevehicleincentives.py +++ b/django/api/migrations/0006_specialityusevehicleincentives.py @@ -6,31 +6,54 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0005_vindecodedinformation_vin'), + ("api", "0005_vindecodedinformation_vin"), ] operations = [ migrations.CreateModel( - name='SpecialityUseVehicleIncentives', + name="SpecialityUseVehicleIncentives", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('approvals', models.CharField(blank=True, max_length=20, null=True)), - ('date', models.CharField(blank=True, max_length=20, null=True)), - ('applicant_name', models.CharField(blank=True, max_length=250, null=True)), - ('max_incentive_amount_requested', models.IntegerField(blank=True, null=True)), - ('category', models.CharField(blank=True, max_length=250, null=True)), - ('applicant_type', models.CharField(blank=True, max_length=50, null=True)), - ('incentive_paid', models.IntegerField(blank=True, null=True)), - ('total_purchase_price', models.IntegerField(blank=True, null=True)), - ('manufacturer', models.CharField(blank=True, max_length=250, null=True)), - ('model', models.CharField(blank=True, max_length=250, null=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("approvals", models.CharField(blank=True, max_length=20, null=True)), + ("date", models.CharField(blank=True, max_length=20, null=True)), + ( + "applicant_name", + models.CharField(blank=True, max_length=250, null=True), + ), + ( + "max_incentive_amount_requested", + models.IntegerField(blank=True, null=True), + ), + ("category", models.CharField(blank=True, max_length=250, null=True)), + ( + "applicant_type", + models.CharField(blank=True, max_length=50, null=True), + ), + ("incentive_paid", models.IntegerField(blank=True, null=True)), + ("total_purchase_price", models.IntegerField(blank=True, null=True)), + ( + "manufacturer", + models.CharField(blank=True, max_length=250, null=True), + ), + ("model", models.CharField(blank=True, max_length=250, null=True)), ], options={ - 'db_table': 'speciality_use_vehicle_incentives', + "db_table": "speciality_use_vehicle_incentives", }, ), ] diff --git a/django/api/migrations/0007_datasets.py b/django/api/migrations/0007_datasets.py index 2ef4100f..810af89a 100644 --- a/django/api/migrations/0007_datasets.py +++ b/django/api/migrations/0007_datasets.py @@ -6,22 +6,33 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0006_specialityusevehicleincentives'), + ("api", "0006_specialityusevehicleincentives"), ] operations = [ migrations.CreateModel( - name='Datasets', + name="Datasets", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('name', models.CharField(max_length=50, unique=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("name", models.CharField(max_length=50, unique=True)), ], options={ - 'db_table': 'datasets', + "db_table": "datasets", }, ), ] diff --git a/django/api/migrations/0008_chargerrebates.py b/django/api/migrations/0008_chargerrebates.py index 2f92a16e..6a996256 100644 --- a/django/api/migrations/0008_chargerrebates.py +++ b/django/api/migrations/0008_chargerrebates.py @@ -6,32 +6,60 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0007_datasets'), + ("api", "0007_datasets"), ] operations = [ migrations.CreateModel( - name='ChargerRebates', + name="ChargerRebates", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('organization', models.CharField(blank=True, max_length=250, null=True)), - ('region', models.CharField(blank=True, max_length=200, null=True)), - ('city', models.CharField(blank=True, max_length=200, null=True)), - ('address', models.CharField(blank=True, max_length=200, null=True)), - ('postal_code', models.CharField(blank=True, max_length=200, null=True)), - ('number_of_fast_charging_stations', models.IntegerField(blank=True, null=True)), - ('in_service_date', models.CharField(blank=True, max_length=100, null=True)), - ('expected_in_service_date', models.DateField(blank=True, null=True)), - ('announced', models.CharField(blank=True, max_length=200, null=True)), - ('rebate_paid', models.DecimalField(blank=True, decimal_places=2, max_digits=20, null=True)), - ('notes', models.CharField(blank=True, max_length=250, null=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ( + "organization", + models.CharField(blank=True, max_length=250, null=True), + ), + ("region", models.CharField(blank=True, max_length=200, null=True)), + ("city", models.CharField(blank=True, max_length=200, null=True)), + ("address", models.CharField(blank=True, max_length=200, null=True)), + ( + "postal_code", + models.CharField(blank=True, max_length=200, null=True), + ), + ( + "number_of_fast_charging_stations", + models.IntegerField(blank=True, null=True), + ), + ( + "in_service_date", + models.CharField(blank=True, max_length=100, null=True), + ), + ("expected_in_service_date", models.DateField(blank=True, null=True)), + ("announced", models.CharField(blank=True, max_length=200, null=True)), + ( + "rebate_paid", + models.DecimalField( + blank=True, decimal_places=2, max_digits=20, null=True + ), + ), + ("notes", models.CharField(blank=True, max_length=250, null=True)), ], options={ - 'db_table': 'charger_rebates', + "db_table": "charger_rebates", }, ), ] diff --git a/django/api/migrations/0009_publiccharging.py b/django/api/migrations/0009_publiccharging.py index 6532743a..7ba704ba 100644 --- a/django/api/migrations/0009_publiccharging.py +++ b/django/api/migrations/0009_publiccharging.py @@ -6,42 +6,74 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0008_chargerrebates'), + ("api", "0008_chargerrebates"), ] operations = [ migrations.CreateModel( - name='PublicCharging', + name="PublicCharging", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('applicant_name', models.CharField(blank=True, max_length=200, null=True)), - ('city', models.CharField(blank=True, max_length=200, null=True)), - ('postal_code', models.CharField(blank=True, max_length=50, null=True)), - ('address', models.CharField(blank=True, max_length=200, null=True)), - ('charging_station_info', models.CharField(blank=True, max_length=500, null=True)), - ('between_25kw_and_50kw', models.IntegerField(blank=True, null=True)), - ('between_50kw_and_100kw', models.IntegerField(blank=True, null=True)), - ('over_100kw', models.IntegerField(blank=True, null=True)), - ('level_2_units', models.IntegerField(blank=True, null=True)), - ('level_2_ports', models.IntegerField(blank=True, null=True)), - ('estimated_budget', models.DecimalField(decimal_places=2, max_digits=20)), - ('adjusted_rebate', models.DecimalField(decimal_places=2, max_digits=20)), - ('rebate_percent_maximum', models.DecimalField(decimal_places=2, max_digits=3)), - ('pilot_project', models.BooleanField()), - ('region', models.CharField(blank=True, max_length=200, null=True)), - ('organization_type', models.CharField(blank=True, max_length=100, null=True)), - ('project_status', models.CharField(blank=True, max_length=200, null=True)), - ('review_number', models.IntegerField(blank=True, null=True)), - ('rebate_paid', models.DecimalField(decimal_places=2, max_digits=20)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ( + "applicant_name", + models.CharField(blank=True, max_length=200, null=True), + ), + ("city", models.CharField(blank=True, max_length=200, null=True)), + ("postal_code", models.CharField(blank=True, max_length=50, null=True)), + ("address", models.CharField(blank=True, max_length=200, null=True)), + ( + "charging_station_info", + models.CharField(blank=True, max_length=500, null=True), + ), + ("between_25kw_and_50kw", models.IntegerField(blank=True, null=True)), + ("between_50kw_and_100kw", models.IntegerField(blank=True, null=True)), + ("over_100kw", models.IntegerField(blank=True, null=True)), + ("level_2_units", models.IntegerField(blank=True, null=True)), + ("level_2_ports", models.IntegerField(blank=True, null=True)), + ( + "estimated_budget", + models.DecimalField(decimal_places=2, max_digits=20), + ), + ( + "adjusted_rebate", + models.DecimalField(decimal_places=2, max_digits=20), + ), + ( + "rebate_percent_maximum", + models.DecimalField(decimal_places=2, max_digits=3), + ), + ("pilot_project", models.BooleanField()), + ("region", models.CharField(blank=True, max_length=200, null=True)), + ( + "organization_type", + models.CharField(blank=True, max_length=100, null=True), + ), + ( + "project_status", + models.CharField(blank=True, max_length=200, null=True), + ), + ("review_number", models.IntegerField(blank=True, null=True)), + ("rebate_paid", models.DecimalField(decimal_places=2, max_digits=20)), ], options={ - 'db_table': 'public_charging', + "db_table": "public_charging", }, ), ] diff --git a/django/api/migrations/0010_chargerrebates_fix_columns.py b/django/api/migrations/0010_chargerrebates_fix_columns.py index 8eaaad69..a889d8a6 100644 --- a/django/api/migrations/0010_chargerrebates_fix_columns.py +++ b/django/api/migrations/0010_chargerrebates_fix_columns.py @@ -6,11 +6,17 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0009_publiccharging'), + ("api", "0009_publiccharging"), ] operations = [ - migrations.RunSQL('alter table public.charger_rebates alter column number_of_fast_charging_stations type varchar(100)'), - migrations.RunSQL('alter table public.charger_rebates alter column expected_in_service_date type varchar(200)'), - migrations.RunSQL('alter table public.charger_rebates alter column rebate_paid type varchar(200)'), + migrations.RunSQL( + "alter table public.charger_rebates alter column number_of_fast_charging_stations type varchar(100)" + ), + migrations.RunSQL( + "alter table public.charger_rebates alter column expected_in_service_date type varchar(200)" + ), + migrations.RunSQL( + "alter table public.charger_rebates alter column rebate_paid type varchar(200)" + ), ] diff --git a/django/api/migrations/0011_auto_20211216_1944.py b/django/api/migrations/0011_auto_20211216_1944.py index 8d2e7155..c26c14c2 100644 --- a/django/api/migrations/0011_auto_20211216_1944.py +++ b/django/api/migrations/0011_auto_20211216_1944.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0010_chargerrebates_fix_columns'), + ("api", "0010_chargerrebates_fix_columns"), ] operations = [ migrations.AlterField( - model_name='chargerrebates', - name='expected_in_service_date', + model_name="chargerrebates", + name="expected_in_service_date", field=models.CharField(blank=True, max_length=200, null=True), ), ] diff --git a/django/api/migrations/0012_hydrogrenfueling.py b/django/api/migrations/0012_hydrogrenfueling.py index a677e436..b105f33c 100644 --- a/django/api/migrations/0012_hydrogrenfueling.py +++ b/django/api/migrations/0012_hydrogrenfueling.py @@ -6,41 +6,77 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0011_auto_20211216_1944'), + ("api", "0011_auto_20211216_1944"), ] operations = [ migrations.CreateModel( - name='HydrogrenFueling', + name="HydrogrenFueling", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('effective_date', models.DateField(blank=True, null=True)), - ('expiration_date', models.DateField(blank=True, null=True)), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('station_number', models.IntegerField(blank=True, null=True)), - ('rfp_close_date', models.DateField(blank=True, null=True)), - ('station_name', models.CharField(blank=True, max_length=200, null=True)), - ('street_address', models.CharField(blank=True, max_length=200, null=True)), - ('city', models.CharField(blank=True, max_length=200, null=True)), - ('postal_code', models.CharField(blank=True, max_length=50, null=True)), - ('proponent', models.CharField(blank=True, max_length=100, null=True)), - ('location_partner', models.CharField(blank=True, max_length=100, null=True)), - ('capital_funding_awarded', models.DecimalField(blank=True, decimal_places=2, max_digits=20, null=True)), - ('om_funding_potential', models.DecimalField(blank=True, decimal_places=2, max_digits=20, null=True)), - ('daily_capacity', models.IntegerField(blank=True, null=True)), - ('bar_700', models.BooleanField(default=False)), - ('bar_350', models.BooleanField(default=False)), - ('status', models.CharField(blank=True, max_length=200, null=True)), - ('number_of_fueling_positions', models.IntegerField(blank=True, null=True)), - ('operational_date', models.DateField(blank=True, null=True)), - ('opening_date', models.DateField(blank=True, null=True)), - ('total_capital_cost', models.DecimalField(decimal_places=2, max_digits=20)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("effective_date", models.DateField(blank=True, null=True)), + ("expiration_date", models.DateField(blank=True, null=True)), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("station_number", models.IntegerField(blank=True, null=True)), + ("rfp_close_date", models.DateField(blank=True, null=True)), + ( + "station_name", + models.CharField(blank=True, max_length=200, null=True), + ), + ( + "street_address", + models.CharField(blank=True, max_length=200, null=True), + ), + ("city", models.CharField(blank=True, max_length=200, null=True)), + ("postal_code", models.CharField(blank=True, max_length=50, null=True)), + ("proponent", models.CharField(blank=True, max_length=100, null=True)), + ( + "location_partner", + models.CharField(blank=True, max_length=100, null=True), + ), + ( + "capital_funding_awarded", + models.DecimalField( + blank=True, decimal_places=2, max_digits=20, null=True + ), + ), + ( + "om_funding_potential", + models.DecimalField( + blank=True, decimal_places=2, max_digits=20, null=True + ), + ), + ("daily_capacity", models.IntegerField(blank=True, null=True)), + ("bar_700", models.BooleanField(default=False)), + ("bar_350", models.BooleanField(default=False)), + ("status", models.CharField(blank=True, max_length=200, null=True)), + ( + "number_of_fueling_positions", + models.IntegerField(blank=True, null=True), + ), + ("operational_date", models.DateField(blank=True, null=True)), + ("opening_date", models.DateField(blank=True, null=True)), + ( + "total_capital_cost", + models.DecimalField(decimal_places=2, max_digits=20), + ), ], options={ - 'db_table': 'hydrogen_fueling', + "db_table": "hydrogen_fueling", }, ), ] diff --git a/django/api/migrations/0013_hydrogenfleets.py b/django/api/migrations/0013_hydrogenfleets.py index b6fc7f9c..322359ec 100644 --- a/django/api/migrations/0013_hydrogenfleets.py +++ b/django/api/migrations/0013_hydrogenfleets.py @@ -6,36 +6,65 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0012_hydrogrenfueling'), + ("api", "0012_hydrogrenfueling"), ] operations = [ migrations.CreateModel( - name='HydrogenFleets', + name="HydrogenFleets", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('application_number', models.IntegerField(blank=True, null=True)), - ('fleet_number', models.IntegerField(blank=True, null=True)), - ('application_date', models.CharField(blank=True, max_length=100, null=True)), - ('organization_name', models.CharField(blank=True, max_length=250, null=True)), - ('fleet_name', models.CharField(blank=True, max_length=250, null=True)), - ('steet_address', models.CharField(blank=True, max_length=250, null=True)), - ('city', models.CharField(blank=True, max_length=100, null=True)), - ('postal_code', models.CharField(blank=True, max_length=10, null=True)), - ('vin', models.CharField(blank=True, max_length=20, null=True)), - ('make', models.CharField(blank=True, max_length=100, null=True)), - ('model', models.CharField(blank=True, max_length=100, null=True)), - ('year', models.CharField(blank=True, max_length=100, null=True)), - ('purchase_date', models.CharField(blank=True, max_length=100, null=True)), - ('dealer_name', models.CharField(blank=True, max_length=250, null=True)), - ('rebate_amount', models.CharField(blank=True, max_length=250, null=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("application_number", models.IntegerField(blank=True, null=True)), + ("fleet_number", models.IntegerField(blank=True, null=True)), + ( + "application_date", + models.CharField(blank=True, max_length=100, null=True), + ), + ( + "organization_name", + models.CharField(blank=True, max_length=250, null=True), + ), + ("fleet_name", models.CharField(blank=True, max_length=250, null=True)), + ( + "steet_address", + models.CharField(blank=True, max_length=250, null=True), + ), + ("city", models.CharField(blank=True, max_length=100, null=True)), + ("postal_code", models.CharField(blank=True, max_length=10, null=True)), + ("vin", models.CharField(blank=True, max_length=20, null=True)), + ("make", models.CharField(blank=True, max_length=100, null=True)), + ("model", models.CharField(blank=True, max_length=100, null=True)), + ("year", models.CharField(blank=True, max_length=100, null=True)), + ( + "purchase_date", + models.CharField(blank=True, max_length=100, null=True), + ), + ( + "dealer_name", + models.CharField(blank=True, max_length=250, null=True), + ), + ( + "rebate_amount", + models.CharField(blank=True, max_length=250, null=True), + ), ], options={ - 'db_table': 'hydrogen_fleets', + "db_table": "hydrogen_fleets", }, ), ] diff --git a/django/api/migrations/0014_datafleets.py b/django/api/migrations/0014_datafleets.py index 7afa757c..07ea9ff8 100644 --- a/django/api/migrations/0014_datafleets.py +++ b/django/api/migrations/0014_datafleets.py @@ -6,47 +6,115 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0013_hydrogenfleets'), + ("api", "0013_hydrogenfleets"), ] operations = [ migrations.CreateModel( - name='DataFleets', + name="DataFleets", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('current_stage', models.CharField(blank=True, max_length=250, null=True)), - ('rebate_value', models.CharField(blank=True, max_length=100, null=True)), - ('legal_name_of_organization_fleet', models.CharField(blank=True, max_length=500, null=True)), - ('business_category', models.CharField(blank=True, max_length=250, null=True)), - ('city', models.CharField(blank=True, max_length=250, null=True)), - ('postal_code', models.CharField(blank=True, max_length=100, null=True)), - ('applicant_first_name', models.CharField(blank=True, max_length=100, null=True)), - ('applicant_last_name', models.CharField(blank=True, max_length=100, null=True)), - ('email_address', models.CharField(blank=True, max_length=100, null=True)), - ('fleet_size_all', models.IntegerField(blank=True, null=True)), - ('fleet_size_light_duty', models.IntegerField(blank=True, null=True)), - ('total_number_of_evs', models.IntegerField(blank=True, null=True)), - ('total_number_of_light_duty_evs', models.IntegerField(blank=True, null=True)), - ('phev', models.IntegerField(blank=True, null=True)), - ('evse', models.IntegerField(blank=True, null=True)), - ('average_daily_travel_distance', models.CharField(blank=True, max_length=100, null=True)), - ('component_being_applyied_for', models.CharField(blank=True, max_length=250, null=True)), - ('estimated_cost', models.CharField(blank=True, max_length=100, null=True)), - ('type_of_charger_being_installing', models.CharField(blank=True, max_length=250, null=True)), - ('number_of_Level_2_Charging_Stations_being_applying_for', models.IntegerField(blank=True, null=True)), - ('number_of_level_3_dc_fast_charging_stations_being_applying_for', models.IntegerField(blank=True, null=True)), - ('application_form_fleets_completion_date_time', models.CharField(blank=True, max_length=100, null=True)), - ('pre_approval_date', models.CharField(blank=True, max_length=100, null=True)), - ('deadline', models.CharField(blank=True, max_length=250, null=True)), - ('application_number', models.CharField(blank=True, max_length=250, null=True)), - ('potential_rebate', models.CharField(blank=True, max_length=100, null=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ( + "current_stage", + models.CharField(blank=True, max_length=250, null=True), + ), + ( + "rebate_value", + models.CharField(blank=True, max_length=100, null=True), + ), + ( + "legal_name_of_organization_fleet", + models.CharField(blank=True, max_length=500, null=True), + ), + ( + "business_category", + models.CharField(blank=True, max_length=250, null=True), + ), + ("city", models.CharField(blank=True, max_length=250, null=True)), + ( + "postal_code", + models.CharField(blank=True, max_length=100, null=True), + ), + ( + "applicant_first_name", + models.CharField(blank=True, max_length=100, null=True), + ), + ( + "applicant_last_name", + models.CharField(blank=True, max_length=100, null=True), + ), + ( + "email_address", + models.CharField(blank=True, max_length=100, null=True), + ), + ("fleet_size_all", models.IntegerField(blank=True, null=True)), + ("fleet_size_light_duty", models.IntegerField(blank=True, null=True)), + ("total_number_of_evs", models.IntegerField(blank=True, null=True)), + ( + "total_number_of_light_duty_evs", + models.IntegerField(blank=True, null=True), + ), + ("phev", models.IntegerField(blank=True, null=True)), + ("evse", models.IntegerField(blank=True, null=True)), + ( + "average_daily_travel_distance", + models.CharField(blank=True, max_length=100, null=True), + ), + ( + "component_being_applyied_for", + models.CharField(blank=True, max_length=250, null=True), + ), + ( + "estimated_cost", + models.CharField(blank=True, max_length=100, null=True), + ), + ( + "type_of_charger_being_installing", + models.CharField(blank=True, max_length=250, null=True), + ), + ( + "number_of_Level_2_Charging_Stations_being_applying_for", + models.IntegerField(blank=True, null=True), + ), + ( + "number_of_level_3_dc_fast_charging_stations_being_applying_for", + models.IntegerField(blank=True, null=True), + ), + ( + "application_form_fleets_completion_date_time", + models.CharField(blank=True, max_length=100, null=True), + ), + ( + "pre_approval_date", + models.CharField(blank=True, max_length=100, null=True), + ), + ("deadline", models.CharField(blank=True, max_length=250, null=True)), + ( + "application_number", + models.CharField(blank=True, max_length=250, null=True), + ), + ( + "potential_rebate", + models.CharField(blank=True, max_length=100, null=True), + ), ], options={ - 'db_table': 'data_fleets', + "db_table": "data_fleets", }, ), ] diff --git a/django/api/migrations/0015_arcprojecttracking.py b/django/api/migrations/0015_arcprojecttracking.py index 490e02f5..8b5e0c22 100644 --- a/django/api/migrations/0015_arcprojecttracking.py +++ b/django/api/migrations/0015_arcprojecttracking.py @@ -6,36 +6,68 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0014_datafleets'), + ("api", "0014_datafleets"), ] operations = [ migrations.CreateModel( - name='ARCProjectTracking', + name="ARCProjectTracking", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('funding_call', models.CharField(blank=True, max_length=50, null=True)), - ('proponent', models.CharField(blank=True, max_length=500, null=True)), - ('reference_number', models.CharField(blank=True, max_length=50, null=True)), - ('project_title', models.CharField(blank=True, max_length=500, null=True)), - ('primary_location', models.CharField(blank=True, max_length=250, null=True)), - ('status', models.CharField(blank=True, max_length=250, null=True)), - ('arc_funding', models.IntegerField(blank=True, null=True)), - ('funds_issued', models.IntegerField(blank=True, null=True)), - ('start_date', models.CharField(blank=True, max_length=250, null=True)), - ('completion_date', models.CharField(blank=True, max_length=250, null=True)), - ('total_project_value', models.IntegerField(blank=True, null=True)), - ('zev_sub_sector', models.CharField(blank=True, max_length=250, null=True)), - ('on_road_off_road', models.CharField(blank=True, max_length=250, null=True)), - ('fuel_type', models.CharField(blank=True, max_length=250, null=True)), - ('publicly_announced', models.BooleanField(default=False)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ( + "funding_call", + models.CharField(blank=True, max_length=50, null=True), + ), + ("proponent", models.CharField(blank=True, max_length=500, null=True)), + ( + "reference_number", + models.CharField(blank=True, max_length=50, null=True), + ), + ( + "project_title", + models.CharField(blank=True, max_length=500, null=True), + ), + ( + "primary_location", + models.CharField(blank=True, max_length=250, null=True), + ), + ("status", models.CharField(blank=True, max_length=250, null=True)), + ("arc_funding", models.IntegerField(blank=True, null=True)), + ("funds_issued", models.IntegerField(blank=True, null=True)), + ("start_date", models.CharField(blank=True, max_length=250, null=True)), + ( + "completion_date", + models.CharField(blank=True, max_length=250, null=True), + ), + ("total_project_value", models.IntegerField(blank=True, null=True)), + ( + "zev_sub_sector", + models.CharField(blank=True, max_length=250, null=True), + ), + ( + "on_road_off_road", + models.CharField(blank=True, max_length=250, null=True), + ), + ("fuel_type", models.CharField(blank=True, max_length=250, null=True)), + ("publicly_announced", models.BooleanField(default=False)), ], options={ - 'db_table': 'arc_project_tracking', + "db_table": "arc_project_tracking", }, ), ] diff --git a/django/api/migrations/0016_scrapit.py b/django/api/migrations/0016_scrapit.py index 2cfaa3fc..1a4bcacb 100644 --- a/django/api/migrations/0016_scrapit.py +++ b/django/api/migrations/0016_scrapit.py @@ -6,32 +6,71 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0015_arcprojecttracking'), + ("api", "0015_arcprojecttracking"), ] operations = [ migrations.CreateModel( - name='ScrapIt', + name="ScrapIt", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('approval_number', models.IntegerField(blank=True, null=True)), - ('application_received_date', models.CharField(blank=True, max_length=250, null=True)), - ('completion_date', models.CharField(blank=True, max_length=250, null=True)), - ('postal_code', models.CharField(blank=True, max_length=250, null=True)), - ('vin', models.CharField(blank=True, max_length=250, null=True)), - ('application_city_fuel', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), - ('incentive_type', models.CharField(blank=True, max_length=250, null=True)), - ('incentive_cost', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), - ('cheque_number', models.CharField(blank=True, max_length=250, null=True)), - ('budget_code', models.CharField(blank=True, max_length=250, null=True)), - ('scrap_date', models.CharField(blank=True, max_length=250, null=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("approval_number", models.IntegerField(blank=True, null=True)), + ( + "application_received_date", + models.CharField(blank=True, max_length=250, null=True), + ), + ( + "completion_date", + models.CharField(blank=True, max_length=250, null=True), + ), + ( + "postal_code", + models.CharField(blank=True, max_length=250, null=True), + ), + ("vin", models.CharField(blank=True, max_length=250, null=True)), + ( + "application_city_fuel", + models.DecimalField( + blank=True, decimal_places=2, max_digits=10, null=True + ), + ), + ( + "incentive_type", + models.CharField(blank=True, max_length=250, null=True), + ), + ( + "incentive_cost", + models.DecimalField( + blank=True, decimal_places=2, max_digits=10, null=True + ), + ), + ( + "cheque_number", + models.CharField(blank=True, max_length=250, null=True), + ), + ( + "budget_code", + models.CharField(blank=True, max_length=250, null=True), + ), + ("scrap_date", models.CharField(blank=True, max_length=250, null=True)), ], options={ - 'db_table': 'scrap_it', + "db_table": "scrap_it", }, ), ] diff --git a/django/api/migrations/0017_whitelistedusers.py b/django/api/migrations/0017_whitelistedusers.py index e58314d5..d06d72c1 100644 --- a/django/api/migrations/0017_whitelistedusers.py +++ b/django/api/migrations/0017_whitelistedusers.py @@ -6,22 +6,33 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0016_scrapit'), + ("api", "0016_scrapit"), ] operations = [ migrations.CreateModel( - name='WhitelistedUsers', + name="WhitelistedUsers", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('user', models.CharField(max_length=100, unique=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("user", models.CharField(max_length=100, unique=True)), ], options={ - 'db_table': 'whitelisted_users', + "db_table": "whitelisted_users", }, ), ] diff --git a/django/api/migrations/0018_auto_20231201_2301.py b/django/api/migrations/0018_auto_20231201_2301.py index b6addc17..58d1ec08 100644 --- a/django/api/migrations/0018_auto_20231201_2301.py +++ b/django/api/migrations/0018_auto_20231201_2301.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0017_whitelistedusers'), + ("api", "0017_whitelistedusers"), ] operations = [ migrations.RenameField( - model_name='hydrogenfleets', - old_name='steet_address', - new_name='street_address', + model_name="hydrogenfleets", + old_name="steet_address", + new_name="street_address", ), ] diff --git a/django/api/migrations/0019_auto_20240223_1820.py b/django/api/migrations/0019_auto_20240223_1820.py index c4c78315..34384558 100644 --- a/django/api/migrations/0019_auto_20240223_1820.py +++ b/django/api/migrations/0019_auto_20240223_1820.py @@ -7,54 +7,101 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0018_auto_20231201_2301'), + ("api", "0018_auto_20231201_2301"), ] operations = [ migrations.CreateModel( - name='Permission', + name="Permission", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('description', models.CharField(max_length=100, unique=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("description", models.CharField(max_length=100, unique=True)), ], options={ - 'db_table': 'permission', + "db_table": "permission", }, ), migrations.CreateModel( - name='User', + name="User", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('idir', models.CharField(max_length=100, unique=True)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ("idir", models.CharField(max_length=100, unique=True)), ], options={ - 'db_table': 'user', + "db_table": "user", }, ), migrations.CreateModel( - name='UserPermission', + name="UserPermission", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('create_timestamp', models.DateTimeField(auto_now_add=True, null=True)), - ('create_user', models.CharField(default='SYSTEM', max_length=130)), - ('update_timestamp', models.DateTimeField(auto_now=True, null=True)), - ('update_user', models.CharField(max_length=130, null=True)), - ('permission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='permission', to='api.permission')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user', to='api.user')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "create_timestamp", + models.DateTimeField(auto_now_add=True, null=True), + ), + ("create_user", models.CharField(default="SYSTEM", max_length=130)), + ("update_timestamp", models.DateTimeField(auto_now=True, null=True)), + ("update_user", models.CharField(max_length=130, null=True)), + ( + "permission", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="permission", + to="api.permission", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="user", + to="api.user", + ), + ), ], options={ - 'db_table': 'user_permission', + "db_table": "user_permission", }, ), migrations.DeleteModel( - name='WhitelistedUsers', + name="WhitelistedUsers", ), ] diff --git a/django/api/migrations/0020_auto_20240311_2136.py b/django/api/migrations/0020_auto_20240311_2136.py index 4a943f82..0475c7d1 100644 --- a/django/api/migrations/0020_auto_20240311_2136.py +++ b/django/api/migrations/0020_auto_20240311_2136.py @@ -6,28 +6,28 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0019_auto_20240223_1820'), + ("api", "0019_auto_20240223_1820"), ] operations = [ migrations.RenameField( - model_name='datafleets', - old_name='component_being_applyied_for', - new_name='component_being_applied_for', + model_name="datafleets", + old_name="component_being_applyied_for", + new_name="component_being_applied_for", ), migrations.RenameField( - model_name='datafleets', - old_name='number_of_Level_2_Charging_Stations_being_applying_for', - new_name='number_of_level_2_charging_stations_being_applied_for', + model_name="datafleets", + old_name="number_of_Level_2_Charging_Stations_being_applying_for", + new_name="number_of_level_2_charging_stations_being_applied_for", ), migrations.RenameField( - model_name='datafleets', - old_name='number_of_level_3_dc_fast_charging_stations_being_applying_for', - new_name='number_of_level_3_dc_fast_charging_stations_being_applied_for', + model_name="datafleets", + old_name="number_of_level_3_dc_fast_charging_stations_being_applying_for", + new_name="number_of_level_3_dc_fast_charging_stations_being_applied_for", ), migrations.RenameField( - model_name='datafleets', - old_name='type_of_charger_being_installing', - new_name='type_of_charger_being_installed', + model_name="datafleets", + old_name="type_of_charger_being_installing", + new_name="type_of_charger_being_installed", ), ] diff --git a/django/api/migrations/0021_auto_20240326_2152.py b/django/api/migrations/0021_auto_20240326_2152.py index 7419b057..6ba7c96b 100644 --- a/django/api/migrations/0021_auto_20240326_2152.py +++ b/django/api/migrations/0021_auto_20240326_2152.py @@ -6,13 +6,13 @@ class Migration(migrations.Migration): dependencies = [ - ('api', '0020_auto_20240311_2136'), + ("api", "0020_auto_20240311_2136"), ] operations = [ migrations.AlterField( - model_name='specialityusevehicleincentives', - name='date', + model_name="specialityusevehicleincentives", + name="date", field=models.DateField(blank=True, max_length=20, null=True), ), ] diff --git a/django/api/models/__init__.py b/django/api/models/__init__.py index c9882bfa..2aebd7a9 100644 --- a/django/api/models/__init__.py +++ b/django/api/models/__init__.py @@ -20,4 +20,4 @@ from . import scrap_it from . import user from . import permission -from . import user_permission \ No newline at end of file +from . import user_permission diff --git a/django/api/models/arc_project_tracking.py b/django/api/models/arc_project_tracking.py index 5047f1e7..8c66bc92 100644 --- a/django/api/models/arc_project_tracking.py +++ b/django/api/models/arc_project_tracking.py @@ -4,101 +4,47 @@ class ARCProjectTracking(Auditable): - funding_call = models.CharField( - blank=True, - null=True, - max_length=50, - unique=False - ) + funding_call = models.CharField(blank=True, null=True, max_length=50, unique=False) - proponent = models.CharField( - blank=True, - null=True, - max_length=500, - unique=False - ) + proponent = models.CharField(blank=True, null=True, max_length=500, unique=False) reference_number = models.CharField( - blank=True, - null=True, - max_length=50, - unique=False + blank=True, null=True, max_length=50, unique=False ) project_title = models.CharField( - blank=True, - null=True, - max_length=500, - unique=False + blank=True, null=True, max_length=500, unique=False ) primary_location = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) - status = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False - ) + status = models.CharField(blank=True, null=True, max_length=250, unique=False) - arc_funding = models.IntegerField( - blank=True, - null=True - ) + arc_funding = models.IntegerField(blank=True, null=True) - funds_issued = models.IntegerField( - blank=True, - null=True - ) + funds_issued = models.IntegerField(blank=True, null=True) - start_date = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False - ) + start_date = models.CharField(blank=True, null=True, max_length=250, unique=False) completion_date = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) - total_project_value = models.IntegerField( - blank=True, - null=True - ) + total_project_value = models.IntegerField(blank=True, null=True) zev_sub_sector = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) on_road_off_road = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) - fuel_type = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False - ) + fuel_type = models.CharField(blank=True, null=True, max_length=250, unique=False) - publicly_announced = models.BooleanField( - default=False - ) + publicly_announced = models.BooleanField(default=False) class Meta: - db_table = "arc_project_tracking" \ No newline at end of file + db_table = "arc_project_tracking" diff --git a/django/api/models/charger_rebates.py b/django/api/models/charger_rebates.py index 6bf23c7f..baea6aee 100644 --- a/django/api/models/charger_rebates.py +++ b/django/api/models/charger_rebates.py @@ -4,80 +4,33 @@ class ChargerRebates(Auditable): - organization = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False - ) + organization = models.CharField(blank=True, null=True, max_length=250, unique=False) - region = models.CharField( - blank=True, - null=True, - max_length=200, - unique=False - ) + region = models.CharField(blank=True, null=True, max_length=200, unique=False) - city = models.CharField( - blank=True, - null=True, - max_length=200, - unique=False - ) + city = models.CharField(blank=True, null=True, max_length=200, unique=False) - address = models.CharField( - blank=True, - null=True, - max_length=200, - unique=False - ) + address = models.CharField(blank=True, null=True, max_length=200, unique=False) - postal_code = models.CharField( - blank=True, - null=True, - max_length=200, - unique=False - ) + postal_code = models.CharField(blank=True, null=True, max_length=200, unique=False) - number_of_fast_charging_stations = models.IntegerField( - blank=True, - null=True - ) + number_of_fast_charging_stations = models.IntegerField(blank=True, null=True) in_service_date = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False + blank=True, null=True, max_length=100, unique=False ) expected_in_service_date = models.CharField( - blank=True, - null=True, - max_length=200, - unique=False + blank=True, null=True, max_length=200, unique=False ) - announced = models.CharField( - blank=True, - null=True, - max_length=200, - unique=False - ) + announced = models.CharField(blank=True, null=True, max_length=200, unique=False) rebate_paid = models.DecimalField( - blank=True, - null=True, - max_digits=20, - decimal_places=2 + blank=True, null=True, max_digits=20, decimal_places=2 ) - notes = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False - ) + notes = models.CharField(blank=True, null=True, max_length=250, unique=False) class Meta: db_table = "charger_rebates" diff --git a/django/api/models/credit_class.py b/django/api/models/credit_class.py index 78f31e4a..4e005f1c 100644 --- a/django/api/models/credit_class.py +++ b/django/api/models/credit_class.py @@ -1,6 +1,7 @@ """ Credit Class model """ + from django.db import models from api.models.mixins.effective_dates import EffectiveDates @@ -12,12 +13,8 @@ class CreditClass(EffectiveDates, Auditable): A lookup table for credit classes. Initially, A or B, but with room to expand later. """ + class Meta: db_table = "credit_class_code" - credit_class = models.CharField( - blank=False, - max_length=3, - null=False, - unique=True - ) + credit_class = models.CharField(blank=False, max_length=3, null=False, unique=True) diff --git a/django/api/models/data_fleets.py b/django/api/models/data_fleets.py index c72b8fb5..045582ec 100644 --- a/django/api/models/data_fleets.py +++ b/django/api/models/data_fleets.py @@ -4,171 +4,88 @@ class DataFleets(Auditable): current_stage = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) - rebate_value = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False - ) + rebate_value = models.CharField(blank=True, null=True, max_length=100, unique=False) legal_name_of_organization_fleet = models.CharField( - blank=True, - null=True, - max_length=500, - unique=False + blank=True, null=True, max_length=500, unique=False ) business_category = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) - city = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False - ) + city = models.CharField(blank=True, null=True, max_length=250, unique=False) - postal_code = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False - ) + postal_code = models.CharField(blank=True, null=True, max_length=100, unique=False) applicant_first_name = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False + blank=True, null=True, max_length=100, unique=False ) applicant_last_name = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False + blank=True, null=True, max_length=100, unique=False ) email_address = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False + blank=True, null=True, max_length=100, unique=False ) - fleet_size_all = models.IntegerField( - blank=True, - null=True - ) + fleet_size_all = models.IntegerField(blank=True, null=True) - fleet_size_light_duty = models.IntegerField( - blank=True, - null=True - ) + fleet_size_light_duty = models.IntegerField(blank=True, null=True) - total_number_of_evs = models.IntegerField( - blank=True, - null=True - ) + total_number_of_evs = models.IntegerField(blank=True, null=True) - total_number_of_light_duty_evs = models.IntegerField( - blank=True, - null=True - ) + total_number_of_light_duty_evs = models.IntegerField(blank=True, null=True) - phev = models.IntegerField( - blank=True, - null=True - ) + phev = models.IntegerField(blank=True, null=True) - evse = models.IntegerField( - blank=True, - null=True - ) + evse = models.IntegerField(blank=True, null=True) average_daily_travel_distance = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False + blank=True, null=True, max_length=100, unique=False ) component_being_applied_for = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) estimated_cost = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False + blank=True, null=True, max_length=100, unique=False ) type_of_charger_being_installed = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) number_of_level_2_charging_stations_being_applied_for = models.IntegerField( - blank=True, - null=True + blank=True, null=True ) number_of_level_3_dc_fast_charging_stations_being_applied_for = models.IntegerField( - blank=True, - null=True + blank=True, null=True ) application_form_fleets_completion_date_time = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False + blank=True, null=True, max_length=100, unique=False ) pre_approval_date = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False + blank=True, null=True, max_length=100, unique=False ) - deadline = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False - ) + deadline = models.CharField(blank=True, null=True, max_length=250, unique=False) application_number = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) potential_rebate = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False + blank=True, null=True, max_length=100, unique=False ) - class Meta: db_table = "data_fleets" diff --git a/django/api/models/datasets.py b/django/api/models/datasets.py index f5242bb3..514e7a2a 100644 --- a/django/api/models/datasets.py +++ b/django/api/models/datasets.py @@ -11,4 +11,4 @@ class Datasets(Auditable): ) class Meta: - db_table = 'datasets' + db_table = "datasets" diff --git a/django/api/models/hydrogen_fleets.py b/django/api/models/hydrogen_fleets.py index 31651a37..9420eeb4 100644 --- a/django/api/models/hydrogen_fleets.py +++ b/django/api/models/hydrogen_fleets.py @@ -4,105 +4,44 @@ class HydrogenFleets(Auditable): - application_number = models.IntegerField( - blank=True, - null=True - ) + application_number = models.IntegerField(blank=True, null=True) - fleet_number = models.IntegerField( - blank=True, - null=True - ) + fleet_number = models.IntegerField(blank=True, null=True) application_date = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False + blank=True, null=True, max_length=100, unique=False ) organization_name = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) - fleet_name = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False - ) + fleet_name = models.CharField(blank=True, null=True, max_length=250, unique=False) street_address = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) - city = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False - ) + city = models.CharField(blank=True, null=True, max_length=100, unique=False) - postal_code = models.CharField( - blank=True, - null=True, - max_length=10, - unique=False - ) + postal_code = models.CharField(blank=True, null=True, max_length=10, unique=False) - vin = models.CharField( - blank=True, - null=True, - max_length=20, - unique=False - ) + vin = models.CharField(blank=True, null=True, max_length=20, unique=False) - make = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False - ) + make = models.CharField(blank=True, null=True, max_length=100, unique=False) - model = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False - ) + model = models.CharField(blank=True, null=True, max_length=100, unique=False) - year = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False - ) + year = models.CharField(blank=True, null=True, max_length=100, unique=False) purchase_date = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False + blank=True, null=True, max_length=100, unique=False ) - dealer_name = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False - ) + dealer_name = models.CharField(blank=True, null=True, max_length=250, unique=False) rebate_amount = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) class Meta: diff --git a/django/api/models/hydrogen_fueling.py b/django/api/models/hydrogen_fueling.py index 08d40845..50eb6e6a 100644 --- a/django/api/models/hydrogen_fueling.py +++ b/django/api/models/hydrogen_fueling.py @@ -1,6 +1,7 @@ """ Hydrogen Fueling """ + from django.db import models from api.models.mixins.effective_dates import EffectiveDates @@ -12,87 +13,25 @@ class HydrogrenFueling(EffectiveDates, Auditable): class Meta: db_table = "hydrogen_fueling" - station_number = models.IntegerField( - null=True, - blank=True - ) - rfp_close_date = models.DateField( - blank=True, - null=True - ) - station_name = models.CharField( - blank=True, - max_length=200, - null=True - ) - street_address = models.CharField( - blank=True, - max_length=200, - null=True - ) - city = models.CharField( - blank=True, - max_length=200, - null=True, - unique=False - ) - postal_code = models.CharField( - blank=True, - max_length=50, - null=True, - unique=False - ) - proponent = models.CharField( - blank=True, - max_length=100, - null=True - ) - location_partner = models.CharField( - max_length=100, - null=True, - blank=True - ) + station_number = models.IntegerField(null=True, blank=True) + rfp_close_date = models.DateField(blank=True, null=True) + station_name = models.CharField(blank=True, max_length=200, null=True) + street_address = models.CharField(blank=True, max_length=200, null=True) + city = models.CharField(blank=True, max_length=200, null=True, unique=False) + postal_code = models.CharField(blank=True, max_length=50, null=True, unique=False) + proponent = models.CharField(blank=True, max_length=100, null=True) + location_partner = models.CharField(max_length=100, null=True, blank=True) capital_funding_awarded = models.DecimalField( - null=True, - blank=True, - max_digits=20, - decimal_places=2 + null=True, blank=True, max_digits=20, decimal_places=2 ) om_funding_potential = models.DecimalField( - null=True, - blank=True, - max_digits=20, - decimal_places=2 - ) - daily_capacity = models.IntegerField( - null=True, - blank=True - ) - bar_700 = models.BooleanField( - default=False - ) - bar_350 = models.BooleanField( - default=False - ) - status = models.CharField( - blank=True, - max_length=200, - null=True, - unique=False - ) - number_of_fueling_positions = models.IntegerField( - null=True, - blank=True - ) - operational_date = models.DateField( - blank=True, - null=True - ) - opening_date = models.DateField( - blank=True, - null=True - ) - total_capital_cost = models.DecimalField( - max_digits=20, - decimal_places=2 - ) + null=True, blank=True, max_digits=20, decimal_places=2 + ) + daily_capacity = models.IntegerField(null=True, blank=True) + bar_700 = models.BooleanField(default=False) + bar_350 = models.BooleanField(default=False) + status = models.CharField(blank=True, max_length=200, null=True, unique=False) + number_of_fueling_positions = models.IntegerField(null=True, blank=True) + operational_date = models.DateField(blank=True, null=True) + opening_date = models.DateField(blank=True, null=True) + total_capital_cost = models.DecimalField(max_digits=20, decimal_places=2) diff --git a/django/api/models/icbc_registration_data.py b/django/api/models/icbc_registration_data.py index 05df30eb..6f6902b4 100644 --- a/django/api/models/icbc_registration_data.py +++ b/django/api/models/icbc_registration_data.py @@ -4,23 +4,15 @@ class IcbcRegistrationData(Auditable): icbc_vehicle = models.ForeignKey( - 'IcbcVehicle', - related_name=None, - on_delete=models.CASCADE + "IcbcVehicle", related_name=None, on_delete=models.CASCADE ) vin = models.CharField( - blank=False, - null=False, - unique=True, - max_length=20, - db_index=True + blank=False, null=False, unique=True, max_length=20, db_index=True ) icbc_upload_date = models.ForeignKey( - 'IcbcUploadDate', - related_name=None, - on_delete=models.CASCADE + "IcbcUploadDate", related_name=None, on_delete=models.CASCADE ) class Meta: diff --git a/django/api/models/icbc_upload_date.py b/django/api/models/icbc_upload_date.py index de51753d..8390c87a 100644 --- a/django/api/models/icbc_upload_date.py +++ b/django/api/models/icbc_upload_date.py @@ -3,11 +3,7 @@ class IcbcUploadDate(Auditable): - upload_date = models.DateField( - blank=False, - null=False, - auto_now=False - ) + upload_date = models.DateField(blank=False, null=False, auto_now=False) class Meta: - db_table = 'icbc_upload_date' + db_table = "icbc_upload_date" diff --git a/django/api/models/icbc_vehicle.py b/django/api/models/icbc_vehicle.py index 3c1a53e8..63275d6f 100644 --- a/django/api/models/icbc_vehicle.py +++ b/django/api/models/icbc_vehicle.py @@ -1,6 +1,7 @@ """ ICBC Vehicle Model """ + from django.db import models from auditable.models import Auditable @@ -9,33 +10,19 @@ class IcbcVehicle(Auditable): "All vehicle models that have been added from icbc registration" "spreadsheet." - make = models.CharField( - blank=False, - null=False, - max_length=250, - db_index=True - ) + make = models.CharField(blank=False, null=False, max_length=250, db_index=True) model_name = models.CharField( - blank=False, - max_length=250, - null=False, - db_index=True + blank=False, max_length=250, null=False, db_index=True ) model_year = models.ForeignKey( - 'ModelYear', + "ModelYear", related_name=None, on_delete=models.PROTECT, null=False, - db_index=True + db_index=True, ) class Meta: - db_table = 'icbc_vehicle' - unique_together = [[ - 'make', 'model_name', - 'model_year' - ]] - index_together = [[ - 'make', 'model_name', - 'model_year' - ]] + db_table = "icbc_vehicle" + unique_together = [["make", "model_name", "model_year"]] + index_together = [["make", "model_name", "model_year"]] diff --git a/django/api/models/ldv_rebates.py b/django/api/models/ldv_rebates.py index c73f7511..10bc2541 100644 --- a/django/api/models/ldv_rebates.py +++ b/django/api/models/ldv_rebates.py @@ -3,108 +3,50 @@ class LdvRebates(Auditable): - submission_id = models.IntegerField( - unique=False - ) - casl_consent = models.BooleanField( - default=False - ) + submission_id = models.IntegerField(unique=False) + casl_consent = models.BooleanField(default=False) date_approved = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False + blank=True, null=True, max_length=100, unique=False ) submission_date = models.CharField( - blank=True, - null=True, - max_length=100, - unique=False - ) - company_name = models.CharField( - blank=True, - max_length=200, - null=True, - unique=False - ) - company_city = models.CharField( - blank=True, - max_length=200, - null=True, - unique=False + blank=True, null=True, max_length=100, unique=False ) + company_name = models.CharField(blank=True, max_length=200, null=True, unique=False) + company_city = models.CharField(blank=True, max_length=200, null=True, unique=False) applicant_name = models.CharField( - blank=True, - max_length=200, - null=True, - unique=False + blank=True, max_length=200, null=True, unique=False ) applicant_address_1 = models.CharField( - blank=True, - max_length=200, - null=True, - unique=False + blank=True, max_length=200, null=True, unique=False ) applicant_address_2 = models.CharField( - blank=True, - max_length=200, - null=True, - unique=False + blank=True, max_length=200, null=True, unique=False ) applicant_city = models.CharField( - blank=True, - max_length=100, - null=True, - unique=False + blank=True, max_length=100, null=True, unique=False ) applicant_postal_code = models.CharField( - blank=True, - max_length=50, - null=True, - unique=False + blank=True, max_length=50, null=True, unique=False ) applicant_phone = models.CharField( - blank=True, - max_length=25, - null=True, - unique=False + blank=True, max_length=25, null=True, unique=False ) applicant_email = models.CharField( - blank=True, - max_length=200, - null=True, - unique=False - ) - applicant_use = models.CharField( - blank=True, - max_length=50, - null=True, - unique=False + blank=True, max_length=200, null=True, unique=False ) + applicant_use = models.CharField(blank=True, max_length=50, null=True, unique=False) applicant_type = models.CharField( - blank=True, - max_length=100, - null=True, - unique=False + blank=True, max_length=100, null=True, unique=False ) business_name = models.CharField( - blank=True, - max_length=100, - null=True, - unique=False + blank=True, max_length=100, null=True, unique=False ) business_number = models.CharField( - blank=True, - max_length=50, - null=True, - unique=False + blank=True, max_length=50, null=True, unique=False ) drivers_license = models.CharField( - blank=True, - max_length=50, - null=True, - unique=False + blank=True, max_length=50, null=True, unique=False ) province = models.CharField( blank=True, @@ -120,34 +62,15 @@ class LdvRebates(Auditable): max_digits=20, decimal_places=2, ) - document_type = models.CharField( - blank=True, - max_length=50, - null=True, - unique=False - ) - vehicle = models.CharField( - blank=True, - max_length=200, - null=True, - unique=False - ) + document_type = models.CharField(blank=True, max_length=50, null=True, unique=False) + vehicle = models.CharField(blank=True, max_length=200, null=True, unique=False) incentive_amount = models.DecimalField( max_digits=20, decimal_places=2, ) - vin = models.CharField( - blank=True, - max_length=255, - null=True, - unique=False - ) - delivered = models.BooleanField( - default=False - ) - consent_to_contact = models.BooleanField( - default=False - ) + vin = models.CharField(blank=True, max_length=255, null=True, unique=False) + delivered = models.BooleanField(default=False) + consent_to_contact = models.BooleanField(default=False) class Meta: db_table = "ldv_rebates" diff --git a/django/api/models/mixins/effective_dates.py b/django/api/models/mixins/effective_dates.py index 7ccc05ca..693f7b64 100644 --- a/django/api/models/mixins/effective_dates.py +++ b/django/api/models/mixins/effective_dates.py @@ -2,15 +2,9 @@ class EffectiveDates(models.Model): - effective_date = models.DateField( - blank=True, - null=True - ) + effective_date = models.DateField(blank=True, null=True) - expiration_date = models.DateField( - blank=True, - null=True - ) + expiration_date = models.DateField(blank=True, null=True) class Meta: abstract = True diff --git a/django/api/models/mixins/named.py b/django/api/models/mixins/named.py index fdba1a61..0cfb06b6 100644 --- a/django/api/models/mixins/named.py +++ b/django/api/models/mixins/named.py @@ -3,10 +3,7 @@ class Description(models.Model): description = models.CharField( - blank=False, - db_column="description", - max_length=250, - null=False + blank=False, db_column="description", max_length=250, null=False ) class Meta: @@ -15,10 +12,7 @@ class Meta: class Named(models.Model): name = models.CharField( - blank=False, - db_column="description", - max_length=250, - null=False + blank=False, db_column="description", max_length=250, null=False ) class Meta: @@ -27,11 +21,7 @@ class Meta: class UniquelyNamed(models.Model): name = models.CharField( - blank=False, - db_column="description", - unique=True, - null=False, - max_length=250 + blank=False, db_column="description", unique=True, null=False, max_length=250 ) class Meta: diff --git a/django/api/models/organization.py b/django/api/models/organization.py index b8bf1650..4582f0e9 100644 --- a/django/api/models/organization.py +++ b/django/api/models/organization.py @@ -5,25 +5,15 @@ class Organization(Auditable): name = models.CharField( - db_column="organization_name", - max_length=500, - null=False, - unique=True + db_column="organization_name", max_length=500, null=False, unique=True ) short_name = models.CharField( - db_column='short_name', - unique=True, - null=True, - max_length=64 + db_column="short_name", unique=True, null=True, max_length=64 ) - is_active = models.BooleanField( - default=False - ) - is_government = models.BooleanField( - default=False - ) + is_active = models.BooleanField(default=False) + is_government = models.BooleanField(default=False) class Meta: - db_table = 'organization' + db_table = "organization" diff --git a/django/api/models/permission.py b/django/api/models/permission.py index a9483873..78975b04 100644 --- a/django/api/models/permission.py +++ b/django/api/models/permission.py @@ -1,6 +1,7 @@ from django.db import models from auditable.models import Auditable + class Permission(Auditable): description = models.CharField( blank=False, @@ -10,6 +11,9 @@ class Permission(Auditable): ) class Meta: - db_table = 'permission' - db_table_comment = "Contains the list of permissions to grant access to " \ - "certain actions of areas for the system." \ No newline at end of file + db_table = "permission" + + db_table_comment = ( + "Contains the list of permissions to grant access to " + "certain actions of areas for the system." + ) diff --git a/django/api/models/public_charging.py b/django/api/models/public_charging.py index df957671..c4ee262a 100644 --- a/django/api/models/public_charging.py +++ b/django/api/models/public_charging.py @@ -1,6 +1,7 @@ """ Public Charging Model """ + from django.db import models from api.models.mixins.effective_dates import EffectiveDates @@ -13,23 +14,10 @@ class Meta: db_table = "public_charging" applicant_name = models.CharField( - blank=True, - max_length=200, - null=True, - unique=False - ) - city = models.CharField( - blank=True, - max_length=200, - null=True, - unique=False - ) - postal_code = models.CharField( - blank=True, - max_length=50, - null=True, - unique=False + blank=True, max_length=200, null=True, unique=False ) + city = models.CharField(blank=True, max_length=200, null=True, unique=False) + postal_code = models.CharField(blank=True, max_length=50, null=True, unique=False) address = models.CharField( blank=True, max_length=200, @@ -40,62 +28,21 @@ class Meta: max_length=500, null=True, ) - between_25kw_and_50kw = models.IntegerField( - null=True, - blank=True - ) - between_50kw_and_100kw = models.IntegerField( - null=True, - blank=True - ) - over_100kw = models.IntegerField( - null=True, - blank=True - ) - level_2_units = models.IntegerField( - null=True, - blank=True - ) - level_2_ports = models.IntegerField( - null=True, - blank=True - ) - estimated_budget = models.DecimalField( - max_digits=20, - decimal_places=2 - ) - adjusted_rebate = models.DecimalField( - max_digits=20, - decimal_places=2 - ) - rebate_percent_maximum = models.DecimalField( - max_digits=3, - decimal_places=2 - ) + between_25kw_and_50kw = models.IntegerField(null=True, blank=True) + between_50kw_and_100kw = models.IntegerField(null=True, blank=True) + over_100kw = models.IntegerField(null=True, blank=True) + level_2_units = models.IntegerField(null=True, blank=True) + level_2_ports = models.IntegerField(null=True, blank=True) + estimated_budget = models.DecimalField(max_digits=20, decimal_places=2) + adjusted_rebate = models.DecimalField(max_digits=20, decimal_places=2) + rebate_percent_maximum = models.DecimalField(max_digits=3, decimal_places=2) pilot_project = models.BooleanField() - region = models.CharField( - blank=True, - max_length=200, - null=True, - unique=False - ) + region = models.CharField(blank=True, max_length=200, null=True, unique=False) organization_type = models.CharField( - blank=True, - max_length=100, - null=True, - unique=False + blank=True, max_length=100, null=True, unique=False ) project_status = models.CharField( - blank=True, - max_length=200, - null=True, - unique=False - ) - review_number = models.IntegerField( - null=True, - blank=True - ) - rebate_paid = models.DecimalField( - max_digits=20, - decimal_places=2 + blank=True, max_length=200, null=True, unique=False ) + review_number = models.IntegerField(null=True, blank=True) + rebate_paid = models.DecimalField(max_digits=20, decimal_places=2) diff --git a/django/api/models/scrap_it.py b/django/api/models/scrap_it.py index 409f3753..1f8c9fd9 100644 --- a/django/api/models/scrap_it.py +++ b/django/api/models/scrap_it.py @@ -4,82 +4,39 @@ class ScrapIt(Auditable): - approval_number = models.IntegerField( - blank=True, - null=True - ) + approval_number = models.IntegerField(blank=True, null=True) application_received_date = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) completion_date = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) - postal_code = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False - ) + postal_code = models.CharField(blank=True, null=True, max_length=250, unique=False) - vin = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False - ) + vin = models.CharField(blank=True, null=True, max_length=250, unique=False) application_city_fuel = models.DecimalField( - blank=True, - null=True, - max_digits=10, - decimal_places=2, - unique=False + blank=True, null=True, max_digits=10, decimal_places=2, unique=False ) incentive_type = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) incentive_cost = models.DecimalField( - blank=True, - null=True, - max_digits=10, - decimal_places=2, - unique=False + blank=True, null=True, max_digits=10, decimal_places=2, unique=False ) cheque_number = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False + blank=True, null=True, max_length=250, unique=False ) - budget_code = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False - ) + budget_code = models.CharField(blank=True, null=True, max_length=250, unique=False) - scrap_date = models.CharField( - blank=True, - null=True, - max_length=250, - unique=False - ) + scrap_date = models.CharField(blank=True, null=True, max_length=250, unique=False) class Meta: - db_table = "scrap_it" \ No newline at end of file + db_table = "scrap_it" diff --git a/django/api/models/speciality_use_vehicle_incentives.py b/django/api/models/speciality_use_vehicle_incentives.py index 175e052e..13b74877 100644 --- a/django/api/models/speciality_use_vehicle_incentives.py +++ b/django/api/models/speciality_use_vehicle_incentives.py @@ -4,35 +4,15 @@ class SpecialityUseVehicleIncentives(Auditable): - approvals = models.CharField( - blank=True, - null=True, - max_length=20 - ) - date = models.DateField( - max_length=20, - null=True, - blank=True - ) - applicant_name = models.CharField( - blank=True, - null=True, - max_length=250 - ) + approvals = models.CharField(blank=True, null=True, max_length=20) + date = models.DateField(max_length=20, null=True, blank=True) + applicant_name = models.CharField(blank=True, null=True, max_length=250) max_incentive_amount_requested = models.IntegerField( null=True, blank=True, ) - category = models.CharField( - blank=True, - max_length=250, - null=True - ) - applicant_type = models.CharField( - blank=True, - max_length=50, - null=True - ) + category = models.CharField(blank=True, max_length=250, null=True) + applicant_type = models.CharField(blank=True, max_length=50, null=True) incentive_paid = models.IntegerField( null=True, blank=True, @@ -41,16 +21,8 @@ class SpecialityUseVehicleIncentives(Auditable): null=True, blank=True, ) - manufacturer = models.CharField( - blank=True, - max_length=250, - null=True - ) - model = models.CharField( - blank=True, - max_length=250, - null=True - ) + manufacturer = models.CharField(blank=True, max_length=250, null=True) + model = models.CharField(blank=True, max_length=250, null=True) class Meta: - db_table = 'speciality_use_vehicle_incentives' + db_table = "speciality_use_vehicle_incentives" diff --git a/django/api/models/user.py b/django/api/models/user.py index e62538b5..e9850b0b 100644 --- a/django/api/models/user.py +++ b/django/api/models/user.py @@ -1,6 +1,7 @@ from django.db import models from auditable.models import Auditable + class User(Auditable): idir = models.CharField( blank=False, @@ -10,5 +11,6 @@ class User(Auditable): ) class Meta: - db_table = 'user' - db_table_comment = "Contains the list of users in the system " \ No newline at end of file + db_table = "user" + + db_table_comment = "Contains the list of users in the system " diff --git a/django/api/models/user_permission.py b/django/api/models/user_permission.py index 57cfc706..6ccc0c75 100644 --- a/django/api/models/user_permission.py +++ b/django/api/models/user_permission.py @@ -1,18 +1,14 @@ from django.db import models from auditable.models import Auditable + class UserPermission(Auditable): - user = models.ForeignKey( - 'User', - related_name='user', - on_delete=models.CASCADE - ) + user = models.ForeignKey("User", related_name="user", on_delete=models.CASCADE) permission = models.ForeignKey( - 'Permission', - related_name='permission', - on_delete=models.CASCADE + "Permission", related_name="permission", on_delete=models.CASCADE ) class Meta: - db_table = 'user_permission' - db_table_comment = "Contains the relationship between user and permission tables " \ No newline at end of file + db_table = "user_permission" + + db_table_comment = "Contains the relationship between user and permission tables " diff --git a/django/api/models/vehicle.py b/django/api/models/vehicle.py index 045b27ff..a69d23b9 100644 --- a/django/api/models/vehicle.py +++ b/django/api/models/vehicle.py @@ -4,70 +4,30 @@ class Vehicle(Auditable): - make = models.CharField( - blank=False, - null=False, - max_length=250 - ) + make = models.CharField(blank=False, null=False, max_length=250) vehicle_zev_type = models.ForeignKey( - 'ZevType', - related_name=None, - on_delete=models.PROTECT + "ZevType", related_name=None, on_delete=models.PROTECT ) vehicle_class_code = models.ForeignKey( - 'VehicleClass', - related_name=None, - on_delete=models.PROTECT + "VehicleClass", related_name=None, on_delete=models.PROTECT ) range = models.IntegerField() - model_name = models.CharField( - blank=False, - max_length=250, - null=False - ) + model_name = models.CharField(blank=False, max_length=250, null=False) model_year = models.ForeignKey( - 'ModelYear', - related_name=None, - on_delete=models.PROTECT, - null=False - ) - validation_status = models.CharField( - max_length=20, - null=False, - default="DRAFT" + "ModelYear", related_name=None, on_delete=models.PROTECT, null=False ) + validation_status = models.CharField(max_length=20, null=False, default="DRAFT") organization = models.ForeignKey( - 'Organization', - related_name=None, - on_delete=models.PROTECT, - null=False - ) - weight_kg = models.DecimalField( - blank=False, - max_digits=6, - decimal_places=0 + "Organization", related_name=None, on_delete=models.PROTECT, null=False ) + weight_kg = models.DecimalField(blank=False, max_digits=6, decimal_places=0) credit_class = models.ForeignKey( - 'CreditClass', - related_name='+', - on_delete=models.PROTECT, - null=True - ) - has_passed_us_06_test = models.BooleanField( - default=False - ) - credit_value = models.DecimalField( - null=True, - decimal_places=2, - max_digits=20 - ) - is_active = models.BooleanField( - default=True + "CreditClass", related_name="+", on_delete=models.PROTECT, null=True ) + has_passed_us_06_test = models.BooleanField(default=False) + credit_value = models.DecimalField(null=True, decimal_places=2, max_digits=20) + is_active = models.BooleanField(default=True) class Meta: - db_table = 'vehicle' - unique_together = [[ - 'make', 'model_name', 'vehicle_zev_type', - 'model_year' - ]] + db_table = "vehicle" + unique_together = [["make", "model_name", "vehicle_zev_type", "model_year"]] diff --git a/django/api/models/vehicle_class.py b/django/api/models/vehicle_class.py index 456232fb..fec2f26b 100644 --- a/django/api/models/vehicle_class.py +++ b/django/api/models/vehicle_class.py @@ -7,11 +7,8 @@ class VehicleClass(Auditable, Description, EffectiveDates): vehicle_class_code = models.CharField( - blank=False, - max_length=3, - null=False, - unique=True + blank=False, max_length=3, null=False, unique=True ) class Meta: - db_table = 'vehicle_class_code' + db_table = "vehicle_class_code" diff --git a/django/api/models/vehicle_zev_type.py b/django/api/models/vehicle_zev_type.py index f496459f..102444cd 100644 --- a/django/api/models/vehicle_zev_type.py +++ b/django/api/models/vehicle_zev_type.py @@ -7,11 +7,8 @@ class ZevType(Auditable, Description, EffectiveDates): vehicle_zev_code = models.CharField( - blank=False, - max_length=4, - null=False, - unique=True + blank=False, max_length=4, null=False, unique=True ) class Meta: - db_table = 'vehicle_zev_type' + db_table = "vehicle_zev_type" diff --git a/django/api/models/vin_decoded_information.py b/django/api/models/vin_decoded_information.py index d0a6d669..dba4edb5 100644 --- a/django/api/models/vin_decoded_information.py +++ b/django/api/models/vin_decoded_information.py @@ -4,35 +4,15 @@ class VINDecodedInformation(Auditable): - vin = models.CharField( - blank=False, - null=False, - max_length=20 - ) - manufacturer = models.CharField( - max_length=500, - null=True, - blank=True - ) - make = models.CharField( - blank=True, - null=True, - max_length=250 - ) - model = models.CharField( - blank=True, - max_length=250, - null=True - ) + vin = models.CharField(blank=False, null=False, max_length=20) + manufacturer = models.CharField(max_length=500, null=True, blank=True) + make = models.CharField(blank=True, null=True, max_length=250) + model = models.CharField(blank=True, max_length=250, null=True) model_year = models.IntegerField( null=True, blank=True, ) - fuel_type_primary = models.CharField( - blank=True, - max_length=250, - null=True - ) + fuel_type_primary = models.CharField(blank=True, max_length=250, null=True) class Meta: - db_table = 'vin_decoded_information' + db_table = "vin_decoded_information" diff --git a/django/api/pagination.py b/django/api/pagination.py index 8b1b28d0..31895298 100644 --- a/django/api/pagination.py +++ b/django/api/pagination.py @@ -3,6 +3,7 @@ Further reading: https://www.django-rest-framework.org/api-guide/pagination/ """ + from rest_framework.pagination import PageNumberPagination @@ -10,6 +11,7 @@ class StandardResultsSetPagination(PageNumberPagination): """ Default page settings """ + page_size = 100 - page_size_query_param = 'page_size' + page_size_query_param = "page_size" max_page_size = 1000 diff --git a/django/api/serializers/datasets.py b/django/api/serializers/datasets.py index 3292f0cd..2e8152bb 100644 --- a/django/api/serializers/datasets.py +++ b/django/api/serializers/datasets.py @@ -1,4 +1,3 @@ - from rest_framework.serializers import ModelSerializer from api.models.datasets import Datasets @@ -8,4 +7,4 @@ class DatasetsSerializer(ModelSerializer): class Meta: model = Datasets - fields = ('name', 'id') + fields = ("name", "id") diff --git a/django/api/serializers/icbc_registration_data.py b/django/api/serializers/icbc_registration_data.py index 9775bcc0..b1264c64 100644 --- a/django/api/serializers/icbc_registration_data.py +++ b/django/api/serializers/icbc_registration_data.py @@ -2,6 +2,7 @@ Further reading: https://www.django-rest-framework.org/api-guide/serializers/ """ + from rest_framework.serializers import ModelSerializer from api.models.icbc_registration_data import IcbcRegistrationData @@ -12,8 +13,9 @@ class IcbcRegistrationDataSerializer(ModelSerializer): """ Default Serializer for ICBC Vehicle """ + icbc_vehicle = IcbcVehicleSerializer() class Meta: model = IcbcRegistrationData - fields = '__all__' + fields = "__all__" diff --git a/django/api/serializers/icbc_vehicle.py b/django/api/serializers/icbc_vehicle.py index d3943b09..ca50a1bf 100644 --- a/django/api/serializers/icbc_vehicle.py +++ b/django/api/serializers/icbc_vehicle.py @@ -2,6 +2,7 @@ Further reading: https://www.django-rest-framework.org/api-guide/serializers/ """ + from rest_framework.serializers import ModelSerializer, SlugRelatedField from api.models.icbc_vehicle import IcbcVehicle @@ -11,11 +12,9 @@ class IcbcVehicleSerializer(ModelSerializer): """ Default Serializer for ICBC Vehicle """ - model_year = SlugRelatedField( - read_only=True, - slug_field='name' - ) + + model_year = SlugRelatedField(read_only=True, slug_field="name") class Meta: model = IcbcVehicle - fields = '__all__' + fields = "__all__" diff --git a/django/api/serializers/permission.py b/django/api/serializers/permission.py index 73efc23e..ceeb9500 100644 --- a/django/api/serializers/permission.py +++ b/django/api/serializers/permission.py @@ -3,14 +3,18 @@ from api.models.permission import Permission from api.models.user_permission import UserPermission + class PermissionSerializer(ModelSerializer): description = SerializerMethodField() + def get_description(self, obj): permission = Permission.objects.filter(id=obj.permission_id).first() if permission: return permission.description + class Meta: model = Permission fields = ( - 'id', 'description', + "id", + "description", ) diff --git a/django/api/serializers/user.py b/django/api/serializers/user.py index 93946f77..3324cef3 100644 --- a/django/api/serializers/user.py +++ b/django/api/serializers/user.py @@ -2,36 +2,46 @@ Further reading: https://www.django-rest-framework.org/api-guide/serializers/ """ -from rest_framework.serializers import ModelSerializer, SerializerMethodField, ValidationError + +from rest_framework.serializers import ( + ModelSerializer, + SerializerMethodField, + ValidationError, +) from api.models.user import User from api.models.user_permission import UserPermission from api.services.permissions import get_permissions_representation + class UserSerializer(ModelSerializer): """ Default Serializer for User """ + user_permissions = SerializerMethodField() def get_user_permissions(self, obj): - user_permission = UserPermission.objects.select_related("permission").filter(user_id=obj.id) + user_permission = UserPermission.objects.select_related("permission").filter( + user_id=obj.id + ) permissions = [] for each in user_permission: permissions.append(each.permission) return get_permissions_representation(permissions) - + def validate_idir(self, value): if isinstance(value, str) and value.strip(): return value.strip().upper() raise ValidationError("IDIR error!") - + def create(self, validated_data): return User.objects.create(**validated_data) class Meta: model = User - fields = ('idir', 'user_permissions') + fields = ("idir", "user_permissions") + # requires permissions_map object class UserListSerializer(ModelSerializer): @@ -44,4 +54,4 @@ def get_user_permissions(self, obj): class Meta: model = User - fields = ('idir', 'user_permissions') + fields = ("idir", "user_permissions") diff --git a/django/api/services/datasheet_template_generator.py b/django/api/services/datasheet_template_generator.py index ea8f3402..5a5bdc3a 100644 --- a/django/api/services/datasheet_template_generator.py +++ b/django/api/services/datasheet_template_generator.py @@ -2,20 +2,21 @@ from io import BytesIO from api.constants import * + def generate_template(dataset_name): """ Generates an Excel spreadsheet template for a specified dataset. """ dataset_column_enum_map = { - 'ARC Project Tracking': ARCProjectTrackingColumns, - 'EV Charging Rebates': EVChargingRebatesColumns, - 'Data Fleets': DataFleetsColumns, - 'Hydrogen Fleets': HydrogenFleetsColumns, - 'Hydrogen Fueling': HydrogenFuelingColumns, - 'LDV Rebates': LDVRebatesColumns, - 'Public Charging': PublicChargingColumns, - 'Scrap It': ScrapItColumns, - 'Specialty Use Vehicle Incentive Program': SpecialityUseVehicleIncentiveProgramColumns, + "ARC Project Tracking": ARCProjectTrackingColumns, + "EV Charging Rebates": EVChargingRebatesColumns, + "Data Fleets": DataFleetsColumns, + "Hydrogen Fleets": HydrogenFleetsColumns, + "Hydrogen Fueling": HydrogenFuelingColumns, + "LDV Rebates": LDVRebatesColumns, + "Public Charging": PublicChargingColumns, + "Scrap It": ScrapItColumns, + "Specialty Use Vehicle Incentive Program": SpecialityUseVehicleIncentiveProgramColumns, } if dataset_name not in dataset_column_enum_map: @@ -26,24 +27,24 @@ def generate_template(dataset_name): df = pd.DataFrame(columns=columns) excel_buffer = BytesIO() - with pd.ExcelWriter(excel_buffer, engine='xlsxwriter') as writer: + with pd.ExcelWriter(excel_buffer, engine="xlsxwriter") as writer: sheet_name = dataset_name.replace(" ", "_") start_row = 0 custom_sheet_names = { - 'ARC Project Tracking': 'Project_Tracking', - 'Specialty Use Vehicle Incentive Program': 'Sheet1', - 'Public Charging': 'Project_applications', - 'LDV Rebates': 'Raw Data', - 'EV Charging Rebates': 'Updated', - 'Hydrogen Fueling': 'Station_Tracking', - 'Hydrogen Fleets': 'Fleets', - 'Scrap It': 'TOP OTHER TRANSACTIONS', + "ARC Project Tracking": "Project_Tracking", + "Specialty Use Vehicle Incentive Program": "Sheet1", + "Public Charging": "Project_applications", + "LDV Rebates": "Raw Data", + "EV Charging Rebates": "Updated", + "Hydrogen Fueling": "Station_Tracking", + "Hydrogen Fleets": "Fleets", + "Scrap It": "TOP OTHER TRANSACTIONS", } custom_start_rows = { - 'Public Charging': 2, - 'EV Charging Rebates': 2, - 'Scrap It': 5, + "Public Charging": 2, + "EV Charging Rebates": 2, + "Scrap It": 5, } sheet_name = custom_sheet_names.get(dataset_name, sheet_name) @@ -52,4 +53,4 @@ def generate_template(dataset_name): df.to_excel(writer, sheet_name=sheet_name, startrow=start_row, index=False) excel_buffer.seek(0) - return excel_buffer \ No newline at end of file + return excel_buffer diff --git a/django/api/services/ldv_rebates.py b/django/api/services/ldv_rebates.py index e7e9bcd9..8fb211ee 100644 --- a/django/api/services/ldv_rebates.py +++ b/django/api/services/ldv_rebates.py @@ -12,41 +12,21 @@ def trim_all_columns(df): def import_from_xls(excel_file): row_count = 1 - df = pd.read_excel(excel_file, 'Raw Data') + df = pd.read_excel(excel_file, "Raw Data") df = trim_all_columns(df) df = df.applymap(lambda s: s.upper() if type(s) == str else s) - df['CASL Consent'].replace( - to_replace=['YES', 'Y'], - value=True, - inplace=True - ) - df['CASL Consent'].replace( - to_replace=['NO', 'N'], - value=False, - inplace=True - ) - df['Delivered'].replace( - to_replace=['YES', 'Y'], - value=True, - inplace=True - ) - df['Delivered'].replace( - to_replace=['NO', 'N', 'OEM', 'INCENTIVE_FUNDS_AVAILABLE'], + df["CASL Consent"].replace(to_replace=["YES", "Y"], value=True, inplace=True) + df["CASL Consent"].replace(to_replace=["NO", "N"], value=False, inplace=True) + df["Delivered"].replace(to_replace=["YES", "Y"], value=True, inplace=True) + df["Delivered"].replace( + to_replace=["NO", "N", "OEM", "INCENTIVE_FUNDS_AVAILABLE"], value=False, - inplace=True + inplace=True, ) - df['Consent to Contact'].replace( - to_replace=['YES', 'Y'], - value=True, - inplace=True - ) - df['Consent to Contact'].replace( - to_replace=['NO', 'N'], - value=False, - inplace=True - ) - df.fillna('') + df["Consent to Contact"].replace(to_replace=["YES", "Y"], value=True, inplace=True) + df["Consent to Contact"].replace(to_replace=["NO", "N"], value=False, inplace=True) + df.fillna("") try: for _, row in df.iterrows(): @@ -77,8 +57,8 @@ def import_from_xls(excel_file): incentive_amount=row["Incentive Amount"], vin=row["VIN#"], delivered=row["Delivered"], - consent_to_contact=row["Consent to Contact"] + consent_to_contact=row["Consent to Contact"], ) except Exception as error: - return (error,'data',row_count) + return (error, "data", row_count) return True diff --git a/django/api/services/minio.py b/django/api/services/minio.py index 48c75d7f..de1b0fd5 100644 --- a/django/api/services/minio.py +++ b/django/api/services/minio.py @@ -7,14 +7,14 @@ settings.MINIO_ENDPOINT, access_key=settings.MINIO_ACCESS_KEY, secret_key=settings.MINIO_SECRET_KEY, - secure=settings.MINIO_USE_SSL + secure=settings.MINIO_USE_SSL, ) def get_refined_object_name(object_name): prefix = settings.MINIO_PREFIX if prefix: - return prefix + '/' + object_name + return prefix + "/" + object_name return object_name @@ -22,7 +22,7 @@ def minio_get_object(object_name): return MINIO.presigned_get_object( bucket_name=settings.MINIO_BUCKET_NAME, object_name=get_refined_object_name(object_name), - expires=timedelta(seconds=3600) + expires=timedelta(seconds=3600), ) @@ -30,7 +30,7 @@ def minio_put_object(object_name): return MINIO.presigned_put_object( bucket_name=settings.MINIO_BUCKET_NAME, object_name=get_refined_object_name(object_name), - expires=timedelta(seconds=7200) + expires=timedelta(seconds=7200), ) diff --git a/django/api/services/permissions.py b/django/api/services/permissions.py index fa597983..d4d52a49 100644 --- a/django/api/services/permissions.py +++ b/django/api/services/permissions.py @@ -2,6 +2,7 @@ from api.models.user_permission import UserPermission from api.models.permission import Permission + def create_permission_list(user): user = User.objects.filter(idir=user).first() user_permission = UserPermission.objects.filter(user_id=user.id) @@ -15,7 +16,9 @@ def create_permission_list(user): def get_permissions_map(users): result = {} - user_permissions = UserPermission.objects.select_related("user", "permission").filter(user__in=users) + user_permissions = UserPermission.objects.select_related( + "user", "permission" + ).filter(user__in=users) for each in user_permissions: user = each.user permission = each.permission @@ -30,4 +33,4 @@ def get_permissions_representation(permissions): if permissions is not None: for permission in permissions: result[permission.description] = True - return result \ No newline at end of file + return result diff --git a/django/api/services/spreadsheet_uploader.py b/django/api/services/spreadsheet_uploader.py index f350c7b5..6caa6452 100644 --- a/django/api/services/spreadsheet_uploader.py +++ b/django/api/services/spreadsheet_uploader.py @@ -3,25 +3,29 @@ import traceback from django.db import transaction + def get_field_default(model, field): field = model._meta.get_field(field) - + if callable(field.default): return field.default() return field.default + def get_nullable_fields(model): nullable_fields = {} for field in model._meta.get_fields(): - if hasattr(field, 'null') and field.null: + if hasattr(field, "null") and field.null: nullable_fields[field.name] = True return nullable_fields + def trim_all_columns(df): trim_strings = lambda x: x.strip() if isinstance(x, str) else x return df.applymap(trim_strings) + def extract_data(excel_file, sheet_name, header_row): try: df = pd.read_excel(excel_file, sheet_name, header=header_row) @@ -32,7 +36,13 @@ def extract_data(excel_file, sheet_name, header_row): raise -def transform_data(df, dataset_columns, column_mapping_enum, preparation_functions=[], validation_functions=[]): +def transform_data( + df, + dataset_columns, + column_mapping_enum, + preparation_functions=[], + validation_functions=[], +): required_columns = [col.value for col in dataset_columns] df = df[[col for col in df.columns if col in required_columns]] @@ -40,13 +50,13 @@ def transform_data(df, dataset_columns, column_mapping_enum, preparation_functio missing_columns = [col for col in required_columns if col not in df.columns] if missing_columns: raise ValueError(f"Missing columns: {', '.join(missing_columns)}") - + for prep_func in preparation_functions: df = prep_func(df) for validate in validation_functions: df = validate(df) - + column_mapping = {col.name: col.value for col in column_mapping_enum} # Need to use the inverse (keys) for mapping the columns to what the database expects in order to use enums inverse_column_mapping = {v: k for k, v in column_mapping.items()} @@ -54,6 +64,7 @@ def transform_data(df, dataset_columns, column_mapping_enum, preparation_functio return df + @transaction.atomic def load_data(df, model, field_types, replace_data, user): row_count = 0 @@ -73,7 +84,7 @@ def load_data(df, model, field_types, replace_data, user): expected_type = field_types.get(column) is_nullable = column in nullable_fields - if pd.isna(value) or value == '': + if pd.isna(value) or value == "": if is_nullable: row_dict[column] = None else: @@ -83,37 +94,52 @@ def load_data(df, model, field_types, replace_data, user): row_dict[column] = float(value) elif isinstance(value, float): row_dict[column] = round(value, 2) - elif isinstance(value, str) and value.strip() != '': + elif isinstance(value, str) and value.strip() != "": try: float_value = float(value) row_dict[column] = round(float_value, 2) except ValueError: - errors.append(f"Row {index + 1}: Unable to convert value to float for '{column}'. Value was '{value}'.") + errors.append( + f"Row {index + 1}: Unable to convert value to float for '{column}'. Value was '{value}'." + ) valid_row = False continue - elif expected_type == int and ((isinstance(value, str) and value.strip() != '') or isinstance(value, float)): + elif expected_type == int and ( + (isinstance(value, str) and value.strip() != "") + or isinstance(value, float) + ): try: row_dict[column] = int(value) except ValueError: - errors.append(f"Row {index + 1}: Unable to convert value to int for '{column}'. Value was '{value}'.") + errors.append( + f"Row {index + 1}: Unable to convert value to int for '{column}'. Value was '{value}'." + ) valid_row = False continue - elif expected_type == Decimal and ((isinstance(value, int) or isinstance(value, float))): + elif expected_type == Decimal and ( + (isinstance(value, int) or isinstance(value, float)) + ): try: - decimal_value = Decimal(value).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) + decimal_value = Decimal(value).quantize( + Decimal("0.01"), rounding=ROUND_HALF_UP + ) row_dict[column] = decimal_value except ValueError: - errors.append(f"Row {index + 1}: Unable to convert value to int for '{column}'. Value was '{value}'.") + errors.append( + f"Row {index + 1}: Unable to convert value to int for '{column}'. Value was '{value}'." + ) valid_row = False continue - elif not isinstance(value, expected_type) and value != '': - errors.append(f"Row {index + 1}: Incorrect type for '{column}'. Expected {expected_type.__name__}, got {type(value).__name__}.") + elif not isinstance(value, expected_type) and value != "": + errors.append( + f"Row {index + 1}: Incorrect type for '{column}'. Expected {expected_type.__name__}, got {type(value).__name__}." + ) valid_row = False continue if valid_row: try: - row_dict['update_user'] = user + row_dict["update_user"] = user model_instance = model(**row_dict) model_instance.full_clean() model_instance.save() @@ -126,45 +152,58 @@ def load_data(df, model, field_types, replace_data, user): return { "row_count": row_count, "records_inserted": records_inserted, - "errors": errors + "errors": errors, } -def import_from_xls(excel_file, sheet_name, model, dataset_columns, header_row, column_mapping_enum, field_types, replace_data, user, preparation_functions=[], validation_functions=[]): +def import_from_xls( + excel_file, + sheet_name, + model, + dataset_columns, + header_row, + column_mapping_enum, + field_types, + replace_data, + user, + preparation_functions=[], + validation_functions=[], +): try: df = extract_data(excel_file, sheet_name, header_row) - df = transform_data(df, dataset_columns, column_mapping_enum, preparation_functions, validation_functions) + df = transform_data( + df, + dataset_columns, + column_mapping_enum, + preparation_functions, + validation_functions, + ) result = load_data(df, model, field_types, replace_data, user) - total_rows = result['row_count'] - inserted_rows = result['records_inserted'] + total_rows = result["row_count"] + inserted_rows = result["records_inserted"] - if result['errors'] and result['records_inserted'] > 0: + if result["errors"] and result["records_inserted"] > 0: return { "success": True, "message": f"{inserted_rows} out of {total_rows} rows successfully inserted with some errors encountered.", - "errors": result['errors'], - "rows_processed": result['row_count'] + "errors": result["errors"], + "rows_processed": result["row_count"], } - elif len(result['errors']) > 0: + elif len(result["errors"]) > 0: return { "success": False, "message": "Errors encountered with no successful insertions.", - "errors": result['errors'], - "rows_processed": result['row_count'] + "errors": result["errors"], + "rows_processed": result["row_count"], } else: return { "success": True, "message": f"All {inserted_rows} records successfully inserted out of {total_rows}.", - "rows_processed": result['row_count'] + "rows_processed": result["row_count"], } except Exception as error: traceback.print_exc() error_msg = f"Unexpected error: {str(error)}" - return { - "success": False, - "errors": [str(error)], - "rows_processed": 0 - } - + return {"success": False, "errors": [str(error)], "rows_processed": 0} diff --git a/django/api/services/spreadsheet_uploader_prep.py b/django/api/services/spreadsheet_uploader_prep.py index 5395fa9c..dfda4ed1 100644 --- a/django/api/services/spreadsheet_uploader_prep.py +++ b/django/api/services/spreadsheet_uploader_prep.py @@ -2,88 +2,105 @@ import numpy as np import pandas as pd + def prepare_arc_project_tracking(df): - df['Publicly Announced'] = df['Publicly Announced'].replace({'No': False, 'N': False, 'Yes': True, 'Y': True}) + df["Publicly Announced"] = df["Publicly Announced"].replace( + {"No": False, "N": False, "Yes": True, "Y": True} + ) return df + def prepare_hydrogen_fleets(df): df.applymap(lambda s: s.upper() if type(s) == str else s) - df.apply(lambda x: x.fillna(0) if x.dtype.kind in 'biufc' else x.fillna('')) + df.apply(lambda x: x.fillna(0) if x.dtype.kind in "biufc" else x.fillna("")) return df + def prepare_hydrogen_fueling(df): decimal_columns = ["Capital Funding Awarded", "O&M Funding Potential"] - for column in ['700 Bar', '350 Bar']: - df[column].replace(to_replace=['NO', 'N'], value=False, inplace=True) - df[column].replace(to_replace=['YES', 'Y'], value=True, inplace=True) + for column in ["700 Bar", "350 Bar"]: + df[column].replace(to_replace=["NO", "N"], value=False, inplace=True) + df[column].replace(to_replace=["YES", "Y"], value=True, inplace=True) for field in decimal_columns: try: - df[field] = df[field].apply(lambda x: round(Decimal(x), 2) if pd.notnull(x) else None) + df[field] = df[field].apply( + lambda x: round(Decimal(x), 2) if pd.notnull(x) else None + ) except: - print({f'{field} Should be a header row'}) + print({f"{field} Should be a header row"}) return df + def prepare_ldv_rebates(df): replacements = { - "CASL Consent": {'YES': True, 'Y': True, 'NO': False, 'N': False}, - "Delivered": {'YES': True, 'Y': True, 'NO': False, 'N': False, 'OEM': False, 'INCENTIVE_FUNDS_AVAILABLE': False}, - "Consent to Contact": {'YES': True, 'Y': True, 'NO': False, 'N': False} + "CASL Consent": {"YES": True, "Y": True, "NO": False, "N": False}, + "Delivered": { + "YES": True, + "Y": True, + "NO": False, + "N": False, + "OEM": False, + "INCENTIVE_FUNDS_AVAILABLE": False, + }, + "Consent to Contact": {"YES": True, "Y": True, "NO": False, "N": False}, } for column, replacement_dict in replacements.items(): df[column].replace(replacement_dict, inplace=True) - df.fillna('') + df.fillna("") return df + def prepare_public_charging(df): - + df = df.applymap(lambda s: s.upper() if type(s) == str else s) - - df = df.apply(lambda x: x.fillna(0) if x.dtype.kind in 'biufc' else x.fillna('')) - - df['Pilot Project (Y/N)'].replace(to_replace=['NO', 'N'], value=False, inplace=True) - df['Pilot Project (Y/N)'].replace(to_replace=['YES', 'Y'], value=True, inplace=True) + + df = df.apply(lambda x: x.fillna(0) if x.dtype.kind in "biufc" else x.fillna("")) + + df["Pilot Project (Y/N)"].replace(to_replace=["NO", "N"], value=False, inplace=True) + df["Pilot Project (Y/N)"].replace(to_replace=["YES", "Y"], value=True, inplace=True) return df + def prepare_scrap_it(df): df = df.applymap(lambda s: s.upper() if type(s) == str else s) - df = df.apply(lambda x: x.fillna(0) if x.dtype.kind in 'biufc' else x.fillna('')) + df = df.apply(lambda x: x.fillna(0) if x.dtype.kind in "biufc" else x.fillna("")) return df + def applicant_type(row): if isinstance((row["Fleet"]), str): - return 'Fleet' + return "Fleet" elif isinstance((row["Individual"]), str): - return 'Individual' + return "Individual" else: - return '' + return "" + def prepare_speciality_use_vehicle_incentives(df): df = df.applymap(lambda s: s.upper() if type(s) == str else s) - num_columns = df.select_dtypes(include=['number']).columns.tolist() + num_columns = df.select_dtypes(include=["number"]).columns.tolist() df[num_columns] = df[num_columns].fillna(0) non_num_columns = df.columns.difference(num_columns) - df[non_num_columns] = df[non_num_columns].fillna('') + df[non_num_columns] = df[non_num_columns].fillna("") - df['Applicant Type'] = df.apply(lambda row: applicant_type(row), axis=1) + df["Applicant Type"] = df.apply(lambda row: applicant_type(row), axis=1) - if 'Fleet' in df.columns: - df = df.drop(columns=['Fleet']) - - if 'Individual' in df.columns: - df = df.drop(columns=['Individual']) - - return df + if "Fleet" in df.columns: + df = df.drop(columns=["Fleet"]) + if "Individual" in df.columns: + df = df.drop(columns=["Individual"]) + return df diff --git a/django/api/services/user.py b/django/api/services/user.py index f1c62f37..66a4584b 100644 --- a/django/api/services/user.py +++ b/django/api/services/user.py @@ -21,5 +21,7 @@ def update_permissions(user_permissions): if value == True: permission_objects.append(permissions_map.get(description)) for permission_object in permission_objects: - user_permissions_to_add.append(UserPermission(user=user, permission=permission_object)) + user_permissions_to_add.append( + UserPermission(user=user, permission=permission_object) + ) UserPermission.objects.bulk_create(user_permissions_to_add) diff --git a/django/api/services/vin_decoder.py b/django/api/services/vin_decoder.py index b1fa8474..23e17c8b 100644 --- a/django/api/services/vin_decoder.py +++ b/django/api/services/vin_decoder.py @@ -12,41 +12,41 @@ def parse_vin(vin, item): - us_market_data = item.get('us_market_data') - common_data = us_market_data.get('common_us_data') + us_market_data = item.get("us_market_data") + common_data = us_market_data.get("common_us_data") if common_data is None: - supplemental_data = item.get('supplemental_data') - common_data = supplemental_data.get('common_supplemental_data') + supplemental_data = item.get("supplemental_data") + common_data = supplemental_data.get("common_supplemental_data") - basic_data = common_data.get('basic_data') - engines = common_data.get('engines') + basic_data = common_data.get("basic_data") + engines = common_data.get("engines") model_year = None - if basic_data.get('year'): - model_year = int(basic_data.get('year')) + if basic_data.get("year"): + model_year = int(basic_data.get("year")) - query_error = item.get('query_error') + query_error = item.get("query_error") - if query_error.get('error_code') == '' and len(engines) > 0: + if query_error.get("error_code") == "" and len(engines) > 0: return VINDecodedInformation.objects.create( - fuel_type_primary=engines[0].get('fuel_type'), - make=basic_data.get('make'), - manufacturer=basic_data.get('country_of_manufacture'), + fuel_type_primary=engines[0].get("fuel_type"), + make=basic_data.get("make"), + manufacturer=basic_data.get("country_of_manufacture"), model_year=model_year, - model=basic_data.get('model'), - vin=vin + model=basic_data.get("model"), + vin=vin, ) return None def decoder(): - url = 'https://api.dataonesoftware.com/webservices/vindecoder/decode' + url = "https://api.dataonesoftware.com/webservices/vindecoder/decode" json_response = None - vin_queryset = IcbcRegistrationData.objects.values_list( - 'vin', flat=True - ).order_by('vin') + vin_queryset = IcbcRegistrationData.objects.values_list("vin", flat=True).order_by( + "vin" + ) pages = Paginator(vin_queryset, 50) @@ -56,29 +56,22 @@ def decoder(): index = 0 for vin in page.object_list: index += 1 - query_requests.update({ - 'query_request_' + str(index): { - 'vin': vin - } - }) + query_requests.update({"query_request_" + str(index): {"vin": vin}}) decoder_query_object = { - 'decoder_settings': { - 'display': 'full', - 'version': '7.2.0', - 'common_data': 'on', - 'common_data_packs': { - 'basic_data': 'on', - 'engines': 'on' - } + "decoder_settings": { + "display": "full", + "version": "7.2.0", + "common_data": "on", + "common_data_packs": {"basic_data": "on", "engines": "on"}, }, - 'query_requests': query_requests + "query_requests": query_requests, } post_data = { - 'access_key_id': settings.DECODER_ACCESS_KEY, - 'secret_access_key': settings.DECODER_SECRET_KEY, - 'decoder_query': json.dumps(decoder_query_object) + "access_key_id": settings.DECODER_ACCESS_KEY, + "secret_access_key": settings.DECODER_SECRET_KEY, + "decoder_query": json.dumps(decoder_query_object), } try: response = requests.post(url, data=post_data) @@ -88,13 +81,13 @@ def decoder(): json_response = response.json() - results = json_response.get('query_responses') + results = json_response.get("query_responses") if results: for request in results: item = results.get(request) query_request = query_requests.get(request) - vin = query_request.get('vin') if query_request else None + vin = query_request.get("vin") if query_request else None parse_vin(vin, item) diff --git a/django/api/services/vin_decoder_old.py b/django/api/services/vin_decoder_old.py index 8e70114c..b201b904 100644 --- a/django/api/services/vin_decoder_old.py +++ b/django/api/services/vin_decoder_old.py @@ -10,20 +10,20 @@ def decoder(): - url = 'https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVINValuesBatch/' + url = "https://vpic.nhtsa.dot.gov/api/vehicles/DecodeVINValuesBatch/" json_response = None model_year = None - vin_queryset = IcbcRegistrationData.objects.values_list( - 'vin', flat=True - ).order_by('vin') + vin_queryset = IcbcRegistrationData.objects.values_list("vin", flat=True).order_by( + "vin" + ) pages = Paginator(vin_queryset, 50) for each in pages: page = pages.page(each.number) - vin_batch = ';'.join(page.object_list) - post_fields = {'format': 'json', 'data': vin_batch} + vin_batch = ";".join(page.object_list) + post_fields = {"format": "json", "data": vin_batch} try: response = requests.post(url, data=post_fields) if not response.status_code == 200: @@ -31,18 +31,18 @@ def decoder(): return json_response = response.json() - results = json_response['Results'] + results = json_response["Results"] if results: for item in results: - if item.get('ModelYear'): - model_year = int(item.get('ModelYear')) + if item.get("ModelYear"): + model_year = int(item.get("ModelYear")) VINDecodedInformation.objects.create( - fuel_type_primary=item.get('FuelTypePrimary'), - make=item.get('Make'), - manufacturer=item.get('Manufacturer'), + fuel_type_primary=item.get("FuelTypePrimary"), + make=item.get("Make"), + manufacturer=item.get("Manufacturer"), model_year=model_year, - model=item.get('Model'), - vin=item.get('VIN') + model=item.get("Model"), + vin=item.get("VIN"), ) except requests.exceptions.RequestException as error: LOGGER.error("Error: %s", error) diff --git a/django/api/settings.py b/django/api/settings.py index 31dfbe1e..1a6ddbb1 100644 --- a/django/api/settings.py +++ b/django/api/settings.py @@ -9,6 +9,7 @@ For the full list of settings and their values, see https://docs.djangoproject.com/en/3.1/ref/settings/ """ + import os import sys @@ -22,111 +23,117 @@ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.getenv( - 'DJANGO_SECRET_KEY', - '#8+m(ba_(ra1=lo+-7jyp#x49l27guk*i4)w@xp7j9b9umkwh^' + "DJANGO_SECRET_KEY", "#8+m(ba_(ra1=lo+-7jyp#x49l27guk*i4)w@xp7j9b9umkwh^" ) # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -TESTING = 'test' in sys.argv +TESTING = "test" in sys.argv -ALLOWED_HOSTS = [os.getenv('ALLOWED_HOSTS', '*')] +ALLOWED_HOSTS = [os.getenv("ALLOWED_HOSTS", "*")] -CORS_ORIGIN_ALLOW_ALL = os.getenv('CORS_ORIGIN_ALLOW_ALL', 'False') == 'True' -CORS_ORIGIN_WHITELIST = [ - os.getenv('CORS_ORIGIN_WHITELIST', 'https://localhost:3000') -] +CORS_ORIGIN_ALLOW_ALL = os.getenv("CORS_ORIGIN_ALLOW_ALL", "False") == "True" +CORS_ORIGIN_WHITELIST = [os.getenv("CORS_ORIGIN_WHITELIST", "https://localhost:3000")] # Application definition INSTALLED_APPS = [ - 'api.apps.ApiConfig', - 'tfrs.apps.ApiConfig', - 'metabase.apps.MetabaseConfig', - 'corsheaders', - 'django_filters', - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.messages', - 'django.contrib.sessions', - 'django.contrib.staticfiles', - 'rest_framework', + "api.apps.ApiConfig", + "tfrs.apps.ApiConfig", + "metabase.apps.MetabaseConfig", + "corsheaders", + "django_filters", + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.messages", + "django.contrib.sessions", + "django.contrib.staticfiles", + "rest_framework", ] MIDDLEWARE = [ - 'corsheaders.middleware.CorsMiddleware', - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'whitenoise.middleware.WhiteNoiseMiddleware', + "corsheaders.middleware.CorsMiddleware", + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", + "whitenoise.middleware.WhiteNoiseMiddleware", ] -ROOT_URLCONF = 'api.urls' - -TEMPLATES = [{ - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [os.path.join(BASE_DIR, "../", "frontend", "public")], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', - ], - }, -}] +ROOT_URLCONF = "api.urls" + +TEMPLATES = [ + { + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [os.path.join(BASE_DIR, "../", "frontend", "public")], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", + ], + }, + } +] -WSGI_APPLICATION = 'api.wsgi.application' +WSGI_APPLICATION = "api.wsgi.application" # Database # https://docs.djangoproject.com/en/3.1/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': os.getenv('DB_ENGINE', 'django.db.backends.postgresql'), - 'NAME': os.getenv('DB_NAME', 'postgres'), - 'USER': os.getenv('DB_USER', 'postgres'), - 'PASSWORD': os.getenv('DB_PASSWORD', 'postgres'), - 'HOST': os.getenv('DB_HOST', 'db'), - 'PORT': os.getenv('DB_PORT', '5432'), + "default": { + "ENGINE": os.getenv("DB_ENGINE", "django.db.backends.postgresql"), + "NAME": os.getenv("DB_NAME", "postgres"), + "USER": os.getenv("DB_USER", "postgres"), + "PASSWORD": os.getenv("DB_PASSWORD", "postgres"), + "HOST": os.getenv("DB_HOST", "db"), + "PORT": os.getenv("DB_PORT", "5432"), }, - 'metabase': { - 'ENGINE': os.getenv('METABASE_DB_ENGINE', 'django.db.backends.postgresql'), - 'NAME': os.getenv('METABASE_DB_NAME', 'metabase'), - 'USER': os.getenv('METABASE_DB_USER', 'postgres'), - 'PASSWORD': os.getenv('METABASE_DB_PASSWORD', 'postgres'), - 'HOST': os.getenv('METABASE_DB_HOST', 'db'), - 'PORT': os.getenv('METABASE_DB_PORT', '5432'), + "metabase": { + "ENGINE": os.getenv("METABASE_DB_ENGINE", "django.db.backends.postgresql"), + "NAME": os.getenv("METABASE_DB_NAME", "metabase"), + "USER": os.getenv("METABASE_DB_USER", "postgres"), + "PASSWORD": os.getenv("METABASE_DB_PASSWORD", "postgres"), + "HOST": os.getenv("METABASE_DB_HOST", "db"), + "PORT": os.getenv("METABASE_DB_PORT", "5432"), }, } -DATABASE_ROUTERS = ['metabase.db_router.MetabaseRouter',] +DATABASE_ROUTERS = [ + "metabase.db_router.MetabaseRouter", +] # Password validation # https://docs.djangoproject.com/en/3.1/ref/settings/#auth-password-validators -AUTH_PASSWORD_VALIDATORS = [{ - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', -}, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', -}, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', -}, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', -}] +AUTH_PASSWORD_VALIDATORS = [ + { + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", + }, + { + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", + }, +] # Internationalization # https://docs.djangoproject.com/en/3.1/topics/i18n/ -LANGUAGE_CODE = 'en-us' -TIME_ZONE = 'UTC' +LANGUAGE_CODE = "en-us" +TIME_ZONE = "UTC" USE_I18N = True USE_L10N = True USE_TZ = True @@ -135,43 +142,40 @@ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.1/howto/static-files/ STATICFILES_DIRS = [os.path.join(BASE_DIR, "../", "frontend", "public")] -STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' -STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') +STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" +STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles") -STATIC_URL = '/static/' +STATIC_URL = "/static/" WHITENOISE_ROOT = os.path.join(BASE_DIR, "../", "frontend", "public", "root") # Django Rest Framework Settings REST_FRAMEWORK = { - 'DEFAULT_AUTHENTICATION_CLASSES': [ - 'api.keycloak_authentication.KeycloakAuthentication', + "DEFAULT_AUTHENTICATION_CLASSES": [ + "api.keycloak_authentication.KeycloakAuthentication", ], - 'DEFAULT_PERMISSION_CLASSES': ( - 'rest_framework.permissions.IsAuthenticated',), - 'COERCE_DECIMAL_TO_STRING': False, - 'DEFAULT_PAGINATION_CLASS': 'api.pagination.StandardResultsSetPagination', - 'DEFAULT_FILTER_BACKENDS': [ - 'django_filters.rest_framework.DjangoFilterBackend', - 'api.filters.order_by.RelatedOrderingFilter', + "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",), + "COERCE_DECIMAL_TO_STRING": False, + "DEFAULT_PAGINATION_CLASS": "api.pagination.StandardResultsSetPagination", + "DEFAULT_FILTER_BACKENDS": [ + "django_filters.rest_framework.DjangoFilterBackend", + "api.filters.order_by.RelatedOrderingFilter", ], } -KEYCLOAK_CLIENT_ID = os.getenv('KEYCLOAK_CLIENT_ID') -KEYCLOAK_REALM = os.getenv('KEYCLOAK_REALM') -KEYCLOAK_URL = os.getenv('KEYCLOAK_URL', 'http://localhost:8080') +KEYCLOAK_CLIENT_ID = os.getenv("KEYCLOAK_CLIENT_ID") +KEYCLOAK_REALM = os.getenv("KEYCLOAK_REALM") +KEYCLOAK_URL = os.getenv("KEYCLOAK_URL", "http://localhost:8080") -MINIO_ACCESS_KEY = os.getenv('MINIO_ROOT_USER') -MINIO_SECRET_KEY = os.getenv('MINIO_ROOT_PASSWORD') -MINIO_BUCKET_NAME = os.getenv('MINIO_BUCKET_NAME', 'cthub') -MINIO_ENDPOINT = os.getenv('MINIO_ENDPOINT', None) -MINIO_USE_SSL = bool( - os.getenv('MINIO_USE_SSL', 'False').lower() in ['true', 1] -) -MINIO_PREFIX = os.getenv('MINIO_PREFIX') +MINIO_ACCESS_KEY = os.getenv("MINIO_ROOT_USER") +MINIO_SECRET_KEY = os.getenv("MINIO_ROOT_PASSWORD") +MINIO_BUCKET_NAME = os.getenv("MINIO_BUCKET_NAME", "cthub") +MINIO_ENDPOINT = os.getenv("MINIO_ENDPOINT", None) +MINIO_USE_SSL = bool(os.getenv("MINIO_USE_SSL", "False").lower() in ["true", 1]) +MINIO_PREFIX = os.getenv("MINIO_PREFIX") -DECODER_ACCESS_KEY = os.getenv('DECODER_ACCESS_KEY') -DECODER_SECRET_KEY = os.getenv('DECODER_SECRET_KEY') +DECODER_ACCESS_KEY = os.getenv("DECODER_ACCESS_KEY") +DECODER_SECRET_KEY = os.getenv("DECODER_SECRET_KEY") diff --git a/django/api/tests/base_test.py b/django/api/tests/base_test.py index 75c2678a..926e3ef2 100644 --- a/django/api/tests/base_test.py +++ b/django/api/tests/base_test.py @@ -1,6 +1,7 @@ """ Default instructions for the test cases """ + from django.test import TestCase @@ -8,5 +9,5 @@ class BaseTestCase(TestCase): """ Load the following fixtures for each test case """ - fixtures = [ - ] + + fixtures = [] diff --git a/django/api/urls.py b/django/api/urls.py index 1d2c48db..89abbbf9 100644 --- a/django/api/urls.py +++ b/django/api/urls.py @@ -13,6 +13,7 @@ 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ + from django.contrib import admin from django.urls import path, include from rest_framework import routers @@ -24,22 +25,14 @@ ROUTER = routers.SimpleRouter(trailing_slash=False) -ROUTER.register( - r'icbc-data', IcbcViewset, basename='icbc-data' -) +ROUTER.register(r"icbc-data", IcbcViewset, basename="icbc-data") -ROUTER.register( - r'uploads', UploadViewset, basename='uploads' -) +ROUTER.register(r"uploads", UploadViewset, basename="uploads") -ROUTER.register( - r'minio', MinioViewSet, basename='minio' -) -ROUTER.register( - r'users', UserViewSet -) +ROUTER.register(r"minio", MinioViewSet, basename="minio") +ROUTER.register(r"users", UserViewSet) urlpatterns = [ - path('admin/', admin.site.urls), - path('api/', include(ROUTER.urls)), + path("admin/", admin.site.urls), + path("api/", include(ROUTER.urls)), ] diff --git a/django/api/viewsets/icbc_data.py b/django/api/viewsets/icbc_data.py index e5000eb4..e6f10153 100644 --- a/django/api/viewsets/icbc_data.py +++ b/django/api/viewsets/icbc_data.py @@ -1,14 +1,14 @@ """ Viewset for ICBC Data """ + from rest_framework.mixins import ListModelMixin from rest_framework.permissions import AllowAny from rest_framework.viewsets import GenericViewSet from api.filters.icbc_data import IcbcDataFilter from api.models.icbc_registration_data import IcbcRegistrationData -from api.serializers.icbc_registration_data import \ - IcbcRegistrationDataSerializer +from api.serializers.icbc_registration_data import IcbcRegistrationDataSerializer class IcbcViewset(GenericViewSet, ListModelMixin): @@ -16,15 +16,14 @@ class IcbcViewset(GenericViewSet, ListModelMixin): This will build the list view and tie it with the serializer and permissions """ + permission_classes = (AllowAny,) - http_method_names = ['get'] + http_method_names = ["get"] filterset_class = IcbcDataFilter - ordering_fields = '__all_related__' - ordering = ('icbc_vehicle__make',) + ordering_fields = "__all_related__" + ordering = ("icbc_vehicle__make",) - serializer_classes = { - 'default': IcbcRegistrationDataSerializer - } + serializer_classes = {"default": IcbcRegistrationDataSerializer} def get_queryset(self): queryset = IcbcRegistrationData.objects.all() @@ -35,4 +34,4 @@ def get_serializer_class(self): if self.action in list(self.serializer_classes.keys()): return self.serializer_classes.get(self.action) - return self.serializer_classes.get('default') + return self.serializer_classes.get("default") diff --git a/django/api/viewsets/minio.py b/django/api/viewsets/minio.py index 833f7b5c..dfa4ee53 100644 --- a/django/api/viewsets/minio.py +++ b/django/api/viewsets/minio.py @@ -8,17 +8,15 @@ from api.decorators.permission import check_upload_permission from api.services.minio import minio_put_object + class MinioViewSet(GenericViewSet): permission_classes = (AllowAny,) - http_method_names = ['get'] + http_method_names = ["get"] - @action(detail=False, methods=['get']) + @action(detail=False, methods=["get"]) @method_decorator(check_upload_permission()) def put(self, request): object_name = uuid.uuid4().hex url = minio_put_object(object_name) - return Response({ - 'url': url, - 'minio_object_name': object_name - }) + return Response({"url": url, "minio_object_name": object_name}) diff --git a/django/api/viewsets/upload.py b/django/api/viewsets/upload.py index 5a70faa8..03c29e20 100644 --- a/django/api/viewsets/upload.py +++ b/django/api/viewsets/upload.py @@ -17,26 +17,37 @@ import api.constants as constants from api.services.spreadsheet_uploader_prep import * + class UploadViewset(GenericViewSet): permission_classes = (AllowAny,) - http_method_names = ['post', 'put', 'get'] + http_method_names = ["post", "put", "get"] - @action(detail=False, methods=['get']) + @action(detail=False, methods=["get"]) def datasets_list(self, request): - - incomplete_datasets = ['LDV Rebates', 'Specialty Use Vehicle Incentive Program', 'Public Charging', 'EV Charging Rebates', 'Hydrogen Fueling', 'Hydrogen Fleets', 'ARC Project Tracking', 'Data Fleets', 'Scrap It'] + + incomplete_datasets = [ + "LDV Rebates", + "Specialty Use Vehicle Incentive Program", + "Public Charging", + "EV Charging Rebates", + "Hydrogen Fueling", + "Hydrogen Fleets", + "ARC Project Tracking", + "Data Fleets", + "Scrap It", + ] datasets = Datasets.objects.all().exclude(name__in=incomplete_datasets) serializer = DatasetsSerializer(datasets, many=True, read_only=True) return Response(serializer.data) - @action(detail=False, methods=['post']) + @action(detail=False, methods=["post"]) @method_decorator(check_upload_permission()) def import_data(self, request): - filename = request.data.get('filename') - dataset_selected = request.data.get('datasetSelected') - replace_data = request.data.get('replace', False) + filename = request.data.get("filename") + dataset_selected = request.data.get("datasetSelected") + replace_data = request.data.get("replace", False) try: url = minio_get_object(filename) @@ -44,55 +55,62 @@ def import_data(self, request): config = constants.DATASET_CONFIG.get(dataset_selected) if not config: - return Response(f"Dataset '{dataset_selected}' is not supported.", status=status.HTTP_400_BAD_REQUEST) - model = config['model'] - columns = config.get('columns') - mapping = config.get('column_mapping') - sheet_name = config.get('sheet_name', 'Sheet1') # Default to 'Sheet1' if not specified - preparation_functions = config.get('preparation_functions', []) - validation_functions = config.get('validation_functions', []) - header_row = config.get('header_row', 0) - + return Response( + f"Dataset '{dataset_selected}' is not supported.", + status=status.HTTP_400_BAD_REQUEST, + ) + model = config["model"] + columns = config.get("columns") + mapping = config.get("column_mapping") + sheet_name = config.get( + "sheet_name", "Sheet1" + ) # Default to 'Sheet1' if not specified + preparation_functions = config.get("preparation_functions", []) + validation_functions = config.get("validation_functions", []) + header_row = config.get("header_row", 0) result = import_from_xls( excel_file=filename, sheet_name=sheet_name, model=model, - header_row = header_row, + header_row=header_row, preparation_functions=preparation_functions, validation_functions=validation_functions, dataset_columns=columns, column_mapping_enum=mapping, field_types=constants.FIELD_TYPES.get(dataset_selected), replace_data=replace_data, - user = request.user + user=request.user, ) - if not result['success']: + if not result["success"]: return Response(result, status=status.HTTP_400_BAD_REQUEST) return Response(result, status=status.HTTP_201_CREATED) except Exception as e: - return Response(f"An error occurred: {str(e)}", status=status.HTTP_400_BAD_REQUEST) - - finally: + return Response( + f"An error occurred: {str(e)}", status=status.HTTP_400_BAD_REQUEST + ) + + finally: os.remove(filename) minio_remove_object(filename) - - - @action(detail=False, methods=['get']) + + @action(detail=False, methods=["get"]) def download_dataset(self, request): - dataset_name = request.GET.get('datasetSelected') + dataset_name = request.GET.get("datasetSelected") if not dataset_name: return HttpResponse("Dataset name is required.", status=400) - + try: excel_file = generate_template(dataset_name) response = HttpResponse( excel_file.read(), - content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ) + response["Content-Disposition"] = ( + f'attachment; filename="{dataset_name}.xlsx"' ) - response['Content-Disposition'] = f'attachment; filename="{dataset_name}.xlsx"' return response except ValueError as e: - return HttpResponse(str(e), status=400) \ No newline at end of file + return HttpResponse(str(e), status=400) diff --git a/django/api/viewsets/user.py b/django/api/viewsets/user.py index 326ff90e..f4e23aef 100644 --- a/django/api/viewsets/user.py +++ b/django/api/viewsets/user.py @@ -11,39 +11,40 @@ from api.services.user import update_permissions from api.services.permissions import get_permissions_map + class UserViewSet(GenericViewSet, CreateModelMixin, DestroyModelMixin): """ This viewset automatically provides `list`, `create`, `retrieve`, and `update` actions. """ + permission_classes = (AllowAny,) - http_method_names = ['get', 'post', 'put', 'patch', 'delete'] + http_method_names = ["get", "post", "put", "patch", "delete"] queryset = User.objects.all() - lookup_field = 'idir' + lookup_field = "idir" serializer_classes = { - 'default': UserSerializer, + "default": UserSerializer, } - def get_serializer_class(self): if self.action in list(self.serializer_classes.keys()): return self.serializer_classes[self.action] - return self.serializer_classes['default'] - + return self.serializer_classes["default"] @method_decorator(check_admin_permission()) def destroy(self, request, idir=None): if request.user == idir: - return Response('you cannot delete your own idir', status=status.HTTP_400_BAD_REQUEST ) + return Response( + "you cannot delete your own idir", status=status.HTTP_400_BAD_REQUEST + ) return super().destroy(self, request) - @method_decorator(check_admin_permission()) def create(self, request): return super().create(request) - @action(detail=False, methods=['put']) + @action(detail=False, methods=["put"]) @method_decorator(check_admin_permission()) def update_permissions(self, request): user_permissions = request.data @@ -51,8 +52,8 @@ def update_permissions(self, request): update_permissions(user_permissions) except Exception as e: return Response(str(e), status=status.HTTP_400_BAD_REQUEST) - return Response('User permissions were updated!', status=status.HTTP_200_OK) - + return Response("User permissions were updated!", status=status.HTTP_200_OK) + @action(detail=False) def current(self, request): """ @@ -61,9 +62,11 @@ def current(self, request): user = User.objects.filter(idir=request.user).first() serializer = self.get_serializer(user) return Response(serializer.data) - + @method_decorator(check_admin_permission()) def list(self, request): - users = User.objects.all().order_by('idir') - serializer = UserListSerializer(users, many=True, context={"permissions_map": get_permissions_map(users)}) - return Response(serializer.data) \ No newline at end of file + users = User.objects.all().order_by("idir") + serializer = UserListSerializer( + users, many=True, context={"permissions_map": get_permissions_map(users)} + ) + return Response(serializer.data) diff --git a/django/api/wsgi.py b/django/api/wsgi.py index 0d8bcb9d..2613f828 100644 --- a/django/api/wsgi.py +++ b/django/api/wsgi.py @@ -11,6 +11,6 @@ from django.core.wsgi import get_wsgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'api.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "api.settings") application = get_wsgi_application() diff --git a/django/requirements.txt b/django/requirements.txt index b66bee95..f17c6e41 100644 --- a/django/requirements.txt +++ b/django/requirements.txt @@ -1,3 +1,4 @@ +black==24.3.0 Django==3.1.6 psycopg2-binary==2.8.6 djangorestframework==3.12.2 diff --git a/frontend/package.json b/frontend/package.json index c444fd99..d528a73f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -32,6 +32,7 @@ }, "devDependencies": { "css-loader": "^5.2.7", + "prettier": "3.2.5", "sass": "^1.43.4", "sass-loader": "^11.1.1", "source-map-loader": "^2.0.2", diff --git a/frontend/src/app/components/AlertDialog.js b/frontend/src/app/components/AlertDialog.js index c0b052c4..fe9977b0 100644 --- a/frontend/src/app/components/AlertDialog.js +++ b/frontend/src/app/components/AlertDialog.js @@ -1,11 +1,11 @@ -import PropTypes from 'prop-types'; -import * as React from 'react'; -import Button from '@mui/material/Button'; -import Dialog from '@mui/material/Dialog'; -import DialogActions from '@mui/material/DialogActions'; -import DialogContent from '@mui/material/DialogContent'; -import DialogContentText from '@mui/material/DialogContentText'; -import DialogTitle from '@mui/material/DialogTitle'; +import PropTypes from "prop-types"; +import * as React from "react"; +import Button from "@mui/material/Button"; +import Dialog from "@mui/material/Dialog"; +import DialogActions from "@mui/material/DialogActions"; +import DialogContent from "@mui/material/DialogContent"; +import DialogContentText from "@mui/material/DialogContentText"; +import DialogTitle from "@mui/material/DialogTitle"; const AlertDialog = (props) => { const { @@ -15,37 +15,35 @@ const AlertDialog = (props) => { cancelText, handleCancel, confirmText, - handleConfirm + handleConfirm, } = props; if (!open) { - return null + return null; } return (
{ - handleCancel() + handleCancel(); }} aria-labelledby="alert-dialog-title" aria-describedby="alert-dialog-description" > - - {title} - + {title} {dialogue} -
); -} +}; AlertDialog.defaultProps = { - dialogue: '', - title: '', + dialogue: "", + title: "", }; AlertDialog.propTypes = { open: PropTypes.bool.isRequired, @@ -72,7 +70,7 @@ AlertDialog.propTypes = { cancelText: PropTypes.string.isRequired, handleCancel: PropTypes.func.isRequired, confirmText: PropTypes.string.isRequired, - handleConfirm: PropTypes.func.isRequired + handleConfirm: PropTypes.func.isRequired, }; -export default AlertDialog +export default AlertDialog; diff --git a/frontend/src/app/components/App.js b/frontend/src/app/components/App.js index 3153bd5d..9c42460a 100644 --- a/frontend/src/app/components/App.js +++ b/frontend/src/app/components/App.js @@ -1,24 +1,20 @@ -import React from 'react'; -import { - BrowserRouter as Router, - Route, - Switch, -} from 'react-router-dom'; +import React from "react"; +import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; -import IcbcDataRouter from '../../icbc_data/router'; -import UploadRouter from '../../uploads/router'; -import DashboardContainer from '../../dashboard/DashboardContainer'; -import useKeycloak from '../utilities/useKeycloak' -import Login from './Login' -import Layout from './Layout' -import { ENABLE_KEYCLOAK } from '../../config'; +import IcbcDataRouter from "../../icbc_data/router"; +import UploadRouter from "../../uploads/router"; +import DashboardContainer from "../../dashboard/DashboardContainer"; +import useKeycloak from "../utilities/useKeycloak"; +import Login from "./Login"; +import Layout from "./Layout"; +import { ENABLE_KEYCLOAK } from "../../config"; const App = () => { - const keycloak = useKeycloak() - + const keycloak = useKeycloak(); + if (ENABLE_KEYCLOAK && !keycloak.authenticated) { - const redirectUri = window.location.href - return + const redirectUri = window.location.href; + return ; } return ( diff --git a/frontend/src/app/components/Footer.js b/frontend/src/app/components/Footer.js index 677de896..cc6b28b1 100644 --- a/frontend/src/app/components/Footer.js +++ b/frontend/src/app/components/Footer.js @@ -1,42 +1,42 @@ -import React from 'react' +import React from "react"; const Footer = () => { - return ( - - ); - }; - - export default Footer; \ No newline at end of file + return ( + + ); +}; + +export default Footer; diff --git a/frontend/src/app/components/Header.js b/frontend/src/app/components/Header.js index d4fb7cbd..c18cdbd7 100644 --- a/frontend/src/app/components/Header.js +++ b/frontend/src/app/components/Header.js @@ -1,25 +1,25 @@ -import React from 'react'; -import logo from '../styles/images/BCID_H_rgb_rev.png'; -import Logout from './Logout' +import React from "react"; +import logo from "../styles/images/BCID_H_rgb_rev.png"; +import Logout from "./Logout"; const Header = () => { - return ( -
-
- -
- -
+ return ( + + ); +}; -export default Header; \ No newline at end of file +export default Header; diff --git a/frontend/src/app/components/KeycloakProvider.js b/frontend/src/app/components/KeycloakProvider.js index 269213e6..e0e5bd22 100644 --- a/frontend/src/app/components/KeycloakProvider.js +++ b/frontend/src/app/components/KeycloakProvider.js @@ -1,28 +1,33 @@ -import React, { useState, useEffect } from 'react' -import { KeycloakContext } from '../../contexts' -import { ENABLE_KEYCLOAK } from '../../config' +import React, { useState, useEffect } from "react"; +import { KeycloakContext } from "../../contexts"; +import { ENABLE_KEYCLOAK } from "../../config"; -const KeycloakProvider = ({authClient, initOptions, LoadingComponent, children}) => { - const [loading, setLoading] = useState(ENABLE_KEYCLOAK ? true : false) - const [keycloak, setKeycloak] = useState({}) +const KeycloakProvider = ({ + authClient, + initOptions, + LoadingComponent, + children, +}) => { + const [loading, setLoading] = useState(ENABLE_KEYCLOAK ? true : false); + const [keycloak, setKeycloak] = useState({}); useEffect(() => { if (ENABLE_KEYCLOAK) { authClient.init(initOptions).then(() => { - setKeycloak(authClient) - setLoading(false) - }) + setKeycloak(authClient); + setLoading(false); + }); } - }, [authClient, initOptions]) + }, [authClient, initOptions]); if (loading) { - return + return ; } return ( {children} - ) -} + ); +}; -export default KeycloakProvider \ No newline at end of file +export default KeycloakProvider; diff --git a/frontend/src/app/components/Layout.js b/frontend/src/app/components/Layout.js index b8c1aad8..4898eb4e 100644 --- a/frontend/src/app/components/Layout.js +++ b/frontend/src/app/components/Layout.js @@ -1,15 +1,15 @@ -import React from 'react' -import Header from './Header' -import Footer from './Footer' +import React from "react"; +import Header from "./Header"; +import Footer from "./Footer"; const Layout = ({ children }) => { return (
-
{children}
+
{children}
- ) -} + ); +}; -export default Layout \ No newline at end of file +export default Layout; diff --git a/frontend/src/app/components/Loading.js b/frontend/src/app/components/Loading.js index a6d7fe57..d59e9005 100644 --- a/frontend/src/app/components/Loading.js +++ b/frontend/src/app/components/Loading.js @@ -1,10 +1,8 @@ -import React from 'react'; -import { CircularProgress } from '@mui/material'; +import React from "react"; +import { CircularProgress } from "@mui/material"; -const Loading = ({ color = 'inherit' }) => { - return ( - - ); +const Loading = ({ color = "inherit" }) => { + return ; }; export default Loading; diff --git a/frontend/src/app/components/Login.js b/frontend/src/app/components/Login.js index 3e7f6f3f..f268add5 100644 --- a/frontend/src/app/components/Login.js +++ b/frontend/src/app/components/Login.js @@ -1,16 +1,16 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import useKeycloak from '../../app/utilities/useKeycloak'; +import React from "react"; +import PropTypes from "prop-types"; +import useKeycloak from "../../app/utilities/useKeycloak"; const Login = (props) => { const { redirectUri } = props; const loginOptions = { - idpHint: 'idir' - } + idpHint: "idir", + }; if (redirectUri) { - loginOptions.redirectUri = redirectUri + loginOptions.redirectUri = redirectUri; } - const keycloak = useKeycloak() + const keycloak = useKeycloak(); return (
@@ -21,7 +21,12 @@ const Login = (props) => {
- @@ -33,7 +38,7 @@ const Login = (props) => { }; Login.propTypes = { - redirectUri: PropTypes.string + redirectUri: PropTypes.string, }; export default Login; diff --git a/frontend/src/app/components/Logout.js b/frontend/src/app/components/Logout.js index 31a4031f..1cd54a80 100644 --- a/frontend/src/app/components/Logout.js +++ b/frontend/src/app/components/Logout.js @@ -1,25 +1,25 @@ -import React from 'react'; -import useKeycloak from '../utilities/useKeycloak' +import React from "react"; +import useKeycloak from "../utilities/useKeycloak"; const Logout = () => { const keycloak = useKeycloak(); if (keycloak.authenticated) { const kcToken = keycloak.tokenParsed; return ( -
- {'Logged in as: ' + kcToken.idir_username + ' |'} +
+ {"Logged in as: " + kcToken.idir_username + " |"}
- ) + ); } - return null -} + return null; +}; -export default Logout +export default Logout; diff --git a/frontend/src/app/components/ReactTable.js b/frontend/src/app/components/ReactTable.js index 4b01c049..dec5cf63 100644 --- a/frontend/src/app/components/ReactTable.js +++ b/frontend/src/app/components/ReactTable.js @@ -1,84 +1,84 @@ -import PropTypes from 'prop-types'; -import React, { useEffect, useState } from 'react'; +import PropTypes from "prop-types"; +import React, { useEffect, useState } from "react"; import { useAsyncDebounce, useFilters, usePagination, useSortBy, useTable, -} from 'react-table'; +} from "react-table"; // material-ui core components -import CircularProgress from '@mui/material/CircularProgress'; -import IconButton from '@mui/material/IconButton'; -import InputAdornment from '@mui/material/InputAdornment'; -import Popover from '@mui/material/Popover'; -import Table from '@mui/material/Table'; -import TableBody from '@mui/material/TableBody'; -import TableCell from '@mui/material/TableCell'; -import TableContainer from '@mui/material/TableContainer'; -import TableHead from '@mui/material/TableHead'; -import TablePagination from '@mui/material/TablePagination'; -import TableRow from '@mui/material/TableRow'; -import TableSortLabel from '@mui/material/TableSortLabel'; -import TextField from '@mui/material/TextField'; -import Tooltip from '@mui/material/Tooltip'; -import { makeStyles } from '@mui/styles'; +import CircularProgress from "@mui/material/CircularProgress"; +import IconButton from "@mui/material/IconButton"; +import InputAdornment from "@mui/material/InputAdornment"; +import Popover from "@mui/material/Popover"; +import Table from "@mui/material/Table"; +import TableBody from "@mui/material/TableBody"; +import TableCell from "@mui/material/TableCell"; +import TableContainer from "@mui/material/TableContainer"; +import TableHead from "@mui/material/TableHead"; +import TablePagination from "@mui/material/TablePagination"; +import TableRow from "@mui/material/TableRow"; +import TableSortLabel from "@mui/material/TableSortLabel"; +import TextField from "@mui/material/TextField"; +import Tooltip from "@mui/material/Tooltip"; +import { makeStyles } from "@mui/styles"; // material-ui icons -import FilterListIcon from '@mui/icons-material/FilterList'; -import MoreVert from '@mui/icons-material/MoreVert'; +import FilterListIcon from "@mui/icons-material/FilterList"; +import MoreVert from "@mui/icons-material/MoreVert"; // components -import ReactTablePagination from './ReactTablePagination'; +import ReactTablePagination from "./ReactTablePagination"; const useStyles = makeStyles(() => ({ moreOptions: { - alignItems: 'center', - display: 'inline-flex', - height: '100%', - position: 'absolute', + alignItems: "center", + display: "inline-flex", + height: "100%", + position: "absolute", right: 0, top: 0, - zIndex: '999', - '&.active': { - opacity: '1 !important', + zIndex: "999", + "&.active": { + opacity: "1 !important", }, }, cellMoreOptions: { - '& $moreOptions': { + "& $moreOptions": { opacity: 0, }, - '&:hover $moreOptions': { + "&:hover $moreOptions": { opacity: 0.5, }, }, popoverContainer: { - padding: '0.75rem', + padding: "0.75rem", }, popoverInputFilter: { - '& input': { - padding: '0.75rem', + "& input": { + padding: "0.75rem", }, }, reactTable: { - position: 'relative', - '& caption': { - backgroundColor: 'rgba(255, 255, 255, 0.7)', + position: "relative", + "& caption": { + backgroundColor: "rgba(255, 255, 255, 0.7)", bottom: 0, left: 0, padding: 0, - position: 'absolute', + position: "absolute", right: 0, top: 0, zIndex: 999, }, - '& caption > div': { - alignItems: 'center', - display: 'flex', - height: '100%', - justifyContent: 'center', - width: '100%', + "& caption > div": { + alignItems: "center", + display: "flex", + height: "100%", + justifyContent: "center", + width: "100%", }, }, })); @@ -111,26 +111,27 @@ const ReactTable = (props) => { page, prepareRow, setPageSize, - state: { - pageIndex, - pageSize, - sortBy, - }, - } = useTable({ - columns, - data, - disableSortBy: !sortable, - disableSortRemove: true, - initialState: { - filters: [], - pageIndex: 0, - sortBy: defaultSortBy, + state: { pageIndex, pageSize, sortBy }, + } = useTable( + { + columns, + data, + disableSortBy: !sortable, + disableSortRemove: true, + initialState: { + filters: [], + pageIndex: 0, + sortBy: defaultSortBy, + }, + manualFilters: true, + manualPagination: true, + manualSortBy: true, + pageCount: controlledPageCount, }, - manualFilters: true, - manualPagination: true, - manualSortBy: true, - pageCount: controlledPageCount, - }, useFilters, useSortBy, usePagination); + useFilters, + useSortBy, + usePagination, + ); const handleFilterColumn = useAsyncDebounce((event) => { const { value } = event.target; @@ -140,7 +141,7 @@ const ReactTable = (props) => { filterBy = filterColumn.id; } - const foundIndex = filters.findIndex((filter) => (filter.id === filterBy)); + const foundIndex = filters.findIndex((filter) => filter.id === filterBy); if (foundIndex >= 0) { filters[foundIndex].value = value; @@ -156,20 +157,24 @@ const ReactTable = (props) => { const handleOpenMoreOptions = (event) => { event.stopPropagation(); - event.currentTarget.parentNode.classList.add('active'); + event.currentTarget.parentNode.classList.add("active"); setAnchorEl(event.currentTarget); }; const handleClose = () => { - anchorEl.parentNode.classList.remove('active'); + anchorEl.parentNode.classList.remove("active"); setAnchorEl(null); }; useEffect(() => { onFetchData({ - columns, pageIndex, pageSize, sortBy, filters, + columns, + pageIndex, + pageSize, + sortBy, + filters, }); }, [onFetchData, pageIndex, pageSize, sortBy, filters]); @@ -178,7 +183,12 @@ const ReactTable = (props) => { return ( <> - +
{loading && (
@@ -192,15 +202,17 @@ const ReactTable = (props) => { {headerGroup.headers.map((column) => ( - {column.render('Header')} + {column.render("Header")} {filterable && column.filterable !== false && ( @@ -226,23 +238,24 @@ const ReactTable = (props) => { - {page && page.map((row) => { - prepareRow(row); + {page && + page.map((row) => { + prepareRow(row); - return ( - - {row.cells.map((cell) => ( - - {cell.render('Cell')} - - ))} - - ); - })} + return ( + + {row.cells.map((cell) => ( + + {cell.render("Cell")} + + ))} + + ); + })}
@@ -265,23 +278,32 @@ const ReactTable = (props) => {
filter.id === filterColumn.filterBy || filter.id === filterColumn.id, - ) ? filters.find((filter) => filter.id === filterColumn.filterBy || filter.id === filterColumn.id).value : '' + filterColumn && + filters.find( + (filter) => + filter.id === filterColumn.filterBy || + filter.id === filterColumn.id, + ) + ? filters.find( + (filter) => + filter.id === filterColumn.filterBy || + filter.id === filterColumn.id, + ).value + : "" } InputLabelProps={{ shrink: true, @@ -294,7 +316,7 @@ const ReactTable = (props) => { ), }} label={`Filter by ${filterColumn && filterColumn.Header}`} - onChange={(event) => (handleFilterColumn(event))} + onChange={(event) => handleFilterColumn(event)} placeholder={filterColumn && filterColumn.Header} type="text" variant="outlined" @@ -308,7 +330,7 @@ const ReactTable = (props) => { ReactTable.defaultProps = { defaultSortBy: [], filterable: true, - size: 'small', + size: "small", sortable: true, }; diff --git a/frontend/src/app/components/ReactTablePagination.js b/frontend/src/app/components/ReactTablePagination.js index 3a5246fb..665e372b 100644 --- a/frontend/src/app/components/ReactTablePagination.js +++ b/frontend/src/app/components/ReactTablePagination.js @@ -1,31 +1,26 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import IconButton from '@mui/material/IconButton'; -import MenuItem from '@mui/material/MenuItem'; -import Select from '@mui/material/Select'; -import { makeStyles } from '@mui/styles'; +import PropTypes from "prop-types"; +import React from "react"; +import IconButton from "@mui/material/IconButton"; +import MenuItem from "@mui/material/MenuItem"; +import Select from "@mui/material/Select"; +import { makeStyles } from "@mui/styles"; -import KeyboardArrowLeft from '@mui/icons-material/KeyboardArrowLeft'; -import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight'; +import KeyboardArrowLeft from "@mui/icons-material/KeyboardArrowLeft"; +import KeyboardArrowRight from "@mui/icons-material/KeyboardArrowRight"; const useStyles = makeStyles(() => ({ pagination: { flexShrink: 0, - '& .MuiSelect-select': { - paddingBottom: '0.5rem', - paddingTop: '0.5rem', + "& .MuiSelect-select": { + paddingBottom: "0.5rem", + paddingTop: "0.5rem", }, }, })); const ReactTablePagination = (props) => { const classes = useStyles(); - const { - count, - onPageChange, - page, - rowsPerPage, - } = props; + const { count, onPageChange, page, rowsPerPage } = props; const pagesCount = Math.ceil(count / rowsPerPage); @@ -53,7 +48,9 @@ const ReactTablePagination = (props) => { value={page} > {Array.from(Array(pagesCount).keys()).map((value) => ( - {(value + 1)} + + {value + 1} + ))} diff --git a/frontend/src/app/styles/App.scss b/frontend/src/app/styles/App.scss index ed163a71..86664c1e 100644 --- a/frontend/src/app/styles/App.scss +++ b/frontend/src/app/styles/App.scss @@ -2,16 +2,16 @@ Base styling for "App" ie General Container */ -$bg-alt-black: #1E1F21; +$bg-alt-black: #1e1f21; $bg-primary: #244074; $bg-black: #000; -$bg-white: #FFF; +$bg-white: #fff; $default-text-color: #000; $default-table-border-color: rgba(249, 249, 249, 0.2); -$default-table-color: #F9F9F9; -$highlight: #0078FD; -$default-link-blue: #568DBA; -$default-background-grey: #F2F2F2; +$default-table-color: #f9f9f9; +$highlight: #0078fd; +$default-link-blue: #568dba; +$default-background-grey: #f2f2f2; $md: 991px; $button-background-blue: #003366; @@ -38,7 +38,7 @@ $button-background-blue: #003366; } .logo { - background: url('../static/logo.png') center center no-repeat; + background: url("../static/logo.png") center center no-repeat; background-size: 100% auto; height: 100px; width: 200px; @@ -50,18 +50,19 @@ $button-background-blue: #003366; } } - body { background-color: $bg-white; color: $default-text-color; - font-family: 'Roboto', 'Open Sans', sans-serif; + font-family: "Roboto", "Open Sans", sans-serif; font-weight: 400; height: 100%; margin: 0; } -h2, h3, h4 { - font-family: 'Roboto', 'Open Sans', sans-serif; +h2, +h3, +h4 { + font-family: "Roboto", "Open Sans", sans-serif; color: #003366; font-weight: 500; } @@ -87,7 +88,6 @@ h4 { &:disabled { background-color: white !important; - } } diff --git a/frontend/src/app/styles/FileUpload.scss b/frontend/src/app/styles/FileUpload.scss index 29c37000..ee6608c5 100644 --- a/frontend/src/app/styles/FileUpload.scss +++ b/frontend/src/app/styles/FileUpload.scss @@ -2,7 +2,7 @@ background-color: $default-background-grey; } .bordered { - border: 1px solid #E0E0E0; + border: 1px solid #e0e0e0; padding: 0.5rem; } #dataset-select { @@ -10,19 +10,17 @@ margin-top: 1rem; padding: 1rem; background-color: $default-background-grey; - } #trash-button { height: 15px; } .upload-list { font-weight: normal; - } .upload-row { background-color: $default-background-grey; - padding: .5rem; - margin: .5rem; + padding: 0.5rem; + margin: 0.5rem; } .file-upload { border: 1px dashed $button-background-blue; @@ -30,7 +28,6 @@ padding: 1rem; text-align: center; flex-direction: column; - } .upload-bar { diff --git a/frontend/src/app/styles/Footer.scss b/frontend/src/app/styles/Footer.scss index 80595d1a..9065df47 100644 --- a/frontend/src/app/styles/Footer.scss +++ b/frontend/src/app/styles/Footer.scss @@ -1,66 +1,71 @@ footer { - position: relative; - width: 100%; - bottom: 0; - background-color: #036; - border-top: 2px solid #fcba19; + position: relative; + width: 100%; + bottom: 0; + background-color: #036; + border-top: 2px solid #fcba19; + color: #fff; + font-family: + ‘BCSans’, + ‘Noto Sans’, + Verdana, + Arial, + sans-serif; + .container { + display: flex; + justify-content: center; + flex-direction: column; + text-align: center; + height: 46px; + } + ul { + display: flex; + flex-direction: row; + flex-wrap: wrap; + margin: 0; color: #fff; - font-family: ‘BCSans’, ‘Noto Sans’, Verdana, Arial, sans-serif; - .container { - display: flex; - justify-content: center; - flex-direction: column; - text-align: center; - height: 46px; + list-style: none; + align-items: center; + height: 100%; + li a { + font-size: 0.813em; + font-weight: normal; /* 400 */ + color: #fff; + border-right: 1px solid #4b5e7e; + padding-left: 5px; + padding-right: 5px; + text-decoration: none; } - ul { - display: flex; - flex-direction: row; - flex-wrap: wrap; - margin: 0; + a:hover { color: #fff; - list-style: none; - align-items: center; - height: 100%; - li a { - font-size: 0.813em; - font-weight: normal; /* 400 */ - color: #fff; - border-right: 1px solid #4b5e7e; - padding-left: 5px; - padding-right: 5px; - text-decoration: none; - } - a:hover { - color: #fff; - text-decoration: underline; - } - a:focus { - outline: 4px solid #3b99fc; - outline-offset: 1px; - } + text-decoration: underline; } - } - @media (max-width: 600px) { - .footer { - .container { - ul li a { - font-size: 0.8rem; - line-height: 0.9rem; - } - } + a:focus { + outline: 4px solid #3b99fc; + outline-offset: 1px; } } - @media (max-width: 485px) { - .footer { - height: 3.5rem; - .container { - justify-content: space-evenly; +} +@media (max-width: 600px) { + .footer { + .container { + ul li a { + font-size: 0.8rem; + line-height: 0.9rem; } } } - @media (max-width: 282px) { - .footer { - height: 6rem; +} +@media (max-width: 485px) { + .footer { + height: 3.5rem; + .container { + justify-content: space-evenly; } - } \ No newline at end of file + } +} +@media (max-width: 282px) { + .footer { + height: 6rem; + } +} diff --git a/frontend/src/app/styles/Header.scss b/frontend/src/app/styles/Header.scss index d287abc6..64efbb0b 100644 --- a/frontend/src/app/styles/Header.scss +++ b/frontend/src/app/styles/Header.scss @@ -1,108 +1,108 @@ .cthub-banner { - background-color: $banner-blue; - display: flex; - border-bottom: 3px solid $border-orange; - flex-direction: row; - justify-content: space-between; - align-items: center; - padding-left: 6rem; - padding-right: 6rem; + background-color: $banner-blue; + display: flex; + border-bottom: 3px solid $border-orange; + flex-direction: row; + justify-content: space-between; + align-items: center; + padding-left: 6rem; + padding-right: 6rem; +} + +.cthub-banner .left, +.cthub-banner .right { + display: flex; + flex-direction: row; + align-items: center; + font-size: 1.25rem; + a { + color: $white; + text-decoration: none; + font-weight: bold; } - - .cthub-banner .left, - .cthub-banner .right { - display: flex; - flex-direction: row; - align-items: center; - font-size: 1.25rem; - a { + img { + height: 4.5rem; + width: auto; + } + .logout { + color: $white; + font-size: 1rem; + .logoutButton { + cursor: pointer; + border: none; + background: none; + font: inherit; + color: inherit; + } + } +} + +.page-header { + background-color: $banner-blue; + width: 100%; + //height: 191px; + + .title { + padding-left: 6rem; + h1 { color: $white; - text-decoration: none; - font-weight: bold; } + } +} + +@media (max-width: 992px) { + .cthub-banner { + font-weight: normal; + flex-direction: column; img { - height: 4.5rem; - width: auto; + margin-left: 1rem; + height: 3rem; } .logout { - color: $white; - font-size: 1rem; - .logoutButton { - cursor: pointer; - border: none; - background: none; - font: inherit; - color: inherit; - } + font-size: 0.75rem; } } - .page-header { - background-color: $banner-blue; width: 100%; - //height: 191px; - + position: relative; + margin: 0; + height: 180px; .title { - padding-left: 6rem; + margin: 5px 0 0 1rem; + padding-left: 0; h1 { - color: $white; + font-size: 2rem; } } } - - @media (max-width: 992px) { - .cthub-banner { - font-weight: normal; - flex-direction: column; - img { - margin-left: 1rem; - height: 3rem; - } - .logout { - font-size: 0.75rem; - } - } - .page-header { - width: 100%; - position: relative; - margin: 0; - height: 180px; - .title { - margin: 5px 0 0 1rem; - padding-left: 0; - h1 { - font-size: 2rem; - } +} +@media (max-width: 688px) { + .page-header { + .title { + h1 { + font-size: 1.75rem; } } } - @media (max-width: 688px) { - .page-header { - .title { - h1 { - font-size: 1.75rem; - } - } +} +@media (max-width: 380px) { + .page-header { + a { + font-size: 10pt; } - } - @media (max-width: 380px) { - .page-header { - a { - font-size: 10pt; - } - .title { - h1 { - font-size: 1.5rem; - } + .title { + h1 { + font-size: 1.5rem; } } } - @media (max-width: 330px) { - .page-header { - .title { - h1 { - font-size: 1.2rem; - } +} +@media (max-width: 330px) { + .page-header { + .title { + h1 { + font-size: 1.2rem; } } - } \ No newline at end of file + } +} diff --git a/frontend/src/app/styles/Login.scss b/frontend/src/app/styles/Login.scss index 42b414ba..aec718fa 100644 --- a/frontend/src/app/styles/Login.scss +++ b/frontend/src/app/styles/Login.scss @@ -1,5 +1,5 @@ #login-page { - background-image: url('./images/tof.jpg'); + background-image: url("./images/tof.jpg"); background-position-x: center; background-position-y: top; background-repeat: no-repeat; @@ -17,7 +17,7 @@ padding: 0 5rem; position: fixed; width: 100%; - + .text { color: $bg-primary; font-size: 2.5rem; @@ -50,7 +50,7 @@ } .brand-logo { - background-image: url('./images/BCID_H_rgb_pos.png'); + background-image: url("./images/BCID_H_rgb_pos.png"); background-position: left; background-repeat: no-repeat; background-size: contain; @@ -79,7 +79,6 @@ text-decoration: none; width: 100%; } - } .flex-container { @@ -100,9 +99,9 @@ #main-content { width: 30rem; - } + } } - + @media (max-width: $md) { #header { background-color: $bg-white; @@ -113,7 +112,7 @@ padding: 1rem; position: relative; z-index: 999; - + .text { align-self: center; font-size: 4vw; @@ -128,9 +127,9 @@ } .display-name { - height: 100%; - min-width: 5rem; - width: 10vw; + height: 100%; + min-width: 5rem; + width: 10vw; } #main-content { @@ -150,7 +149,7 @@ .brand-logo { align-self: center; - background-image: url('./images/BCID_V_rgb_pos.png'); + background-image: url("./images/BCID_V_rgb_pos.png"); background-position: center; background-size: contain; height: 20vh; @@ -160,4 +159,4 @@ } } } -} \ No newline at end of file +} diff --git a/frontend/src/app/styles/ReactTable.scss b/frontend/src/app/styles/ReactTable.scss index 1ff731ca..0c7e532d 100644 --- a/frontend/src/app/styles/ReactTable.scss +++ b/frontend/src/app/styles/ReactTable.scss @@ -16,7 +16,7 @@ Base styling for any React Table font-size: 1rem; font-weight: 700; text-transform: uppercase; - + &:not([disabled]):hover { opacity: 0.65; } @@ -49,7 +49,7 @@ Base styling for any React Table &.-sort-desc { box-shadow: inset 0 -3px 0 0 $highlight !important; } - } + } } .rt-tr-group { @@ -66,4 +66,4 @@ Base styling for any React Table padding: 1rem 0.5rem; } } -} \ No newline at end of file +} diff --git a/frontend/src/app/styles/Roboto.scss b/frontend/src/app/styles/Roboto.scss index c675214e..53159c92 100644 --- a/frontend/src/app/styles/Roboto.scss +++ b/frontend/src/app/styles/Roboto.scss @@ -3,19 +3,19 @@ Roboto Webfont */ @font-face { - font-family: 'Roboto'; - src: url('./fonts/Roboto-Regular.ttf') format('ttf'); + font-family: "Roboto"; + src: url("./fonts/Roboto-Regular.ttf") format("ttf"); } @font-face { - font-family: 'Roboto'; + font-family: "Roboto"; font-weight: bold; - src: url('./fonts/Roboto-Bold.ttf') format('ttf'); + src: url("./fonts/Roboto-Bold.ttf") format("ttf"); } @font-face { - font-family: 'Roboto'; + font-family: "Roboto"; font-style: italic; font-weight: bold; - src: url('./fonts/Roboto-BoldItalic.ttf') format('woff'); -} \ No newline at end of file + src: url("./fonts/Roboto-BoldItalic.ttf") format("woff"); +} diff --git a/frontend/src/app/styles/Users.scss b/frontend/src/app/styles/Users.scss index 20bd7092..c5c574b0 100644 --- a/frontend/src/app/styles/Users.scss +++ b/frontend/src/app/styles/Users.scss @@ -7,25 +7,23 @@ background-color: $default-background-grey; align-content: space-around; width: 10%; - .checkbox { + .checkbox { width: 40%; } - @media (max-width:991px) { + @media (max-width: 991px) { width: 20%; -} - @media (max-width:599px) { + } + @media (max-width: 599px) { width: 40%; -} - + } } .user-input { - margin-left: 10px; - margin-right: 10px; - background-color: white; + margin-left: 10px; + margin-right: 10px; + background-color: white; } .button-dark-blue { background-color: #003366 !important; } - diff --git a/frontend/src/app/styles/index.scss b/frontend/src/app/styles/index.scss index 5845cf87..a5b22410 100644 --- a/frontend/src/app/styles/index.scss +++ b/frontend/src/app/styles/index.scss @@ -1,9 +1,9 @@ -@import 'variables.scss'; -@import 'App.scss'; -@import 'Login.scss'; -@import 'ReactTable.scss'; -@import 'FileUpload.scss'; -@import 'Roboto.scss'; -@import 'Users.scss'; -@import 'Header.scss'; -@import 'Footer.scss'; +@import "variables.scss"; +@import "App.scss"; +@import "Login.scss"; +@import "ReactTable.scss"; +@import "FileUpload.scss"; +@import "Roboto.scss"; +@import "Users.scss"; +@import "Header.scss"; +@import "Footer.scss"; diff --git a/frontend/src/app/styles/variables.scss b/frontend/src/app/styles/variables.scss index 3d386ad6..af1bdba0 100644 --- a/frontend/src/app/styles/variables.scss +++ b/frontend/src/app/styles/variables.scss @@ -17,4 +17,4 @@ $default-background-grey: #f2f2f2; $background-light-blue: #e7f4f7; -$table-border: rgba(49, 49, 50, 0.33); \ No newline at end of file +$table-border: rgba(49, 49, 50, 0.33); diff --git a/frontend/src/app/utilities/getFileSize.js b/frontend/src/app/utilities/getFileSize.js index 5dcfefd2..9d899322 100644 --- a/frontend/src/app/utilities/getFileSize.js +++ b/frontend/src/app/utilities/getFileSize.js @@ -1,13 +1,14 @@ const getFileSize = (bytes) => { if (bytes === 0) { - return '0 bytes'; + return "0 bytes"; } const k = 1000; - const sizes = ['bytes', 'KB', 'MB', 'GB', 'TB']; + const sizes = ["bytes", "KB", "MB", "GB", "TB"]; let i = Math.floor(Math.log(bytes) / Math.log(k)); - if (i > 4) { // nothing bigger than a terrabyte + if (i > 4) { + // nothing bigger than a terrabyte i = 4; } diff --git a/frontend/src/app/utilities/props.js b/frontend/src/app/utilities/props.js index ab5157ea..5f87dffe 100644 --- a/frontend/src/app/utilities/props.js +++ b/frontend/src/app/utilities/props.js @@ -1,4 +1,4 @@ -import PropTypes from 'prop-types'; +import PropTypes from "prop-types"; const CustomPropTypes = { keycloak: PropTypes.shape({ diff --git a/frontend/src/app/utilities/reactTable.js b/frontend/src/app/utilities/reactTable.js index 074b8ad6..4569ab0c 100644 --- a/frontend/src/app/utilities/reactTable.js +++ b/frontend/src/app/utilities/reactTable.js @@ -4,13 +4,13 @@ const findSortBy = (columns, id) => { for (let i = 0; i < columns.length; i += 1) { const column = columns[i]; - if ('columns' in column) { + if ("columns" in column) { value = findSortBy(column.columns, id); if (value !== id) { return value; } - } else if (column.id === id && 'sortBy' in column) { + } else if (column.id === id && "sortBy" in column) { return column.sortBy; } } @@ -39,13 +39,11 @@ const getOrderBy = (state) => { } sortByFields.forEach((value) => { - orderBy.push(`${arr.desc ? '-' : ''}${value}`); + orderBy.push(`${arr.desc ? "-" : ""}${value}`); }); }); - return orderBy.join(','); + return orderBy.join(","); }; -export { - findSortBy, getFilters, getOrderBy, -}; +export { findSortBy, getFilters, getOrderBy }; diff --git a/frontend/src/app/utilities/useAxios.js b/frontend/src/app/utilities/useAxios.js index 1b932994..5de66a49 100644 --- a/frontend/src/app/utilities/useAxios.js +++ b/frontend/src/app/utilities/useAxios.js @@ -1,30 +1,30 @@ -import axios from 'axios' -import useKeycloak from './useKeycloak' -import { API_BASE } from '../../config'; +import axios from "axios"; +import useKeycloak from "./useKeycloak"; +import { API_BASE } from "../../config"; const useAxios = (useDefault = false, opts = {}) => { - const keycloak = useKeycloak() + const keycloak = useKeycloak(); if (useDefault) { - return axios.create(opts) + return axios.create(opts); } const instance = axios.create({ baseURL: API_BASE, ...opts, - }) + }); instance.interceptors.request.use(async (config) => { if (keycloak.authenticated) { try { - await keycloak.updateToken(30) - config.headers = { - 'Authorization': `Bearer ${keycloak.token}`, - } - } catch(error) { + await keycloak.updateToken(30); + config.headers = { + Authorization: `Bearer ${keycloak.token}`, + }; + } catch (error) { // do something here? } } - return config - }) - return instance -} + return config; + }); + return instance; +}; -export default useAxios \ No newline at end of file +export default useAxios; diff --git a/frontend/src/app/utilities/useKeycloak.js b/frontend/src/app/utilities/useKeycloak.js index f56bdf77..bb306cba 100644 --- a/frontend/src/app/utilities/useKeycloak.js +++ b/frontend/src/app/utilities/useKeycloak.js @@ -1,9 +1,9 @@ -import { useContext } from 'react' -import { KeycloakContext } from '../../contexts' +import { useContext } from "react"; +import { KeycloakContext } from "../../contexts"; const useKeycloak = () => { - const keycloak = useContext(KeycloakContext) - return keycloak -} + const keycloak = useContext(KeycloakContext); + return keycloak; +}; -export default useKeycloak \ No newline at end of file +export default useKeycloak; diff --git a/frontend/src/contexts.js b/frontend/src/contexts.js index 2b7751c7..42218924 100644 --- a/frontend/src/contexts.js +++ b/frontend/src/contexts.js @@ -1,3 +1,3 @@ -import { createContext } from 'react' +import { createContext } from "react"; -export const KeycloakContext = createContext({}) \ No newline at end of file +export const KeycloakContext = createContext({}); diff --git a/frontend/src/dashboard/DashboardContainer.js b/frontend/src/dashboard/DashboardContainer.js index f49ec102..3f7da555 100644 --- a/frontend/src/dashboard/DashboardContainer.js +++ b/frontend/src/dashboard/DashboardContainer.js @@ -1,9 +1,9 @@ -import { withRouter, useHistory } from 'react-router-dom'; +import { withRouter, useHistory } from "react-router-dom"; const DashboardContainer = () => { const history = useHistory(); - history.push('/upload'); + history.push("/upload"); return null; }; diff --git a/frontend/src/dashboard/router.js b/frontend/src/dashboard/router.js index 7d740664..01f50893 100644 --- a/frontend/src/dashboard/router.js +++ b/frontend/src/dashboard/router.js @@ -1,14 +1,11 @@ -import React from 'react'; -import { Route } from 'react-router-dom'; +import React from "react"; +import { Route } from "react-router-dom"; -import DashboardContainer from './DashboardContainer'; +import DashboardContainer from "./DashboardContainer"; const Router = () => ( <> - + ); diff --git a/frontend/src/icbc_data/IcbcDataContainer.js b/frontend/src/icbc_data/IcbcDataContainer.js index a7e26afc..8a666f5d 100644 --- a/frontend/src/icbc_data/IcbcDataContainer.js +++ b/frontend/src/icbc_data/IcbcDataContainer.js @@ -1,10 +1,10 @@ -import React, { useCallback, useRef, useState } from 'react'; -import { withRouter } from 'react-router-dom'; +import React, { useCallback, useRef, useState } from "react"; +import { withRouter } from "react-router-dom"; -import { getFilters, getOrderBy } from '../app/utilities/reactTable'; -import IcbcDataTable from './components/IcbcDataTable'; -import ROUTES from './routes'; -import useAxios from '../app/utilities/useAxios'; +import { getFilters, getOrderBy } from "../app/utilities/reactTable"; +import IcbcDataTable from "./components/IcbcDataTable"; +import ROUTES from "./routes"; +import useAxios from "../app/utilities/useAxios"; const IcbcDataContainer = () => { const [data, setData] = useState([]); @@ -12,7 +12,7 @@ const IcbcDataContainer = () => { const [pageCount, setPageCount] = useState(-1); const [totalRowsCount, setTotalRowsCount] = useState(0); const fetchIdRef = useRef(0); - const axios = useAxios() + const axios = useAxios(); const onFetchData = useCallback((state) => { setLoading(true); diff --git a/frontend/src/icbc_data/components/IcbcDataTable.js b/frontend/src/icbc_data/components/IcbcDataTable.js index a4bb67fa..c6e5e19e 100644 --- a/frontend/src/icbc_data/components/IcbcDataTable.js +++ b/frontend/src/icbc_data/components/IcbcDataTable.js @@ -1,49 +1,52 @@ -import PropTypes from 'prop-types'; -import React from 'react'; +import PropTypes from "prop-types"; +import React from "react"; -import ReactTable from '../../app/components/ReactTable'; +import ReactTable from "../../app/components/ReactTable"; const IcbcDataTable = (props) => { - const columns = [{ - accessor: 'icbc_vehicle.model_year', - align: 'center', - filterBy: 'icbc_vehicle__model_year__name', - Header: 'Year', - id: 'year', - sortBy: 'icbc_vehicle__model_year__name', - width: 50, - }, { - accessor: 'icbc_vehicle.make', - filterBy: 'icbc_vehicle__make', - Header: 'Make', - headerAlign: 'left', - id: 'make', - sortBy: 'icbc_vehicle__make', - width: 100, - }, { - accessor: 'icbc_vehicle.model_name', - filterBy: 'icbc_vehicle__model_name', - Header: 'Model', - headerAlign: 'left', - id: 'Model', - sortBy: 'icbc_vehicle__model_name', - width: 100, - }, { - accessor: 'vin', - Header: 'VIN', - headerAlign: 'left', - id: 'vin', - }]; + const columns = [ + { + accessor: "icbc_vehicle.model_year", + align: "center", + filterBy: "icbc_vehicle__model_year__name", + Header: "Year", + id: "year", + sortBy: "icbc_vehicle__model_year__name", + width: 50, + }, + { + accessor: "icbc_vehicle.make", + filterBy: "icbc_vehicle__make", + Header: "Make", + headerAlign: "left", + id: "make", + sortBy: "icbc_vehicle__make", + width: 100, + }, + { + accessor: "icbc_vehicle.model_name", + filterBy: "icbc_vehicle__model_name", + Header: "Model", + headerAlign: "left", + id: "Model", + sortBy: "icbc_vehicle__model_name", + width: 100, + }, + { + accessor: "vin", + Header: "VIN", + headerAlign: "left", + id: "vin", + }, + ]; - const { - data, loading, onFetchData, pageCount, totalRowsCount, - } = props; + const { data, loading, onFetchData, pageCount, totalRowsCount } = props; return ( ([ - +const Router = () => [ + , -]); +]; export default Router; diff --git a/frontend/src/icbc_data/routes.js b/frontend/src/icbc_data/routes.js index 5433c012..fdce9647 100644 --- a/frontend/src/icbc_data/routes.js +++ b/frontend/src/icbc_data/routes.js @@ -1,5 +1,5 @@ const ROUTES = { - LIST: '/api/icbc-data', + LIST: "/api/icbc-data", }; export default ROUTES; diff --git a/frontend/src/index.js b/frontend/src/index.js index 667ea39e..420c26eb 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -1,23 +1,23 @@ -import React from 'react'; -import ReactDOM from 'react-dom' -import Keycloak from 'keycloak-js'; +import React from "react"; +import ReactDOM from "react-dom"; +import Keycloak from "keycloak-js"; -import KeycloakProvider from './app/components/KeycloakProvider'; -import App from './app/components/App'; -import Loading from './app/components/Loading'; -import { KEYCLOAK_CLIENT_ID, KEYCLOAK_REALM, KEYCLOAK_URL } from './config'; +import KeycloakProvider from "./app/components/KeycloakProvider"; +import App from "./app/components/App"; +import Loading from "./app/components/Loading"; +import { KEYCLOAK_CLIENT_ID, KEYCLOAK_REALM, KEYCLOAK_URL } from "./config"; -import './app/styles/index.scss'; +import "./app/styles/index.scss"; const keycloak = new Keycloak({ clientId: KEYCLOAK_CLIENT_ID, realm: KEYCLOAK_REALM, - url: KEYCLOAK_URL -}) + url: KEYCLOAK_URL, +}); const keycloakInitOptions = { - onLoad: 'check-sso', - pkceMethod: 'S256' -} + onLoad: "check-sso", + pkceMethod: "S256", +}; ReactDOM.render( , - document.getElementById('root') -) + document.getElementById("root"), +); diff --git a/frontend/src/uploads/UploadContainer.js b/frontend/src/uploads/UploadContainer.js index 44532f6a..315400aa 100644 --- a/frontend/src/uploads/UploadContainer.js +++ b/frontend/src/uploads/UploadContainer.js @@ -1,27 +1,25 @@ -import { withRouter } from 'react-router-dom'; -import React, { useState, useEffect } from 'react'; -import { - Paper, Alert, Stack, -} from '@mui/material'; -import ROUTES_UPLOAD from './routes'; -import ROUTES_USERS from '../users/routes'; -import UploadPage from './components/UploadPage'; -import AlertDialog from '../app/components/AlertDialog'; -import UsersContainer from '../users/UsersContainer'; -import Loading from '../app/components/Loading'; -import useAxios from '../app/utilities/useAxios'; +import { withRouter } from "react-router-dom"; +import React, { useState, useEffect } from "react"; +import { Paper, Alert, Stack } from "@mui/material"; +import ROUTES_UPLOAD from "./routes"; +import ROUTES_USERS from "../users/routes"; +import UploadPage from "./components/UploadPage"; +import AlertDialog from "../app/components/AlertDialog"; +import UsersContainer from "../users/UsersContainer"; +import Loading from "../app/components/Loading"; +import useAxios from "../app/utilities/useAxios"; const UploadContainer = () => { const [uploadFiles, setUploadFiles] = useState([]); // array of objects for files to be uploaded const [datasetList, setDatasetList] = useState([{}]); // holds the array of names of datasets const [loading, setLoading] = useState(false); const [refresh, setRefresh] = useState(false); // Used for page refresh instead of loading progress - const [datasetSelected, setDatasetSelected] = useState(''); // string identifying which dataset is being uploaded + const [datasetSelected, setDatasetSelected] = useState(""); // string identifying which dataset is being uploaded const [replaceData, setReplaceData] = useState(false); // if true, we will replace all const [alertContent, setAlertContent] = useState(); const [alert, setAlert] = useState(false); - const [currentUser, setCurrentUser] = useState(''); - const [alertSeverity, setAlertSeverity] = useState(''); + const [currentUser, setCurrentUser] = useState(""); + const [alertSeverity, setAlertSeverity] = useState(""); const [openDialog, setOpenDialog] = useState(false); const [adminUser, setAdminUser] = useState(false); const axios = useAxios(); @@ -33,7 +31,11 @@ const UploadContainer = () => { setDatasetList(response.data); setRefresh(false); axios.get(ROUTES_USERS.CURRENT).then((currentUserResp) => { - if (currentUserResp.data && currentUserResp.data.user_permissions && currentUserResp.data.user_permissions.admin === true) { + if ( + currentUserResp.data && + currentUserResp.data.user_permissions && + currentUserResp.data.user_permissions.admin === true + ) { setAdminUser(true); setCurrentUser(currentUserResp.data.idir); } @@ -43,75 +45,88 @@ const UploadContainer = () => { const showError = (error) => { const { response: errorResponse } = error; - setAlertContent(`${errorResponse.data.message}\n${errorResponse.data.errors ? 'Errors: ' + errorResponse.data.errors.join('\n') : ''}`); - setAlertSeverity('error'); + setAlertContent( + `${errorResponse.data.message}\n${errorResponse.data.errors ? "Errors: " + errorResponse.data.errors.join("\n") : ""}`, + ); + setAlertSeverity("error"); setAlert(true); }; - const doUpload = () => uploadFiles.forEach((file) => { - setLoading(true) - const uploadPromises = uploadFiles.map((file) => { - return axios.get(ROUTES_UPLOAD.MINIO_URL).then((response) => { - const { url: uploadUrl, minio_object_name: filename } = response.data; - return axiosDefault.put(uploadUrl, file).then(() => { - let replace = false; - if (replaceData === true) { - replace = true; - } - return axios.post(ROUTES_UPLOAD.UPLOAD, { - filename, - datasetSelected, - replace, + const doUpload = () => + uploadFiles.forEach((file) => { + setLoading(true); + const uploadPromises = uploadFiles.map((file) => { + return axios.get(ROUTES_UPLOAD.MINIO_URL).then((response) => { + const { url: uploadUrl, minio_object_name: filename } = response.data; + return axiosDefault.put(uploadUrl, file).then(() => { + let replace = false; + if (replaceData === true) { + replace = true; + } + return axios.post(ROUTES_UPLOAD.UPLOAD, { + filename, + datasetSelected, + replace, + }); }); }); }); - }); - - Promise.all(uploadPromises).then((responses) => { - - const errorCheck = responses.some(response => response.data.success) - - setAlertSeverity(errorCheck ? 'success' : 'error') - const message = responses.map(response => - `${response.data.message}${response.data.errors ? '\nErrors: ' + response.data.errors.join('\n') : ''}` - ).join('\n'); - - setAlertContent(message); - setAlert(true); - setUploadFiles([]); - }).catch((error) => { - showError(error); - }).finally(() => { - setLoading(false); + Promise.all(uploadPromises) + .then((responses) => { + const errorCheck = responses.some( + (response) => response.data.success, + ); + + setAlertSeverity(errorCheck ? "success" : "error"); + + const message = responses + .map( + (response) => + `${response.data.message}${response.data.errors ? "\nErrors: " + response.data.errors.join("\n") : ""}`, + ) + .join("\n"); + + setAlertContent(message); + setAlert(true); + setUploadFiles([]); + }) + .catch((error) => { + showError(error); + }) + .finally(() => { + setLoading(false); + }); }); - }); const downloadSpreadsheet = () => { - axios.get(ROUTES_UPLOAD.DOWNLOAD_SPREADSHEET, { - params: { - datasetSelected, - }, - responseType: 'blob', - }).then((response) => { - const url = window.URL.createObjectURL(new Blob([response.data])); - const link = document.createElement('a'); - - link.href = url; - link.setAttribute('download', `${datasetSelected}.xlsx`); - document.body.appendChild(link); - link.click(); - - link.parentNode.removeChild(link); - window.URL.revokeObjectURL(url); - }).catch((error) => { - showError(error); - }); + axios + .get(ROUTES_UPLOAD.DOWNLOAD_SPREADSHEET, { + params: { + datasetSelected, + }, + responseType: "blob", + }) + .then((response) => { + const url = window.URL.createObjectURL(new Blob([response.data])); + const link = document.createElement("a"); + + link.href = url; + link.setAttribute("download", `${datasetSelected}.xlsx`); + document.body.appendChild(link); + link.click(); + + link.parentNode.removeChild(link); + window.URL.revokeObjectURL(url); + }) + .catch((error) => { + showError(error); + }); }; const handleRadioChange = (event) => { const choice = event.target.value; - if (choice === 'replace') { + if (choice === "replace") { setOpenDialog(true); } else { setReplaceData(false); @@ -119,13 +134,13 @@ const UploadContainer = () => { }; const handleReplaceDataConfirm = () => { - setReplaceData(true) - setOpenDialog(false) - } + setReplaceData(true); + setOpenDialog(false); + }; const handleReplaceDataCancel = () => { - setOpenDialog(false) - } + setOpenDialog(false); + }; useEffect(() => { refreshList(true); @@ -135,13 +150,17 @@ const UploadContainer = () => { return ; } - const alertElement = alert && alertContent && alertSeverity ? - {alertContent.split('\n').map((line, index) => ( - - {line} -
-
- ))}
: null + const alertElement = + alert && alertContent && alertSeverity ? ( + + {alertContent.split("\n").map((line, index) => ( + + {line} +
+
+ ))} +
+ ) : null; return (
@@ -149,11 +168,13 @@ const UploadContainer = () => { <> @@ -184,5 +205,5 @@ const UploadContainer = () => {
); -} +}; export default withRouter(UploadContainer); diff --git a/frontend/src/uploads/components/FileDrop.js b/frontend/src/uploads/components/FileDrop.js index 7780eba4..31650e1d 100644 --- a/frontend/src/uploads/components/FileDrop.js +++ b/frontend/src/uploads/components/FileDrop.js @@ -1,38 +1,32 @@ -import PropTypes from 'prop-types'; -import React, { useCallback, useState } from 'react'; -import { Box, Button } from '@mui/material'; -import UploadIcon from '@mui/icons-material/Upload'; -import { useDropzone } from 'react-dropzone'; +import PropTypes from "prop-types"; +import React, { useCallback, useState } from "react"; +import { Box, Button } from "@mui/material"; +import UploadIcon from "@mui/icons-material/Upload"; +import { useDropzone } from "react-dropzone"; const FileDrop = (props) => { - const { - disabled, - setFiles, - setAlert, - } = props; - const [dropMessage, setDropMessage] = useState(''); + const { disabled, setFiles, setAlert } = props; + const [dropMessage, setDropMessage] = useState(""); const onDrop = useCallback((files) => { - setAlert(false) - setDropMessage(''); + setAlert(false); + setDropMessage(""); setFiles(files); }, []); const { getRootProps, getInputProps } = useDropzone({ onDrop }); - const uploadBoxClassNames = disabled ? "file-upload disabled" : "file-upload" + const uploadBoxClassNames = disabled ? "file-upload disabled" : "file-upload"; return (

- Drag and Drop files here or - {' '} -
+ Drag and Drop files here or
- + - {dropMessage && ( -
{dropMessage}
- )} + {dropMessage &&
{dropMessage}
}
); diff --git a/frontend/src/uploads/components/FileDropArea.js b/frontend/src/uploads/components/FileDropArea.js index 680a088f..97dd05e0 100644 --- a/frontend/src/uploads/components/FileDropArea.js +++ b/frontend/src/uploads/components/FileDropArea.js @@ -1,20 +1,15 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { Box, Button, Grid } from '@mui/material'; -import ClearIcon from '@mui/icons-material/Clear'; -import FileDrop from './FileDrop'; -import getFileSize from '../../app/utilities/getFileSize'; +import React from "react"; +import PropTypes from "prop-types"; +import { Box, Button, Grid } from "@mui/material"; +import ClearIcon from "@mui/icons-material/Clear"; +import FileDrop from "./FileDrop"; +import getFileSize from "../../app/utilities/getFileSize"; const FileDropArea = (props) => { - const { - disabled, - setUploadFiles, - uploadFiles, - setAlert, - } = props; + const { disabled, setUploadFiles, uploadFiles, setAlert } = props; const removeFile = (removedFile) => { - const found = uploadFiles.findIndex((file) => (file === removedFile)); + const found = uploadFiles.findIndex((file) => file === removedFile); uploadFiles.splice(found, 1); setUploadFiles([...uploadFiles]); }; @@ -38,7 +33,7 @@ const FileDropArea = (props) => { type="button" id="trash-button" > - + @@ -57,20 +52,18 @@ const FileDropArea = (props) => {
{uploadFiles.length > 0 && ( - - - -

Filename

+ + + +

Filename

+
+ +

Size

+
+ + {uploadFiles.map((file) => FormRow(file))} - -

Size

-
- - {uploadFiles.map((file) => ( - FormRow(file) - ))} - -
+
)}
diff --git a/frontend/src/uploads/components/UploadPage.js b/frontend/src/uploads/components/UploadPage.js index 330ff4a4..6228e42b 100644 --- a/frontend/src/uploads/components/UploadPage.js +++ b/frontend/src/uploads/components/UploadPage.js @@ -1,11 +1,18 @@ -import PropTypes from 'prop-types'; -import React from 'react'; +import PropTypes from "prop-types"; +import React from "react"; import { - Box, Button, MenuItem, Select, Radio, RadioGroup, FormControlLabel, FormControl, -} from '@mui/material'; -import UploadIcon from '@mui/icons-material/Upload'; -import FileDropArea from './FileDropArea'; -import Loading from '../../app/components/Loading'; + Box, + Button, + MenuItem, + Select, + Radio, + RadioGroup, + FormControlLabel, + FormControl, +} from "@mui/material"; +import UploadIcon from "@mui/icons-material/Upload"; +import FileDropArea from "./FileDropArea"; +import Loading from "../../app/components/Loading"; const UploadPage = (props) => { const { @@ -34,19 +41,23 @@ const UploadPage = (props) => { {alertElement}
-

- Select Program     -

+

Select Program    

- {datasetSelected && } - + {datasetSelected && ( + + )}
@@ -58,13 +69,13 @@ const UploadPage = (props) => { defaultValue="add" > } label="Add to existing data (default)" /> } label="Replace existing data (data cannot be restored, proceed only if you are certain that the new file contains all required data)." @@ -74,13 +85,20 @@ const UploadPage = (props) => {
- + {loading ? ( ) : ( @@ -112,10 +130,8 @@ UploadPage.propTypes = { setUploadFiles: PropTypes.func.isRequired, doUpload: PropTypes.func.isRequired, setDatasetSelected: PropTypes.func.isRequired, - replaceData: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.bool, - ]).isRequired, + replaceData: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]) + .isRequired, handleRadioChange: PropTypes.func.isRequired, downloadSpreadsheet: PropTypes.func.isRequired, setAlert: PropTypes.func.isRequired, diff --git a/frontend/src/uploads/router.js b/frontend/src/uploads/router.js index 3575a73d..19d0271d 100644 --- a/frontend/src/uploads/router.js +++ b/frontend/src/uploads/router.js @@ -1,16 +1,12 @@ -import React from 'react'; -import { Route } from 'react-router-dom'; +import React from "react"; +import { Route } from "react-router-dom"; -import UploadContainer from './UploadContainer'; +import UploadContainer from "./UploadContainer"; -const Router = () => ([ - +const Router = () => [ + , -]); +]; export default Router; diff --git a/frontend/src/uploads/routes.js b/frontend/src/uploads/routes.js index 6d3299f5..3a41f837 100644 --- a/frontend/src/uploads/routes.js +++ b/frontend/src/uploads/routes.js @@ -1,10 +1,10 @@ -const API_BASE_PATH = '/api/uploads'; +const API_BASE_PATH = "/api/uploads"; const UPLOAD = { - MINIO_URL: '/api/minio/put', + MINIO_URL: "/api/minio/put", UPLOAD: `${API_BASE_PATH}/import_data`, LIST: `${API_BASE_PATH}/datasets_list`, // backend route for retrieving list of datasets (eg ldv_rebates) - DOWNLOAD_SPREADSHEET: `${API_BASE_PATH}/download_dataset` + DOWNLOAD_SPREADSHEET: `${API_BASE_PATH}/download_dataset`, }; export default UPLOAD; diff --git a/frontend/src/users/UsersContainer.js b/frontend/src/users/UsersContainer.js index 5f0381bc..38711305 100644 --- a/frontend/src/users/UsersContainer.js +++ b/frontend/src/users/UsersContainer.js @@ -1,50 +1,52 @@ -import { withRouter } from 'react-router-dom'; -import PropTypes from 'prop-types'; -import { Alert } from '@mui/material'; -import React, { useState, useEffect, useCallback } from 'react'; -import { produce } from 'immer'; -import ROUTES_USERS from './routes'; -import UsersPage from './components/UsersPage'; -import useAxios from '../app/utilities/useAxios'; -import AlertDialog from '../app/components/AlertDialog'; -import Loading from '../app/components/Loading'; +import { withRouter } from "react-router-dom"; +import PropTypes from "prop-types"; +import { Alert } from "@mui/material"; +import React, { useState, useEffect, useCallback } from "react"; +import { produce } from "immer"; +import ROUTES_USERS from "./routes"; +import UsersPage from "./components/UsersPage"; +import useAxios from "../app/utilities/useAxios"; +import AlertDialog from "../app/components/AlertDialog"; +import Loading from "../app/components/Loading"; const UsersContainer = (props) => { - const { - currentUser, - } = props; + const { currentUser } = props; const [loading, setLoading] = useState(false); const [users, setUsers] = useState([]); - const [newUser, setNewUser] = useState(''); - const [message, setMessage] = useState(''); - const [messageSeverity, setMessageSeverity] = useState(''); - const [userToDelete, setUserToDelete] = useState(''); + const [newUser, setNewUser] = useState(""); + const [message, setMessage] = useState(""); + const [messageSeverity, setMessageSeverity] = useState(""); + const [userToDelete, setUserToDelete] = useState(""); const [openDialog, setOpenDialog] = useState(false); const axios = useAxios(); const handleAddNewUser = () => { - axios.post(ROUTES_USERS.CREATE, { idir: newUser }) + axios + .post(ROUTES_USERS.CREATE, { idir: newUser }) .then((response) => { const userAdded = response.data.idir; - setMessageSeverity('success'); + setMessageSeverity("success"); setMessage(`${userAdded} was added to the user list`); - const userObject = { idir: userAdded, user_permissions: { admin: false, uploader: false } }; + const userObject = { + idir: userAdded, + user_permissions: { admin: false, uploader: false }, + }; setUsers( produce((draft) => { draft.push(userObject); draft.sort((a, b) => a.idir.localeCompare(b.idir)); }), ); - setNewUser('') + setNewUser(""); }) .catch((error) => { - setMessageSeverity('error'); - setMessage('new user could not be added, sorry!'); + setMessageSeverity("error"); + setMessage("new user could not be added, sorry!"); }); }; const handleCheckboxChange = useCallback((event) => { - setMessage(''); + setMessage(""); const idir = event.target.name; const permissionType = event.target.id; const { checked } = event.target; @@ -59,43 +61,47 @@ const UsersContainer = (props) => { const handleDeleteUserClick = (idir) => { setUserToDelete(idir); setOpenDialog(true); - } + }; const handleDeleteUser = () => { - axios.delete(ROUTES_USERS.DETAILS.replace(/:id/g, userToDelete)) + axios + .delete(ROUTES_USERS.DETAILS.replace(/:id/g, userToDelete)) .then((response) => { - setMessageSeverity('success'); + setMessageSeverity("success"); setMessage(`${userToDelete} was deleted from the user table`); setUsers( produce((draft) => { - const indexOfUserToRemove = draft.findIndex((user) => user.idir === userToDelete); + const indexOfUserToRemove = draft.findIndex( + (user) => user.idir === userToDelete, + ); draft.splice(indexOfUserToRemove, 1); }), ); }) .catch((error) => { - setMessageSeverity('error'); - setMessage('something went wrong when deleting the user, sorry!'); + setMessageSeverity("error"); + setMessage("something went wrong when deleting the user, sorry!"); }) .finally(() => { - setUserToDelete(''); - setOpenDialog(false) + setUserToDelete(""); + setOpenDialog(false); }); - } + }; const handleDeleteUserCancel = () => { - setUserToDelete(''); + setUserToDelete(""); setOpenDialog(false); - } + }; const handleSubmitUserUpdates = () => { - axios.put(ROUTES_USERS.UPDATE, users) + axios + .put(ROUTES_USERS.UPDATE, users) .then((response) => { - setMessageSeverity('success'); + setMessageSeverity("success"); setMessage(response.data); }) .catch((error) => { - setMessageSeverity('error'); + setMessageSeverity("error"); setMessage(error.data); }); }; @@ -109,20 +115,20 @@ const UsersContainer = (props) => { }, []); if (loading) { - return + return ; } return (
{message && {message}} - + { const { @@ -24,10 +30,32 @@ const UsersPage = (props) => { return ( - { handleCheckboxChange(event); }} /> - + { + handleCheckboxChange(event); + }} + /> + - { handleCheckboxChange(event); }} /> + { + handleCheckboxChange(event); + }} + /> @@ -35,14 +63,22 @@ const UsersPage = (props) => { {user.idir} - + { handleXClick(user.idir); }} + onClick={() => { + handleXClick(user.idir); + }} > - + @@ -58,20 +94,47 @@ const UsersPage = (props) => {

Admin

- - + + -

- IDIR Username -

+

IDIR Username

- { setNewUser(event.target.value); setMessage(''); }} /> + { + setNewUser(event.target.value); + setMessage(""); + }} + /> - + - @@ -81,7 +144,13 @@ const UsersPage = (props) => {
- +

Upload

@@ -89,11 +158,20 @@ const UsersPage = (props) => {

Admin

- {users.map((user) => ( - userRow(user) - ))} - - @@ -103,7 +181,7 @@ const UsersPage = (props) => { ); }; UsersPage.defaultProps = { - newUser: '', + newUser: "", }; UsersPage.propTypes = { diff --git a/frontend/src/users/routes.js b/frontend/src/users/routes.js index 6cb6c026..8d6d7793 100644 --- a/frontend/src/users/routes.js +++ b/frontend/src/users/routes.js @@ -1,4 +1,4 @@ -const API_BASE_PATH = '/api/users'; +const API_BASE_PATH = "/api/users"; const USERS = { LIST: API_BASE_PATH,