Compare commits

..

3 commits

59 changed files with 1192 additions and 274 deletions

1
.gitignore vendored
View file

@ -2,6 +2,7 @@
__pycache__
.python_version
*.egg-info
*.mo
media/
./static/

View file

@ -28,9 +28,16 @@ following might sound familiar:
- ForgeJo: `git clone https://git.dunkelstern.de/dunkelstern/inventory.git`
2. Change to checkout: `cd inventory`
3. Install virtualenv and dependencies: `poetry install --no-root`
4. Migrate the Database: `poetry run python manage.py migrate`
5. Create an admin user: `poetry run python manage.py createsuperuser`
6. Run the server
4. If you want to use the system in another language than the default english set it
up in the `inventory_project/settings.py`:
```python
LANGUAGE_CODE = 'en-us' # or something like 'de-de'
```
see the settings file for defined languages.
5. If you changed the language rebuild the translation files: `poetry run python manage.py compilemessages`
6. Migrate the Database: `poetry run python manage.py migrate`
7. Create an admin user: `poetry run python manage.py createsuperuser`
8. Run the server
- Development server (not for deployment!): `poetry run python manage.py runserver`
- Deployment via `gunicorn` on port 8000: `poetry run gunicorn inventory_project.wsgi -b 0.0.0.0:8000`
@ -51,6 +58,16 @@ go to `http://localhost:8000` to enter the inventory management system directly
[the service file](inventory.service) in the root of this repository for an
example.
### Changelog
#### 1.1
- Part count can be configured to be available in settings
- Currency can be configured in settings
- Complete system is translateable (English and German are provided)
![Settings](docs/settings.jpeg)
### Screenshots
#### Login

BIN
docs/settings.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View file

@ -3,7 +3,7 @@ from django.shortcuts import redirect
from django.contrib import admin
from django.conf import settings
from inventory.models import Item, Documentation
from inventory.models import Item, Documentation, Settings
class DocumentationAdmin(admin.ModelAdmin):
@ -19,6 +19,12 @@ class ItemAdmin(admin.ModelAdmin):
readonly_fields = ['created_at', 'changed_at']
filter_horizontal = ('tags', 'documentation')
def get_exclude(self, request, obj=None):
s = Settings.objects.first()
if (s.track_amount):
return self.exclude
return (self.exclude or tuple()) + ('count', 'low_count')
def view_on_site(self, obj):
url = reverse('item-detail', kwargs={'pk': obj.id})
return settings.SERVER_URL + url

View file

