Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create table project status 46 #449

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions app/core/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from .models import PracticeArea
from .models import ProgramArea
from .models import Project
from .models import ProjectStatus
from .models import Sdg
from .models import Skill
from .models import SocMajor
Expand Down Expand Up @@ -244,6 +245,11 @@ class CheckTypeAdmin(admin.ModelAdmin):
list_display = ("name", "description")


@admin.register(ProjectStatus)
class ProjectStatusAdmin(admin.ModelAdmin):
list_display = ("name", "description")


@admin.register(SocMajor)
class SocMajorAdmin(admin.ModelAdmin):
list_display = ("occ_code", "title")
Expand Down
12 changes: 12 additions & 0 deletions app/core/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from core.models import PracticeArea
from core.models import ProgramArea
from core.models import Project
from core.models import ProjectStatus
from core.models import Sdg
from core.models import Skill
from core.models import SocMajor
Expand Down Expand Up @@ -362,6 +363,17 @@ class Meta:
read_only_fields = ("uuid", "created_at", "updated_at")


class ProjectStatusSerializer(serializers.ModelSerializer):
"""
Used to retrieve project_status info
"""

class Meta:
model = ProjectStatus
fields = ("uuid", "name", "description")
read_only_fields = ("uuid", "created_at", "updated_at")


class SocMajorSerializer(serializers.ModelSerializer):
"""Used to retrieve soc_major info"""

