Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/BesLogic/releaf-canopeum in…
Browse files Browse the repository at this point in the history
…to bugfix/proper-use-of-theme-colors
  • Loading branch information
Samuel-Therrien-Beslogic committed Nov 15, 2024
2 parents a431a84 + 5711a78 commit 2088559
Show file tree
Hide file tree
Showing 51 changed files with 448 additions and 405 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/canopeum_backend_pr_validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,35 @@ jobs:
version: PATH
python-version: "3.12"
working-directory: canopeum_backend

Ruff-Autofixes:
runs-on: unbuntu-latest
defaults:
run:
working-directory: canopeum_backend
# Only run autofixes on PRs
if: ${{ github.event_name == 'pull_request' }}
steps:
- uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.ref }}
# Token with Contents permissions to allow retriggering workflow
token: ${{ secrets.PR_AUTOFIX_PAT }}
- run: echo "${{github.event.head_commit.author.name}}"
- uses: astral-sh/ruff-action@v1
with:
args: check --fix
- uses: astral-sh/ruff-action@v1
# Format even on lint failure
if: ${{ !cancelled() }}
with:
args: format
- name: Commit autofixes
uses: EndBug/add-and-commit@v9
# TODO: Prevent infinite loops, github.event.head_commit.author.name is not accessible in this context
# if: ${{ github.event.head_commit.author.name != 'github-actions' }}
# Push autofixes even on failure
if: ${{ !cancelled() }}
with:
default_author: github_actions
20 changes: 18 additions & 2 deletions .github/workflows/canopeum_frontend_pr_validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,32 @@ on:
- ".github/workflows/canopeum_frontend_pr_validation.yml"

jobs:
Lint:
Lint-Autofixes:
runs-on: ubuntu-latest
defaults:
run:
working-directory: canopeum_frontend
# Only run autofixes on PRs
if: ${{ github.event_name == 'pull_request' }}
steps:
- uses: actions/checkout@v4
with:
repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.ref }}
# Token with Contents permissions to allow retriggering workflow
token: ${{ secrets.PR_AUTOFIX_PAT }}
- uses: actions/setup-node@v4
- run: npm ci
- run: npm run lint
- run: npm run lint:fix
- name: Commit autofixes
uses: EndBug/add-and-commit@v9
# TODO: Prevent infinite loops, github.event.head_commit.author.name is not accessible in this context
# if: ${{ github.event.head_commit.author.name != 'github-actions' }}
# Push autofixes even on failure
if: ${{ !cancelled() }}
with:
default_author: github_actions

Build:
runs-on: ubuntu-latest
defaults:
Expand Down
77 changes: 0 additions & 77 deletions .pre-commit-config.yaml

This file was deleted.