@ -0,0 +1,561 @@
# Translation for Inventory management system
# Copyright (C) 2025 Johannes Schriewer
# This file is distributed under the same license as the Inventory package.
# Johannes Schriewer <hallo@dunkelstern.de>, 2025
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-01-07 23:07+0100\n"
"PO-Revision-Date: 2025-01-07 23:00+0100\n"
"Last-Translator: Johannes Schriewer <hallo@dunkelstern.de>\n"
"Language: German\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: .\inventory\models\area.py:8 .\inventory\models\box.py:10
#: .\inventory\models\distributor.py:6 .\inventory\models\documentation.py:6
#: .\inventory\models\form_factor.py:6 .\inventory\models\item.py:8
#: .\inventory\models\layout.py:6 .\inventory\models\manufacturer.py:6
#: .\inventory\models\tag.py:6 .\inventory\models\workshop.py:8
#: .\inventory\templates\inventory\distributor_detail.html:26
#: .\inventory\templates\inventory\item_detail.html:27
#: .\inventory\templates\inventory\item_list.html:7
#: .\inventory\templates\inventory\manufacturer_detail.html:26
msgid "Name"
msgstr "Name"
#: .\inventory\models\area.py:9 .\inventory\models\box.py:11
#: .\inventory\models\distributor.py:7 .\inventory\models\form_factor.py:7
#: .\inventory\models\item.py:9 .\inventory\models\layout.py:7
#: .\inventory\models\manufacturer.py:7 .\inventory\models\tag.py:7
#: .\inventory\models\workshop.py:9
#: .\inventory\templates\inventory\distributor_detail.html:30
#: .\inventory\templates\inventory\item_detail.html:31
#: .\inventory\templates\inventory\item_list.html:9
#: .\inventory\templates\inventory\manufacturer_detail.html:30
msgid "Description"
msgstr "Beschreibung"
#: .\inventory\models\area.py:11
msgid "Show sub area"
msgstr "Unterbereiche anzeigen"
#: .\inventory\models\area.py:13
msgid "Allow sub-areas to be defined in this area"
msgstr "Erlaube Unterbereiche in diesem Bereich"
#: .\inventory\models\area.py:15 .\inventory\models\box.py:14
#: .\inventory\models\distributor.py:16 .\inventory\models\documentation.py:7
#: .\inventory\models\form_factor.py:13 .\inventory\models\item.py:76
#: .\inventory\models\layout.py:8 .\inventory\models\manufacturer.py:13
#: .\inventory\models\tag.py:8 .\inventory\models\workshop.py:17
#: .\inventory\templates\inventory\distributor_detail.html:89
#: .\inventory\templates\inventory\item_detail.html:128
#: .\inventory\templates\inventory\manufacturer_detail.html:57
msgid "Created at"
msgstr "Erstellt am"
#: .\inventory\models\area.py:16 .\inventory\models\box.py:15
#: .\inventory\models\distributor.py:17 .\inventory\models\documentation.py:8
#: .\inventory\models\form_factor.py:14 .\inventory\models\item.py:77
#: .\inventory\models\layout.py:9 .\inventory\models\manufacturer.py:14
#: .\inventory\models\tag.py:9 .\inventory\models\workshop.py:18
#: .\inventory\templates\inventory\distributor_detail.html:91
#: .\inventory\templates\inventory\item_detail.html:130
#: .\inventory\templates\inventory\manufacturer_detail.html:59
msgid "Changed at"
msgstr "Geändert am"
#: .\inventory\models\area.py:24
msgid "Area"
msgstr "Bereich"
#: .\inventory\models\area.py:25
#: .\inventory\templates\inventory\area_detail.html:25
#: .\inventory\templates\inventory\workshop_detail.html:23
msgid "Areas"
msgstr "Bereiche"
#: .\inventory\models\box.py:12 .\inventory\models\distributor.py:14
#: .\inventory\models\form_factor.py:11 .\inventory\models\item.py:58
#: .\inventory\models\manufacturer.py:11 .\inventory\models\tag.py:17
#: .\inventory\models\workshop.py:15 .\inventory\templates\base.html:58
#: .\inventory\templates\inventory\distributor_detail.html:77
#: .\inventory\templates\inventory\item_detail.html:54
#: .\inventory\templates\inventory\manufacturer_detail.html:45
#: .\inventory\templates\inventory\tag_list.html:9
msgid "Tags"
msgstr "Tags"
#: .\inventory\models\box.py:35
msgid "Box"
msgstr "Kisten"
#: .\inventory\models\box.py:36
#: .\inventory\templates\inventory\box-generic.html:7
#: .\inventory\templates\inventory\tag_detail.html:43
msgid "Boxes"
msgstr "Kisten"
#: .\inventory\models\container.py:9 .\inventory\models\layout.py:18
msgid "Layout"
msgstr "Layout"
#: .\inventory\models\container.py:35 .\inventory\models\container.py:45
#: .\inventory\models\container.py:51
#: .\inventory\templates\inventory\item_list.html:10
msgid "Container"
msgstr "Behälter"
#: .\inventory\models\container.py:46
#: .\inventory\templates\inventory\area_detail.html:51
#: .\inventory\templates\inventory\workshop_detail.html:49
msgid "Containers"
msgstr "Behälter"
#: .\inventory\models\container.py:56
msgid "Index of compartment in layout"
msgstr "Index des Abteils im Layout"
#: .\inventory\models\distributor.py:9 .\inventory\models\manufacturer.py:9
#: .\inventory\templates\inventory\distributor_detail.html:40
#: .\inventory\templates\inventory\manufacturer_detail.html:40
msgid "Web link"
msgstr "Web link"
#: .\inventory\models\distributor.py:10
#: .\inventory\templates\inventory\item_detail.html:121
msgid "Search link"
msgstr "Such-link"
#: .\inventory\models\distributor.py:10
msgid "Use {} for search placeholder"
msgstr "Benutze {} oder {0} als Platzhalter"
#: .\inventory\models\distributor.py:11
#: .\inventory\templates\inventory\distributor_detail.html:65
msgid "Phone"
msgstr "Telefon"
#: .\inventory\models\distributor.py:12
#: .\inventory\templates\inventory\distributor_detail.html:71
msgid "E-Mail"
msgstr "E-Mail"
#: .\inventory\models\distributor.py:13 .\inventory\models\form_factor.py:9
#: .\inventory\models\manufacturer.py:10
#: .\inventory\templates\inventory\distributor_detail.html:35
#: .\inventory\templates\inventory\distributor_list.html:15
#: .\inventory\templates\inventory\manufacturer_detail.html:35
#: .\inventory\templates\inventory\manufacturer_list.html:15
msgid "Icon"
msgstr "Symbol"
#: .\inventory\models\distributor.py:24 .\inventory\models\item.py:31
#: .\inventory\templates\inventory\distributor_detail.html:6
#: .\inventory\templates\inventory\distributor_detail.html:10
#: .\inventory\templates\inventory\distributor_list.html:16
#: .\inventory\templates\inventory\item_detail.html:96
#: .\inventory\templates\inventory\item_list.html:15
msgid "Distributor"
msgstr "Händler"
#: .\inventory\models\distributor.py:25 .\inventory\templates\base.html:55
#: .\inventory\templates\inventory\distributor_list.html:5
#: .\inventory\templates\inventory\distributor_list.html:8
#: .\inventory\templates\inventory\tag_detail.html:63
msgid "Distributors"
msgstr "Händler"
#: .\inventory\models\documentation.py:17
#: .\inventory\models\documentation.py:18 .\inventory\models\item.py:52
#: .\inventory\templates\inventory\item_detail.html:135
msgid "Documentation"
msgstr "Dokumentation"
#: .\inventory\models\form_factor.py:10
#: .\inventory\templates\inventory\cell.html:16
#: .\inventory\templates\inventory\item_list.html:25
#: .\inventory\templates\inventory\search_result_item.html:6
msgid "Datasheet"
msgstr "Datenblatt"
#: .\inventory\models\form_factor.py:23 .\inventory\models\item.py:17
#: .\inventory\templates\inventory\item_detail.html:68
msgid "Form factor"
msgstr "Formfaktor"
#: .\inventory\models\form_factor.py:24
#: .\inventory\templates\inventory\tag_detail.html:121
msgid "Form factors"
msgstr "Formfaktoren"
#: .\inventory\models\item.py:11
msgid "Size"
msgstr "Größe"
#: .\inventory\models\item.py:13
msgid "Number of sub-compartments this item takes up"
msgstr "Anzahl der Unterteilungen die dieses Teil benötigt"
#: .\inventory\models\item.py:24 .\inventory\models\manufacturer.py:21
#: .\inventory\templates\inventory\item_detail.html:85
#: .\inventory\templates\inventory\item_list.html:12
#: .\inventory\templates\inventory\manufacturer_detail.html:6
#: .\inventory\templates\inventory\manufacturer_detail.html:10
#: .\inventory\templates\inventory\manufacturer_list.html:16
msgid "Manufacturer"
msgstr "Hersteller"
#: .\inventory\models\item.py:37
msgid "Distributor item no."
msgstr "Händler Bestellnummer"
#: .\inventory\models\item.py:43
#: .\inventory\templates\inventory\item_detail.html:107
msgid "Price"
msgstr "Preis"
#: .\inventory\models\item.py:49
msgid "Last ordered on"
msgstr "Zuletzt bestellt am"
#: .\inventory\models\item.py:63
msgid "Count"
msgstr "Anzahl"
#: .\inventory\models\item.py:66
msgid "Number of parts available"
msgstr "Anzahl der verfügbaren Teile"
#: .\inventory\models\item.py:69
#: .\inventory\templates\inventory\item_detail.html:49
msgid "Low watermark"
msgstr "Bestellgrenze"
#: .\inventory\models\item.py:72
msgid "Low watermark on which to alert ordering more"
msgstr "Untere Grenze ab der das Teil nachbestellt werden soll"
#: .\inventory\models\item.py:75
msgid "Custom metadata, used by templates"
msgstr "Metadaten die in der Vorlage verwendet werden können"
#: .\inventory\models\item.py:98
msgid "Item"
msgstr "Teil"
#: .\inventory\models\item.py:99
#: .\inventory\templates\inventory\box-generic.html:16
#: .\inventory\templates\inventory\manufacturer_detail.html:64
#: .\inventory\templates\inventory\tag_detail.html:113
msgid "Items"
msgstr "Teile"
#: .\inventory\models\layout.py:10
msgid "Data"
msgstr "Konfiguration"
#: .\inventory\models\layout.py:11
msgid "Template name"
msgstr "Vorlage"
#: .\inventory\models\layout.py:19
msgid "Layouts"
msgstr "Layouts"
#: .\inventory\models\manufacturer.py:22 .\inventory\templates\base.html:52
#: .\inventory\templates\inventory\manufacturer_list.html:5
#: .\inventory\templates\inventory\manufacturer_list.html:8
#: .\inventory\templates\inventory\tag_detail.html:88
msgid "Manufacturers"
msgstr "Hersteller"
#: .\inventory\models\settings.py:13
msgid "Default container to display when calling the index page"
msgstr "Standardbehälter der beim Aufruf der Index-Seite gezeigt werden soll"
#: .\inventory\models\settings.py:17
msgid "Show item count in overview and warn on low watermarks"
msgstr "Aktiviere die Mengenangaben und Nachbestellgrenzen"
#: .\inventory\models\settings.py:19
msgid "Currency"
msgstr "Währung"
#: .\inventory\models\settings.py:19
msgid "Currency name"
msgstr "Name der Währung"
#: .\inventory\models\settings.py:20
msgid "Currency symbol"
msgstr "Währungssymbol"
#: .\inventory\models\settings.py:22
msgid "Currency symbol at end"
msgstr "Währungssymbol am Ende"
#: .\inventory\models\settings.py:24
msgid "Currency symbol after amount"
msgstr "Zeige das Währungssymbol nach der Zahl an"
#: .\inventory\models\settings.py:28 .\inventory\models\settings.py:31
#: .\inventory\models\settings.py:32
msgid "Settings"
msgstr "Einstellungen"
#: .\inventory\models\tag.py:16
#: .\inventory\templates\inventory\tag_detail.html:5
msgid "Tag"
msgstr "Tag"
#: .\inventory\models\workshop.py:11
msgid "Show boxes"
msgstr "Behälter anzeigen"
#: .\inventory\models\workshop.py:13
msgid "Allow boxes to be defined directly in this workshop"
msgstr "Erlaube Behälter in dieser Werkstatt"
#: .\inventory\models\workshop.py:26 .\inventory\templates\base.html:61
#: .\inventory\templates\inventory\workshop_detail.html:5
msgid "Workshop"
msgstr "Werkstatt"
#: .\inventory\models\workshop.py:27
#: .\inventory\templates\inventory\tag_detail.html:23
#: .\inventory\templates\inventory\workshop_list.html:5
#: .\inventory\templates\inventory\workshop_list.html:8
msgid "Workshops"
msgstr "Werkstätten"
#: .\inventory\templates\base.html:43 .\inventory\templates\base.html:46
#: .\inventory\templates\base.html:47
#: .\inventory\templates\inventory\distributor_detail.html:45
#: .\inventory\templates\inventory\distributor_detail.html:58
#: .\inventory\templates\inventory\search.html:5
#: .\inventory\templates\inventory\search.html:8
#: .\inventory\templates\inventory\search.html:13
#: .\inventory\templates\inventory\search.html:14
#: .\inventory\templates\inventory\search_result.html:6
#: .\inventory\templates\inventory\search_result.html:9
#: .\inventory\templates\inventory\search_result.html:14
#: .\inventory\templates\inventory\search_result.html:15
#: .\inventory\templates\inventory\tag_list.html:43
#: .\inventory\templates\inventory\tag_list.html:44
msgid "Search"
msgstr "Suchen"
#: .\inventory\templates\base.html:68
msgid "Logout"
msgstr "Ausloggen"
#: .\inventory\templates\inventory\area_detail.html:16
#: .\inventory\templates\inventory\area_detail.html:36
#: .\inventory\templates\inventory\area_detail.html:62
#: .\inventory\templates\inventory\box-detail.html:20
#: .\inventory\templates\inventory\cell.html:19
#: .\inventory\templates\inventory\distributor_detail.html:17
#: .\inventory\templates\inventory\distributor_list.html:33
#: .\inventory\templates\inventory\item_detail.html:18
#: .\inventory\templates\inventory\item_list.html:28
#: .\inventory\templates\inventory\manufacturer_detail.html:17
#: .\inventory\templates\inventory\manufacturer_list.html:33
#: .\inventory\templates\inventory\tag_detail.html:16
#: .\inventory\templates\inventory\tag_detail.html:33
#: .\inventory\templates\inventory\tag_detail.html:53
#: .\inventory\templates\inventory\tag_detail.html:78
#: .\inventory\templates\inventory\tag_detail.html:103
#: .\inventory\templates\inventory\workshop_detail.html:16
#: .\inventory\templates\inventory\workshop_detail.html:34
#: .\inventory\templates\inventory\workshop_detail.html:59
#: .\inventory\templates\inventory\workshop_list.html:21
msgid "Edit"
msgstr "Bearbeiten"
#: .\inventory\templates\inventory\area_detail.html:41
#: .\inventory\templates\inventory\workshop_detail.html:39
msgid "No areas defined"
msgstr "Keine Bereiche definiert"
#: .\inventory\templates\inventory\area_detail.html:47
#: .\inventory\templates\inventory\workshop_detail.html:45
msgid "Create new area..."
msgstr "Neuen Bereich anlegen..."
#: .\inventory\templates\inventory\area_detail.html:67
#: .\inventory\templates\inventory\workshop_detail.html:64
msgid "No containers defined"
msgstr "Keine Behälter definiert..."
#: .\inventory\templates\inventory\area_detail.html:73
#: .\inventory\templates\inventory\workshop_detail.html:70
msgid "Create new container..."
msgstr "Neuen Behälter anlegen..."
#: .\inventory\templates\inventory\box-detail.html:12
#: .\inventory\templates\inventory\distributor_detail.html:9
#: .\inventory\templates\inventory\item_detail.html:10
#: .\inventory\templates\inventory\manufacturer_detail.html:9
#: .\inventory\templates\inventory\tag_detail.html:8
#: .\inventory\templates\inventory\workshop_detail.html:8
msgid "Back"
msgstr "Zurück"
#: .\inventory\templates\inventory\cell.html:21
msgid "Details"
msgstr "Details"
#: .\inventory\templates\inventory\cell.html:26
#: .\inventory\templates\inventory\item_detail.html:42
msgid "Low stock"
msgstr "Wenig Vorrat"
#: .\inventory\templates\inventory\cell.html:43
msgid "New item..."
msgstr "Neues Teil..."
#: .\inventory\templates\inventory\distributor_detail.html:57
msgid "Search query"
msgstr "Suchanfrage"
#: .\inventory\templates\inventory\distributor_detail.html:83
#: .\inventory\templates\inventory\item_detail.html:60
#: .\inventory\templates\inventory\manufacturer_detail.html:51
#: .\inventory\templates\inventory\tag_list.html:50
msgid "No tags"
msgstr "Keine Tags"
#: .\inventory\templates\inventory\distributor_list.html:8
#: .\inventory\templates\inventory\tag_list.html:9
#: .\inventory\templates\inventory\workshop_list.html:8
#: .\inventory\templates\registration\login.html:5
msgid "Inventory management"
msgstr "Inventarverwaltung"
#: .\inventory\templates\inventory\distributor_list.html:43
msgid "Create new distributor..."
msgstr "Neuen Händler anlegen..."
#: .\inventory\templates\inventory\item_detail.html:36
#: .\inventory\templates\inventory\item_detail.html:45
msgid "Amount"
msgstr "Anzahl"
#: .\inventory\templates\inventory\item_detail.html:46
msgid "Update"
msgstr "Speichern"
#: .\inventory\templates\inventory\item_detail.html:108
msgid "Sum"
msgstr "Summe"
#: .\inventory\templates\inventory\item_detail.html:114
msgid "Last ordered"
msgstr "Zuletzt bestellt"
#: .\inventory\templates\inventory\manufacturer_list.html:8
msgid "Inventory Management"
msgstr "Inventarverwaltung"
#: .\inventory\templates\inventory\manufacturer_list.html:42
msgid "Create new manufacturer..."
msgstr "Neuen Hersteller anlegen..."
#: .\inventory\templates\inventory\pagination.html:6
#: .\inventory\templates\inventory\search_result.html:33
msgid "First page"
msgstr "Erste Seite"
#: .\inventory\templates\inventory\pagination.html:7
#: .\inventory\templates\inventory\search_result.html:34
msgid "Previous page"
msgstr "Vorherige Seite"
#: .\inventory\templates\inventory\pagination.html:13
#: .\inventory\templates\inventory\search_result.html:38
msgid "Next page"
msgstr "Nächste Seite"
#: .\inventory\templates\inventory\pagination.html:14
#: .\inventory\templates\inventory\search_result.html:39
msgid "Last page"
msgstr "Letzte Seite"
#: .\inventory\templates\inventory\search_result.html:18
msgid "Search result for"
msgstr "Suchergebnisse für"
#: .\inventory\templates\inventory\search_result.html:27
msgid "Nothing found"
msgstr "Nichts gefunden"
#: .\inventory\templates\inventory\search_result_item.html:11
msgid "Contained in"
msgstr "Im Behälter"
#: .\inventory\templates\inventory\set_index.html:10
msgid "Currently set as index page"
msgstr "Momentan als Index-Seite definiert"
#: .\inventory\templates\inventory\set_index.html:12
msgid "Promote to index page"
msgstr "Als Index-Seite definieren"
#: .\inventory\templates\inventory\tag_list.html:55
msgid "Create new tag..."
msgstr "Neues Tag anlegen..."
#: .\inventory\templates\inventory\workshop_list.html:30
msgid "Create new workshop..."
msgstr "Neue Werkstatt anlegen..."
#: .\inventory\templates\registration\login.html:5
msgid "Login"
msgstr "Einloggen"
#: .\inventory\templates\registration\login.html:11
msgid "Your username and password didn't match. Please try again."
msgstr ""
"Benutzername und Passwort passen nicht zusammen, bitte versuche es noch "
"einmal."
#: .\inventory\templates\registration\login.html:17
msgid ""
"\n"
" Your account doesn't have access to this page. To proceed,\n"
" please login with an account that has access.\n"
" "
msgstr ""
"\n"
" Dein Zugang hat keinen Zugriff auf diese Seite.\n"
" Zum Fortfahren bitte mit einem Zugang einloggen der die\n"
" entsprechenden Rechte besitzt!\n"
" "
#: .\inventory\templates\registration\login.html:24
msgid ""
"\n"
" Please login to see this page.\n"
" "
msgstr ""
"\n"
" Bitte einloggen um auf diese Seite Zugriff zu bekommen.\n"
" "
#: .\inventory\templates\registration\login.html:49
msgid "Lost password?"
msgstr "Passwort vergessen?"
#: .\inventory_project\settings.py:121
msgid "German"
msgstr "Deutsch"
#: .\inventory_project\settings.py:122
msgid "English"
msgstr "Englisch"

