fnschool 20251018.81021.825__tar.gz → 20251020.82239.858__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of fnschool might be problematic. Click here for more details.
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/PKG-INFO +1 -1
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/__init__.py +1 -1
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/forms.py +1 -1
- fnschool-20251020.82239.858/src/fnschoo1/canteen/migrations/0017_ingredient_updated_at_alter_category_created_at_and_more.py +30 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/models.py +14 -2
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/consumption/create.html +5 -4
- fnschool-20251020.82239.858/src/fnschoo1/canteen/templates/canteen/ingredient/list.html +171 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/views.py +51 -2
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/workbook/generate.py +172 -174
- fnschool-20251020.82239.858/src/fnschoo1/fnschool/_settings.py +3 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/fnschool/settings.py +12 -1
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/static/css/fnschool.css +6 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/static/js/fnschool.js +24 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschool.egg-info/PKG-INFO +1 -1
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschool.egg-info/SOURCES.txt +2 -0
- fnschool-20251018.81021.825/src/fnschoo1/canteen/templates/canteen/ingredient/list.html +0 -139
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/LICENSE +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/README.md +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/pyproject.toml +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/setup.cfg +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/__init__.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/admin.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/apps.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0001_initial.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0002_ingredient_is_disabled.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0003_consumption_is_disabled_alter_ingredient_is_disabled.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0004_alter_ingredient_name_category_and_more.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0005_alter_category_created_at_alter_category_name_and_more.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0006_category_is_disabled_alter_category_user_and_more.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0007_alter_consumption_amount_used_and_more.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0008_category_abbreviation_mealtype.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0009_alter_category_abbreviation_and_more.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0010_alter_consumption_options_alter_ingredient_options_and_more.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0011_category_pin_to_consumptions_top.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0012_alter_ingredient_storage_date.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0013_alter_consumption_options_alter_ingredient_options_and_more.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0014_category_priority.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0015_alter_category_options_alter_category_priority.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/0016_consumption_unique_ingredient_date_of_using.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/migrations/__init__.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/category/create.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/category/delete.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/category/list.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/category/update.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/close.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/consumption/_create.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/ingredient/close.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/ingredient/create.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/ingredient/create_one.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/ingredient/delete.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/ingredient/update.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/meal_type/create.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/meal_type/delete.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/meal_type/list.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/templates/canteen/meal_type/update.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/tests.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/urls.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/canteen/workbook/__init__.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/fnschool/__init__.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/fnschool/asgi.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/fnschool/templatetags/__init__.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/fnschool/templatetags/fnschool_tags.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/fnschool/urls.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/fnschool/views.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/fnschool/wsgi.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/locale/en/LC_MESSAGES/django.mo +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/manage.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/__init__.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/admin.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/apps.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/forms.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/migrations/0001_initial.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/migrations/0002_alter_profile_bio.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/migrations/0003_alter_profile_options_alter_profile_address_and_more.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/migrations/0004_profile_gender.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/migrations/0005_alter_profile_gender.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/migrations/__init__.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/models.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/signals.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/templates/profiles/create.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/templates/profiles/detail.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/templates/profiles/edit.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/templates/profiles/log_in.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/templates/profiles/log_out.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/tests.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/urls.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/profiles/views.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/static/css/bootstrap.min.css +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/static/images/favicon.ico +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/static/js/bootstrap.bundle.min.js +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/static/js/bootstrap.min.js +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/static/js/jquery.min.js +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/static/js/jquery.slim.min.js +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/static/js/popper.min.js +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/templates/base/_content.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/templates/base/_css.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/templates/base/_js.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/templates/base/content.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/templates/base/header_content_footer.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/templates/close.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/templates/home.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/templates/includes/_footer.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/templates/includes/_header.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/templates/includes/_navigation.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/templates/includes/_paginator.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/templates/registration/logged_out.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschoo1/templates/registration/login.html +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschool.egg-info/SOURCES.txt.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschool.egg-info/dependency_links.txt +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschool.egg-info/dependency_links.txt.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschool.egg-info/entry_points.txt +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschool.egg-info/entry_points.txt.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschool.egg-info/requires.txt +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschool.egg-info/requires.txt.py +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschool.egg-info/top_level.txt +0 -0
- {fnschool-20251018.81021.825 → fnschool-20251020.82239.858}/src/fnschool.egg-info/top_level.txt.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fnschool
|
|
3
|
-
Version:
|
|
3
|
+
Version: 20251020.82239.858
|
|
4
4
|
Summary: Just some school related scripts, without any ambition.
|
|
5
5
|
Author-email: larryw3i <larryw3i@163.com>, Larry Wei <larryw3i@126.com>, Larry W3i <larryw3i@yeah.net>
|
|
6
6
|
Maintainer-email: larryw3i <larryw3i@163.com>, Larry Wei <larryw3i@126.com>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Generated by Django 4.2.25 on 2025-10-19 02:03
|
|
2
|
+
|
|
3
|
+
from django.db import migrations, models
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Migration(migrations.Migration):
|
|
7
|
+
|
|
8
|
+
dependencies = [
|
|
9
|
+
("canteen", "0016_consumption_unique_ingredient_date_of_using"),
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
operations = [
|
|
13
|
+
migrations.AddField(
|
|
14
|
+
model_name="ingredient",
|
|
15
|
+
name="updated_at",
|
|
16
|
+
field=models.DateTimeField(
|
|
17
|
+
auto_now=True, null=True, verbose_name="Time of updating"
|
|
18
|
+
),
|
|
19
|
+
),
|
|
20
|
+
migrations.AlterField(
|
|
21
|
+
model_name="category",
|
|
22
|
+
name="created_at",
|
|
23
|
+
field=models.DateTimeField(null=True, verbose_name="创建日期"),
|
|
24
|
+
),
|
|
25
|
+
migrations.AlterField(
|
|
26
|
+
model_name="mealtype",
|
|
27
|
+
name="created_at",
|
|
28
|
+
field=models.DateTimeField(null=True, verbose_name="创建日期"),
|
|
29
|
+
),
|
|
30
|
+
]
|
|
@@ -21,7 +21,9 @@ class MealType(models.Model):
|
|
|
21
21
|
abbreviation = models.CharField(
|
|
22
22
|
null=True, blank=True, max_length=100, verbose_name=_("Abbreviation")
|
|
23
23
|
)
|
|
24
|
-
created_at = models.
|
|
24
|
+
created_at = models.DateTimeField(
|
|
25
|
+
null=True, verbose_name=_("Creating Date")
|
|
26
|
+
)
|
|
25
27
|
is_disabled = models.BooleanField(
|
|
26
28
|
default=False, verbose_name=_("Is Disabled")
|
|
27
29
|
)
|
|
@@ -41,7 +43,9 @@ class Category(models.Model):
|
|
|
41
43
|
abbreviation = models.CharField(
|
|
42
44
|
null=True, blank=True, max_length=100, verbose_name=_("abbreviation")
|
|
43
45
|
)
|
|
44
|
-
created_at = models.
|
|
46
|
+
created_at = models.DateTimeField(
|
|
47
|
+
null=True, verbose_name=_("Creating Date")
|
|
48
|
+
)
|
|
45
49
|
is_disabled = models.BooleanField(
|
|
46
50
|
default=False, verbose_name=_("Is Disabled")
|
|
47
51
|
)
|
|
@@ -74,6 +78,9 @@ class Ingredient(models.Model):
|
|
|
74
78
|
verbose_name=_("User"),
|
|
75
79
|
)
|
|
76
80
|
storage_date = models.DateField(verbose_name=_("Storage Date"))
|
|
81
|
+
updated_at = models.DateTimeField(
|
|
82
|
+
null=True, auto_now=True, verbose_name=_("Time of updating")
|
|
83
|
+
)
|
|
77
84
|
name = models.CharField(max_length=100, verbose_name=_("Ingredient Name"))
|
|
78
85
|
meal_type = models.ForeignKey(
|
|
79
86
|
MealType,
|
|
@@ -139,6 +146,9 @@ class Ingredient(models.Model):
|
|
|
139
146
|
return quantity
|
|
140
147
|
|
|
141
148
|
def get_consuming_quantity(self, date_end):
|
|
149
|
+
|
|
150
|
+
if self.storage_date < date_end:
|
|
151
|
+
return 0
|
|
142
152
|
consumptions = self.cleaned_consumptions
|
|
143
153
|
if not consumptions:
|
|
144
154
|
return 0
|
|
@@ -152,6 +162,8 @@ class Ingredient(models.Model):
|
|
|
152
162
|
return quantity
|
|
153
163
|
|
|
154
164
|
def get_remaining_quantity(self, date_end):
|
|
165
|
+
if self.storage_date < date_end:
|
|
166
|
+
return 0
|
|
155
167
|
return self.quantity - self.get_consuming_quantity(date_end)
|
|
156
168
|
|
|
157
169
|
@property
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
onclick="list_consumptions();">{% trans "Refresh" %}</button>
|
|
43
43
|
</div>
|
|
44
44
|
</div>
|
|
45
|
-
<div class="table
|
|
45
|
+
<div class="table-responsive table-container">
|
|
46
46
|
<table class="table table-consumptions cotable-bordered table-striped table-hover table-condensed scroll-vertical ">
|
|
47
47
|
<thead>
|
|
48
48
|
<tr>
|
|
@@ -97,7 +97,8 @@
|
|
|
97
97
|
</table>
|
|
98
98
|
</div>
|
|
99
99
|
<div class="">
|
|
100
|
-
<button
|
|
100
|
+
<button id="generate_spreadsheet_btn"
|
|
101
|
+
onclick="generate_spreadsheet();"
|
|
101
102
|
class="btn btn-submit-consumptions btn-success float-end">
|
|
102
103
|
{% trans "Generate Spreadsheet" %}
|
|
103
104
|
</button>
|
|
@@ -405,11 +406,11 @@
|
|
|
405
406
|
}
|
|
406
407
|
|
|
407
408
|
function set_consumptions_table_size() {
|
|
408
|
-
const
|
|
409
|
+
const generate_spreadsheet_btn = $("#generate_spreadsheet_btn")
|
|
409
410
|
const consumptions_table = $(".table-consumptions")
|
|
410
411
|
const header = $("header")
|
|
411
412
|
const footer = $("footer")
|
|
412
|
-
const height = Math.round((footer.offset().top -
|
|
413
|
+
const height = Math.round((footer.offset().top - generate_spreadsheet_btn.height() - consumptions_table.offset().top) * 0.95)
|
|
413
414
|
consumptions_table.parent().height(height)
|
|
414
415
|
}
|
|
415
416
|
$(window).resize(function() {
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
{% extends "base/header_content_footer.html" %}
|
|
2
|
+
{% load tz %}
|
|
3
|
+
{% load crispy_forms_tags %}
|
|
4
|
+
{% block title %}
|
|
5
|
+
{% trans "Ingredient List" %}
|
|
6
|
+
{% endblock %}
|
|
7
|
+
{% block content %}
|
|
8
|
+
<h1>{% trans "Ingredient List" %}</h1>
|
|
9
|
+
<form method="get"
|
|
10
|
+
action="{% url 'canteen:list_ingredients' %}"
|
|
11
|
+
class="d-flex justify-content-between align-items-center">
|
|
12
|
+
<input type="text"
|
|
13
|
+
name="q"
|
|
14
|
+
onkeydown="if(event.keyCode==13){submit_q();return false;}"
|
|
15
|
+
value="{{ search_query }}"
|
|
16
|
+
placeholder="{% trans 'Search ingredient ...' %}"
|
|
17
|
+
class="form-control" />
|
|
18
|
+
<button type="button"
|
|
19
|
+
onclick="submit_q();"
|
|
20
|
+
class="btn btn-primary text-nowrap">{% trans "Search" %}</button>
|
|
21
|
+
{% if search_query %}
|
|
22
|
+
<a onclick="clear_q();" class="text-nowrap">{% trans "Clear" %}</a>
|
|
23
|
+
{% endif %}
|
|
24
|
+
</form>
|
|
25
|
+
<div class="d-flex justify-content-end pt-2">
|
|
26
|
+
<a class="btn btn-primary mx-1"
|
|
27
|
+
href="{% url "canteen:list_meal_types" %}">{% trans "Ingredient Meal Types" %}</a>
|
|
28
|
+
<a class="btn btn-primary mx-1"
|
|
29
|
+
href="{% url "canteen:list_categories" %}">{% trans "Ingredient Categories" %}</a>
|
|
30
|
+
<a class="btn btn-warning mx-1"
|
|
31
|
+
href="{% url "canteen:create_consumptions" %}">{% trans "Consume" %}</a>
|
|
32
|
+
<a class="btn btn-primary mx-1"
|
|
33
|
+
onclick="open_small_window('{% url 'canteen:create_ingredients' %}')">{% trans "Add via template" %}</a>
|
|
34
|
+
<a class="btn btn-primary"
|
|
35
|
+
onclick="open_small_window('{% url 'canteen:create_ingredient' %}')">{% trans "Add one" %}</a>
|
|
36
|
+
</div>
|
|
37
|
+
<hr />
|
|
38
|
+
<div class="container">
|
|
39
|
+
<div class="table-responsive-lg table-container">
|
|
40
|
+
<table class="table table-bordered table-ingredient table-striped table-hover table-condensed">
|
|
41
|
+
<thead>
|
|
42
|
+
<tr>
|
|
43
|
+
<th scope="col">#</th>
|
|
44
|
+
{% for name,sort, header in headers %}
|
|
45
|
+
<th scope="col"
|
|
46
|
+
data-sort="sort_{{ name }} {{ sort }}"
|
|
47
|
+
onclick="sort_ingredients(this.dataset.sort);">
|
|
48
|
+
{{ header }}
|
|
49
|
+
{% if sort == "+" %}
|
|
50
|
+
↑
|
|
51
|
+
{% elif sort == "-" %}
|
|
52
|
+
↓
|
|
53
|
+
{% endif %}
|
|
54
|
+
</th>
|
|
55
|
+
{% endfor %}
|
|
56
|
+
<th scope="col"></th>
|
|
57
|
+
</tr>
|
|
58
|
+
</thead>
|
|
59
|
+
<tbody>
|
|
60
|
+
{% for ingredient in page_obj %}
|
|
61
|
+
<tr class="tr-ingredient"
|
|
62
|
+
data-ingredient_updated_at="{{ ingredient.updated_at|localtime|date:'Y/m/d H:i:s' }}"
|
|
63
|
+
data-ingredient_storage_date="{{ ingredient.storage_date|localtime|date:'Y/m/d' }}">
|
|
64
|
+
<th scope="row">
|
|
65
|
+
<div class="form-check"
|
|
66
|
+
title="{% trans 'It helps you check the ingredients.' %}">
|
|
67
|
+
<input type="checkbox"
|
|
68
|
+
class="form-check-input"
|
|
69
|
+
id="ingredient_free_nark_{{ ingredient.id }}" />
|
|
70
|
+
<label class="form-check-label"
|
|
71
|
+
for="ingredient_free_nark_{{ ingredient.id }}">
|
|
72
|
+
{{ forloop.counter }}
|
|
73
|
+
</label>
|
|
74
|
+
</div>
|
|
75
|
+
</th>
|
|
76
|
+
<td>{{ ingredient.storage_date }}</td>
|
|
77
|
+
<td>{{ ingredient.name }}</td>
|
|
78
|
+
<td>{{ ingredient.meal_type }}</td>
|
|
79
|
+
<td>{{ ingredient.category }}</td>
|
|
80
|
+
<td>{{ ingredient.quantity }}</td>
|
|
81
|
+
<td>{{ ingredient.quantity_unit_name }}</td>
|
|
82
|
+
<td>{{ ingredient.total_price }}</td>
|
|
83
|
+
<td>
|
|
84
|
+
{% if ingredient.is_ignorable %}
|
|
85
|
+
{% trans "Yes" %}
|
|
86
|
+
{% endif %}
|
|
87
|
+
</td>
|
|
88
|
+
<td>
|
|
89
|
+
{% if ingredient.is_disabled %}
|
|
90
|
+
{% trans "Yes" %}
|
|
91
|
+
{% endif %}
|
|
92
|
+
</td>
|
|
93
|
+
<td class="">
|
|
94
|
+
<a class=""
|
|
95
|
+
target="_blank"
|
|
96
|
+
onclick="open_small_window('{% url 'canteen:edit_ingredient' ingredient.id %}'); return false;">
|
|
97
|
+
{% trans "Edit" %}
|
|
98
|
+
</a>
|
|
99
|
+
|
|
|
100
|
+
<a class="text-danger"
|
|
101
|
+
target="_blank"
|
|
102
|
+
onclick="open_small_window('{% url 'canteen:delete_ingredient' ingredient.id %}'); return false;">
|
|
103
|
+
{% trans "Delete" %}
|
|
104
|
+
</a>
|
|
105
|
+
</td>
|
|
106
|
+
</tr>
|
|
107
|
+
{% empty %}
|
|
108
|
+
{% endfor %}
|
|
109
|
+
</tbody>
|
|
110
|
+
</table>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
{% include 'includes/_paginator.html' %}
|
|
114
|
+
<script>
|
|
115
|
+
$(document).ready(function() {
|
|
116
|
+
var ingredient_table = $('.table-ingredient')
|
|
117
|
+
var pagination = $('.pagination')
|
|
118
|
+
var footer = $("footer")
|
|
119
|
+
var height = Math.round((footer.offset().top - pagination.height() - ingredient_table.offset().top) * 0.98)
|
|
120
|
+
ingredient_table.parent().height(
|
|
121
|
+
height
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
$(document).ready(
|
|
125
|
+
function() {
|
|
126
|
+
make_highlight(".tr-ingredient", "ingredient_updated_at")
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
function clear_q() {
|
|
130
|
+
update_href({
|
|
131
|
+
"q": ""
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function submit_q() {
|
|
136
|
+
const q_value = document.querySelector('input[name="q"]').value;
|
|
137
|
+
update_href({
|
|
138
|
+
q: q_value
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function sort_ingredients(value) {
|
|
143
|
+
value = value.trim().split(/\s+/);
|
|
144
|
+
name = value[0];
|
|
145
|
+
value = value[1] || "";
|
|
146
|
+
const url = new URL(window.location.href);
|
|
147
|
+
const params = new URLSearchParams(url.search);
|
|
148
|
+
if (value == "-") {
|
|
149
|
+
value = "";
|
|
150
|
+
} else if (value == "") {
|
|
151
|
+
value = "+";
|
|
152
|
+
} else {
|
|
153
|
+
value = "-";
|
|
154
|
+
}
|
|
155
|
+
i_sort = {};
|
|
156
|
+
i_sort[name] = value;
|
|
157
|
+
update_href(i_sort);
|
|
158
|
+
}
|
|
159
|
+
</script>
|
|
160
|
+
<style>
|
|
161
|
+
.table-container {
|
|
162
|
+
overflow: auto;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.table-container thead th {
|
|
166
|
+
position: sticky;
|
|
167
|
+
top: 0;
|
|
168
|
+
}
|
|
169
|
+
</style>
|
|
170
|
+
|
|
171
|
+
{% endblock %}
|
|
@@ -395,7 +395,31 @@ def edit_ingredient(request, ingredient_id):
|
|
|
395
395
|
ingredient = get_object_or_404(Ingredient, pk=ingredient_id)
|
|
396
396
|
|
|
397
397
|
if request.method == "POST":
|
|
398
|
+
|
|
398
399
|
form = IngredientForm(request.POST, instance=ingredient)
|
|
400
|
+
|
|
401
|
+
total_price = form.instance.total_price
|
|
402
|
+
quantity = form.instance.quantity
|
|
403
|
+
|
|
404
|
+
[total_price0, quantity0], [total_price1, quantity1] = split_price(
|
|
405
|
+
total_price, quantity
|
|
406
|
+
)
|
|
407
|
+
|
|
408
|
+
if total_price1:
|
|
409
|
+
unit_price_error_msg = _(
|
|
410
|
+
"The unit pricei ({unit_price}) has more than 3 decimal places and cannot be saved. Please modify it again."
|
|
411
|
+
).format(
|
|
412
|
+
unit_price=(
|
|
413
|
+
Decimal(str(total_price)) / Decimal(str(float(quantity)))
|
|
414
|
+
).normalize()
|
|
415
|
+
)
|
|
416
|
+
form.add_error("total_price", unit_price_error_msg)
|
|
417
|
+
form.add_error("quantity", unit_price_error_msg)
|
|
418
|
+
return render(
|
|
419
|
+
request, "canteen/ingredient/update.html", {"form": form}
|
|
420
|
+
)
|
|
421
|
+
|
|
422
|
+
form.instance.user = request.user
|
|
399
423
|
if form.is_valid():
|
|
400
424
|
form.save()
|
|
401
425
|
return render(
|
|
@@ -413,9 +437,10 @@ def list_ingredients(request):
|
|
|
413
437
|
search_query = request.GET.get("q", "")
|
|
414
438
|
search_query_cp = search_query
|
|
415
439
|
fields = [
|
|
416
|
-
f
|
|
440
|
+
f
|
|
441
|
+
for f in Ingredient._meta.fields
|
|
442
|
+
if f.name in IngredientForm._meta.fields
|
|
417
443
|
]
|
|
418
|
-
|
|
419
444
|
if search_query:
|
|
420
445
|
queries = Q(user=request.user)
|
|
421
446
|
|
|
@@ -846,6 +871,30 @@ class IngredientCreateView(LoginRequiredMixin, CreateView):
|
|
|
846
871
|
|
|
847
872
|
def form_valid(self, form):
|
|
848
873
|
form.instance.user = self.request.user
|
|
874
|
+
total_price = form.instance.total_price
|
|
875
|
+
quantity = form.instance.quantity
|
|
876
|
+
|
|
877
|
+
[total_price0, quantity0], [total_price1, quantity1] = split_price(
|
|
878
|
+
total_price, quantity
|
|
879
|
+
)
|
|
880
|
+
|
|
881
|
+
if form.is_valid() and total_price1:
|
|
882
|
+
Ingredient.objects.create(
|
|
883
|
+
user=form.instance.user,
|
|
884
|
+
storage_date=form.instance.storage_date,
|
|
885
|
+
name=form.instance.name + _("(2)"),
|
|
886
|
+
meal_type=form.instance.meal_type,
|
|
887
|
+
category=form.instance.category,
|
|
888
|
+
quantity=quantity1,
|
|
889
|
+
total_price=total_price1,
|
|
890
|
+
quantity_unit_name=form.instance.quantity_unit_name,
|
|
891
|
+
is_ignorable=form.instance.is_ignorable,
|
|
892
|
+
)
|
|
893
|
+
form.instance.name = form.instance.name + _("(1)")
|
|
894
|
+
|
|
895
|
+
form.instance.total_price = total_price0
|
|
896
|
+
form.instance.quantity = quantity0
|
|
897
|
+
|
|
849
898
|
return super().form_valid(form)
|
|
850
899
|
|
|
851
900
|
|