6 changes: 0 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,6 @@ For backend
uv run ./scripts/checkers.py
```

For both: (autofixers)

```shell
pre-commit run --all
```

### Quickly running the application locally

We've made a `start-local-env.ps1` helper script to ease starting up the application. Feel free to use and improve it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
Mulchlayertype,
Post,
Role,
RoleName,
Site,
Siteadmin,
Sitetreespecies,
Expand Down Expand Up @@ -305,7 +306,6 @@ def create_batches_for_site(site):
soil_condition="Good",
survived_count=survived_count,
replace_count=replace_count,
total_number_seed=number_of_seed,
total_propagation=random.randint(0, number_of_seed),
)
create_batch_species_for_batch(batch)
Expand Down Expand Up @@ -423,7 +423,7 @@ def create_tree_types(self):
)

def create_site_types(self):
# This mapping MUST MATCH pinMap in canopeum_frontend/src/pages/Map.tsx
# This mapping MUST MATCH pinMap in canopeum_frontend/src/models/SiteType.ts
site_type_names = {
1: ("Canopeum", "Canopeum"),
2: ("Parks", "Parcs"),
Expand Down Expand Up @@ -456,9 +456,8 @@ def create_assets(self):
asset.asset.save(file_name, django_file, save=True)

def create_roles(self):
Role.objects.create(name="User")
Role.objects.create(name="SiteManager")
Role.objects.create(name="MegaAdmin")
for role in RoleName:
Role.objects.create(name=role)

def create_users(self):
User.objects.create_user(
Expand All @@ -467,37 +466,37 @@ def create_users(self):
password="Adminbeslogic!", # noqa: S106 # MOCK_PASSWORD
is_staff=True,
is_superuser=True,
role=Role.objects.get(name="MegaAdmin"),
role=Role.objects.get(name=RoleName.MegaAdmin),
)
User.objects.create_user(
username="TyrionLannister",
email="[email protected]",
password="tyrion123", # noqa: S106 # MOCK_PASSWORD
role=Role.objects.get(name="SiteManager"),
role=Role.objects.get(name=RoleName.ForestSteward),
)
User.objects.create_user(
username="DaenerysTargaryen",
email="[email protected]",
password="daenerys123", # noqa: S106 # MOCK_PASSWORD
role=Role.objects.get(name="SiteManager"),
role=Role.objects.get(name=RoleName.ForestSteward),
)
User.objects.create_user(
username="JonSnow",
email="[email protected]",
password="jon123", # noqa: S106 # MOCK_PASSWORD
role=Role.objects.get(name="SiteManager"),
role=Role.objects.get(name=RoleName.ForestSteward),
)
User.objects.create_user(
username="OberynMartell",
email="[email protected]",
password="oberyn123", # noqa: S106 # MOCK_PASSWORD
role=Role.objects.get(name="SiteManager"),
role=Role.objects.get(name=RoleName.ForestSteward),
)
User.objects.create_user(
username="NormalUser",
email="[email protected]",
password="normal123", # noqa: S106 # MOCK_PASSWORD
role=Role.objects.get(name="User"),
role=Role.objects.get(name=RoleName.User),
)

def create_sites(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 5.1 on 2024-10-29 21:39

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("canopeum_backend", "0001_initial"),
]

operations = [
migrations.AlterField(
model_name="role",
name="name",
field=models.CharField(
choices=[
("User", "User"),
("ForestSteward", "Foreststeward"),
("MegaAdmin", "Megaadmin"),
],
max_length=13,
),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.1 on 2024-10-29 19:34

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("canopeum_backend", "0001_initial"),
]

operations = [
migrations.RemoveField(
model_name="batch",
name="total_number_seed",
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Generated by Django 5.1 on 2024-11-14 17:18

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("canopeum_backend", "0002_alter_role_name"),
("canopeum_backend", "0002_remove_batch_total_number_seed"),
]

operations = []
47 changes: 29 additions & 18 deletions canopeum_backend/canopeum_backend/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import re
from datetime import UTC, datetime, timedelta
from typing import TYPE_CHECKING, Any, ClassVar, TypeVar, override
from enum import auto
from typing import TYPE_CHECKING, Any, ClassVar, Literal, TypeVar, cast, override

import googlemaps
from django.contrib.auth.models import AbstractUser
Expand All @@ -22,35 +23,38 @@


class RoleName(models.TextChoices):
USER = "User"
SITEMANAGER = "SiteManager"
MEGAADMIN = "MegaAdmin"
User = auto()
ForestSteward = auto()
MegaAdmin = auto()

@classmethod
def from_string(cls, value: str):
try:
return cls(value)
except ValueError:
return cls.USER
return cls.User


class Role(models.Model):
name = models.CharField(
max_length=11,
choices=RoleName.choices,
default=RoleName.USER,
# TODO: Request at https://github.com/typeddjango/django-stubs/issues
# for "choices" CharField to be understood as the enum type instead of a simple "str"
name = cast(
Literal["User", "ForestSteward", "MegaAdmin"],
models.CharField(max_length=max(len(val) for val in RoleName), choices=RoleName.choices),
)


class User(AbstractUser):
email = models.EmailField(
verbose_name="email address",
max_length=255,
unique=True,
)
email = models.EmailField(verbose_name="email address", max_length=255, unique=True)
USERNAME_FIELD = "email"
REQUIRED_FIELDS: ClassVar[list[str]] = []
role = models.ForeignKey[Role, Role](Role, models.RESTRICT, null=False, default=1)
role = models.ForeignKey[Role, Role](
Role,
models.RESTRICT,
null=False,
# Role.objects.get(name=RoleName.User).pk, but statically so we don't access DB during init
default=1,
)
if TYPE_CHECKING:
# Missing "id" in "Model" or some base "User" class?
id: int
Expand Down Expand Up @@ -166,7 +170,7 @@ def get_sponsor_progress(self) -> float:
return 0

batches = Batch.objects.filter(site=self)
sponsored_plant_count = sum(batch.plant_count() for batch in batches)
sponsored_plant_count = sum(batch.get_plant_count() for batch in batches)

# Note: We don't cap the progress at 100% so it's obvious if there's a data issue
return sponsored_plant_count / total_plant_count * 100
Expand Down Expand Up @@ -208,10 +212,13 @@ class Batch(models.Model):
soil_condition = models.TextField(blank=True, null=True)
survived_count = models.IntegerField(blank=True, null=True)
replace_count = models.IntegerField(blank=True, null=True)
total_number_seed = models.IntegerField(blank=True, null=True)
total_propagation = models.IntegerField(blank=True, null=True)
image = models.ForeignKey(Asset, models.DO_NOTHING, blank=True, null=True)

@property
def total_number_seeds(self):
return 100

def add_fertilizer_by_id(self, pk: int):
fertilizer_type = Fertilizertype.objects.get(pk=pk)
return Batchfertilizer.objects.create(fertilizer_type=fertilizer_type, batch=self)
Expand All @@ -232,7 +239,11 @@ def add_supported_specie_by_id(self, pk: int):
tree_type = Treetype.objects.get(pk=pk)
return BatchSupportedSpecies.objects.create(tree_type=tree_type, batch=self)

def plant_count(self) -> int:
def get_total_number_seeds(self) -> int:
batch_seeds = BatchSeed.objects.filter(batch=self)
return sum(seed.quantity for seed in batch_seeds)

def get_plant_count(self) -> int:
batch_species = BatchSpecies.objects.filter(batch=self)
return sum(specie.quantity for specie in batch_species)

Expand Down
Loading

0 comments on commit 2088559

Please sign in to comment.