Skip to content

Commit ce17054

Browse files
authored
Merge pull request #2615 from IFRCGo/feat/dref-static-translation
DREF: Add static string translation on dref
2 parents 4258713 + 711e931 commit ce17054

File tree

17 files changed

+3361
-2979
lines changed

17 files changed

+3361
-2979
lines changed

.gitmodules

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[submodule "assets"]
2-
path = assets
3-
url = https://github.com/IFRCGo/go-api-artifacts
2+
path = assets
3+
url = git@github.com:IFRCGo/go-api-artifacts.git

assets

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Generated by Django 4.2.26 on 2025-12-19 13:23
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
dependencies = [
8+
("deployments", "0092_alter_eru_type_alter_erureadinesstype_type"),
9+
]
10+
11+
operations = [
12+
migrations.AddField(
13+
model_name="sector",
14+
name="title_ar",
15+
field=models.CharField(max_length=255, null=True, verbose_name="title"),
16+
),
17+
migrations.AddField(
18+
model_name="sector",
19+
name="title_en",
20+
field=models.CharField(max_length=255, null=True, verbose_name="title"),
21+
),
22+
migrations.AddField(
23+
model_name="sector",
24+
name="title_es",
25+
field=models.CharField(max_length=255, null=True, verbose_name="title"),
26+
),
27+
migrations.AddField(
28+
model_name="sector",
29+
name="title_fr",
30+
field=models.CharField(max_length=255, null=True, verbose_name="title"),
31+
),
32+
migrations.AddField(
33+
model_name="sector",
34+
name="translation_module_original_language",
35+
field=models.CharField(
36+
choices=[
37+
("en", "English"),
38+
("es", "Spanish"),
39+
("fr", "French"),
40+
("ar", "Arabic"),
41+
],
42+
default="en",
43+
help_text="Language used to create this entity",
44+
max_length=2,
45+
verbose_name="Entity Original language",
46+
),
47+
),
48+
migrations.AddField(
49+
model_name="sector",
50+
name="translation_module_skip_auto_translation",
51+
field=models.BooleanField(
52+
default=False,
53+
help_text="Skip auto translation operation for this entity?",
54+
verbose_name="Skip auto translation",
55+
),
56+
),
57+
]

deployments/test_views.py

Lines changed: 138 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,14 @@ def test_regional_project_get(self, mock_now):
205205
district1a = District.objects.create(name="district1aa", country=country1)
206206
district2 = District.objects.create(name="district2", country=country2)
207207
district2a = District.objects.create(name="district2a", country=country2)
208+
sector_1 = Sector.objects.create(title="Sector 1")
209+
sector_2 = Sector.objects.create(title="Sector 2")
210+
sector_3 = Sector.objects.create(title="Sector 3")
211+
sector_4 = Sector.objects.create(title="Sector 4")
212+
sector_5 = Sector.objects.create(title="Sector 5")
213+
sector_6 = Sector.objects.create(title="Sector 6")
214+
sector_7 = Sector.objects.create(title="Sector 7")
215+
sector_8 = Sector.objects.create(title="Sector 8")
208216