View file

@ -0,0 +1,23 @@
# Generated by Django 5.1.4 on 2025-01-07 17:20
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0005_alter_sorting_collation'),
]
operations = [
migrations.AddField(
model_name='item',
name='count',
field=models.PositiveIntegerField(default=1, help_text='Number of parts available'),
),
migrations.AddField(
model_name='item',
name='low_count',
field=models.PositiveIntegerField(default=0, help_text='Low watermark on which to alert ordering more'),
),
]

View file

@ -0,0 +1,18 @@
# Generated by Django 5.1.4 on 2025-01-07 17:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0006_item_count_item_low_count'),
]
operations = [
migrations.AddField(
model_name='settings',
name='track_amount',
field=models.BooleanField(default=False, help_text='Show item count in overview and warn on low watermarks'),
),
]

View file

@ -0,0 +1,28 @@
# Generated by Django 5.1.4 on 2025-01-07 18:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('inventory', '0007_settings_track_amount'),
]
operations = [
migrations.AddField(
model_name='settings',
name='currency',
field=models.CharField(default='Euro', help_text='Currency name', max_length=30),
),
migrations.AddField(
model_name='settings',
name='currency_symbol',
field=models.CharField(default='&euro;', help_text='Currency symbol', max_length=20),
),
migrations.AddField(
model_name='settings',
name='currency_symbol_position',
field=models.BooleanField(default=True, help_text='Currency symbol after amount'),
),
]

View file

@ -1,14 +1,19 @@
from django.utils.translation import gettext_lazy as _
from django.urls import reverse
from django.db import models
from .container import Container, CanBeContained
class Area(CanBeContained, Container):
name = models.CharField(max_length=255, unique=True)
description = models.CharField(max_length=4096)
show_sub_area = models.BooleanField(default=True, help_text="Allow sub-areas to be defined in this area")
created_at = models.DateTimeField(auto_now_add=True)
changed_at = models.DateTimeField(auto_now=True)
name = models.CharField(_("Name"), max_length=255, unique=True)
description = models.CharField(_("Description"), max_length=4096)
show_sub_area = models.BooleanField(
_("Show sub area"),
default=True,
help_text=_("Allow sub-areas to be defined in this area")
)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True)
changed_at = models.DateTimeField(_("Changed at"), auto_now=True)
@property
def url(self):
@ -16,3 +21,5 @@ class Area(CanBeContained, Container):
class Meta:
ordering = ("name", )
verbose_name = _("Area")
verbose_name_plural = _("Areas")

View file

@ -1,3 +1,4 @@
from django.utils.translation import gettext_lazy as _
from django.urls import reverse
from django.utils.text import slugify
from django.template.loader import get_template, TemplateDoesNotExist
@ -6,15 +7,12 @@ from .container import CanBeContained, Container
class Box(CanBeContained, Container):
name = models.CharField(max_length=255, unique=True)
description = models.CharField(max_length=4096)
tags = models.ManyToManyField('inventory.Tag', blank=True)
name = models.CharField(_("Name"), max_length=255, unique=True)
description = models.CharField(_("Description"), max_length=4096)
tags = models.ManyToManyField('inventory.Tag', verbose_name=_("Tags"), blank=True)
created_at = models.DateTimeField(auto_now_add=True)
changed_at = models.DateTimeField(auto_now=True)
class Meta:
verbose_name_plural = 'Boxes'
created_at = models.DateTimeField(_("Created at"), auto_now_add=True)
changed_at = models.DateTimeField(_("Changed at"), auto_now=True)
@property
def template_name(self):
@ -34,3 +32,5 @@ class Box(CanBeContained, Container):
class Meta:
ordering = ("name", )
verbose_name = _("Box")
verbose_name_plural = _("Boxes")

View file

@ -1,9 +1,16 @@
from django.utils.translation import gettext_lazy as _
from django.db import models
from django.apps import apps
class Container(models.Model):
layout = models.ForeignKey('inventory.Layout', on_delete=models.PROTECT, null=True, blank=True)
layout = models.ForeignKey(
'inventory.Layout',
verbose_name=_("Layout"),
on_delete=models.PROTECT,
null=True,
blank=True
)
@property
def subclass(self):
@ -25,7 +32,7 @@ class Container(models.Model):
_, obj = self.subclass
if obj is not None:
return obj.name
return 'Container'
return _("Container")
@property
def url(self):
@ -34,15 +41,19 @@ class Container(models.Model):
return obj.url
return None
class Meta:
verbose_name = _("Container")
verbose_name_plural = _("Containers")
class CanBeContained(models.Model):
container = models.ForeignKey(
'inventory.Container',
verbose_name=_("Container"),
related_name="%(class)s_related",
null=True,
on_delete=models.CASCADE
)
index = models.PositiveIntegerField('Index of compartment in layout')
index = models.PositiveIntegerField(_("Index of compartment in layout"))
class Meta:
abstract = True

View file

@ -1,22 +1,25 @@
from django.utils.translation import gettext_lazy as _
from django.db import models
class Distributor(models.Model):
name = models.CharField(max_length=255, unique=True)
description = models.CharField(max_length=4096)
name = models.CharField(_("Name"), max_length=255, unique=True)
description = models.CharField(_("Description"), max_length=4096)
web_link = models.URLField(null=True, blank=True)
search_link = models.URLField(help_text='Use {} for search placeholder', null=True, blank=True)
phone = models.CharField(max_length=128, null=True, blank=True)
email = models.EmailField(null=True, blank=True, default=None)
icon = models.ImageField(null=True, blank=True)
tags = models.ManyToManyField('inventory.Tag', blank=True)
web_link = models.URLField(_("Web link"), null=True, blank=True)
search_link = models.URLField(_("Search link"), help_text=_("Use {} for search placeholder"), null=True, blank=True)
phone = models.CharField(_("Phone"), max_length=128, null=True, blank=True)
email = models.EmailField(_("E-Mail"), null=True, blank=True, default=None)
icon = models.ImageField(_("Icon"), null=True, blank=True)
tags = models.ManyToManyField('inventory.Tag', verbose_name=_("Tags"), blank=True)
created_at = models.DateTimeField(auto_now_add=True)
changed_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True)
changed_at = models.DateTimeField(_("Changed at"), auto_now=True)
def __str__(self):
return self.name
class Meta:
ordering = ("name", )
ordering = ("name", )
verbose_name = _("Distributor")
verbose_name_plural = _("Distributors")

View file

@ -1,10 +1,11 @@
from django.utils.translation import gettext_lazy as _
from django.db import models
class Documentation(models.Model):
name = models.CharField(max_length=255, unique=True)
created_at = models.DateTimeField(auto_now_add=True)
changed_at = models.DateTimeField(auto_now=True)
name = models.CharField(_("Name"), max_length=255, unique=True)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True)
changed_at = models.DateTimeField(_("Changed at"), auto_now=True)
file = models.FileField()
@ -13,3 +14,5 @@ class Documentation(models.Model):
class Meta:
ordering = ("name", )
verbose_name = _("Documentation")
verbose_name_plural = _("Documentation")

View file

@ -1,16 +1,17 @@
from django.utils.translation import gettext_lazy as _
from django.db import models
class FormFactor(models.Model):
name = models.CharField(max_length=255, unique=True, db_collation="numeric")
description = models.CharField(max_length=4096, db_collation="numeric")
name = models.CharField(_("Name"), max_length=255, unique=True, db_collation="numeric")
description = models.CharField(_("Description"), max_length=4096, db_collation="numeric")
icon = models.ImageField(null=True, blank=True)
datasheet = models.FileField(null=True, blank=True)
tags = models.ManyToManyField('inventory.Tag', blank=True)
icon = models.ImageField(_("Icon"), null=True, blank=True)
datasheet = models.FileField(_("Datasheet"), null=True, blank=True)
tags = models.ManyToManyField('inventory.Tag', verbose_name=_("Tags"), blank=True)
created_at = models.DateTimeField(auto_now_add=True)
changed_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True)
changed_at = models.DateTimeField(_("Changed at"), auto_now=True)
def __str__(self):
items = [self.name]
@ -19,3 +20,5 @@ class FormFactor(models.Model):
class Meta:
ordering = ("name", )
verbose_name = _("Form factor")
verbose_name_plural = _("Form factors")

View file

@ -1,24 +1,80 @@
from django.utils.translation import gettext_lazy as _
from django.db import models
from .container import CanBeContained
class Item(CanBeContained):
name = models.TextField(max_length=255, db_collation="numeric")
description = models.CharField(max_length=4096, db_collation="numeric")
size = models.PositiveIntegerField(default=1, help_text="Number of sub-compartments this item takes up")
form_factor = models.ForeignKey('inventory.FormFactor', null=True, blank=True, on_delete=models.PROTECT)
manufacturer = models.ForeignKey('inventory.Manufacturer', null=True, blank=True, on_delete=models.PROTECT)
distributor = models.ForeignKey('inventory.Distributor', null=True, blank=True, on_delete=models.PROTECT)
distributor_item_no = models.CharField(max_length=255, null=True, blank=True)
price = models.DecimalField(decimal_places=3, max_digits=7, null=True, blank=True)
last_ordered_on = models.DateField(null=True, blank=True)
documentation = models.ManyToManyField('inventory.Documentation', related_name='items', blank=True)
tags = models.ManyToManyField('inventory.Tag', blank=True)
name = models.TextField(_("Name"), max_length=255, db_collation="numeric")
description = models.CharField(_("Description"), max_length=4096, db_collation="numeric")
size = models.PositiveIntegerField(
_("Size"),
default=1,
help_text=_("Number of sub-compartments this item takes up")
)
form_factor = models.ForeignKey(
'inventory.FormFactor',
verbose_name=_("Form factor"),
null=True,
blank=True,
on_delete=models.PROTECT
)
manufacturer = models.ForeignKey(
'inventory.Manufacturer',
verbose_name=_("Manufacturer"),
null=True,
blank=True,
on_delete=models.PROTECT
)
distributor = models.ForeignKey(
'inventory.Distributor',
verbose_name=_("Distributor"),
null=True,
blank=True,
on_delete=models.PROTECT
)
distributor_item_no = models.CharField(
_("Distributor item no."),
max_length=255,
null=True,
blank=True
)
price = models.DecimalField(
_("Price"),
decimal_places=3,
max_digits=7,
null=True,
blank=True
)
last_ordered_on = models.DateField(_("Last ordered on"), null=True, blank=True)
documentation = models.ManyToManyField(
'inventory.Documentation',
verbose_name=_("Documentation"),
related_name='items',
blank=True
)
tags = models.ManyToManyField(
'inventory.Tag',
verbose_name=_("Tags"),
blank=True
)
metadata = models.JSONField('Custom metadata, used by templates', blank=True, null=True)
created_at = models.DateTimeField(auto_now_add=True)
changed_at = models.DateTimeField(auto_now=True)
count = models.PositiveIntegerField(
_("Count"),
default=1,
null=False,
help_text=_("Number of parts available")
)
low_count = models.PositiveIntegerField(
_("Low watermark"),
default=0,
null=False,
help_text=_("Low watermark on which to alert ordering more")
)
metadata = models.JSONField(_("Custom metadata, used by templates"), blank=True, null=True)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True)
changed_at = models.DateTimeField(_("Changed at"), auto_now=True)
def __str__(self):
items = [self.name, self.description]
@ -32,6 +88,12 @@ class Item(CanBeContained):
return list(self.tags.all()) + list(self.form_factor.tags.all())
else:
return list(self.tags.all())
@property
def value(self):
return self.count * self.price
class Meta:
ordering = ("name", )
verbose_name = _("Item")
verbose_name_plural = _("Items")

