From efd464404566f58d0a7644f86ecc5cb55ba9109f Mon Sep 17 00:00:00 2001
From: Matthias <matmair@live.de>
Date: Wed, 4 Aug 2021 07:55:58 +0200
Subject: [PATCH 1/6] translation information

---
 InvenTree/templates/InvenTree/settings/user.html | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/InvenTree/templates/InvenTree/settings/user.html b/InvenTree/templates/InvenTree/settings/user.html
index 140d2f6b86..3fcdc326bc 100644
--- a/InvenTree/templates/InvenTree/settings/user.html
+++ b/InvenTree/templates/InvenTree/settings/user.html
@@ -90,6 +90,8 @@
             <input type="submit" value="{% trans 'Set Language' %}" class="btn btn btn-primary">
         </div>
     </form>
+    <h3>{% trans "Help the translation efforts!" %}</h3>
+    <p>{% blocktrans with link="https://crowdin.com/project/inventree" %}Native language translation of the InvenTree web application is <a href="{{link}}">community contributed via crowdin</a>. Contributions are welcomed and encouraged.{% endblocktrans} %}</p>
 </div>
 
 {% endblock %}
\ No newline at end of file

From 3ecb1e6577c65d10775b975b0a1900bb5784f7c9 Mon Sep 17 00:00:00 2001
From: Matthias <matmair@live.de>
Date: Wed, 4 Aug 2021 19:44:01 +0200
Subject: [PATCH 2/6] cleaner structure

---
 .../templates/InvenTree/settings/user.html    | 46 ++++++++++---------
 1 file changed, 25 insertions(+), 21 deletions(-)

diff --git a/InvenTree/templates/InvenTree/settings/user.html b/InvenTree/templates/InvenTree/settings/user.html
index 3fcdc326bc..aa3f7f079c 100644
--- a/InvenTree/templates/InvenTree/settings/user.html
+++ b/InvenTree/templates/InvenTree/settings/user.html
@@ -71,27 +71,31 @@
 </div>
 
 <div class="row">
-    <form action="{% url 'set_language' %}" method="post">
-        {% csrf_token %}
-        <input name="next" type="hidden" value="{% url 'settings' %}">
-        <div class="col-sm-6" style="width: 200px;"><div id="div_id_language" class="form-group"><div class="controls ">
-            <select name="language" class="select form-control">
-                {% get_current_language as LANGUAGE_CODE %}
-                {% get_available_languages as LANGUAGES %}
-                {% get_language_info_list for LANGUAGES as languages %}
-                {% for language in languages %}
-                    <option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
-                        {{ language.name_local }} ({{ language.code }})
-                    </option>
-                {% endfor %}
-            </select>
-        </div></div></div>
-        <div class="col-sm-6" style="width: auto;">
-            <input type="submit" value="{% trans 'Set Language' %}" class="btn btn btn-primary">
-        </div>
-    </form>
-    <h3>{% trans "Help the translation efforts!" %}</h3>
-    <p>{% blocktrans with link="https://crowdin.com/project/inventree" %}Native language translation of the InvenTree web application is <a href="{{link}}">community contributed via crowdin</a>. Contributions are welcomed and encouraged.{% endblocktrans} %}</p>
+    <div class="col">
+        <form action="{% url 'set_language' %}" method="post">
+            {% csrf_token %}
+            <input name="next" type="hidden" value="{% url 'settings' %}">
+            <div class="col-sm-6" style="width: 200px;"><div id="div_id_language" class="form-group"><div class="controls ">
+                <select name="language" class="select form-control">
+                    {% get_current_language as LANGUAGE_CODE %}
+                    {% get_available_languages as LANGUAGES %}
+                    {% get_language_info_list for LANGUAGES as languages %}
+                    {% for language in languages %}
+                        <option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
+                            {{ language.name_local }} ({{ language.code }})
+                        </option>
+                    {% endfor %}
+                </select>
+            </div></div></div>
+            <div class="col-sm-6" style="width: auto;">
+                <input type="submit" value="{% trans 'Set Language' %}" class="btn btn btn-primary">
+            </div>
+        </form>
+    </div>
+    <div class="col">
+        <h4>{% trans "Help the translation efforts!" %}</h4>
+        <p>{% blocktrans with link="https://crowdin.com/project/inventree" %}Native language translation of the InvenTree web application is <a href="{{link}}">community contributed via crowdin</a>. Contributions are welcomed and encouraged.{% endblocktrans %}</p>
+    </div>
 </div>
 
 {% endblock %}
\ No newline at end of file

From d6672372a51541fd77913f9ad3d5962456bbd898 Mon Sep 17 00:00:00 2001
From: Matthias <matthias.mair@oewf.org>
Date: Thu, 5 Aug 2021 00:44:02 +0200
Subject: [PATCH 3/6] script to save the locale stats

---
 .gitignore                            | 5 ++++-
 InvenTree/script/translation_stats.py | 8 ++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index c53a837e24..5610fc4304 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,4 +67,7 @@ secret_key.txt
 htmlcov/
 
 # Development files
