Repository: WeblateOrg/weblate

Issue:
Translation propagation not working for uploaded file
**Describe the issue**

[Translation propagation](https://docs.weblate.org/en/weblate-4.8/admin/continuous.html#translation-propagation) is not working when uploading a translation within the UI.

**I already tried**

Describe the steps you tried to solve the problem yourself.

- [x] I've read and searched [the docs](https://docs.weblate.org/) and did not find the answer there.
- [x] Searched for issues within GitHub repository and did not find a similar ticket

**To Reproduce the issue**

Steps to reproduce the behavior:

1. Create a new project
2. Create two components with translation propagation enabled

![image](https://user-images.githubusercontent.com/1008534/133253423-009f9513-fce6-4198-a982-5c2ec23b5bae.png)

3. Navigate to non-source language in one component (in our case Germany) and upload a translation file

![image](https://user-images.githubusercontent.com/1008534/133253622-ce944d02-4336-4497-95ff-00ba2b6f1b5f.png)

4. A translation got changed for the current component, but not for the other component, and I get the following warning:

![image](https://user-images.githubusercontent.com/1008534/133253878-6c19aad0-0222-4384-a171-20a1f417597c.png)

5. Now, if I do not change anything and simply click on "Save", the translation is also pushed to the other component

**Expected behavior**

While uploading a new translation via UI, I would to propagate translations to other components, too.

**Exception traceback**

No error.

**Server configuration and status**

Docker, Weblate version 4.8.

```
 * Weblate: 4.8
 * Django: 3.2.6
 * siphashc: 2.1
 * translate-toolkit: 3.4.0
 * lxml: 4.6.3
 * Pillow: 8.3.1
 * bleach: 4.0.0
 * python-dateutil: 2.8.2
 * social-auth-core: 4.1.0
 * social-auth-app-django: 5.0.0
 * django-crispy-forms: 1.12.0
 * oauthlib: 3.1.1
 * django-compressor: 2.4.1
 * djangorestframework: 3.12.4
 * django-filter: 2.4.0
 * django-appconf: 1.0.4
 * user-agents: 2.2.0
 * filelock: 3.0.12
 * setuptools: 40.8.0
 * jellyfish: 0.8.2
 * openpyxl: 3.0.7
 * celery: 5.1.2
 * kombu: 5.1.0
 * translation-finder: 2.10
 * weblate-language-data: 2021.5
 * html2text: 2020.1.16
 * pycairo: 1.16.2
 * pygobject: 3.30.4
 * diff-match-patch: 20200713
 * requests: 2.26.0
 * django-redis: 5.0.0
 * hiredis: 2.0.0
 * sentry_sdk: 1.3.1
 * Cython: 0.29.24
 * misaka: 2.1.1
 * GitPython: 3.1.18
 * borgbackup: 1.1.17
 * pyparsing: 2.4.7
 * pyahocorasick: 1.4.2
 * python-redis-lock: 3.7.0
 * Python: 3.7.3
 * Git: 2.20.1
 * psycopg2: 2.9.1
 * psycopg2-binary: 2.9.1
 * phply: 1.2.5
 * chardet: 4.0.0
 * ruamel.yaml: 0.17.11
 * tesserocr: 2.5.2
 * akismet: 1.1
 * boto3: 1.18.26
 * zeep: 4.1.0
 * aeidon: 1.9
 * iniparse: 0.5
 * mysqlclient: 2.0.3
 * Mercurial: 5.9
 * git-svn: 2.20.1
 * git-review: 2.1.0
 * Redis server: 6.2.5
 * PostgreSQL server: 13.3
 * Database backends: django.db.backends.postgresql
 * Cache backends: default:RedisCache, avatar:FileBasedCache
 * Email setup: django.core.mail.backends.smtp.EmailBackend: smtp.mailersend.net
 * OS encoding: filesystem=utf-8, default=utf-8
 * Celery: redis://:WjUonTNhHsgHzp8iM66ofyALIz3u@weblate_redis:6379/1, redis://:WjUonTNhHsgHzp8iM66ofyALIz3u@weblate_redis:6379/1, regular
 * Platform: Linux 5.10.28-scaleway (x86_64)
```

**Weblate deploy checks**

```
System check identified some issues:

WARNINGS:
?: (security.W018) You should not have DEBUG set to True in deployment.

INFOS:
?: (weblate.I021) Error collection is not set up, it is highly recommended for production use
        HINT: https://docs.weblate.org/en/weblate-4.8/admin/install.html#collecting-errors
?: (weblate.I031) New Weblate version is available, please upgrade to 4.8.1.
        HINT: https://docs.weblate.org/en/weblate-4.8/admin/upgrade.html

System check identified 3 issues (1 silenced).
```

**Additional context**

Nothing.

***Current workaround***

The current workaround is a bit crazy. I open the inconsistent list in "Zen" mode and open the developer tools in my browser. Afterwards, I trigger a save of the translation for each element with the following code:

```js
(async() => {
    const checkboxes = jQuery(".fuzzy_checkbox");
    let i = 0;
    for (const checkbox of checkboxes) {
        i++;
        console.log(`Checkbox ${i} / ${checkboxes.length} ...`);
        jQuery(checkbox).click();
        await new Promise(r => setTimeout(r, 1000));
        jQuery(checkbox).click();
        await new Promise(r => setTimeout(r, 1000));
    }
})();
```


Discussion:
This issue has been automatically marked as stale because there wasn’t any recent activity.

It will be closed soon if no further action occurs.

Thank you for your contributions!
Reopen
It was intentionally disabled for file uploads in c31b7e9f48d. The question is whether all these points are still valid.
This issue has been put aside. It is currently unclear if it will ever be implemented as it seems to cover too narrow of a use case or doesn't seem to fit into Weblate.

Please try to clarify the use case or consider proposing something more generic to make it useful to more users.

Resolving patch:
diff --git a/weblate/trans/models/translation.py b/weblate/trans/models/translation.py
--- a/weblate/trans/models/translation.py
+++ b/weblate/trans/models/translation.py
@@ -842,6 +842,19 @@ def merge_translations(
         add_fuzzy = method == "fuzzy"
         add_approve = method == "approve"
 
+        # Are there any translations to propagate?
+        # This is just an optimalization to avoid doing that for every unit.
+        propagate = (
+            Translation.objects.filter(
+                language=self.language,
+                component__source_language_id=self.component.source_language_id,
+                component__project=self.component.project,
+            )
+            .filter(component__allow_translation_propagation=True)
+            .exclude(pk=self.pk)
+            .exists()
+        )
+
         unit_set = self.unit_set.all()
 
         for set_fuzzy, unit2 in store2.iterate_merge(fuzzy):
@@ -880,7 +893,7 @@ def merge_translations(
                 split_plural(unit2.target),
                 state,
                 change_action=Change.ACTION_UPLOAD,
-                propagate=False,
+                propagate=propagate,
             )
 
         if accepted > 0:


Test patch: