We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Store pretranslations for each locale separately
We currently retrieve pretranslations for each locale separately, and store them all at once with a single DB query (for all locales). That makes our DB performance a little bit better, but risks the need for additional retrieval of already retrieved pretranslations in case of an error.

Since retrieving pretranslations is significantly slower than writing them to the DB, we should write to DB for each locale separately.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pontoon/pretranslation/tasks.py`
Content:
```
1 import logging
2 
3 from django.db.models import Q, CharField, Value as V
4 from django.db.models.functions import Concat
5 from django.conf import settings
6 from pontoon.base.models import (
7     Project,
8     Entity,
9     TranslatedResource,
10     Translation,
11     User,
12 )
13 from pontoon.actionlog.models import ActionLog
14 from pontoon.pretranslation import AUTHORS
15 from pontoon.pretranslation.pretranslate import (
16     get_pretranslations,
17     update_changed_instances,
18 )
19 from pontoon.base.tasks import PontoonTask
20 from pontoon.sync.core import serial_task
21 from pontoon.checks.libraries import run_checks
22 from pontoon.checks.utils import bulk_run_checks
23 
24 
25 log = logging.getLogger(__name__)
26 
27 
28 @serial_task(settings.SYNC_TASK_TIMEOUT, base=PontoonTask, lock_key="project={0}")
29 def pretranslate(self, project_pk, locales=None, entities=None):
30     """
31     Identifies strings without any translations and any suggestions.
32     Engages TheAlgorithm (bug 1552796) to gather pretranslations.
33     Stores pretranslations as suggestions (approved=False) to DB.
34 
35     :arg project_pk: the pk of the project to be pretranslated
36     :arg Queryset locales: the locales for the project to be pretranslated
37     :arg Queryset entites: the entities for the project to be pretranslated
38 
39     :returns: None
40     """
41     project = Project.objects.get(pk=project_pk)
42 
43     if not project.pretranslation_enabled:
44         log.info(f"Pretranslation not enabled for project {project.name}")
45         return
46 
47     if locales:
48         locales = project.locales.filter(pk__in=locales)
49     else:
50         locales = project.locales
51 
52     locales = locales.filter(
53         project_locale__project=project,
54         project_locale__pretranslation_enabled=True,
55         project_locale__readonly=False,
56     )
57 
58     if not locales:
59         log.info(
60             f"Pretranslation not enabled for any locale within project {project.name}"
61         )
62         return
63 
64     log.info(f"Fetching pretranslations for project {project.name} started")
65 
66     if not entities:
67         entities = Entity.objects.filter(
68             resource__project=project,
69             obsolete=False,
70         )
71 
72     entities = entities.prefetch_related("resource")
73 
74     # Fetch all available locale-resource pairs (TranslatedResource objects)
75     tr_pairs = (
76         TranslatedResource.objects.filter(
77             resource__project=project,
78             locale__in=locales,
79         )
80         .annotate(
81             locale_resource=Concat(
82                 "locale_id", V("-"), "resource_id", output_field=CharField()
83             )
84         )
85         .values_list("locale_resource", flat=True)
86         .distinct()
87     )
88 
89     # Fetch all locale-entity pairs with non-rejected or pretranslated translations
90     pt_authors = [User.objects.get(email=email) for email in AUTHORS.values()]
91     translated_entities = (
92         Translation.objects.filter(
93             locale__in=locales,
94             entity__in=entities,
95         )
96         .filter(Q(rejected=False) | Q(user__in=pt_authors))
97         .annotate(
98             locale_entity=Concat(
99                 "locale_id", V("-"), "entity_id", output_field=CharField()
100             )
101         )
102         .values_list("locale_entity", flat=True)
103         .distinct()
104     )
105 
106     translated_entities = list(translated_entities)
107 
108     translations = []
109 
110     # To keep track of changed TranslatedResources and their latest_translation
111     tr_dict = {}
112 
113     tr_filter = []
114     index = -1
115 
116     for locale in locales:
117         log.info(f"Fetching pretranslations for locale {locale.code} started")
118         for entity in entities:
119             locale_entity = f"{locale.id}-{entity.id}"
120             locale_resource = f"{locale.id}-{entity.resource.id}"
121             if locale_entity in translated_entities or locale_resource not in tr_pairs:
122                 continue
123 
124             pretranslations = get_pretranslations(entity, locale)
125 
126             if not pretranslations:
127                 continue
128 
129             failed_checks = run_checks(
130                 entity,
131                 locale.code,
132                 entity.string,
133                 pretranslations[0][0],
134                 use_tt_checks=False,
135             )
136 
137             if failed_checks:
138                 pretranslations = get_pretranslations(
139                     entity, locale, preserve_placeables=True
140                 )
141 
142             for string, plural_form, user in pretranslations:
143                 t = Translation(
144                     entity=entity,
145                     locale=locale,
146                     string=string,
147                     user=user,
148                     approved=False,
149                     pretranslated=True,
150                     active=True,
151                     plural_form=plural_form,
152                 )
153 
154                 index += 1
155                 translations.append(t)
156 
157                 if locale_resource not in tr_dict:
158                     tr_dict[locale_resource] = index
159 
160                     # Add query for fetching respective TranslatedResource.
161                     tr_filter.append(
162                         Q(locale__id=locale.id) & Q(resource__id=entity.resource.id)
163                     )
164 
165                 # Update the latest translation index
166                 tr_dict[locale_resource] = index
167 
168         log.info(f"Fetching pretranslations for locale {locale.code} done")
169 
170     if len(translations) == 0:
171         return
172 
173     translations = Translation.objects.bulk_create(translations)
174 
175     # Log creating actions
176     actions_to_log = [
177         ActionLog(
178             action_type=ActionLog.ActionType.TRANSLATION_CREATED,
179             performed_by=t.user,
180             translation=t,
181         )
182         for t in translations
183     ]
184 
185     ActionLog.objects.bulk_create(actions_to_log)
186 
187     # Run checks on all translations
188     translation_pks = {translation.pk for translation in translations}
189     bulk_run_checks(Translation.objects.for_checks().filter(pk__in=translation_pks))
190 
191     # Mark translations as changed
192     changed_translations = Translation.objects.filter(
193         pk__in=translation_pks,
194         # Do not sync translations with errors and warnings
195         errors__isnull=True,
196         warnings__isnull=True,
197     )
198     changed_translations.bulk_mark_changed()
199 
200     # Update latest activity and stats for changed instances.
201     update_changed_instances(tr_filter, tr_dict, translations)
202 
203     log.info(f"Fetching pretranslations for project {project.name} done")
204
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pontoon/pretranslation/tasks.py b/pontoon/pretranslation/tasks.py
--- a/pontoon/pretranslation/tasks.py
+++ b/pontoon/pretranslation/tasks.py
@@ -105,16 +105,16 @@
 
     translated_entities = list(translated_entities)
 