-dev/
\ No newline at end of file
+dev/
+
+# Locale stats file
+locale_stats.json
diff --git a/InvenTree/script/translation_stats.py b/InvenTree/script/translation_stats.py
index f47a21f168..c6126f2944 100644
--- a/InvenTree/script/translation_stats.py
+++ b/InvenTree/script/translation_stats.py
@@ -3,6 +3,7 @@ This script calculates translation coverage for various languages
 """
 
 import os
+import json
 
 
 def calculate_coverage(filename):
@@ -36,8 +37,10 @@ if __name__ == '__main__':
 
     MY_DIR = os.path.dirname(os.path.realpath(__file__))
     LC_DIR = os.path.abspath(os.path.join(MY_DIR, '..', 'locale'))
+    STAT_FILE = os.path.abspath(os.path.join(MY_DIR, '..', 'InvenTree/locale_stats.json'))
 
     locales = {}
+    locales_perc = {}
 
     print("InvenTree translation coverage:")
 
@@ -64,5 +67,10 @@ if __name__ == '__main__':
             percentage = 0
 
         print(f"| {locale.ljust(4, ' ')} : {str(percentage).rjust(4, ' ')}% |")
+        locales_perc[locale] = percentage
 
     print("-" * 16)
+
+    # write locale stats
+    with open(STAT_FILE, 'w') as target:
+        json.dump(locales_perc, target)

From 58f2dce18d3b97997d41d04849d303503d54a0f6 Mon Sep 17 00:00:00 2001
From: Matthias <matthias.mair@oewf.org>
Date: Thu, 5 Aug 2021 01:23:11 +0200
Subject: [PATCH 4/6] show translation level in ui

---
 InvenTree/InvenTree/views.py                     | 10 ++++++++++
 InvenTree/templates/InvenTree/settings/user.html | 13 ++++++++++---
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/InvenTree/InvenTree/views.py b/InvenTree/InvenTree/views.py
index 9749fd60d0..69deb8fd97 100644
--- a/InvenTree/InvenTree/views.py
+++ b/InvenTree/InvenTree/views.py
@@ -7,12 +7,15 @@ as JSON objects and passing them to modal forms (using jQuery / bootstrap).
 
 # -*- coding: utf-8 -*-
 from __future__ import unicode_literals
+import os
+import json
 
 from django.utils.translation import gettext_lazy as _
 from django.template.loader import render_to_string
 from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
 from django.urls import reverse_lazy
 from django.shortcuts import redirect
+from django.conf import settings
 
 from django.contrib.auth.mixins import PermissionRequiredMixin
 
@@ -802,6 +805,13 @@ class SettingsView(TemplateView):
         except:
             ctx["rates_updated"] = None
 
+        # load locale stats
+        STAT_FILE = os.path.abspath(os.path.join(settings.BASE_DIR, 'InvenTree/locale_stats.json'))
+        try:
+            ctx["locale_stats"] = json.load(open(STAT_FILE, 'r'))
+        except:
+            ctx["locale_stats"] = {}
+
         return ctx
 
 
diff --git a/InvenTree/templates/InvenTree/settings/user.html b/InvenTree/templates/InvenTree/settings/user.html
index aa3f7f079c..922e9ebc79 100644
--- a/InvenTree/templates/InvenTree/settings/user.html
+++ b/InvenTree/templates/InvenTree/settings/user.html
@@ -81,8 +81,15 @@
                     {% get_available_languages as LANGUAGES %}
                     {% get_language_info_list for LANGUAGES as languages %}
                     {% for language in languages %}
-                        <option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
-                            {{ language.name_local }} ({{ language.code }})
+                        {% define language.code as lang_code %}
+                        {% define locale_stats|keyvalue:lang_code as lang_translated %}
+                        <option value="{{ lang_code }}"{% if lang_code == LANGUAGE_CODE %} selected{% endif %}>
+                            {{ language.name_local }} ({{ lang_code }}) 
+                            {% if lang_translated %}
+                                {% blocktrans %}{{ lang_translated }}% translated{% endblocktrans %}
+                            {% else %}
+                                {% trans 'No translations available' %}
+                            {% endif %}
                         </option>
                     {% endfor %}
                 </select>
@@ -92,7 +99,7 @@
             </div>
         </form>
     </div>
-    <div class="col">
+    <div class="col-sm-6">
         <h4>{% trans "Help the translation efforts!" %}</h4>
         <p>{% blocktrans with link="https://crowdin.com/project/inventree" %}Native language translation of the InvenTree web application is <a href="{{link}}">community contributed via crowdin</a>. Contributions are welcomed and encouraged.{% endblocktrans %}</p>
     </div>

From d6c6cb96ba10c82cafc55eb63bbe48e64bce3946 Mon Sep 17 00:00:00 2001
From: Matthias <matthias.mair@oewf.org>
Date: Thu, 5 Aug 2021 01:24:49 +0200
Subject: [PATCH 5/6] make keyvalue non-existing key tolerant

---
 InvenTree/part/templatetags/inventree_extras.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py
index 5ebc939305..dce3d248e5 100644
--- a/InvenTree/part/templatetags/inventree_extras.py
+++ b/InvenTree/part/templatetags/inventree_extras.py
@@ -269,7 +269,7 @@ def keyvalue(dict, key):
     usage:
     {% mydict|keyvalue:mykey %}
     """
-    return dict[key]
+    return dict.get(key)
 
 
 @register.simple_tag()

From 6234581fab18e247f01265db17264757caf73695 Mon Sep 17 00:00:00 2001
From: Oliver <oliver.henry.walters@gmail.com>
Date: Sat, 7 Aug 2021 11:16:37 +1000
Subject: [PATCH 6/6] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 2a23ab608e..7ace518175 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ However, powerful business logic works in the background to ensure that stock tr
 
 InvenTree is [available via Docker](https://hub.docker.com/r/inventree/inventree). Read the [docker guide](https://inventree.readthedocs.io/en/latest/start/docker/) for full details.
 
-# Companion App
+# Mobile App
 
 InvenTree is supported by a [companion mobile app](https://inventree.readthedocs.io/en/latest/app/app/) which allows users access to stock control information and functionality.