209217
mock_now.return_value = datetime.datetime(2011, 11, 11, tzinfo=pytz.utc)
210218
# Create new Projects
@@ -214,7 +222,7 @@ def test_regional_project_get(self, mock_now):
214222
rcountry1,
215223
[district1, district1a],
216224
ProgrammeTypes.BILATERAL,
217-
Sector.objects.get(pk=0),
225+
sector_1,
218226
OperationTypes.PROGRAMME,
219227
[datetime.date(2011, 11, 12), datetime.date(2011, 12, 13)],
220228
6000,
@@ -225,7 +233,7 @@ def test_regional_project_get(self, mock_now):
225233
rcountry1,
226234
[district1],
227235
ProgrammeTypes.MULTILATERAL,
228-
Sector.objects.get(pk=0),
236+
sector_2,
229237
OperationTypes.EMERGENCY_OPERATION,
230238
[datetime.date(2011, 11, 1), datetime.date(2011, 12, 15)],
231239
1000,
@@ -236,7 +244,7 @@ def test_regional_project_get(self, mock_now):
236244
rcountry1,
237245
[district2, district2a],
238246
ProgrammeTypes.DOMESTIC,
239-
Sector.objects.get(pk=2),
247+
sector_3,
240248
OperationTypes.PROGRAMME,
241249
[datetime.date(2011, 11, 1), datetime.date(2011, 12, 15)],
242250
4000,
@@ -247,7 +255,7 @@ def test_regional_project_get(self, mock_now):
247255
rcountry1,
248256
[district2],
249257
ProgrammeTypes.BILATERAL,
250-
Sector.objects.get(pk=9),
258+
sector_4,
251259
OperationTypes.EMERGENCY_OPERATION,
252260
[datetime.date(2010, 11, 12), datetime.date(2010, 1, 13)],
253261
6000,
@@ -258,7 +266,7 @@ def test_regional_project_get(self, mock_now):
258266
rcountry2,
259267
[district1, district1a],
260268
ProgrammeTypes.BILATERAL,
261-
Sector.objects.get(pk=0),
269+
sector_5,
262270
OperationTypes.PROGRAMME,
263271
[datetime.date(2011, 11, 12), datetime.date(2011, 12, 13)],
264272
86000,
@@ -269,7 +277,7 @@ def test_regional_project_get(self, mock_now):
269277
rcountry2,
270278
[district1],
271279
ProgrammeTypes.MULTILATERAL,
272-
Sector.objects.get(pk=8),
280+
sector_6,
273281
OperationTypes.EMERGENCY_OPERATION,
274282
[datetime.date(2010, 11, 12), datetime.date(2010, 1, 13)],
275283
6000,
@@ -280,7 +288,7 @@ def test_regional_project_get(self, mock_now):
280288
rcountry2,
281289
[district2, district2a],
282290
ProgrammeTypes.DOMESTIC,
283-
Sector.objects.get(pk=5),
291+
sector_7,
284292
OperationTypes.PROGRAMME,
285293
[datetime.date(2011, 11, 12), datetime.date(2011, 12, 13)],
286294
100,
@@ -291,7 +299,7 @@ def test_regional_project_get(self, mock_now):
291299
rcountry2,
292300
[district2],
293301
ProgrammeTypes.BILATERAL,
294-
Sector.objects.get(pk=3),
302+
sector_8,
295303
OperationTypes.PROGRAMME,
296304
[datetime.date(2010, 11, 12), datetime.date(2010, 1, 13)],
297305
2,
@@ -329,87 +337,141 @@ def test_regional_project_get(self, mock_now):
329337
resp.json(),
330338
)
331339

