Skip to content

Commit

Permalink
Merge pull request #1591 from BLSQ/POLIO-1657-chronogram-make-field-o…
Browse files Browse the repository at this point in the history
…ptional

POLIO-1657 Chronogram: make `user_in_charge` a `CharField` instead of a `ForeignKey`
  • Loading branch information
kemar authored Aug 28, 2024
2 parents e0038f0 + c840700 commit 32d5d49
Show file tree
Hide file tree
Showing 14 changed files with 96 additions and 47 deletions.
9 changes: 2 additions & 7 deletions plugins/polio/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ def save_related(self, request, form, formsets, change):
class ChronogramTaskAdminInline(admin.StackedInline):
model = ChronogramTask
extra = 0
raw_id_fields = ("user_in_charge", "created_by", "updated_by")
raw_id_fields = ("created_by", "updated_by")
readonly_fields = (
"created_at",
"created_by",
Expand All @@ -342,12 +342,7 @@ class ChronogramTaskAdminInline(admin.StackedInline):
)

def get_queryset(self, request):
return (
super()
.get_queryset(request)
.valid()
.select_related("chronogram__round", "user_in_charge", "created_by", "updated_by")
)
return super().get_queryset(request).valid().select_related("chronogram__round", "created_by", "updated_by")


@admin.register(Chronogram)
Expand Down
5 changes: 0 additions & 5 deletions plugins/polio/api/chronogram/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,6 @@ class Meta:
"get_status_display": {"read_only": True},
}

def to_representation(self, instance):
representation = super().to_representation(instance)
representation["user_in_charge"] = UserNestedSerializer(instance.user_in_charge, read_only=True).data
return representation


class ChronogramSerializer(DynamicFieldsModelSerializer, serializers.ModelSerializer):
campaign_obr_name = serializers.CharField(source="round.campaign.obr_name")
Expand Down
4 changes: 2 additions & 2 deletions plugins/polio/api/chronogram/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def get_queryset(self) -> QuerySet:
.filter(round_id__in=rounds_ids)
.select_related("round__campaign", "created_by", "updated_by")
.prefetch_related(Prefetch("tasks", queryset=ChronogramTask.objects.valid()))
.prefetch_related("tasks__user_in_charge", "tasks__created_by", "tasks__updated_by")
.prefetch_related("tasks__created_by", "tasks__updated_by")
.order_by("created_at")
)