Expand Down
2 changes: 2 additions & 0 deletions app/core/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from .views import PermissionTypeViewSet
from .views import PracticeAreaViewSet
from .views import ProgramAreaViewSet
from .views import ProjectStatusViewSet
from .views import ProjectViewSet
from .views import SdgViewSet
from .views import SkillViewSet
Expand Down Expand Up @@ -47,6 +48,7 @@
basename="affiliation",
)
router.register(r"check-types", CheckTypeViewSet, basename="check-type")
router.register(r"project-statuses", ProjectStatusViewSet, basename="project-status")
router.register(r"soc-majors", SocMajorViewSet, basename="soc-major")
router.register(r"url-types", UrlTypeViewSet, basename="url-type")
router.register(
Expand Down
16 changes: 16 additions & 0 deletions app/core/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from ..models import PracticeArea
from ..models import ProgramArea
from ..models import Project
from ..models import ProjectStatus
from ..models import Sdg
from ..models import Skill
from ..models import SocMajor
Expand All @@ -41,6 +42,7 @@
from .serializers import PracticeAreaSerializer
from .serializers import ProgramAreaSerializer
from .serializers import ProjectSerializer
from .serializers import ProjectStatusSerializer
from .serializers import SdgSerializer
from .serializers import SkillSerializer
from .serializers import SocMajorSerializer
Expand Down Expand Up @@ -356,6 +358,20 @@ class CheckTypeViewSet(viewsets.ModelViewSet):
serializer_class = CheckTypeSerializer


@extend_schema_view(
list=extend_schema(description="Return a list of all the project statuses"),
create=extend_schema(description="Create a new project status"),
retrieve=extend_schema(description="Return the details of an project status"),
destroy=extend_schema(description="Delete a project status"),
update=extend_schema(description="Update a project status"),
partial_update=extend_schema(description="Patch a project status"),
)
class ProjectStatusViewSet(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
queryset = ProjectStatus.objects.all()
serializer_class = ProjectStatusSerializer


@extend_schema_view(
list=extend_schema(description="Return a list of all the user permissions"),
retrieve=extend_schema(description="Return the details of a user permission"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name,description
Active,Has a project team and current meetings
On Hold,No project team or meetings scheduled
Completed,Project is completed
Closed,"Closed, possibly not completed (usually does not show up on the website). Unlikely to be reopened."
Deleted,"Holds for 90 days before final removal (used for test project entries, or mistakes that do not need to be remembered)"
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Generated by Django 4.2.11 on 2024-11-21 05:47

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


class Migration(migrations.Migration):

dependencies = [
("core", "0031_userstatustype_user_user_status"),
]

operations = [
migrations.CreateModel(
name="ProjectStatus",
fields=[
(
"uuid",
models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
unique=True,
),
),
(
"created_at",
models.DateTimeField(auto_now_add=True, verbose_name="Created at"),
),
(
"updated_at",
models.DateTimeField(auto_now=True, verbose_name="Updated at"),
),
("name", models.CharField(max_length=255)),
("description", models.TextField(blank=True)),
],
options={
"abstract": False,
},
),
migrations.AddField(
model_name="project",
name="current_status_id",
field=models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.PROTECT,
to="core.projectstatus",
),
),
]
2 changes: 1 addition & 1 deletion app/core/migrations/max_migration.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0031_userstatustype_user_user_status
0032_projectstatus_project_current_status_id
16 changes: 15 additions & 1 deletion app/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,18 @@ def __str__(self):
return f"{self.email}"


class ProjectStatus(AbstractBaseModel):
"""
Dictionary of status options for project
"""

name = models.CharField(max_length=255)
description = models.TextField(blank=True)

def __str__(self):
return f"{self.name}"


class Project(AbstractBaseModel):
"""
List of projects
Expand All @@ -137,7 +149,9 @@ class Project(AbstractBaseModel):
"Authorization: token [gh_PAT]" \
https://api.github.com/repos/[org]/[repo]',
)
# current_status_id = models.ForeignKey("status", on_delete=models.PROTECT)
current_status_id = models.ForeignKey(
ProjectStatus, null=True, on_delete=models.PROTECT
)
hide = models.BooleanField(default=True)
# location_id = models.ForeignKey("location", on_delete=models.PROTECT)
google_drive_id = models.CharField(max_length=255, blank=True)
Expand Down
19 changes: 19 additions & 0 deletions app/core/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from ..models import PracticeArea
from ..models import ProgramArea
from ..models import Project
from ..models import ProjectStatus
from ..models import Sdg
from ..models import Skill
from ..models import SocMajor
Expand Down Expand Up @@ -289,6 +290,24 @@ def check_type():
)


@pytest.fixture
def project_1():
return Project.objects.create(name="Project 1")


@pytest.fixture
def project_2():
return Project.objects.create(name="Project 2")


@pytest.fixture
def project_status():
return ProjectStatus.objects.create(
name="This is a test project_status",
description="This is a test project_status",
)


@pytest.fixture
def soc_major():
return SocMajor.objects.create(occ_code="22-2222", title="Test Soc Major")
Expand Down
11 changes: 11 additions & 0 deletions app/core/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
SDGS_URL = reverse("sdg-list")
AFFILIATION_URL = reverse("affiliation-list")
CHECK_TYPE_URL = reverse("check-type-list")
PROJECT_STATUSES_URL = reverse("project-status-list")
SOC_MAJOR_URL = reverse("soc-major-list")
URL_TYPE_URL = reverse("url-type-list")

Expand Down Expand Up @@ -374,6 +375,16 @@ def test_create_check_type(auth_client):
assert res.data["name"] == payload["name"]


def test_create_project_status(auth_client):
payload = {
"name": "This is a api-test project status name",
"description": "This is a api-test project status description",
}
res = auth_client.post(PROJECT_STATUSES_URL, payload)
assert res.status_code == status.HTTP_201_CREATED
assert res.data["name"] == payload["name"]


def test_create_soc_major(auth_client):
"""Test that we can create a soc major"""

Expand Down
29 changes: 29 additions & 0 deletions app/core/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from ..models import Event
from ..models import ProjectSdgXref
from ..models import ProjectStatus
from ..models import Sdg

pytestmark = pytest.mark.django_db
Expand Down Expand Up @@ -169,6 +170,34 @@ def test_project_sdg_relationship(project):
assert not climate_action_sdg.projects.contains(project)


def test_project_status(project_status):
assert str(project_status) == "This is a test project_status"
assert project_status.description == "This is a test project_status"


def test_project_has_a_project_status_relationship(
project_1,
project_2,
):
active_project_status = ProjectStatus.objects.get(name="Active")
closed_project_status = ProjectStatus.objects.get(name="Closed")

active_project_status.project_set.add(project_1)
active_project_status.project_set.add(project_2)
assert active_project_status.project_set.count() == 2

assert project_1.current_status_id == active_project_status
assert project_2.current_status_id == active_project_status

active_project_status.project_set.remove(project_1)
closed_project_status.project_set.add(project_1)

assert active_project_status.project_set.count() == 1
assert closed_project_status.project_set.count() == 1

assert project_1.current_status_id == closed_project_status


def test_url_type(url_type):
assert str(url_type) == "This is a test url type name"

Expand Down
31 changes: 31 additions & 0 deletions app/data/migrations/0009_projectstatus_seed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from django.db import migrations

from core.models import ProjectStatus


def forward(__code__, __reverse_code__):
items = [
("Active", "Has a project team and current meetings"),
("On Hold", "No project team or meetings scheduled "),
("Completed", "Project is completed"),
(
"Closed",
"Closed, possibly not completed (usually does not show up on the website). Unlikely to be reopened.",
),
(
"Deleted",
"Holds for 90 days before final removal (used for test project entries, or mistakes that do not need to be remembered)",
),
]
for name, description in items:
ProjectStatus.objects.create(name=name, description=description)


def reverse(__code__, __reverse_code__):
ProjectStatus.objects.all().delete()


class Migration(migrations.Migration):
dependencies = [("data", "0008_userstatustype_seed")]

operations = [migrations.RunPython(forward, reverse)]
2 changes: 1 addition & 1 deletion app/data/migrations/max_migration.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0008_userstatustype_seed
0009_projectstatus_seed