View file

@ -1,16 +1,19 @@
from django.utils.translation import gettext_lazy as _
from django.db import models
class Layout(models.Model):
name = models.CharField(max_length=255, unique=True)
description = models.CharField(max_length=4096)
created_at = models.DateTimeField(auto_now_add=True)
changed_at = models.DateTimeField(auto_now=True)
data = models.JSONField()
template_name = models.CharField(max_length=255, null=True, blank=True)
name = models.CharField(_("Name"), max_length=255, unique=True)
description = models.CharField(_("Description"), max_length=4096)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True)
changed_at = models.DateTimeField(_("Changed at"), auto_now=True)
data = models.JSONField(_("Data"))
template_name = models.CharField(_("Template name"), max_length=255, null=True, blank=True)
def __str__(self):
return self.name
class Meta:
ordering = ("name", )
verbose_name = _("Layout")
verbose_name_plural = _("Layouts")

View file

@ -1,19 +1,22 @@
from django.utils.translation import gettext_lazy as _
from django.db import models
class Manufacturer(models.Model):
name = models.CharField(max_length=255, unique=True)
description = models.CharField(max_length=4096, blank=True)
name = models.CharField(_("Name"), max_length=255, unique=True)
description = models.CharField(_("Description"), max_length=4096, blank=True)
web_link = models.URLField(null=True, blank=True)
icon = models.ImageField(null=True, blank=True)
tags = models.ManyToManyField('inventory.Tag', blank=True)
web_link = models.URLField(_("Web link"), null=True, blank=True)
icon = models.ImageField(_("Icon"), null=True, blank=True)
tags = models.ManyToManyField('inventory.Tag', verbose_name=_("Tags"), blank=True)
created_at = models.DateTimeField(auto_now_add=True)
changed_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True)
changed_at = models.DateTimeField(_("Changed at"), auto_now=True)
def __str__(self):
return self.name
class Meta:
ordering = ("name", )
verbose_name = _("Manufacturer")
verbose_name_plural = _("Manufacturers")

View file

@ -1,3 +1,5 @@
from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext
from django.db import models
@ -8,11 +10,23 @@ class Settings(models.Model):
default=None,
null=True,
blank=True,
help_text='Default container to display when calling the index page'
help_text=_("Default container to display when calling the index page")
)
track_amount = models.BooleanField(
default=False,
help_text=_("Show item count in overview and warn on low watermarks")
)
currency = models.CharField(_("Currency"), max_length=30, help_text=_("Currency name"), default="Euro")
currency_symbol = models.CharField(_("Currency symbol"), max_length=20, default="&euro;")
currency_symbol_position = models.BooleanField(
_("Currency symbol at end"),
default=True,
help_text=_("Currency symbol after amount")
)
def __str__(self):
return 'Settings'
return gettext("Settings")
class Meta:
verbose_name_plural = 'Settings'
verbose_name = _("Settings")
verbose_name_plural = _("Settings")

View file

@ -1,14 +1,17 @@
from django.utils.translation import gettext_lazy as _
from django.db import models
class Tag(models.Model):
name = models.CharField(max_length=255, unique=True, db_collation="numeric")
description = models.CharField(max_length=4096, db_collation="numeric")
created_at = models.DateTimeField(auto_now_add=True)
changed_at = models.DateTimeField(auto_now=True)
name = models.CharField(_("Name"), max_length=255, unique=True, db_collation="numeric")
description = models.CharField(_("Description"), max_length=4096, db_collation="numeric")
created_at = models.DateTimeField(_("Created at"), auto_now_add=True)
changed_at = models.DateTimeField(_("Changed at"), auto_now=True)
def __str__(self):
return self.name
class Meta:
ordering = ['name', 'pk']
verbose_name = _("Tag")
verbose_name_plural = _("Tags")

View file

@ -1,16 +1,21 @@
from django.utils.translation import gettext_lazy as _
from django.urls import reverse
from django.db import models
from .container import Container
class Workshop(Container):
name = models.CharField(max_length=255, unique=True)
description = models.CharField(max_length=4096)
show_boxes = models.BooleanField(default=True, help_text="Allow boxes to be defined directly in this workshop")
tags = models.ManyToManyField('inventory.Tag', blank=True)
name = models.CharField(_("Name"), max_length=255, unique=True)
description = models.CharField(_("Description"), max_length=4096)
show_boxes = models.BooleanField(
_("Show boxes"),
default=True,
help_text=_("Allow boxes to be defined directly in this workshop")
)
tags = models.ManyToManyField('inventory.Tag', verbose_name=_("Tags"), blank=True)
created_at = models.DateTimeField(auto_now_add=True)
changed_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(_("Created at"), auto_now_add=True)
changed_at = models.DateTimeField(_("Changed at"), auto_now=True)
@property
def url(self):
@ -18,3 +23,5 @@ class Workshop(Container):
class Meta:
ordering = ("name", )
verbose_name = _("Workshop")
verbose_name_plural = _("Workshops")

View file