Expand Down Expand Up @@ -130,7 +130,7 @@ def get_queryset(self) -> QuerySet:
return (
ChronogramTask.objects.valid()
.filter(chronogram__round__campaign__in=campaigns)
.select_related("chronogram__round", "user_in_charge", "created_by", "updated_by")
.select_related("chronogram__round", "created_by", "updated_by")
.order_by("created_at")
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export type ChronogramTask = {
deadline_date: string; // Date
status: string;
get_status_display: string;
user_in_charge: User;
user_in_charge: string;
delay_in_days: number;
comment: string;
// Optional fields.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import * as Permission from '../../../../../../../../hat/assets/js/apps/Iaso/uti
import TextInput from '../../../../../../../../hat/assets/js/apps/Iaso/domains/pages/components/TextInput';
import { EditIconButton } from '../../../../../../../../hat/assets/js/apps/Iaso/components/Buttons/EditIconButton';
import { InputWithInfos } from '../../../../../../../../hat/assets/js/apps/Iaso/components/InputWithInfos';
import { useGetProfilesDropdown } from '../../../../../../../../hat/assets/js/apps/Iaso/domains/teams/hooks/requests/useGetProfilesDropdown';

import MESSAGES from '../messages';
import { ChronogramTask } from '../../Chronogram/types';
Expand Down Expand Up @@ -45,9 +44,6 @@ const CreateEditChronogramTaskModal: FunctionComponent<Props> = ({
}) => {
const { formatMessage } = useSafeIntl();

const { data: profilesDropdown, isFetching: isFetchingProfiles } =
useGetProfilesDropdown();

const { mutate: confirm } = useCreateEditChronogramTask();
const schema = useChronogramTaskSchema();
const formik = useFormik({
Expand All @@ -59,7 +55,7 @@ const CreateEditChronogramTaskModal: FunctionComponent<Props> = ({
description_fr: chronogramTask?.description_fr,
start_offset_in_days: chronogramTask?.start_offset_in_days,
status: chronogramTask?.status,
user_in_charge: chronogramTask?.user_in_charge.id,
user_in_charge: chronogramTask?.user_in_charge,
comment: chronogramTask?.comment,
},
enableReinitialize: true,
Expand Down Expand Up @@ -158,9 +154,7 @@ const CreateEditChronogramTaskModal: FunctionComponent<Props> = ({
<Field
label={formatMessage(MESSAGES.labelUserInCharge)}
name="user_in_charge"
component={SingleSelect}
options={profilesDropdown}
isLoading={isFetchingProfiles}
component={TextInput}
disabled={!userHasReadAndWritePerm}
/>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ export const useChronogramDetailsTableColumn = (
{
Header: formatMessage(MESSAGES.labelUserInCharge),
id: 'user_in_charge',
accessor: row =>
row.user_in_charge.full_name || row.user_in_charge.username,
accessor: 'user_in_charge',
sortable: false,
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const useChronogramTaskSchema = () => {
.string()
.trim()
.required(formatMessage(MESSAGES.validationFieldRequired)),
user_in_charge: yup.number().nullable(),
user_in_charge: yup.string().trim().nullable(),
comment: yup.string().trim(),
});
};
17 changes: 17 additions & 0 deletions plugins/polio/migrations/0194_chronogramtask_user_in_charge_new.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 4.2.14 on 2024-08-27 14:47

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("polio", "0193_alter_incidentreport_stock_correction"),
]

operations = [
migrations.AddField(
model_name="chronogramtask",
name="user_in_charge_new",
field=models.CharField(blank=True, max_length=255),
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 4.2.14 on 2024-08-27 14:49

from django.db import migrations


def migrate_data_forward(apps, schema_editor):
ChronogramTask = apps.get_model("polio", "ChronogramTask")
tasks = ChronogramTask.objects.filter(user_in_charge__isnull=False).select_related("user_in_charge")
objs = []
for task in tasks:
user = task.user_in_charge
user_str = ""
if user.first_name and user.last_name:
user_str = f"{user.first_name} {user.last_name}"
elif user.first_name or user.last_name:
user_str = user.first_name or user.last_name
elif user.username:
user_str = user.username
if user_str:
task.user_in_charge_new = user_str
objs.append(task)
ChronogramTask.objects.bulk_update(objs, ["user_in_charge_new"])


class Migration(migrations.Migration):
dependencies = [
("polio", "0194_chronogramtask_user_in_charge_new"),
]

operations = [migrations.RunPython(migrate_data_forward, migrations.RunPython.noop, elidable=True)]
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Generated by Django 4.2.14 on 2024-08-27 15:11

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("polio", "0195_migrate_chronogramtask_user_in_charge"),
]

operations = [
migrations.RemoveField(
model_name="chronogramtask",
name="user_in_charge",
),
migrations.RenameField(
model_name="chronogramtask",
old_name="user_in_charge_new",
new_name="user_in_charge",
),
]
4 changes: 1 addition & 3 deletions plugins/polio/models/chronogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,7 @@ class Status(models.TextChoices):
description = TranslatedField(models.TextField(max_length=300), {"fr": {"blank": True}})
start_offset_in_days = models.IntegerField(default=0)
status = models.CharField(max_length=15, choices=Status.choices, default=Status.PENDING)
user_in_charge = models.ForeignKey(
User, null=True, blank=True, on_delete=models.SET_NULL, related_name="chronogram_tasks"
)
user_in_charge = models.CharField(max_length=255, blank=True)
comment = models.TextField(max_length=300, blank=True)
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
created_by = models.ForeignKey(
Expand Down
10 changes: 5 additions & 5 deletions plugins/polio/tests/api/test_chronogram_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def setUpTestData(cls):
description_en="Ordering markers",
description_fr="Assurer la commande des marqueurs",
start_offset_in_days=0,
user_in_charge=cls.user,
user_in_charge="John Doe",
comment="Comment",
)

Expand All @@ -73,7 +73,7 @@ def test_serialize_chronogram_task(self):
"deadline_date": "2024-06-27",
"status": "PENDING",
"get_status_display": "Not started",
"user_in_charge": {"id": self.user.id, "username": "test", "full_name": "John Doe"},
"user_in_charge": "John Doe",
"delay_in_days": 0,
"comment": "Comment",
"created_at": "2024-06-27T14:00:00Z",
Expand All @@ -98,7 +98,7 @@ def test_serialize_chronogram_task(self):
"deadline_date": "2024-06-27",
"status": "PENDING",
"get_status_display": "Pas commencé",
"user_in_charge": {"id": self.user.id, "username": "test", "full_name": "John Doe"},
"user_in_charge": "John Doe",
"delay_in_days": 0,
"comment": "Comment",
"created_at": "2024-06-27T14:00:00Z",
Expand All @@ -116,7 +116,7 @@ def test_deserialize_chronogram_task(self):
"description_fr": "Foo FR",
"start_offset_in_days": 0,
"status": ChronogramTask.Status.IN_PROGRESS,
"user_in_charge": self.user.pk,
"user_in_charge": "John Doe",
"delay_in_days": 0,
"comment": "Comment",
}
Expand All @@ -131,7 +131,7 @@ def test_deserialize_chronogram_task(self):
self.assertEqual(chronogram_task.description_fr, "Foo FR")
self.assertEqual(chronogram_task.start_offset_in_days, 0)
self.assertEqual(chronogram_task.status, "IN_PROGRESS")
self.assertEqual(chronogram_task.user_in_charge, self.user)
self.assertEqual(chronogram_task.user_in_charge, "John Doe")
self.assertEqual(chronogram_task.comment, "Comment")
self.assertEqual(chronogram_task.created_by, self.user)
self.assertEqual(chronogram_task.created_at, TODAY)
Expand Down
16 changes: 8 additions & 8 deletions plugins/polio/tests/api/test_chronogram_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def setUpTestData(cls):
description_en="Ordering markers",
description_fr="Assurer la commande des marqueurs",
start_offset_in_days=0,
user_in_charge=cls.user,
user_in_charge="John Doe",
comment="Comment",
)

Expand Down Expand Up @@ -82,7 +82,7 @@ def test_create_ok(self):
"description_fr": "Baz FR",
"start_offset_in_days": 0,
"status": ChronogramTask.Status.IN_PROGRESS,
"user_in_charge": self.user.pk,
"user_in_charge": "John Doe",
"comment": "Comment",
}
response = self.client.post("/api/polio/chronograms/tasks/", data=data, format="json")
Expand All @@ -93,7 +93,7 @@ def test_create_ok(self):
self.assertEqual(chronogram_task.description_en, "Baz EN")
self.assertEqual(chronogram_task.description_fr, "Baz FR")
self.assertEqual(chronogram_task.start_offset_in_days, 0)
self.assertEqual(chronogram_task.user_in_charge, self.user)
self.assertEqual(chronogram_task.user_in_charge, "John Doe")
self.assertEqual(chronogram_task.comment, "Comment")
self.assertEqual(chronogram_task.created_by, self.user)
self.assertEqual(chronogram_task.created_at, TODAY)
Expand Down Expand Up @@ -345,23 +345,23 @@ def setUpTestData(cls):
description_en="Foo EN",
description_fr="Foo FR",
start_offset_in_days=0,
user_in_charge=cls.user,
user_in_charge="John Doe",
)
ChronogramTask.objects.create(
period=Period.DURING,
chronogram=cls.chronogram,
description_en="Bar EN",
description_fr="Bar FR",
start_offset_in_days=0,
user_in_charge=cls.user,
user_in_charge="John Doe",
)
ChronogramTask.objects.create(
period=Period.AFTER,
chronogram=cls.chronogram,
description_en="Baz EN",
description_fr="BaZ FR",
start_offset_in_days=0,
user_in_charge=cls.user,
user_in_charge="John Doe",
)

def test_get_without_auth(self):
Expand All @@ -377,7 +377,7 @@ def test_get_without_perm(self):
def test_get_ok(self):
self.client.force_authenticate(self.user)

with self.assertNumQueries(7):
with self.assertNumQueries(6):
response = self.client.get(f"/api/polio/chronograms/{self.chronogram.pk}/")
self.assertJSONResponse(response, 200)
self.assertEqual(
Expand All @@ -396,7 +396,7 @@ def test_get_ok(self):
def test_get_all_fields_ok(self):
self.client.force_authenticate(self.user)

with self.assertNumQueries(7):
with self.assertNumQueries(6):
response = self.client.get(f"/api/polio/chronograms/{self.chronogram.pk}/?fields=:all")
self.assertJSONResponse(response, 200)
self.assertEqual(len(response.data["tasks"]), 3)
Expand Down
10 changes: 5 additions & 5 deletions plugins/polio/tests/models/test_chronogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def setUpTestData(cls):
description_en="Ordering markers",
description_fr="Assurer la commande des marqueurs",
start_offset_in_days=-20,
user_in_charge=cls.user,
user_in_charge="John Doe",
comment="Comment 1",
)
cls.chronogram_task_2 = ChronogramTask.objects.create(
Expand All @@ -61,7 +61,7 @@ def setUpTestData(cls):
description_en="Daily supervision of logistics activities",
description_fr="Supervision journalière des activités logistiques",
start_offset_in_days=0,
user_in_charge=cls.user,
user_in_charge="John Doe",
comment="Comment 2",
)
cls.chronogram_task_3 = ChronogramTask.objects.create(
Expand All @@ -70,7 +70,7 @@ def setUpTestData(cls):
description_en="Share waste destruction report",
description_fr="Partager le rapport de destruction des déchets",
start_offset_in_days=14,
user_in_charge=cls.user,
user_in_charge="John Doe",
comment="Comment 2",
)

Expand Down Expand Up @@ -137,14 +137,14 @@ def test_percentage_of_completion(self):
status=ChronogramTask.Status.DONE,
chronogram=self.chronogram,
start_offset_in_days=i,
user_in_charge=self.user,
user_in_charge="John Doe",
)
ChronogramTask.objects.create(
period=Period.DURING,
status=ChronogramTask.Status.DONE,
chronogram=self.chronogram,
start_offset_in_days=0,
user_in_charge=self.user,
user_in_charge="John Doe",
)

with self.assertNumQueries(1):
Expand Down

0 comments on commit 32d5d49

Please sign in to comment.