-    translations = []
+    for locale in locales:
+        log.info(f"Fetching pretranslations for locale {locale.code} started")
 
-    # To keep track of changed TranslatedResources and their latest_translation
-    tr_dict = {}
+        translations = []
 
-    tr_filter = []
-    index = -1
+        # To keep track of changed TranslatedResources and their latest_translation
+        tr_dict = {}
+        tr_filter = []
+        index = -1
 
-    for locale in locales:
-        log.info(f"Fetching pretranslations for locale {locale.code} started")
         for entity in entities:
             locale_entity = f"{locale.id}-{entity.id}"
             locale_resource = f"{locale.id}-{entity.resource.id}"
@@ -165,39 +165,42 @@
                 # Update the latest translation index
                 tr_dict[locale_resource] = index
 
-        log.info(f"Fetching pretranslations for locale {locale.code} done")
+        if len(translations) == 0:
+            log.info(
+                f"Fetching pretranslations for locale {locale.code} done: No pretranslation fetched"
+            )
+            continue
 
-    if len(translations) == 0:
-        return
+        translations = Translation.objects.bulk_create(translations)
 
-    translations = Translation.objects.bulk_create(translations)
+        # Log creating actions
+        actions_to_log = [
+            ActionLog(
+                action_type=ActionLog.ActionType.TRANSLATION_CREATED,
+                performed_by=t.user,
+                translation=t,
+            )
+            for t in translations
+        ]
 
-    # Log creating actions
-    actions_to_log = [
-        ActionLog(
-            action_type=ActionLog.ActionType.TRANSLATION_CREATED,
-            performed_by=t.user,
-            translation=t,
-        )
-        for t in translations
-    ]
+        ActionLog.objects.bulk_create(actions_to_log)
 
-    ActionLog.objects.bulk_create(actions_to_log)
+        # Run checks on all translations
+        translation_pks = {translation.pk for translation in translations}
+        bulk_run_checks(Translation.objects.for_checks().filter(pk__in=translation_pks))
 