@ -89,6 +89,24 @@ td.disabled {
opacity: 0.75;
}
.cell .stock {
position: absolute;
top: 5px;
left: 5px;
display: inline;
font-size: xx-small;
color: #808080;
line-height: 10px;
}
.cell .stock .icon {
display: inline-block;
width: 10px;
height: 10px;
margin: 0 2px 0 0;
vertical-align: text-top;
}
.cell .form_factor {
position: absolute;
display: inline;
@ -153,7 +171,13 @@ td.disabled {
top: 3px;
right: 7px;
}
.cell .stock {
font-size: 75%;
top: 3px;
left: 3px;
}
.cell .price {
font-size: 75%;
bottom: 3px;

View file

@ -26,6 +26,11 @@ table.attribute-list th {
border-style: solid;
}
table.attribute-list .small {
color: #808080;
font-size: xx-small;
}
table.box {
width: 100%;
border-collapse: collapse;
@ -158,8 +163,7 @@ img.icon {
margin-right: 10px;
width: 18px;
height: 18px;
position: relative;
top: 2px;
vertical-align: middle;
}
img.logo {
@ -277,9 +281,6 @@ table.list thead th {
padding: 10px;
}
table.list tbody tr {
}
table.list tbody td {
border-bottom: 1px solid black;
padding: 10px;
@ -322,3 +323,16 @@ table.list tbody td {
font-weight: normal;
color: #808080;
}
div.icon {
width: 18px;
height: 18px;
display: inline-block;
vertical-align: middle;
}
div.warning-icon {
background-color: #c00000;
-webkit-mask: url(/static/inventory/img/warn.svg) no-repeat center;
mask: url(/static/inventory/img/warn.svg) no-repeat center;
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480L40 480c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"/></svg>

After

Width:  |  Height:  |  Size: 542 B

View file

@ -1,6 +1,8 @@
{% load static %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
<!DOCTYPE html>
<html>
<html lang="{{ LANGUAGE_CODE }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
@ -38,32 +40,32 @@
}
}
</script>
<a href="{% url 'search' %}" onclick="showSearch(event)"><img class="icon" title="Search" src="{% static "inventory/img/search.svg" %}"></a>
<a href="{% url 'search' %}" onclick="showSearch(event)"><img class="icon" title="{% translate 'Search' %}" src="{% static "inventory/img/search.svg" %}"></a>
<div id="search-container">
<form action="{% url 'search' %}" method="get">
<input name="q" id="search" type="text" placeholder="Search">
<button type="submit">Search</button>
<input name="q" id="search" type="text" placeholder="{% translate 'Search' %}">
<button type="submit">{% translate 'Search' %}</button>
</form>
</div>
</li>
<li>
<a href="{% url 'manufacturer-list' %}"><img class="icon" title="Manufacturers" src="{% static "inventory/img/manufacturer.svg" %}"></a>
<a href="{% url 'manufacturer-list' %}"><img class="icon" title="{% translate 'Manufacturers' %}" src="{% static "inventory/img/manufacturer.svg" %}"></a>
</li>
<li>
<a href="{% url 'distributor-list' %}"><img class="icon" title="Distributors" src="{% static "inventory/img/distributor.svg" %}"></a>
<a href="{% url 'distributor-list' %}"><img class="icon" title="{% translate 'Distributors' %}" src="{% static "inventory/img/distributor.svg" %}"></a>
</li>
<li>
<a href="{% url 'tag-list' %}"><img class="icon" title="Tags" src="{% static "inventory/img/tags.svg" %}"></a>
<a href="{% url 'tag-list' %}"><img class="icon" title="{% translate 'Tags' %}" src="{% static "inventory/img/tags.svg" %}"></a>
</li>
<li>
<a href="{% url 'index' %}"><img class="icon" title="Workshops" src="{% static "inventory/img/workshop.svg" %}"></a>
<a href="{% url 'index' %}"><img class="icon" title="{% translate 'Workshop' %}" src="{% static "inventory/img/workshop.svg" %}"></a>
</li>
</ul>
{% if user.is_authenticated %}
<form method="POST" action="{% url "logout" %}">
{% csrf_token %}
<button><img class="icon" src="{% static "inventory/img/logout.svg" %}"> Logout</button>
<button type="submit"><img class="icon" src="{% static "inventory/img/logout.svg" %}" title="{% translate 'Logout' %}"> {% translate 'Logout' %}</button>
</form>
{% endif %}
</nav>

View file

@ -1,5 +1,6 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% block title %}{{ area.name }}{% endblock %}
@ -12,7 +13,7 @@
{% block header_icons %}
{% if user.is_staff %}
<li>
<a href="{% url "admin:inventory_area_change" object_id=area.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}"></a>
<a href="{% url "admin:inventory_area_change" object_id=area.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}" title="{% translate 'Edit' %}"></a>
</li>
{% include 'inventory/set_index.html' with item=area is_index=is_index %}
{% endif %}
@ -21,7 +22,7 @@
{% block content %}
{% if area.show_sub_area %}
<h3>Areas</h3>
<h3>{% translate 'Areas' %}</h3>
<table class="list">
<tbody>
@ -32,22 +33,22 @@
</td>
<td>
{% if user.is_staff %}
<a class="edit" href="{% url "admin:inventory_area_change" object_id=a.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}"></a>
<a class="edit" href="{% url "admin:inventory_area_change" object_id=a.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}" title="{% translate 'Edit' %}"></a>
{% endif %}
</td>
</tr>
{% empty %}
<tr><td>No areas defined</td></tr>
<tr><td>{% translate 'No areas defined' %}</td></tr>
{% endfor %}
</tbody>
</table>
{% if user.is_staff %}
<p><a href="{% url "admin:inventory_area_add" %}?container={{ area.id }}&index=0">Create new area...</a></p>
<p><a href="{% url "admin:inventory_area_add" %}?container={{ area.id }}&index=0">{% translate 'Create new area...' %}</a></p>
{% endif %}
{% endif %}
<h3>Containers</h3>
<h3>{% translate 'Containers' %}</h3>
<table class="list">
<tbody>
@ -58,17 +59,17 @@
</td>
<td>
{% if user.is_staff %}
<a class="edit" href="{% url "admin:inventory_box_change" object_id=box.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}"></a>
<a class="edit" href="{% url "admin:inventory_box_change" object_id=box.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}" title="{% translate 'Edit' %}"></a>
{% endif %}
</td>
</tr>
{% empty %}
<tr><td>No containers defined</td></tr>
<tr><td>{% translate 'No containers defined' %}</td></tr>
{% endfor %}
</tbody>
</table>
{% if user.is_staff %}
<p><a href="{% url "admin:inventory_box_add" %}?container={{ area.id }}&index=0">Create new container...</a></p>
<p><a href="{% url "admin:inventory_box_add" %}?container={{ area.id }}&index=0">{% translate 'Create new container...' %}</a></p>
{% endif %}
{% endblock %}

View file

@ -1,5 +1,6 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% block head %}
<link rel="stylesheet" type="text/css" href="{% static "inventory/css/cell.css" %}">
@ -8,7 +9,7 @@
{% block title %}{{ object.name }}{% endblock %}
{% block header_bar %}
<a href="{{ object.container_url }}"><img class="icon" src="{% static "inventory/img/back.svg" %}"></a>
<a href="{{ object.container_url }}"><img class="icon" src="{% static "inventory/img/back.svg" %}" title="{% translate 'Back' %}"></a>
{{ object.name }}
<span class="small">{{ object.description}}</span></h2>
{% endblock %}
@ -16,7 +17,7 @@
{% block header_icons %}
{% if user.is_staff %}
<li>
<a href="{% url "admin:inventory_box_change" object_id=object.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}"></a>
<a href="{% url "admin:inventory_box_change" object_id=object.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}" title="{% translate 'Edit' %}"></a>
</li>
{% include 'inventory/set_index.html' with item=object is_index=is_index %}
{% endif %}

View file

@ -1,9 +1,10 @@
{% extends "inventory/box-detail.html" %}
{% load i18n %}
{% block content %}
{% if box.box_related.exists %}
<h3>Boxes</h3>
<h3>{% translate 'Boxes' %}</h3>
<ul>
{% for b in box.box_related.all %}
<li><a href="{% url 'box-detail' b.id %}" title="{{ b.description }}">{{ b.name }} ({{ b.layout.name }})</a></li>
@ -12,7 +13,7 @@
{% endif %}
{% if box.item_related.exists %}
<h3>Items</h3>
<h3>{% translate 'Items' %}</h3>
<ul>
{% for item in box.item_related.all %}
<li {% if hilight == item.id %}class="hilighted"{% endif %}><a href="{% url 'item-detail' item.id %}" title="{{ item.description }}">{{ item.name }}</a></li>

View file

@ -9,7 +9,7 @@
<td rowspan="2">
<div class="compartments-vertical">
{% for compartment in layouted.0.0 %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -17,7 +17,7 @@
<td class="triple-height" colspan="3">
<div class="compartments">
{% for compartment in layouted.0.1 %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -27,7 +27,7 @@
<td class="triple-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>

View file

@ -9,7 +9,7 @@
<td>
<div class="compartments">
{% for compartment in layouted.0 %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>

View file

@ -10,7 +10,7 @@
<td class="double-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -20,7 +20,7 @@
<td rowspan="2">
<div class="compartments-vertical">
{% for compartment in layouted.1.0 %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -29,7 +29,7 @@
<td class="double-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -40,7 +40,7 @@
<td class="double-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>

View file

@ -11,7 +11,7 @@
<td>
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -27,7 +27,7 @@
<td>
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -42,7 +42,7 @@
<td>
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>

View file

@ -11,7 +11,7 @@
<td class="double-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -27,7 +27,7 @@
<td class="double-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -42,7 +42,7 @@
<td class="double-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>

View file

@ -11,7 +11,7 @@
<td>
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -27,7 +27,7 @@
<td>
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -42,7 +42,7 @@
<td>
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>

View file

@ -11,7 +11,7 @@
<td>
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>

View file

@ -10,7 +10,7 @@
<td>
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>

View file

@ -21,7 +21,7 @@
<td>
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>

View file

@ -10,7 +10,7 @@
<td class="double-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -21,7 +21,7 @@
<td class="double-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -32,7 +32,7 @@
<td class="double-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -45,7 +45,7 @@
<td class="double-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>

View file

@ -10,7 +10,7 @@
<td class="double-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -21,7 +21,7 @@
<td class="double-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -32,7 +32,7 @@
<td class="double-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>
@ -45,7 +45,7 @@
<td class="double-height">
<div class="compartments">
{% for compartment in item %}
{% include "inventory/cell.html" with item=compartment hilight=hilight %}
{% include "inventory/cell.html" with item=compartment hilight=hilight settings=settings %}
{% endfor %}
</div>
</td>

View file

@ -1,5 +1,8 @@
{% load static %}
{% load i18n %}
{% load admin_urls %}
{% load currency %}
<div class="cell{% if hilight == item.id %} search-hilight{% endif %}">
{% if item.name %}
{% if item.metadata.package %}
@ -10,16 +13,23 @@
</a>
<div class="cell-buttons">
{% if item.documentation.all %}
<a class="datasheet" href="{{ item.documentation.all.0.file.url }}"><img class="icon" src="{% static "inventory/img/datasheet.svg" %}"></a>
<a class="datasheet" href="{{ item.documentation.all.0.file.url }}"><img class="icon" src="{% static "inventory/img/datasheet.svg" %}" title="{% translate 'Datasheet' %}"></a>
{% endif %}
{% if user.is_staff %}
<a class="edit" href="{% url "admin:inventory_item_change" object_id=item.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}"></a>
<a class="edit" href="{% url "admin:inventory_item_change" object_id=item.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}" title="{% translate 'Edit' %}"></a>
{% endif %}
<a class="details" href="{% url "item-detail" pk=item.pk %}"><img class="icon" src="{% static "inventory/img/detail.svg" %}"></a>
<a class="details" href="{% url "item-detail" pk=item.pk %}"><img class="icon" src="{% static "inventory/img/detail.svg" %}" title="{% translate 'Details' %}"></a>
</div>
{% if settings.track_amount %}
{% if item.count <= item.low_count %}
<div class="stock"><div class="icon warning-icon" title="{% translate 'Low stock' %}"></div>{{ item.count }}</div>
{% else %}
<div class="stock">{{ item.count }}</div>
{% endif %}
{% endif %}
{% if item.price %}
<div class="price">{{ item.price | floatformat:2 }} &euro;</div>
<div class="price">{{ item.price | currency:"short" }}</div>
{% endif %}
{% if item.form_factor %}
<div class="form_factor">{{ item.form_factor.name }}</div>
@ -30,7 +40,7 @@
{% else %}
<div class="cell-buttons">
{% if user.is_staff %}
<a class="edit" href="{% url "admin:inventory_item_add" %}?index={{ item.index }}&container={{ item.container_id }}"><img class="icon" src="{% static "inventory/img/add.svg" %}"></a>
<a class="edit" href="{% url "admin:inventory_item_add" %}?index={{ item.index }}&container={{ item.container_id }}"><img class="icon" src="{% static "inventory/img/add.svg" %}" title="{% translate 'New item...' %}"></a>
{% endif %}
</div>
{% endif %}

View file

@ -1,19 +1,20 @@
{% extends "base.html" %}
{% load i18n %}
{% load static %}
{% load formatstring %}
{% block title %}Distributor: {{ distributor }}{% endblock %}
{% block title %}{% translate 'Distributor' %}: {{ distributor }}{% endblock %}
{% block header_bar %}
<a href="{% url 'distributor-list' %}"><img class="icon" src="{% static "inventory/img/back.svg" %}"></a>
Distributor: {{ distributor.name }}
<a href="{% url 'distributor-list' %}"><img class="icon" src="{% static "inventory/img/back.svg" %}" title="{% translate 'Back' %}"></a>
{% translate 'Distributor' %}: {{ distributor.name }}
<span class="small">{{ distributor.description }}</span></h2>
{% endblock %}
{% block header_icons %}
{% if user.is_staff %}
<li>
<a href="{% url "admin:inventory_distributor_change" object_id=distributor.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}"></a>
<a href="{% url "admin:inventory_distributor_change" object_id=distributor.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}" title="{% translate 'Edit' %}"></a>
</li>
{% endif %}
{% endblock %}
@ -22,26 +23,26 @@
<table class="attribute-list">
<tbody>
<tr>
<th>Name</th>
<th>{% translate 'Name' %}</th>
<td>{{ distributor.name }}</td>
</tr>
<tr>
<th>Description</th>
<th>{% translate 'Description' %}</th>
<td>{{ distributor.description }}</td>
</tr>
{% if distributor.icon %}
<tr>
<th>Icon</th>
<th>{% translate 'Icon' %}</th>
<td><img src="{{ distributor.icon.url }}" title="{{ distributor.name }}" style="max-height: 20px;"></td>
</tr>
{% endif %}
<tr>
<th>Link</th>
<th>{% translate 'Web link' %}</th>
<td>{% if distributor.web_link %}<a href="{{ distributor.web_link }}" title="{{ distributor.name }}">{{ distributor.web_link }}{% else %}-{% endif %}</td>
</tr>
{% if distributor.search_link %}
<tr>
<th>Search</th>
<th>{% translate 'Search' %}</th>
<td>
<script>
function distro_search(e) {
@ -53,42 +54,41 @@
}
</script>
<form>
<label for="distributor_search">Search query:</label>
<input name="distributor_search" id="distributor_search" type="text">
<button onclick="distro_search(event)" type="submit">Search</button>
<input name="distributor_search" id="distributor_search" type="text" placeholder="{% translate 'Search query' %}">
<button onclick="distro_search(event)" type="submit">{% translate 'Search' %}</button>
</form>
</td>
</tr>
{% endif %}
{% if distributor.phone %}
<tr>
<th>Phone</th>
<th>{% translate 'Phone' %}</th>
<td>{{ distributor.phone }}</td>
</tr>
{% endif %}
{% if distributor.email %}
<tr>
<th>Email</th>
<th>{% translate 'E-Mail' %}</th>
<td><a href="mailto:{{ distributor.email }}">{{ distributor.email }}</a></td>
</tr>
{% endif %}
<tr>
<th>Tags</th>
<th>{% translate 'Tags' %}</th>
<td>
<ul class="tag-list">
{% for tag in distributor.tags.all %}
<li><a href="{% url 'tag-detail' tag.id %}" title="{{ tag.name }}">{{ tag.name }}</a></li>
{% empty %}
No tags
{% translate 'No tags' %}
{% endfor %}
</ul>
</td>
</tr>
<tr><th>Created at</th><td>{{ distributor.created_at }}</td></tr>
<tr><th>{% translate 'Created at' %}</th><td>{{ distributor.created_at }}</td></tr>
{% if distributor.created_at != distributor.changed_at %}
<tr><th>Last change</th><td>{{ distributor.changed_at }}</td></tr>
<tr><th>{% translate 'Changed at' %}</th><td>{{ distributor.changed_at }}</td></tr>
{% endif %}
</tbody>
</table>

View file

@ -1,18 +1,19 @@
{% extends "base.html" %}
{% load i18n %}
{% load static %}
{% block title %}Distributors{% endblock %}
{% block title %}{% translate 'Distributors' %}{% endblock %}
{% block header_bar %}
Inventory management - Distributors
{% translate 'Inventory management' %} - {% translate 'Distributors' %}
{% endblock %}
{% block content %}
<table class="list">
<thead>
<tr>
<th class="icon">Logo</th>
<th>Distributor</th>
<th class="icon">{% translate 'Icon' %}</th>
<th>{% translate 'Distributor' %}</th>
<th></th>
</tr>
</thead>
@ -29,7 +30,7 @@
</td>
<td>
{% if user.is_staff %}
<a class="edit" href="{% url "admin:inventory_distributor_change" object_id=distributor.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}"></a>
<a class="edit" href="{% url "admin:inventory_distributor_change" object_id=distributor.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}" title="{% translate 'Edit' %}"></a>
{% endif %}
</td>
</tr>
@ -39,7 +40,7 @@
{% if user.is_staff %}
<p><a href="{% url "admin:inventory_distributor_add" %}?layout=1">Create new distributor...</a></p>
<p><a href="{% url "admin:inventory_distributor_add" %}?layout=1">{% translate 'Create new distributor...' %}</a></p>
{% endif %}

View file

@ -1,11 +1,13 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load formatstring %}
{% load currency %}
{% block title %}{{ item }}{% endblock %}
{% block header_bar %}
<a href="{{ item.container_url }}"><img class="icon" src="{% static "inventory/img/back.svg" %}"></a>
<a href="{{ item.container_url }}"><img class="icon" src="{% static "inventory/img/back.svg" %}" title="{% translate 'Back' %}"></a>
{{ item.name }}
<span class="small">{{ item.description }}{% if item.form_factor %}, {{ item.form_factor }}{% endif %}</span></h2>
{% endblock %}
@ -13,7 +15,7 @@
{% block header_icons %}
{% if user.is_staff %}
<li>
<a href="{% url "admin:inventory_item_change" object_id=item.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}"></a>
<a href="{% url "admin:inventory_item_change" object_id=item.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}" title="{% translate 'Edit' %}"></a>
</li>
{% endif %}
{% endblock %}
@ -22,21 +24,40 @@
<table class="attribute-list">
<tbody>
<tr>
<th>Name</th>
<th>{% translate 'Name' %}</th>
<td>{{ item.name }}</td>
</tr>
<tr>
<th>Description</th>
<th>{% translate 'Description' %}</th>
<td>{{ item.description }}</td>
</tr>
{% if settings.track_amount %}
<tr>
<th>Tags</th>
<th>{% translate 'Amount' %}</th>
<td>
<form method="post" action="{% url 'item-detail' item.pk %}">
{% csrf_token %}
<label for="amount">
{% if item.count <= item.low_count %}
<div class="icon warning-icon" title="{% translate 'Low stock' %}"></div>
{% endif %}
</label>
<input type="text" name="amount" id="amount" value="{{ item.count }}" placeholder="{% translate 'Amount' %}">
<button name="save" type="submit">{% translate 'Update' %}</button>
<button name="dec" type="submit">-1</button>
</form>
<span class="small right">{% translate 'Low watermark' %}: {{ item.low_count }}</span>
</td>
</tr>
{% endif %}
<tr>
<th>{% translate 'Tags' %}</th>
<td>
<ul class="tag-list">
{% for tag in item.all_tags %}
<li><a href="{% url 'tag-detail' tag.id %}" title="{{ tag.name }}">{{ tag.name }}</a></li>
{% empty %}
No tags
{% translate 'No tags' %}
{% endfor %}
</ul>
</td>
@ -44,7 +65,7 @@
{% if item.form_factor %}
<tr>
<th>Form factor</th>
<th>{% translate 'Form factor' %}</th>
<td>
{% if item.form_factor.datasheet %}
<a href="{% url 'distributor-detail' item.distributor.id %}">
@ -61,7 +82,7 @@
{% if item.manufacturer %}
<tr>
<th>Manufacturer</th>
<th>{% translate 'Manufacturer' %}</th>
<td>
<a href="{% url 'manufacturer-detail' item.manufacturer.id %}">
{% if item.manufacturer.icon %}<img src="{{ item.manufacturer.icon.url }}" class="icon">{% endif %}{{ item.manufacturer.name }}
@ -72,7 +93,7 @@
{% if item.distributor %}
<tr>
<th>Distributor</th>
<th>{% translate 'Distributor' %}</th>
<td>
<a href="{% url 'distributor-detail' item.distributor.id %}">
{% if item.distributor.icon %}<img src="{{ item.distributor.icon.url }}" class="icon">{% endif %}{{ item.distributor.name }}
@ -83,35 +104,35 @@
{% if item.price %}
<tr>
<th>Price</th>
<td>{{ item.price }} Euro</td>
<th>{% translate 'Price' %}</th>
<td>{{ item.price | currency:"detail" }} <span class="small">{% if settings.track_amount %}({% translate 'Sum' %}: {{ item.value | currency:"long" }}){% endif %}</span></td>
</tr>
{% endif %}
{% if item.last_ordered_on %}
<tr>
<th>Last ordered</th>
<th>{% translate 'Last ordered' %}</th>
<td>{{ item.last_ordered_on }}</td>
</tr>
{% endif %}
{% if item.distributor_item_no %}
<tr>
<th>Link</th>
<th>{% translate 'Search link' %}</th>
<td>
<a href="{% formatstring item.distributor.search_link item.distributor_item_no %}">{% formatstring item.distributor.search_link item.distributor_item_no %}</a>
</td>
</tr>
{% endif %}
<tr><th>Created at</th><td>{{ item.created_at }}</td></tr>
<tr><th>{% translate 'Created at' %}</th><td>{{ item.created_at }}</td></tr>
{% if item.created_at != item.changed_at %}
<tr><th>Last change</th><td>{{ item.changed_at }}</td></tr>
<tr><th>{% translate 'Changed at' %}</th><td>{{ item.changed_at }}</td></tr>
{% endif %}
{% if item.documentation.exists %}
<tr>
<th>Datasheets</th>
<th>{% translate 'Documentation' %}</th>
<td>
<ul>
{% for doc in item.documentation.all %}

View file

@ -1,17 +1,18 @@
{% load i18n %}
{% load static %}
<table class="list">
<thead>
<tr>
<th>Name</th>
<th>{% translate 'Name' %}</th>
<th></th>
<th>Description</th>
<th>Container</th>
<th>{% translate 'Description' %}</th>
<th>{% translate 'Container' %}</th>
{% if show_manufacturer %}
<th>Manufacturer</th>
<th>{% translate 'Manufacturer' %}</th>
{% endif %}
{% if show_distributor %}
<th>Distributor</th>
<th>{% translate 'Distributor' %}</th>
{% endif %}
</tr>
</thead>
@ -21,10 +22,10 @@
<td><a href="{% url 'item-detail' item.id %}">{{ item.name }}</a></td>
<td class="right">
{% if item.documentation.all %}
<a class="datasheet" href="{{ item.documentation.all.0.file.url }}"><img class="icon" src="{% static "inventory/img/datasheet.svg" %}"></a>
<a class="datasheet" href="{{ item.documentation.all.0.file.url }}"><img class="icon" src="{% static "inventory/img/datasheet.svg" %}" title="{% translate 'Datasheet' %}"></a>
{% endif %}
{% if user.is_staff %}
<a class="edit" href="{% url "admin:inventory_item_change" object_id=item.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}"></a>
<a class="edit" href="{% url "admin:inventory_item_change" object_id=item.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}" title="{% translate 'Edit' %}"></a>
{% endif %}
</td>
<td>{{ item.description }}</td>

View file

@ -1,19 +1,20 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load formatstring %}
{% block title %}Manufacturer: {{ manufacturer }}{% endblock %}
{% block title %}{% translate 'Manufacturer' %}: {{ manufacturer }}{% endblock %}
{% block header_bar %}
<a href="{% url 'manufacturer-list' %}"><img class="icon" src="{% static "inventory/img/back.svg" %}"></a>
Manufacturer: {{ manufacturer.name }}
<a href="{% url 'manufacturer-list' %}"><img class="icon" src="{% static "inventory/img/back.svg" %}" title="{% translate 'Back' %}"></a>
{% translate 'Manufacturer' %}: {{ manufacturer.name }}
<span class="small">{{ manufacturer.description }}</span></h2>
{% endblock %}
{% block header_icons %}
{% if user.is_staff %}
<li>
<a href="{% url "admin:inventory_manufacturer_change" object_id=manufacturer.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}"></a>
<a href="{% url "admin:inventory_manufacturer_change" object_id=manufacturer.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}" title="{% translate 'Edit' %}"></a>
</li>
{% endif %}
{% endblock %}
@ -22,45 +23,45 @@
<table class="attribute-list">
<tbody>
<tr>
<th>Name</th>
<th>{% translate 'Name' %}</th>
<td>{{ manufacturer.name }}</td>
</tr>
<tr>
<th>Description</th>
<th>{% translate 'Description' %}</th>
<td>{{ manufacturer.description }}</td>
</tr>
{% if manufacturer.icon %}
<tr>
<th>Icon</th>
<th>{% translate 'Icon' %}</th>
<td><img src="{{ manufacturer.icon.url }}" title="{{ manufacturer.name }}" style="max-height: 20px;"></td>
</tr>
{% endif %}
<tr>
<th>Link</th>
<th>{% translate 'Web link' %}</th>
<td>{% if manufacturer.web_link %}<a href="{{ manufacturer.web_link }}" title="{{ manufacturer.name }}">{{ manufacturer.web_link }}{% else %}-{% endif %}</td>
</tr>
<tr>
<th>Tags</th>
<th>{% translate 'Tags' %}</th>
<td>
<ul class="tag-list">
{% for tag in manufacturer.tags.all %}
<li><a href="{% url 'tag-detail' tag.id %}" title="{{ tag.name }}">{{ tag.name }}</a></li>
{% empty %}
No tags
{% translate 'No tags' %}
{% endfor %}
</ul>
</td>
</tr>
<tr><th>Created at</th><td>{{ manufacturer.created_at }}</td></tr>
<tr><th>{% translate 'Created at' %}</th><td>{{ manufacturer.created_at }}</td></tr>
{% if manufacturer.created_at != manufacturer.changed_at %}
<tr><th>Last change</th><td>{{ manufacturer.changed_at }}</td></tr>
<tr><th>{% translate 'Changed at' %}</th><td>{{ manufacturer.changed_at }}</td></tr>
{% endif %}
</tbody>
</table>
<h2>Items</h2>
<h2>{% translate 'Items' %}</h2>
{% url 'manufacturer-detail' manufacturer.id as this_url %}
{% include "inventory/pagination.html" with url=this_url id="paginator_top" param="item" paginator=items %}

View file

@ -1,18 +1,19 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% block title %}Manufacturers{% endblock %}
{% block title %}{% translate 'Manufacturers' %}{% endblock %}
{% block header_bar %}
Inventory management - Manufacturers
{% translate 'Inventory Management' %} - {% translate 'Manufacturers' %}
{% endblock %}
{% block content %}
<table class="list">
<thead>
<tr>
<th>Logo</th>
<th>Manufacturer</th>
<th>{% translate 'Icon' %}</th>
<th>{% translate 'Manufacturer' %}</th>
<th></th>
</tr>
</thead>
@ -29,7 +30,7 @@
</td>
<td>
{% if user.is_staff %}
<a class="edit" href="{% url "admin:inventory_manufacturer_change" object_id=manufacturer.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}"></a>
<a class="edit" href="{% url "admin:inventory_manufacturer_change" object_id=manufacturer.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}" title="{% translate 'Edit' %}"></a>
{% endif %}
</td>
</tr>
@ -38,7 +39,7 @@
</table>
{% if user.is_staff %}
<p><a href="{% url "admin:inventory_manufacturer_add" %}?layout=1">Create new manufacturer...</a></p>
<p><a href="{% url "admin:inventory_manufacturer_add" %}?layout=1">{% translate 'Create new manufacturer...' %}</a></p>
{% endif %}

View file

@ -1,15 +1,16 @@
{% load static %}
{% load i18n %}
<div class="pagination" id="{{ id }}">
{% if paginator.has_previous %}
<a href="{{ url }}?{{ param }}_page=1#{{ id }}"><img src="{% static 'inventory/img/first.svg' %}" class="icon" title="First page"></a>
<a href="{{ url }}?{{ param }}_page={{ paginator.previous_page_number }}#{{ id }}"><img src="{% static 'inventory/img/previous.svg' %}" class="icon" title="Previous page"></a>
<a href="{{ url }}?{{ param }}_page=1#{{ id }}"><img src="{% static 'inventory/img/first.svg' %}" class="icon" title="{% translate 'First page' %}"></a>
<a href="{{ url }}?{{ param }}_page={{ paginator.previous_page_number }}#{{ id }}"><img src="{% static 'inventory/img/previous.svg' %}" class="icon" title="{% translate 'Previous page' %}"></a>
{% endif %}
{% if paginator.paginator.num_pages > 1 %}
{{ paginator.number }}/{{ paginator.paginator.num_pages }}
{% endif %}
{% if paginator.has_next %}
<a href="{{ url }}?{{ param }}_page={{ paginator.next_page_number }}#{{ id }}"><img src="{% static 'inventory/img/next.svg' %}" class="icon" title="Next page"></a>
<a href="{{ url }}?{{ param }}_page={{ paginator.paginator.num_pages}}#{{ id }}"><img src="{% static 'inventory/img/last.svg' %}" class="icon" title="Last page"></a>
<a href="{{ url }}?{{ param }}_page={{ paginator.next_page_number }}#{{ id }}"><img src="{% static 'inventory/img/next.svg' %}" class="icon" title="{% translate 'Next page' %}"></a>
<a href="{{ url }}?{{ param }}_page={{ paginator.paginator.num_pages}}#{{ id }}"><img src="{% static 'inventory/img/last.svg' %}" class="icon" title="{% translate 'Last page' %}"></a>
{% endif %}
</div>

View file

@ -1,15 +1,16 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% block title %}Search{% endblock %}
{% block title %}{% translate 'Search' %}{% endblock %}
{% block header_bar %}
Search
{% translate 'Search' %}
{% endblock %}
{% block content %}
<form method="get" action="{% url 'search' %}">
<input type="text" id="search" name="q">
<button type="submit">Search</button>
<input type="text" id="search" name="q" placeholder="{% translate 'Search' %}">
<button type="submit">{% translate 'Search' %}</button>
</form>
{% endblock %}

View file

@ -1,20 +1,21 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load hilight %}
{% block title %}Search{% endblock %}
{% block title %}{% translate 'Search' %}{% endblock %}
{% block header_bar %}
Search
{% translate 'Search' %}
{% endblock %}
{% block content %}
<form method="get" action="{% url 'search' %}">
<input type="text" id="search" name="q" value="{{ q }}">
<button type="submit">Search</button>
<input type="text" id="search" name="q" value="{{ q }}" placeholder="{% translate 'Search' %}">
<button type="submit">{% translate 'Search' %}</button>
</form>
<h2>Search result for '{{ q }}'</h2>
<h2>{% translate 'Search result for' %} '{{ q }}'</h2>
{% for result in results %}
<div class="search-result">
@ -23,19 +24,19 @@
<hr>
</div>
{% empty %}
<p>Noting found</p>
<p>{% translate 'Nothing found' %}</p>
{% endfor %}
{% if pages > 1 %}
<div class="pagination">
{% if page > 1 %}
<a href="{% url 'search' %}?q={{ q }}&page=1"><img src="{% static 'inventory/img/first.svg' %}" class="icon" title="First page"></a>
<a href="{% url 'search' %}?q={{ q }}&page={{ page | add:'-1'}}"><img src="{% static 'inventory/img/previous.svg' %}" class="icon" title="Previous page"></a>
<a href="{% url 'search' %}?q={{ q }}&page=1"><img src="{% static 'inventory/img/first.svg' %}" class="icon" title="{% translate 'First page' %}"></a>
<a href="{% url 'search' %}?q={{ q }}&page={{ page | add:'-1'}}"><img src="{% static 'inventory/img/previous.svg' %}" class="icon" title="{% translate 'Previous page' %}"></a>
{% endif %}
{{ page }}/{{ pages }}
{% if page < pages %}
<a href="{% url 'search' %}?q={{ q }}&page={{ page | add:'1'}}"><img src="{% static 'inventory/img/next.svg' %}" class="icon" title="Next page"></a>
<a href="{% url 'search' %}?q={{ q }}&page={{ pages }}"><img src="{% static 'inventory/img/last.svg' %}" class="icon" title="Last page"></a>
<a href="{% url 'search' %}?q={{ q }}&page={{ page | add:'1'}}"><img src="{% static 'inventory/img/next.svg' %}" class="icon" title="{% translate 'Next page' %}"></a>
<a href="{% url 'search' %}?q={{ q }}&page={{ pages }}"><img src="{% static 'inventory/img/last.svg' %}" class="icon" title="{% translate 'Last page' %}"></a>
{% endif %}
</div>
{% endif %}

View file

@ -1,17 +1,16 @@
{% load static %}
{% load i18n %}
{% load hilight %}
<p>
{% if item.documentation.all %}
<a class="datasheet" href="{{ item.documentation.all.0.file.url }}"><img class="icon" src="{% static "inventory/img/datasheet.svg" %}"></a>
<a class="datasheet" href="{{ item.documentation.all.0.file.url }}"><img class="icon" src="{% static "inventory/img/datasheet.svg" %}" title="{% translate 'Datasheet' %}"></a>
{% endif %}
{{ item | hilight:tokens }}
<span class="small">{{item.form_factor.name}}</span>
</p>
<p>Contained in: <a href="{{ item.container_url }}?hilight={{ item.id }}">{{ item.container.display_name }}</a></p>
<p>{% translate 'Contained in' %}: <a href="{{ item.container_url }}?hilight={{ item.id }}">{{ item.container.display_name }}</a></p>
<ul class="tag-list">
{% for tag in item.all_tags %}
<li><a href="{% url 'tag-detail' tag.id %}" title="{{ tag.name }}">{{ tag.name }}</a></li>
{% empty %}
No tags
{% endfor %}
</ul>

View file

@ -1,4 +1,5 @@
{% load static %}
{% load i18n %}
<li>
<form method="POST" action="{% url "index" %}">
@ -6,9 +7,9 @@
<input type="hidden" name="index_id" value='{{ item.id }}'>
<button class="icon-only-button">
{% if is_index %}
<img class="icon" src="{% static "inventory/img/star-filled.svg" %}">
<img class="icon" src="{% static "inventory/img/star-filled.svg" %}" title="{% translate 'Currently set as index page' %}">
{% else %}
<img class="icon" src="{% static "inventory/img/star-outline.svg" %}">
<img class="icon" src="{% static "inventory/img/star-outline.svg" %}" title="{% translate 'Promote to index page' %}">
{% endif %}
</button>
</form>

View file

@ -1,10 +1,11 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% block title %}Tag {{ tag.name }}{% endblock %}
{% block title %}{% translate 'Tag' %} {{ tag.name }}{% endblock %}
{% block header_bar %}
<a href="{% url "tag-list" %}"><img class="icon" src="{% static "inventory/img/back.svg" %}"></a>
<a href="{% url "tag-list" %}"><img class="icon" src="{% static "inventory/img/back.svg" %}" title="{% translate 'Back' %}"></a>
{{ tag.name }}
<span class="small">{{ tag.description}}</span>
{% endblock %}
@ -12,14 +13,14 @@
{% block header_icons %}
{% if user.is_staff %}
<li>
<a href="{% url "admin:inventory_tag_change" object_id=tag.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}"></a>
<a href="{% url "admin:inventory_tag_change" object_id=tag.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}" title="{% translate 'Edit' %}"></a>
</li>
{% endif %}
{% endblock %}
{% block content %}
{% if tag.workshop_set.count > 0 %}
<h3>Workshops</h3>
<h3>{% translate 'Workshops' %}</h3>
<table class="list">
<tbody>
{% for workshop in tag.workshop_set.all %}
@ -29,7 +30,7 @@
</td>
<td>
{% if user.is_staff %}
<a class="edit" href="{% url "admin:inventory_workshop_change" object_id=workshop.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}"></a>
<a class="edit" href="{% url "admin:inventory_workshop_change" object_id=workshop.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}" title="{% translate 'Edit' %}"></a>
{% endif %}
</td>
</tr>
@ -39,7 +40,7 @@
{% endif %}
{% if tag.box_set.count > 0 %}
<h3>Boxes</h3>
<h3>{% translate 'Boxes' %}</h3>
<table class="list">
<tbody>
{% for box in tag.box_set.all %}
@ -49,7 +50,7 @@
</td>
<td>
{% if user.is_staff %}
<a class="edit" href="{% url "admin:inventory_workshop_change" object_id=box.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}"></a>
<a class="edit" href="{% url "admin:inventory_workshop_change" object_id=box.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}" title="{% translate 'Edit' %}"></a>
{% endif %}
</td>
</tr>
@ -59,7 +60,7 @@
{% endif %}
{% if tag.distributor_set.count > 0 %}
<h3>Distributors</h3>
<h3>{% translate 'Distributors' %}</h3>
<table class="list">
<tbody>
{% for distributor in tag.distributor_set.all %}
@ -74,7 +75,7 @@
</td>
<td>
{% if user.is_staff %}
<a class="edit" href="{% url "admin:inventory_workshop_change" object_id=distributor.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}"></a>
<a class="edit" href="{% url "admin:inventory_workshop_change" object_id=distributor.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}" title="{% translate 'Edit' %}"></a>
{% endif %}
</td>
</tr>
@ -84,7 +85,7 @@
{% endif %}
{% if tag.manufacturer_set.count > 0 %}
<h3>Manufacturers</h3>
<h3>{% translate 'Manufacturers' %}</h3>
<table class="list">
<tbody>
{% for manufacturer in tag.manufacturer_set.all %}
@ -99,7 +100,7 @@
</td>
<td>
{% if user.is_staff %}
<a class="edit" href="{% url "admin:inventory_workshop_change" object_id=manufacturer.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}"></a>
<a class="edit" href="{% url "admin:inventory_workshop_change" object_id=manufacturer.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}" title="{% translate 'Edit' %}"></a>
{% endif %}
</td>
</tr>
@ -109,7 +110,7 @@
{% endif %}
{% if items %}
<h3>Items</h3>
<h3>{% translate 'Items' %}</h3>
{% url 'tag-detail' tag.id as this_url %}
{% include "inventory/pagination.html" with url=this_url id="items_paginator_top" param="item" paginator=items %}
{% include "inventory/item_list.html" with items=items show_manufacturer=1 show_distributor=1 %}
@ -117,7 +118,7 @@
{% endif %}
{% if tag.formfactor_set.count > 0 %}
<h3>Form factors</h3>
<h3>{% translate 'Form factors' %}</h3>
<ul class="compact-list">
{% for formfactor in tag.formfactor_set.all %}
<li>{{ formfactor.name }}</li>

View file

@ -1,11 +1,12 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load formatstring %}
{% block title %}Tags{% endblock %}
{% block header_bar %}
Inventory Management - Tags
{% translate 'Inventory management' %} - {% translate 'Tags' %}
{% endblock %}
{% block content %}
@ -39,19 +40,19 @@
}
</script>
<form>
<input type="text" id="tag-search" name="tag-search" placeholder="Search" oninput="updateSearch(event)">
<button onclick="updateSearch(event)">Search</button>
<input type="text" id="tag-search" name="tag-search" placeholder="{% translate 'Search' %}" oninput="updateSearch(event)">
<button onclick="updateSearch(event)">{% translate 'Search' %}</button>
</form>
<ul class="tag-list" id="tagcloud">
{% for tag in object_list %}
<li data-search="{{ tag.name | lower }} {{ tag.description | lower }}"><a href="{% url 'tag-detail' tag.id %}" title="{{ tag.name }}">{{ tag.name }}</a></li>
{% empty %}
No tags
{% translate 'No tags' %}
{% endfor %}
</ul>
{% if user.is_staff %}
<p><a href="{% url "admin:inventory_tag_add" %}?layout=1">Create new tag...</a></p>
<p><a href="{% url "admin:inventory_tag_add" %}?layout=1">{% translate 'Create new tag...' %}</a></p>
{% endif %}
{% endblock %}

