Skip to content

Commit

Permalink
feat: 402 - file requirements (#410)
Browse files Browse the repository at this point in the history
  • Loading branch information
tim738745 authored Nov 21, 2024
1 parent a5e7272 commit 49c589a
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 0 deletions.
31 changes: 31 additions & 0 deletions django/api/migrations/0039_filerequirements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generated by Django 3.2.25 on 2024-11-07 22:15

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('api', '0038_addregions'),
]

operations = [
migrations.CreateModel(
name='FileRequirements',
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)),
('sheet', models.TextField(blank=True, null=True)),
('columns', models.TextField(blank=True, null=True)),
('formats', models.TextField(blank=True, null=True)),
('dataset', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='file_requirements', to='api.datasets')),
],
options={
'db_table': 'file_requirements',
},
),
]
63 changes: 63 additions & 0 deletions django/api/migrations/0040_add_datasets_and_file_requirements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Generated by Django 3.2.25 on 2024-11-07 22:17

from django.db import migrations


def add_datasets_and_file_requirements(apps, schema_editor):
Datasets = apps.get_model("api", "Datasets")
FileRequirements = apps.get_model("api", "FileRequirements")
columns_default_text = "All required columns must match the column names exactly as they appear in the provided template"
formats_default_text = "File format should be xlsx. xlsm. only"

ger_obj, ger_created = Datasets.objects.get_or_create(
name="Go Electric Rebates Program", defaults={"update_user": "SYSTEM"}
)
FileRequirements.objects.get_or_create(
dataset=ger_obj,
defaults={
"sheet": """
The sheet name must be "Distribution List - Master"
""",
"columns": columns_default_text,
"formats": formats_default_text,
},
)

arc_obj, arc_created = Datasets.objects.get_or_create(
name="ARC Project Tracking", defaults={"update_user": "SYSTEM"}
)
FileRequirements.objects.get_or_create(
dataset=arc_obj,
defaults={
"sheet": """
The sheet name must be "ARC Data"
""",
"columns": columns_default_text,
"formats": formats_default_text,
},
)

cvp_obj, cvp_created = Datasets.objects.get_or_create(
name="CVP Data", defaults={"update_user": "SYSTEM"}
)
FileRequirements.objects.get_or_create(
dataset=cvp_obj,
defaults={
"sheet": """
The sheet name must be "Data"
""",
"columns": columns_default_text,
"formats": formats_default_text,
},
)


class Migration(migrations.Migration):

dependencies = [
("api", "0039_filerequirements"),
]

operations = [
migrations.RunPython(add_datasets_and_file_requirements),
]
1 change: 1 addition & 0 deletions django/api/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@
from . import decoded_vin_record
from . import regions
from . import cvp_data
from . import file_requirements
20 changes: 20 additions & 0 deletions django/api/models/file_requirements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from django.db import models
from auditable.models import Auditable
from api.models.datasets import Datasets


class FileRequirements(Auditable):
dataset = models.OneToOneField(
Datasets,
related_name="file_requirements",
on_delete=models.CASCADE,
)

sheet = models.TextField(blank=True, null=True)

columns = models.TextField(blank=True, null=True)

formats = models.TextField(blank=True, null=True)

class Meta:
db_table = "file_requirements"
9 changes: 9 additions & 0 deletions django/api/serializers/file_requirements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from rest_framework.serializers import ModelSerializer
from api.models.file_requirements import FileRequirements


class FileRequirementsSerializer(ModelSerializer):

class Meta:
model = FileRequirements
fields = ("sheet", "columns", "formats")
5 changes: 5 additions & 0 deletions django/api/services/file_requirements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from api.models.file_requirements import FileRequirements


def get_file_requirements(dataset_name):
return FileRequirements.objects.filter(dataset__name=dataset_name).first()
11 changes: 11 additions & 0 deletions django/api/viewsets/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import api.constants.constants as constants
from api.services.spreadsheet_uploader_prep import *
from api.services.uploaded_vins_file import create_vins_file
from api.services.file_requirements import get_file_requirements
from api.serializers.file_requirements import FileRequirementsSerializer


class UploadViewset(GenericViewSet):
Expand Down Expand Up @@ -131,3 +133,12 @@ def download_dataset(self, request):
return response
except ValueError as e:
return HttpResponse(str(e), status=400)

@action(detail=False, methods=["get"])
def file_requirements(self, request):
dataset_name = request.query_params.get("dataset")
file_requirements = get_file_requirements(dataset_name)
if file_requirements is None:
return Response({})
serializer = FileRequirementsSerializer(file_requirements)
return Response(serializer.data)
42 changes: 42 additions & 0 deletions frontend/src/uploads/components/FileRequirements.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { useState, useEffect } from "react";
import useAxios from "../../app/utilities/useAxios";
import ROUTES_UPLOAD from "../routes";

const FileRequirements = ({ datasetSelected }) => {
const axios = useAxios();
const [requirements, setRequirements] = useState([]);

useEffect(() => {
if (datasetSelected) {
axios
.get(
ROUTES_UPLOAD.FILE_REQUIREMENTS.replace(":dataset", datasetSelected),
)
.then((response) => {
const list = [];
for (const [key, value] of Object.entries(response.data)) {
list.push(<li key={key}>{value}</li>);
}
setRequirements(list);
})
.catch((error) => {
//do something here?
});
}
}, [datasetSelected]);

if (requirements.length > 0) {
return (
<div id="file-requirements">
<h3>File Requirements</h3>
<div>
Ensure your file meets the following conditions before uploading:
</div>
<ul>{requirements}</ul>
</div>
);
}
return null;
};

export default FileRequirements;
6 changes: 6 additions & 0 deletions frontend/src/uploads/components/UploadPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import UploadIcon from "@mui/icons-material/Upload";
import DownloadIcon from "@mui/icons-material/Download";
import FileDropArea from "./FileDropArea";
import Loading from "../../app/components/Loading";
import FileRequirements from "./FileRequirements";

const UploadPage = (props) => {
const {
Expand Down Expand Up @@ -100,6 +101,11 @@ const UploadPage = (props) => {
uploadFiles={uploadFiles}
/>
</div>
<Box pt={3} rb={2}>
<FileRequirements
datasetSelected={datasetSelected}
/>
</Box>
<Box
pt={2}
className="upload-bar"
Expand Down
1 change: 1 addition & 0 deletions frontend/src/uploads/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const UPLOAD = {
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`,
FILE_REQUIREMENTS: `${API_BASE_PATH}/file_requirements?dataset=:dataset`
};

export default UPLOAD;

0 comments on commit 49c589a

Please sign in to comment.