-    # Run checks on all translations
-    translation_pks = {translation.pk for translation in translations}
-    bulk_run_checks(Translation.objects.for_checks().filter(pk__in=translation_pks))
+        # Mark translations as changed
+        changed_translations = Translation.objects.filter(
+            pk__in=translation_pks,
+            # Do not sync translations with errors and warnings
+            errors__isnull=True,
+            warnings__isnull=True,
+        )
+        changed_translations.bulk_mark_changed()
 
-    # Mark translations as changed
-    changed_translations = Translation.objects.filter(
-        pk__in=translation_pks,
-        # Do not sync translations with errors and warnings
-        errors__isnull=True,
-        warnings__isnull=True,
-    )
-    changed_translations.bulk_mark_changed()
+        # Update latest activity and stats for changed instances.
+        update_changed_instances(tr_filter, tr_dict, translations)
 
-    # Update latest activity and stats for changed instances.
-    update_changed_instances(tr_filter, tr_dict, translations)
+        log.info(f"Fetching pretranslations for locale {locale.code} done")
 
     log.info(f"Fetching pretranslations for project {project.name} done")

{"golden_diff": "diff --git a/pontoon/pretranslation/tasks.py b/pontoon/pretranslation/tasks.py\n--- a/pontoon/pretranslation/tasks.py\n+++ b/pontoon/pretranslation/tasks.py\n@@ -105,16 +105,16 @@\n \n     translated_entities = list(translated_entities)\n \n-    translations = []\n+    for locale in locales:\n+        log.info(f\"Fetching pretranslations for locale {locale.code} started\")\n \n-    # To keep track of changed TranslatedResources and their latest_translation\n-    tr_dict = {}\n+        translations = []\n \n-    tr_filter = []\n-    index = -1\n+        # To keep track of changed TranslatedResources and their latest_translation\n+        tr_dict = {}\n+        tr_filter = []\n+        index = -1\n \n-    for locale in locales:\n-        log.info(f\"Fetching pretranslations for locale {locale.code} started\")\n         for entity in entities:\n             locale_entity = f\"{locale.id}-{entity.id}\"\n             locale_resource = f\"{locale.id}-{entity.resource.id}\"\n@@ -165,39 +165,42 @@\n                 # Update the latest translation index\n                 tr_dict[locale_resource] = index\n \n-        log.info(f\"Fetching pretranslations for locale {locale.code} done\")\n+        if len(translations) == 0:\n+            log.info(\n+                f\"Fetching pretranslations for locale {locale.code} done: No pretranslation fetched\"\n+            )\n+            continue\n \n-    if len(translations) == 0:\n-        return\n+        translations = Translation.objects.bulk_create(translations)\n \n-    translations = Translation.objects.bulk_create(translations)\n+        # Log creating actions\n+        actions_to_log = [\n+            ActionLog(\n+                action_type=ActionLog.ActionType.TRANSLATION_CREATED,\n+                performed_by=t.user,\n+                translation=t,\n+            )\n+            for t in translations\n+        ]\n \n-    # Log creating actions\n-    actions_to_log = [\n-        ActionLog(\n-            action_type=ActionLog.ActionType.TRANSLATION_CREATED,\n-            performed_by=t.user,\n-            translation=t,\n-        )\n-        for t in translations\n-    ]\n+        ActionLog.objects.bulk_create(actions_to_log)\n \n-    ActionLog.objects.bulk_create(actions_to_log)\n+        # Run checks on all translations\n+        translation_pks = {translation.pk for translation in translations}\n+        bulk_run_checks(Translation.objects.for_checks().filter(pk__in=translation_pks))\n \n-    # Run checks on all translations\n-    translation_pks = {translation.pk for translation in translations}\n-    bulk_run_checks(Translation.objects.for_checks().filter(pk__in=translation_pks))\n+        # Mark translations as changed\n+        changed_translations = Translation.objects.filter(\n+            pk__in=translation_pks,\n+            # Do not sync translations with errors and warnings\n+            errors__isnull=True,\n+            warnings__isnull=True,\n+        )\n+        changed_translations.bulk_mark_changed()\n \n-    # Mark translations as changed\n-    changed_translations = Translation.objects.filter(\n-        pk__in=translation_pks,\n-        # Do not sync translations with errors and warnings\n-        errors__isnull=True,\n-        warnings__isnull=True,\n-    )\n-    changed_translations.bulk_mark_changed()\n+        # Update latest activity and stats for changed instances.\n+        update_changed_instances(tr_filter, tr_dict, translations)\n \n-    # Update latest activity and stats for changed instances.\n-    update_changed_instances(tr_filter, tr_dict, translations)\n+        log.info(f\"Fetching pretranslations for locale {locale.code} done\")\n \n     log.info(f\"Fetching pretranslations for project {project.name} done\")\n", "issue": "Store pretranslations for each locale separately\nWe currently retrieve pretranslations for each locale separately, and store them all at once with a single DB query (for all locales). That makes our DB performance a little bit better, but risks the need for additional retrieval of already retrieved pretranslations in case of an error.\r\n\r\nSince retrieving pretranslations is significantly slower than writing them to the DB, we should write to DB for each locale separately.\n", "before_files": [{"content": "import logging\n\nfrom django.db.models import Q, CharField, Value as V\nfrom django.db.models.functions import Concat\nfrom django.conf import settings\nfrom pontoon.base.models import (\n    Project,\n    Entity,\n    TranslatedResource,\n    Translation,\n    User,\n)\nfrom pontoon.actionlog.models import ActionLog\nfrom pontoon.pretranslation import AUTHORS\nfrom pontoon.pretranslation.pretranslate import (\n    get_pretranslations,\n    update_changed_instances,\n)\nfrom pontoon.base.tasks import PontoonTask\nfrom pontoon.sync.core import serial_task\nfrom pontoon.checks.libraries import run_checks\nfrom pontoon.checks.utils import bulk_run_checks\n\n\nlog = logging.getLogger(__name__)\n\n\n@serial_task(settings.SYNC_TASK_TIMEOUT, base=PontoonTask, lock_key=\"project={0}\")\ndef pretranslate(self, project_pk, locales=None, entities=None):\n    \"\"\"\n    Identifies strings without any translations and any suggestions.\n    Engages TheAlgorithm (bug 1552796) to gather pretranslations.\n    Stores pretranslations as suggestions (approved=False) to DB.\n\n    :arg project_pk: the pk of the project to be pretranslated\n    :arg Queryset locales: the locales for the project to be pretranslated\n    :arg Queryset entites: the entities for the project to be pretranslated\n\n    :returns: None\n    \"\"\"\n    project = Project.objects.get(pk=project_pk)\n\n    if not project.pretranslation_enabled:\n        log.info(f\"Pretranslation not enabled for project {project.name}\")\n        return\n\n    if locales:\n        locales = project.locales.filter(pk__in=locales)\n    else:\n        locales = project.locales\n\n    locales = locales.filter(\n        project_locale__project=project,\n        project_locale__pretranslation_enabled=True,\n        project_locale__readonly=False,\n    )\n\n    if not locales:\n        log.info(\n            f\"Pretranslation not enabled for any locale within project {project.name}\"\n        )\n        return\n\n    log.info(f\"Fetching pretranslations for project {project.name} started\")\n\n    if not entities:\n        entities = Entity.objects.filter(\n            resource__project=project,\n            obsolete=False,\n        )\n\n    entities = entities.prefetch_related(\"resource\")\n\n    # Fetch all available locale-resource pairs (TranslatedResource objects)\n    tr_pairs = (\n        TranslatedResource.objects.filter(\n            resource__project=project,\n            locale__in=locales,\n        )\n        .annotate(\n            locale_resource=Concat(\n                \"locale_id\", V(\"-\"), \"resource_id\", output_field=CharField()\n            )\n        )\n        .values_list(\"locale_resource\", flat=True)\n        .distinct()\n    )\n\n    # Fetch all locale-entity pairs with non-rejected or pretranslated translations\n    pt_authors = [User.objects.get(email=email) for email in AUTHORS.values()]\n    translated_entities = (\n        Translation.objects.filter(\n            locale__in=locales,\n            entity__in=entities,\n        )\n        .filter(Q(rejected=False) | Q(user__in=pt_authors))\n        .annotate(\n            locale_entity=Concat(\n                \"locale_id\", V(\"-\"), \"entity_id\", output_field=CharField()\n            )\n        )\n        .values_list(\"locale_entity\", flat=True)\n        .distinct()\n    )\n\n    translated_entities = list(translated_entities)\n\n    translations = []\n\n    # To keep track of changed TranslatedResources and their latest_translation\n    tr_dict = {}\n\n    tr_filter = []\n    index = -1\n\n    for locale in locales:\n        log.info(f\"Fetching pretranslations for locale {locale.code} started\")\n        for entity in entities:\n            locale_entity = f\"{locale.id}-{entity.id}\"\n            locale_resource = f\"{locale.id}-{entity.resource.id}\"\n            if locale_entity in translated_entities or locale_resource not in tr_pairs:\n                continue\n\n            pretranslations = get_pretranslations(entity, locale)\n\n            if not pretranslations:\n                continue\n\n            failed_checks = run_checks(\n                entity,\n                locale.code,\n                entity.string,\n                pretranslations[0][0],\n                use_tt_checks=False,\n            )\n\n            if failed_checks:\n                pretranslations = get_pretranslations(\n                    entity, locale, preserve_placeables=True\n                )\n\n            for string, plural_form, user in pretranslations:\n                t = Translation(\n                    entity=entity,\n                    locale=locale,\n                    string=string,\n                    user=user,\n                    approved=False,\n                    pretranslated=True,\n                    active=True,\n                    plural_form=plural_form,\n                )\n\n                index += 1\n                translations.append(t)\n\n                if locale_resource not in tr_dict:\n                    tr_dict[locale_resource] = index\n\n                    # Add query for fetching respective TranslatedResource.\n                    tr_filter.append(\n                        Q(locale__id=locale.id) & Q(resource__id=entity.resource.id)\n                    )\n\n                # Update the latest translation index\n                tr_dict[locale_resource] = index\n\n        log.info(f\"Fetching pretranslations for locale {locale.code} done\")\n\n    if len(translations) == 0:\n        return\n\n    translations = Translation.objects.bulk_create(translations)\n\n    # Log creating actions\n    actions_to_log = [\n        ActionLog(\n            action_type=ActionLog.ActionType.TRANSLATION_CREATED,\n            performed_by=t.user,\n            translation=t,\n        )\n        for t in translations\n    ]\n\n    ActionLog.objects.bulk_create(actions_to_log)\n\n    # Run checks on all translations\n    translation_pks = {translation.pk for translation in translations}\n    bulk_run_checks(Translation.objects.for_checks().filter(pk__in=translation_pks))\n\n    # Mark translations as changed\n    changed_translations = Translation.objects.filter(\n        pk__in=translation_pks,\n        # Do not sync translations with errors and warnings\n        errors__isnull=True,\n        warnings__isnull=True,\n    )\n    changed_translations.bulk_mark_changed()\n\n    # Update latest activity and stats for changed instances.\n    update_changed_instances(tr_filter, tr_dict, translations)\n\n    log.info(f\"Fetching pretranslations for project {project.name} done\")\n", "path": "pontoon/pretranslation/tasks.py"}], "after_files": [{"content": "import logging\n\nfrom django.db.models import Q, CharField, Value as V\nfrom django.db.models.functions import Concat\nfrom django.conf import settings\nfrom pontoon.base.models import (\n    Project,\n    Entity,\n    TranslatedResource,\n    Translation,\n    User,\n)\nfrom pontoon.actionlog.models import ActionLog\nfrom pontoon.pretranslation import AUTHORS\nfrom pontoon.pretranslation.pretranslate import (\n    get_pretranslations,\n    update_changed_instances,\n)\nfrom pontoon.base.tasks import PontoonTask\nfrom pontoon.sync.core import serial_task\nfrom pontoon.checks.libraries import run_checks\nfrom pontoon.checks.utils import bulk_run_checks\n\n\nlog = logging.getLogger(__name__)\n\n\n@serial_task(settings.SYNC_TASK_TIMEOUT, base=PontoonTask, lock_key=\"project={0}\")\ndef pretranslate(self, project_pk, locales=None, entities=None):\n    \"\"\"\n    Identifies strings without any translations and any suggestions.\n    Engages TheAlgorithm (bug 1552796) to gather pretranslations.\n    Stores pretranslations as suggestions (approved=False) to DB.\n\n    :arg project_pk: the pk of the project to be pretranslated\n    :arg Queryset locales: the locales for the project to be pretranslated\n    :arg Queryset entites: the entities for the project to be pretranslated\n\n    :returns: None\n    \"\"\"\n    project = Project.objects.get(pk=project_pk)\n\n    if not project.pretranslation_enabled:\n        log.info(f\"Pretranslation not enabled for project {project.name}\")\n        return\n\n    if locales:\n        locales = project.locales.filter(pk__in=locales)\n    else:\n        locales = project.locales\n\n    locales = locales.filter(\n        project_locale__project=project,\n        project_locale__pretranslation_enabled=True,\n        project_locale__readonly=False,\n    )\n\n    if not locales:\n        log.info(\n            f\"Pretranslation not enabled for any locale within project {project.name}\"\n        )\n        return\n\n    log.info(f\"Fetching pretranslations for project {project.name} started\")\n\n    if not entities:\n        entities = Entity.objects.filter(\n            resource__project=project,\n            obsolete=False,\n        )\n\n    entities = entities.prefetch_related(\"resource\")\n\n    # Fetch all available locale-resource pairs (TranslatedResource objects)\n    tr_pairs = (\n        TranslatedResource.objects.filter(\n            resource__project=project,\n            locale__in=locales,\n        )\n        .annotate(\n            locale_resource=Concat(\n                \"locale_id\", V(\"-\"), \"resource_id\", output_field=CharField()\n            )\n        )\n        .values_list(\"locale_resource\", flat=True)\n        .distinct()\n    )\n\n    # Fetch all locale-entity pairs with non-rejected or pretranslated translations\n    pt_authors = [User.objects.get(email=email) for email in AUTHORS.values()]\n    translated_entities = (\n        Translation.objects.filter(\n            locale__in=locales,\n            entity__in=entities,\n        )\n        .filter(Q(rejected=False) | Q(user__in=pt_authors))\n        .annotate(\n            locale_entity=Concat(\n                \"locale_id\", V(\"-\"), \"entity_id\", output_field=CharField()\n            )\n        )\n        .values_list(\"locale_entity\", flat=True)\n        .distinct()\n    )\n\n    translated_entities = list(translated_entities)\n\n    for locale in locales:\n        log.info(f\"Fetching pretranslations for locale {locale.code} started\")\n\n        translations = []\n\n        # To keep track of changed TranslatedResources and their latest_translation\n        tr_dict = {}\n        tr_filter = []\n        index = -1\n\n        for entity in entities:\n            locale_entity = f\"{locale.id}-{entity.id}\"\n            locale_resource = f\"{locale.id}-{entity.resource.id}\"\n            if locale_entity in translated_entities or locale_resource not in tr_pairs:\n                continue\n\n            pretranslations = get_pretranslations(entity, locale)\n\n            if not pretranslations:\n                continue\n\n            failed_checks = run_checks(\n                entity,\n                locale.code,\n                entity.string,\n                pretranslations[0][0],\n                use_tt_checks=False,\n            )\n\n            if failed_checks:\n                pretranslations = get_pretranslations(\n                    entity, locale, preserve_placeables=True\n                )\n\n            for string, plural_form, user in pretranslations:\n                t = Translation(\n                    entity=entity,\n                    locale=locale,\n                    string=string,\n                    user=user,\n                    approved=False,\n                    pretranslated=True,\n                    active=True,\n                    plural_form=plural_form,\n                )\n\n                index += 1\n                translations.append(t)\n\n                if locale_resource not in tr_dict:\n                    tr_dict[locale_resource] = index\n\n                    # Add query for fetching respective TranslatedResource.\n                    tr_filter.append(\n                        Q(locale__id=locale.id) & Q(resource__id=entity.resource.id)\n                    )\n\n                # Update the latest translation index\n                tr_dict[locale_resource] = index\n\n        if len(translations) == 0:\n            log.info(\n                f\"Fetching pretranslations for locale {locale.code} done: No pretranslation fetched\"\n            )\n            continue\n\n        translations = Translation.objects.bulk_create(translations)\n\n        # Log creating actions\n        actions_to_log = [\n            ActionLog(\n                action_type=ActionLog.ActionType.TRANSLATION_CREATED,\n                performed_by=t.user,\n                translation=t,\n            )\n            for t in translations\n        ]\n\n        ActionLog.objects.bulk_create(actions_to_log)\n\n        # Run checks on all translations\n        translation_pks = {translation.pk for translation in translations}\n        bulk_run_checks(Translation.objects.for_checks().filter(pk__in=translation_pks))\n\n        # Mark translations as changed\n        changed_translations = Translation.objects.filter(\n            pk__in=translation_pks,\n            # Do not sync translations with errors and warnings\n            errors__isnull=True,\n            warnings__isnull=True,\n        )\n        changed_translations.bulk_mark_changed()\n\n        # Update latest activity and stats for changed instances.\n        update_changed_instances(tr_filter, tr_dict, translations)\n\n        log.info(f\"Fetching pretranslations for locale {locale.code} done\")\n\n    log.info(f\"Fetching pretranslations for project {project.name} done\")\n", "path": "pontoon/pretranslation/tasks.py"}]}