View file

@ -1,10 +1,11 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% block title %}Workshop {{ workshop.name }}{% endblock %}
{% block title %}{% translate 'Workshop' %} {{ workshop.name }}{% endblock %}
{% block header_bar %}
<a href="{% url "workshop-list" %}"><img class="icon" src="{% static "inventory/img/back.svg" %}"></a>
<a href="{% url "workshop-list" %}"><img class="icon" src="{% static "inventory/img/back.svg" %}" title="{% translate 'Back' %}"></a>
{{ workshop.name }}
<span class="small">{{ workshop.description}}</span>
{% endblock %}
@ -12,14 +13,14 @@
{% block header_icons %}
{% if user.is_staff %}
<li>
<a href="{% url "admin:inventory_workshop_change" object_id=workshop.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}"></a>
<a href="{% url "admin:inventory_workshop_change" object_id=workshop.pk %}"><img class="icon" src="{% static "inventory/img/edit.svg" %}" title="{% translate 'Edit' %}"></a>
</li>
{% include 'inventory/set_index.html' with item=workshop is_index=is_index %}
{% endif %}
{% endblock %}
{% block content %}
<h3>Areas</h3>
<h3>{% translate 'Areas' %}</h3>
<table class="list">
<tbody>
@ -30,22 +31,22 @@
</td>
<td>
{% if user.is_staff %}
<a class="edit" href="{% url "admin:inventory_area_change" object_id=area.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}"></a>
<a class="edit" href="{% url "admin:inventory_area_change" object_id=area.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}" title="{% translate 'Edit' %}"></a>
{% endif %}
</td>
</tr>
{% empty %}
<tr><td>No areas defined</td></tr>
<tr><td>{% translate 'No areas defined' %}</td></tr>
{% endfor %}
</tbody>
</table>
{% if user.is_staff %}
<p><a href="{% url "admin:inventory_area_add" %}?container={{ workshop.id }}&index=0">Create new area...</a></p>
<p><a href="{% url "admin:inventory_area_add" %}?container={{ workshop.id }}&index=0">{% translate 'Create new area...' %}</a></p>
{% endif %}
{% if workshop.show_boxes %}
<h3>Containers</h3>
<h3>{% translate 'Containers' %}</h3>
<table class="list">
<tbody>
{% for box in workshop.box_related.all %}
@ -55,18 +56,18 @@
</td>
<td>
{% if user.is_staff %}
<a class="edit" href="{% url "admin:inventory_box_change" object_id=box.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}"></a>
<a class="edit" href="{% url "admin:inventory_box_change" object_id=box.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}" title="{% translate 'Edit' %}"></a>
{% endif %}
</td>
</tr>
{% empty %}
<tr><td>No containers defined</td></tr>
<tr><td>{% translate 'No containers defined' %}</td></tr>
{% endfor %}
</tbody>
</table>
{% if user.is_staff %}
<p><a href="{% url "admin:inventory_box_add" %}?container={{ workshop.id }}&index=0">Create new container...</a></p>
<p><a href="{% url "admin:inventory_box_add" %}?container={{ workshop.id }}&index=0">{% translate 'Create new container...' %}</a></p>
{% endif %}
{% endif %}
{% endblock %}