340+
def deep_sort_response(data):
341+
data["countries_count"] = sorted(data["countries_count"], key=lambda x: x["id"])
342+
data["country_ns_sector_count"] = sorted(data["country_ns_sector_count"], key=lambda x: x["id"])
343+
344+
for country in data["country_ns_sector_count"]:
345+
country["reporting_national_societies"] = sorted(country["reporting_national_societies"], key=lambda x: x["id"])
346+
347+
for ns in country["reporting_national_societies"]:
348+
ns["sectors"] = sorted(ns["sectors"], key=lambda x: x["id"])
349+
350+
data["supporting_ns"] = sorted(data["supporting_ns"], key=lambda x: x["id"])
351+
return data
352+
332353
resp = self.client.get(f"/api/v2/region-project/{region.pk}/movement-activities/", format="json")
333-
self.assertEqual(
334-
"".join(
335-
sorted(
336-
json.dumps(
354+
355+
resp_data = resp.json()
356+
357+
expected_data = {
358+
"total_projects": 8,
359+
"countries_count": [
360+
{
361+
"id": country1.id,
362+
"name": country1.name,
363+
"iso": country1.iso,
364+
"iso3": country1.iso3,
365+
"projects_count": 4,
366+
"planned_projects_count": 2,
367+
"ongoing_projects_count": 1,
368+
"completed_projects_count": 1,
369+
},
370+
{
371+
"id": country2.id,
372+
"name": country2.name,
373+
"iso": country2.iso,
374+
"iso3": country2.iso3,
375+
"projects_count": 4,
376+
"planned_projects_count": 1,
377+
"ongoing_projects_count": 1,
378+
"completed_projects_count": 2,
379+
},
380+
],
381+
"country_ns_sector_count": [
382+
{
383+
"id": country1.id,
384+
"name": country1.name,
385+
"reporting_national_societies": [
386+
{
387+
"id": rcountry1.id,
388+
"name": rcountry1.name,
389+
"sectors": [
390+
{
391+
"id": sector_1.id,
392+
"sector": sector_1.title,
393+
"count": 1,
394+
},
395+
{
396+
"id": sector_2.id,
397+
"sector": sector_2.title,
398+
"count": 1,
399+
},
400+
],
401+
},
337402
{
338-
"total_projects": 8,
339-
"countries_count": [
403+
"id": rcountry2.id,
404+
"name": rcountry2.name,
405+
"sectors": [
340406
{
341-
"id": country1.id,
342-
"name": "country1",
343-
"iso": "WZ",
344-
"iso3": None,
345-
"projects_count": 4,
346-
"planned_projects_count": 2,
347-
"ongoing_projects_count": 1,
348-
"completed_projects_count": 1,
407+
"id": sector_5.id,
408+
"sector": sector_5.title,
409+
"count": 1,
349410
},
350411
{
351-
"id": country2.id,
352-
"name": "country2",
353-
"iso": "WW",
354-
"iso3": None,
355-
"projects_count": 4,
356-
"planned_projects_count": 1,
357-
"ongoing_projects_count": 1,
358-
"completed_projects_count": 2,
412+
"id": sector_6.id,
413+
"sector": sector_6.title,
414+
"count": 1,
359415
},
360416
],
361-
"country_ns_sector_count": [
417+
},
418+
],
419+
},
420+
{
421+
"id": country2.id,
422+
"name": country2.name,
423+
"reporting_national_societies": [
424+
{
425+
"id": rcountry1.id,
426+
"name": rcountry1.name,
427+
"sectors": [
362428
{
363-
"id": country1.id,
364-
"name": "country1",
365-
"reporting_national_societies": [
366-
{
367-
"id": rcountry1.id,
368-
"name": "rcountry1",
369-
"sectors": [{"id": 0, "sector": Sector.objects.get(pk=0).title, "count": 2}],
370-
},
371-
{
372-
"id": rcountry2.id,
373-
"name": "rcountry2",
374-
"sectors": [
375-
{"id": 0, "sector": Sector.objects.get(pk=0).title, "count": 1},
376-
{"id": 8, "sector": Sector.objects.get(pk=8).title, "count": 1},
377-
],
378-
},
379-
],
429+
"id": sector_3.id,
430+
"sector": sector_3.title,
431+
"count": 1,
380432
},
381433
{
382-
"id": country2.id,
383-
"name": "country2",
384-
"reporting_national_societies": [
385-
{
386-
"id": rcountry1.id,
387-
"name": "rcountry1",
388-
"sectors": [
389-
{"id": 2, "sector": Sector.objects.get(pk=2).title, "count": 1},
390-
{"id": 9, "sector": Sector.objects.get(pk=9).title, "count": 1},
391-
],
392-
},
393-
{
394-
"id": rcountry2.id,
395-
"name": "rcountry2",
396-
"sectors": [
397-
{"id": 3, "sector": Sector.objects.get(pk=3).title, "count": 1},
398-
{"id": 5, "sector": Sector.objects.get(pk=5).title, "count": 1},
399-
],
400-
},
401-
],
434+
"id": sector_4.id,
435+
"sector": sector_4.title,
436+
"count": 1,
402437
},
403438
],
404-
"supporting_ns": [
405-
{"count": 4, "id": rcountry1.id, "name": "rcountry1"},
406-
{"count": 4, "id": rcountry2.id, "name": "rcountry2"},
439+
},
440+
{
441+
"id": rcountry2.id,
442+
"name": rcountry2.name,
443+
"sectors": [
444+
{
445+
"id": sector_7.id,
446+
"sector": sector_7.title,
447+
"count": 1,
448+
},
449+
{
450+
"id": sector_8.id,
451+
"sector": sector_8.title,
452+
"count": 1,
453+
},
407454
],
408-
}
409-
)
410-
)
411-
),
412-
"".join(sorted(json.dumps(resp.json()))),
455+
},
456+
],
457+
},
458+
],
459+
"supporting_ns": [
460+
{
461+
"id": rcountry1.id,
462+
"name": rcountry1.name,
463+
"count": 4,
464+
},
465+
{
466+
"id": rcountry2.id,
467+
"name": rcountry2.name,
468+
"count": 4,
469+
},
470+
],
471+
}
472+
self.assertEqual(
473+
deep_sort_response(expected_data),
474+
deep_sort_response(resp_data),
413475
)
414476
# ^ the order of the deep recursive dict could vary, that is why this flat comparison
415477

deployments/translation.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
PersonnelDeployment,
99
Project,
1010
RegionalProject,
11+
Sector,
1112
)
1213

1314

@@ -49,3 +50,8 @@ class ProjectTO(TranslationOptions):
4950
"name",
5051
"description",
5152
)
53+
54+
55+
@register(Sector)
56+
class SectorTO(TranslationOptions):
57+
fields = ("title",)

docs/go-artifacts.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ This is a **GitHub repository** used to store and manage **build files**, **gene
2727

2828
Command
2929
```bash
30-
docker compose run --rm serve ./manage.py spectacular --file .assets/openapi-schema.yaml
30+
docker compose run --rm serve ./manage.py spectacular --file ./assets/openapi-schema.yaml
3131
```
3232

3333
### 🚨 Manually added files
35.7 KB
Binary file not shown.

0 commit comments

Comments
 (0)