View file

@ -1,10 +1,11 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% block title %}Workshops{% endblock %}
{% block title %}{% translate 'Workshops' %}{% endblock %}
{% block header_bar %}
Inventory management - Workshops
{% translate 'Inventory management' %} - {% translate 'Workshops' %}
{% endblock %}
{% block content %}
@ -17,7 +18,7 @@
</td>
<td>
{% if user.is_staff %}
<a class="edit" href="{% url "admin:inventory_workshop_change" object_id=workshop.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}"></a>
<a class="edit" href="{% url "admin:inventory_workshop_change" object_id=workshop.pk %}"><img class="icon" src="{% static 'inventory/img/edit.svg' %}" title="{% translate 'Edit' %}"></a>
{% endif %}
</td>
</tr>
@ -26,7 +27,7 @@
</table>
{% if user.is_staff %}
<p><a href="{% url "admin:inventory_workshop_add" %}?layout=1">Create new workshop...</a></p>
<p><a href="{% url "admin:inventory_workshop_add" %}?layout=1">{% translate 'Create new workshop...' %}</a></p>
{% endif %}

View file

@ -1,21 +1,30 @@
{% extends "base.html" %}
{% load i18n%}
{% block header_bar %}
Inventory management - Login
{% translate 'Inventory management' %} - {% translate 'Login' %}
{% endblock %}
{% block content %}
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
<p>{% blocktranslate %}Your username and password didn't match. Please try again.{% endblocktranslate %}</p>
{% endif %}
{% if next %}
{% if user.is_authenticated %}
<p>Your account doesn't have access to this page. To proceed,
please login with an account that has access.</p>
<p>
{% blocktranslate %}
Your account doesn't have access to this page. To proceed,
please login with an account that has access.
{% endblocktranslate %}
</p>
{% else %}
<p>Please login to see this page.</p>
<p>
{% blocktranslate %}
Please login to see this page.
{% endblocktranslate %}
</p>
{% endif %}
{% endif %}
@ -37,6 +46,6 @@
</form>
{# Assumes you setup the password_reset view in your URLconf #}
<p><a href="{% url 'password_reset' %}">Lost password?</a></p>
<p><a href="{% url 'password_reset' %}">{% translate 'Lost password?' %}</a></p>
{% endblock %}

View file

@ -0,0 +1,29 @@
from django import template
from django.utils.safestring import mark_safe
from django.utils.formats import number_format
from inventory.models import Settings
register = template.Library()
s = Settings.objects.first()
@register.filter(name='currency')
def currency(value, format):
value = float(value)
if format == 'detail':
value = number_format(round(value, 3), 3, use_l10n=True)
else:
value = number_format(round(value, 2), 2, use_l10n=True)
if format == 'long' or format == 'detail':
symbol = s.currency
else:
symbol = s.currency_symbol
if s.currency_symbol_position:
result = f"{value} {symbol}"
else:
result = f"{symbol} {value}"
return mark_safe(result)

View file

@ -4,7 +4,7 @@ from django.utils.decorators import method_decorator
from django.views.generic import ListView, DetailView
from django.db.models import QuerySet
from inventory.models import Box
from inventory.models import Box, Settings
from .utils import CanBeIndexMixin
@ -54,6 +54,7 @@ class BoxView(CanBeIndexMixin, DetailView):
context = self.get_context_data(object=self.object)
context['layouted'], _ = self.layout(self.object.item_related.all().order_by('index'), self.object.layout.data)
context['hilight'] = hilighted
context['settings'] = Settings.objects.first()
return self.render_to_response(context)

View file

@ -1,15 +1,30 @@
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import ListView, DetailView
from django.shortcuts import get_object_or_404
from inventory.models import Item
from inventory.models import Item, Settings
@method_decorator(login_required, name='dispatch')
class ItemView(DetailView):
context_object_name = 'item'
queryset = Item.objects.all().select_related('container', 'container__layout', 'manufacturer', 'distributor').prefetch_related('documentation')
def get_context_data(self, *args, object_list=None, **kwargs):
result = super().get_context_data(*args, object_list=object_list, **kwargs)
result['settings'] = Settings.objects.first()
return result
def post(self, request, pk):
item = get_object_or_404(Item.objects.filter(pk=pk))
if request.POST.get('dec', None) is not None:
if item.count > 0:
item.count -= 1
item.save()
if request.POST.get('save', None) is not None:
item.count = request.POST.get('amount', 0)
item.save()
return self.get(request)
@method_decorator(login_required, name='dispatch')
class ItemListView(ListView):

View file

@ -14,6 +14,7 @@ from typing import List
import os
import sys
import asyncio
from django.utils.translation import gettext_lazy as _
if sys.platform == 'win32':
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
@ -116,6 +117,10 @@ AUTH_PASSWORD_VALIDATORS = [
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGES = [
("de", _("German")),
("en", _("English")),
]
LANGUAGE_CODE = 'en-us'