fnschool 20250109.80500.803__py3-none-any.whl → 20251011.80531.840__py3-none-any.whl
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.
- fnschoo1/__init__.py +52 -0
- fnschoo1/canteen/admin.py +3 -0
- fnschoo1/canteen/apps.py +6 -0
- fnschoo1/canteen/forms.py +84 -0
- fnschoo1/canteen/migrations/0001_initial.py +119 -0
- fnschoo1/canteen/migrations/0002_ingredient_is_disabled.py +20 -0
- fnschoo1/canteen/migrations/0003_consumption_is_disabled_alter_ingredient_is_disabled.py +23 -0
- fnschoo1/canteen/migrations/0004_alter_ingredient_name_category_and_more.py +66 -0
- fnschoo1/canteen/migrations/0005_alter_category_created_at_alter_category_name_and_more.py +41 -0
- fnschoo1/canteen/migrations/0006_category_is_disabled_alter_category_user_and_more.py +49 -0
- fnschoo1/canteen/migrations/0007_alter_consumption_amount_used_and_more.py +30 -0
- fnschoo1/canteen/migrations/0008_category_abbreviation_mealtype.py +67 -0
- fnschoo1/canteen/migrations/0009_alter_category_abbreviation_and_more.py +55 -0
- fnschoo1/canteen/migrations/0010_alter_consumption_options_alter_ingredient_options_and_more.py +215 -0
- fnschoo1/canteen/migrations/0011_category_pin_to_consumptions_top.py +23 -0
- fnschoo1/canteen/migrations/0012_alter_ingredient_storage_date.py +18 -0
- fnschoo1/canteen/models.py +179 -0
- fnschoo1/canteen/templates/canteen/category/create.html +17 -0
- fnschoo1/canteen/templates/canteen/category/delete.html +61 -0
- fnschoo1/canteen/templates/canteen/category/list.html +63 -0
- fnschoo1/canteen/templates/canteen/category/update.html +23 -0
- fnschoo1/canteen/templates/canteen/close.html +11 -0
- fnschoo1/canteen/templates/canteen/consumption/_create.html +19 -0
- fnschoo1/canteen/templates/canteen/consumption/create.html +456 -0
- fnschoo1/canteen/templates/canteen/ingredient/close.html +11 -0
- fnschoo1/canteen/templates/canteen/ingredient/create.html +19 -0
- fnschoo1/canteen/templates/canteen/ingredient/create_one.html +17 -0
- fnschoo1/canteen/templates/canteen/ingredient/delete.html +41 -0
- fnschoo1/canteen/templates/canteen/ingredient/list.html +128 -0
- fnschoo1/canteen/templates/canteen/ingredient/update.html +23 -0
- fnschoo1/canteen/templates/canteen/meal_type/create.html +17 -0
- fnschoo1/canteen/templates/canteen/meal_type/delete.html +56 -0
- fnschoo1/canteen/templates/canteen/meal_type/list.html +59 -0
- fnschoo1/canteen/templates/canteen/meal_type/update.html +23 -0
- fnschoo1/canteen/tests.py +3 -0
- fnschoo1/canteen/urls.py +116 -0
- fnschoo1/canteen/views.py +814 -0
- fnschoo1/canteen/workbook/generate.py +2098 -0
- fnschoo1/db.sqlite3 +0 -0
- fnschoo1/fnschool/__init__.py +13 -0
- fnschoo1/fnschool/asgi.py +16 -0
- fnschoo1/fnschool/settings.py +167 -0
- fnschoo1/fnschool/templatetags/fnschool_tags.py +27 -0
- fnschoo1/fnschool/urls.py +30 -0
- fnschoo1/fnschool/views.py +9 -0
- fnschoo1/fnschool/wsgi.py +16 -0
- fnschoo1/locale/en/LC_MESSAGES/django.mo +0 -0
- fnschoo1/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- fnschoo1/manage.py +25 -0
- fnschoo1/profiles/admin.py +27 -0
- fnschoo1/profiles/apps.py +12 -0
- fnschoo1/profiles/forms.py +67 -0
- fnschoo1/profiles/migrations/0001_initial.py +192 -0
- fnschoo1/profiles/migrations/0002_alter_profile_bio.py +20 -0
- fnschoo1/profiles/migrations/0003_alter_profile_options_alter_profile_address_and_more.py +67 -0
- fnschoo1/profiles/migrations/0004_profile_gender.py +26 -0
- fnschoo1/profiles/migrations/0005_alter_profile_gender.py +23 -0
- fnschoo1/profiles/models.py +60 -0
- fnschoo1/profiles/signals.py +20 -0
- fnschoo1/profiles/templates/profiles/create.html +16 -0
- fnschoo1/profiles/templates/profiles/detail.html +14 -0
- fnschoo1/profiles/templates/profiles/edit.html +12 -0
- fnschoo1/profiles/templates/profiles/log_in.html +20 -0
- fnschoo1/profiles/templates/profiles/log_out.html +12 -0
- fnschoo1/profiles/tests.py +3 -0
- fnschoo1/profiles/urls.py +15 -0
- fnschoo1/profiles/views.py +63 -0
- fnschoo1/static/css/bootstrap.min.css +11776 -0
- fnschoo1/static/css/fnschool.css +26 -0
- fnschoo1/static/js/bootstrap.bundle.min.js +4223 -0
- fnschoo1/static/js/bootstrap.min.js +2919 -0
- fnschoo1/static/js/fnschool.js +84 -0
- fnschoo1/static/js/jquery.min.js +5413 -0
- fnschoo1/static/js/jquery.slim.min.js +4331 -0
- fnschoo1/static/js/popper.min.js +1306 -0
- fnschoo1/static_collected/admin/css/autocomplete.css +377 -0
- fnschoo1/static_collected/admin/css/base.css +1224 -0
- fnschoo1/static_collected/admin/css/changelists.css +334 -0
- fnschoo1/static_collected/admin/css/dark_mode.css +136 -0
- fnschoo1/static_collected/admin/css/dashboard.css +30 -0
- fnschoo1/static_collected/admin/css/forms.css +546 -0
- fnschoo1/static_collected/admin/css/login.css +62 -0
- fnschoo1/static_collected/admin/css/nav_sidebar.css +145 -0
- fnschoo1/static_collected/admin/css/responsive.css +1043 -0
- fnschoo1/static_collected/admin/css/responsive_rtl.css +84 -0
- fnschoo1/static_collected/admin/css/rtl.css +311 -0
- fnschoo1/static_collected/admin/css/vendor/select2/select2.css +708 -0
- fnschoo1/static_collected/admin/css/vendor/select2/select2.min.css +1 -0
- fnschoo1/static_collected/admin/css/widgets.css +639 -0
- fnschoo1/static_collected/admin/js/SelectBox.js +128 -0
- fnschoo1/static_collected/admin/js/SelectFilter2.js +503 -0
- fnschoo1/static_collected/admin/js/actions.js +232 -0
- fnschoo1/static_collected/admin/js/admin/DateTimeShortcuts.js +496 -0
- fnschoo1/static_collected/admin/js/admin/RelatedObjectLookups.js +276 -0
- fnschoo1/static_collected/admin/js/autocomplete.js +33 -0
- fnschoo1/static_collected/admin/js/calendar.js +251 -0
- fnschoo1/static_collected/admin/js/cancel.js +29 -0
- fnschoo1/static_collected/admin/js/change_form.js +21 -0
- fnschoo1/static_collected/admin/js/collapse.js +43 -0
- fnschoo1/static_collected/admin/js/core.js +174 -0
- fnschoo1/static_collected/admin/js/filters.js +37 -0
- fnschoo1/static_collected/admin/js/inlines.js +439 -0
- fnschoo1/static_collected/admin/js/jquery.init.js +8 -0
- fnschoo1/static_collected/admin/js/nav_sidebar.js +81 -0
- fnschoo1/static_collected/admin/js/popup_response.js +24 -0
- fnschoo1/static_collected/admin/js/prepopulate.js +43 -0
- fnschoo1/static_collected/admin/js/prepopulate_init.js +20 -0
- fnschoo1/static_collected/admin/js/theme.js +57 -0
- fnschoo1/static_collected/admin/js/urlify.js +529 -0
- fnschoo1/static_collected/admin/js/vendor/jquery/jquery.js +10913 -0
- fnschoo1/static_collected/admin/js/vendor/jquery/jquery.min.js +2 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/af.js +43 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ar.js +36 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/az.js +33 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/bg.js +38 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/bn.js +39 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/bs.js +48 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ca.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/cs.js +62 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/da.js +37 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/de.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/dsb.js +51 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/el.js +43 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/en.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/es.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/et.js +38 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/eu.js +45 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/fa.js +42 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/fi.js +42 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/fr.js +43 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/gl.js +40 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/he.js +44 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hi.js +40 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hr.js +45 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hsb.js +51 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hu.js +44 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/hy.js +40 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/id.js +36 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/is.js +37 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/it.js +43 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ja.js +40 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ka.js +42 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/km.js +38 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ko.js +42 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/lt.js +45 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/lv.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/mk.js +42 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ms.js +38 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/nb.js +38 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ne.js +44 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/nl.js +46 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/pl.js +43 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ps.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/pt-BR.js +39 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/pt.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ro.js +43 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/ru.js +48 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sk.js +61 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sl.js +41 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sq.js +43 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sr-Cyrl.js +48 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sr.js +48 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/sv.js +40 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/th.js +36 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/tk.js +36 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/tr.js +40 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/uk.js +59 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/vi.js +37 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/zh-CN.js +36 -0
- fnschoo1/static_collected/admin/js/vendor/select2/i18n/zh-TW.js +33 -0
- fnschoo1/static_collected/admin/js/vendor/select2/select2.full.js +7115 -0
- fnschoo1/static_collected/admin/js/vendor/select2/select2.full.min.js +2 -0
- fnschoo1/static_collected/admin/js/vendor/xregexp/xregexp.js +4993 -0
- fnschoo1/static_collected/admin/js/vendor/xregexp/xregexp.min.js +160 -0
- fnschoo1/static_collected/css/bootstrap.min.css +11776 -0
- fnschoo1/static_collected/css/fnschool.css +26 -0
- fnschoo1/static_collected/js/bootstrap.bundle.min.js +4223 -0
- fnschoo1/static_collected/js/bootstrap.min.js +2919 -0
- fnschoo1/static_collected/js/fnschool.js +84 -0
- fnschoo1/static_collected/js/jquery.min.js +5413 -0
- fnschoo1/static_collected/js/jquery.slim.min.js +4331 -0
- fnschoo1/static_collected/js/popper.min.js +1306 -0
- fnschoo1/templates/base/_css.html +1 -0
- fnschoo1/templates/base/_js.html +15 -0
- fnschoo1/templates/base/content.html +30 -0
- fnschoo1/templates/base/header_content_footer.html +35 -0
- fnschoo1/templates/close.html +11 -0
- fnschoo1/templates/home.html +51 -0
- fnschoo1/templates/includes/_footer.html +39 -0
- fnschoo1/templates/includes/_header.html +77 -0
- fnschoo1/templates/includes/_navigation.html +0 -0
- fnschoo1/templates/includes/_paginator.html +27 -0
- fnschoo1/templates/registration/logged_out.html +0 -0
- fnschoo1/templates/registration/login.html +0 -0
- fnschool-20251011.80531.840.dist-info/METADATA +179 -0
- fnschool-20251011.80531.840.dist-info/RECORD +207 -0
- {fnschool-20250109.80500.803.dist-info → fnschool-20251011.80531.840.dist-info}/WHEEL +1 -1
- fnschool-20251011.80531.840.dist-info/entry_points.txt +2 -0
- fnschool-20251011.80531.840.dist-info/top_level.txt +1 -0
- fnschool/__init__.py +0 -35
- fnschool/__main__.py +0 -16
- fnschool/app.py +0 -103
- fnschool/canteen/__init__.py +0 -3
- fnschool/canteen/__main__.py +0 -3
- fnschool/canteen/bill.py +0 -253
- fnschool/canteen/canteen.py +0 -1
- fnschool/canteen/canteen.toml +0 -61
- fnschool/canteen/config.py +0 -10
- fnschool/canteen/consuming.py +0 -53
- fnschool/canteen/currency.py +0 -17
- fnschool/canteen/data/bill.i18n.xlsx +0 -0
- fnschool/canteen/data/bill.xlsx +0 -0
- fnschool/canteen/data/consuming.xlsx +0 -0
- fnschool/canteen/data/purchase_list.xlsx +0 -0
- fnschool/canteen/entry.py +0 -40
- fnschool/canteen/food.py +0 -206
- fnschool/canteen/food_classes.py +0 -33
- fnschool/canteen/food_classes.toml +0 -64
- fnschool/canteen/operator.py +0 -91
- fnschool/canteen/path.py +0 -28
- fnschool/canteen/spreadsheet/base.py +0 -212
- fnschool/canteen/spreadsheet/consuming.py +0 -310
- fnschool/canteen/spreadsheet/consumingsum.py +0 -76
- fnschool/canteen/spreadsheet/cover.py +0 -64
- fnschool/canteen/spreadsheet/ctspreadsheet.py +0 -351
- fnschool/canteen/spreadsheet/food.py +0 -680
- fnschool/canteen/spreadsheet/inventory.py +0 -375
- fnschool/canteen/spreadsheet/merging.py +0 -340
- fnschool/canteen/spreadsheet/preconsuming.py +0 -329
- fnschool/canteen/spreadsheet/purchasing.py +0 -885
- fnschool/canteen/spreadsheet/purchasingsum.py +0 -110
- fnschool/canteen/spreadsheet/spreadsheet.py +0 -363
- fnschool/canteen/spreadsheet/translating.py +0 -12
- fnschool/canteen/spreadsheet/unwarehousing.py +0 -178
- fnschool/canteen/spreadsheet/unwarehousingsum.py +0 -11
- fnschool/canteen/spreadsheet/warehousing.py +0 -360
- fnschool/canteen/spreadsheet/workbook.py +0 -17
- fnschool/canteen/test.py +0 -97
- fnschool/config.py +0 -48
- fnschool/entry.py +0 -67
- fnschool/exam/__init__.py +0 -8
- fnschool/exam/data/parental_emails.xlsx +0 -0
- fnschool/exam/data/score.xlsx +0 -0
- fnschool/exam/email.py +0 -349
- fnschool/exam/entry.py +0 -36
- fnschool/exam/language.py +0 -19
- fnschool/exam/path.py +0 -24
- fnschool/exam/score.py +0 -1191
- fnschool/exam/subject.py +0 -20
- fnschool/exam/teacher.py +0 -54
- fnschool/external.py +0 -89
- fnschool/games/__init__.py +0 -1
- fnschool/games/__main__.py +0 -1
- fnschool/games/games.py +0 -1
- fnschool/inoutput.py +0 -97
- fnschool/language.py +0 -40
- fnschool/locales/en_US/LC_MESSAGES/fnschool.mo +0 -0
- fnschool/locales/zh_CN/LC_MESSAGES/fnschool.mo +0 -0
- fnschool/locales/zh_HK/LC_MESSAGES/fnschool.mo +0 -0
- fnschool/locales/zh_SG/LC_MESSAGES/fnschool.mo +0 -0
- fnschool/locales/zh_TW/LC_MESSAGES/fnschool.mo +0 -0
- fnschool/path.py +0 -45
- fnschool/test.py +0 -24
- fnschool/user.py +0 -262
- fnschool-20250109.80500.803.dist-info/METADATA +0 -342
- fnschool-20250109.80500.803.dist-info/RECORD +0 -78
- fnschool-20250109.80500.803.dist-info/entry_points.txt +0 -5
- fnschool-20250109.80500.803.dist-info/top_level.txt +0 -1
- /fnschool/canteen/consume.py → /fnschoo1/canteen/__init__.py +0 -0
- /fnschool/canteen/food_recount.toml → /fnschoo1/canteen/migrations/__init__.py +0 -0
- {fnschool/canteen/spreadsheet → fnschoo1/canteen/workbook}/__init__.py +0 -0
- /fnschool/exam/__main__.py → /fnschoo1/fnschool/templatetags/__init__.py +0 -0
- /fnschool/canteen/food_recounts.toml → /fnschoo1/profiles/__init__.py +0 -0
- /fnschool/canteen/warehouse.py → /fnschoo1/profiles/migrations/__init__.py +0 -0
- /fnschool/canteen/workbook.toml → /fnschoo1/templates/base/_content.html +0 -0
- {fnschool-20250109.80500.803.dist-info → fnschool-20251011.80531.840.dist-info/licenses}/LICENSE +0 -0
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
{% extends "base/header_content_footer.html" %}
|
|
2
|
+
{% load crispy_forms_tags %}
|
|
3
|
+
{% block title %}
|
|
4
|
+
{% trans "Consume Ingredients" %}
|
|
5
|
+
{% endblock %}
|
|
6
|
+
{% block content %}
|
|
7
|
+
<h1>{% trans "Consume Ingredients" %}</h1>
|
|
8
|
+
<hr>
|
|
9
|
+
<div class="container">
|
|
10
|
+
<div class="row justify-content-end">
|
|
11
|
+
<div class="col col-3 col-md-2 col-lg-2">
|
|
12
|
+
<input class=" form-control"
|
|
13
|
+
onkeydown="if(event.keyCode==13){list_consumptions();}"
|
|
14
|
+
title="{% trans 'The starting date of storage.' %}"
|
|
15
|
+
id="storage_date_start"
|
|
16
|
+
value="{{ request.COOKIES.storage_date_start }}">
|
|
17
|
+
</input>
|
|
18
|
+
</div>
|
|
19
|
+
<div class="col col-3 col-md-2 col-lg-2">
|
|
20
|
+
<input class="form-control "
|
|
21
|
+
onkeydown="if(event.keyCode==13){list_consumptions();}"
|
|
22
|
+
title="{% trans 'The end date of storage.' %}"
|
|
23
|
+
id="storage_date_end"
|
|
24
|
+
value="{{ request.COOKIES.storage_date_end }}">
|
|
25
|
+
</input>
|
|
26
|
+
</div>
|
|
27
|
+
<button class="btn btn-success col-md-1 col-lg-1 col-2"
|
|
28
|
+
onclick="list_consumptions();">{% trans "Refresh" %}</button>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
<div class="table table-responsive table-container">
|
|
32
|
+
<table class="table table-consumptions cotable-bordered table-striped table-hover table-condensed scroll-vertical ">
|
|
33
|
+
<thead>
|
|
34
|
+
<tr>
|
|
35
|
+
{% if ingredients %}
|
|
36
|
+
<th class="">{% trans "Ingredient Name" %}</th>
|
|
37
|
+
<th class="">{% trans "Remaining Quantity" %}</th>
|
|
38
|
+
{% endif %}
|
|
39
|
+
{% for date_h in date_range %}
|
|
40
|
+
<th data-date_of_using="{{ date_h }}" class="consumption-date">{{ date_h }}</th>
|
|
41
|
+
{% empty %}
|
|
42
|
+
<th></th>
|
|
43
|
+
{% endfor %}
|
|
44
|
+
</tr>
|
|
45
|
+
</thead>
|
|
46
|
+
<tbody>
|
|
47
|
+
{% for ingredient in ingredients %}
|
|
48
|
+
<tr class="row-consumption"
|
|
49
|
+
data-ingredient_id="{{ ingredient.id }}"
|
|
50
|
+
data-ingredient_name="{{ ingredient.name }}"
|
|
51
|
+
data-ingredient_quantity="{{ ingredient.quantity }}"
|
|
52
|
+
data-ingredient_total_price="{{ ingredient.total_price }}"
|
|
53
|
+
data-ingredient_meal_type="{{ ingredient.meal_type }}"
|
|
54
|
+
data-ingredient_quantity_unit_name="{{ ingredient.quantity_unit_name }}"
|
|
55
|
+
data-ingredient_unit_price="{{ ingredient.unit_price }}"
|
|
56
|
+
id="ingredient_num_{{ ingredient.id }}">
|
|
57
|
+
<td title="{% blocktrans with storage_date=ingredient.storage_date %}Storaged on {{ storage_date }} .{% endblocktrans %}"
|
|
58
|
+
class="">
|
|
59
|
+
<div class='ingredient-progress'
|
|
60
|
+
style="width:{% widthratio ingredient.remaining_quantity ingredient.quantity 100 %}%"></div>
|
|
61
|
+
{{ ingredient.name }}
|
|
62
|
+
{% if ingredient.meal_type %}
|
|
63
|
+
<br />
|
|
64
|
+
({{ ingredient.meal_type }})
|
|
65
|
+
{% endif %}
|
|
66
|
+
</td>
|
|
67
|
+
<td name="remaining_{{ ingredient.id }}">
|
|
68
|
+
{{ ingredient.quantity }}-{{ ingredient.consuming_quantity }}={{ ingredient.remaining_quantity }}
|
|
69
|
+
</td>
|
|
70
|
+
</tr>
|
|
71
|
+
{% empty %}
|
|
72
|
+
<tr>{% trans "No ingredient found." %}</tr>
|
|
73
|
+
{% endfor %}
|
|
74
|
+
</tbody>
|
|
75
|
+
</table>
|
|
76
|
+
</div>
|
|
77
|
+
<div class="">
|
|
78
|
+
<button onclick="submit_consumptions();"
|
|
79
|
+
class="btn btn-submit-consumptions btn-primary float-start">{% trans "Submit" %}</button>
|
|
80
|
+
<button onclick="generate_spreadsheet();"
|
|
81
|
+
class="btn btn-submit-consumptions btn-success float-end">{% trans "Generate Spreadsheet" %}</button>
|
|
82
|
+
<select class="workbook-month-select form-select float-end mx-2"
|
|
83
|
+
style="width:118px"></select>
|
|
84
|
+
</div>
|
|
85
|
+
{{ ingredient_ids|json_script:'ingredient_ids' }}
|
|
86
|
+
{{ months|json_script:'months' }}
|
|
87
|
+
{{ meal_types|json_script:'meal_types' }}
|
|
88
|
+
{{ date_range|json_script:'date_range' }}
|
|
89
|
+
<script>
|
|
90
|
+
var ingredient_ids = JSON.parse($("#ingredient_ids").text())
|
|
91
|
+
var ingredient_ids_length = ingredient_ids.length
|
|
92
|
+
var months = JSON.parse($("#months").text())
|
|
93
|
+
var meal_types = JSON.parse($("#meal_types").text())
|
|
94
|
+
var dont_submit = false
|
|
95
|
+
|
|
96
|
+
date_range = JSON.parse($("#date_range").text())
|
|
97
|
+
|
|
98
|
+
function get_previous_month_date(date = new Date()) {
|
|
99
|
+
const prevMonthDate = new Date(date);
|
|
100
|
+
prevMonthDate.setDate(1);
|
|
101
|
+
prevMonthDate.setMonth(prevMonthDate.getMonth() - 1);
|
|
102
|
+
return prevMonthDate;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function is_weekend(date) {
|
|
106
|
+
const dayOfWeek = date.getDay();
|
|
107
|
+
return dayOfWeek === 0 || dayOfWeek === 6;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
$(document).ready(function() {
|
|
111
|
+
$(months).each(function(index, value) {
|
|
112
|
+
$('.workbook-month-select').append(`<option>${value}</option>`)
|
|
113
|
+
});
|
|
114
|
+
var now = new Date();
|
|
115
|
+
prev_month = get_previous_month_date(now)
|
|
116
|
+
var year = prev_month.getFullYear();
|
|
117
|
+
var month = prev_month.getMonth() + 1;
|
|
118
|
+
month = month < 10 ? `0${month}` : `${month}`;
|
|
119
|
+
$('.workbook-month-select').val(`${year}-${month}`)
|
|
120
|
+
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
$(document).ready(function() {
|
|
125
|
+
var last_meal_type = ""
|
|
126
|
+
var consumption_rows = $(".row-consumption")
|
|
127
|
+
consumption_rows.each(function(index, element) {
|
|
128
|
+
meal_type = $(element).data("ingredient_meal_type")
|
|
129
|
+
if (last_meal_type != meal_type) {
|
|
130
|
+
$(element).find("td").css({
|
|
131
|
+
"color": "red"
|
|
132
|
+
})
|
|
133
|
+
last_meal_type = meal_type
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
function amount_used_input_blur(element) {
|
|
139
|
+
element = $(element)
|
|
140
|
+
var ingredient_quantity = element.closest('tr').data("ingredient_quantity")
|
|
141
|
+
ingredient_quantity = parseInt(ingredient_quantity) || 0
|
|
142
|
+
var amount_used = element.closest("form").data("amount_used")
|
|
143
|
+
var new_amount_used = $.trim(element.val())
|
|
144
|
+
new_amount_used = parseInt(new_amount_used) || 0
|
|
145
|
+
if (new_amount_used < 0) {
|
|
146
|
+
element.val('0')
|
|
147
|
+
new_amount_used = 0
|
|
148
|
+
}
|
|
149
|
+
if (new_amount_used === 0 && amount_used == "None") {
|
|
150
|
+
element.val('')
|
|
151
|
+
}
|
|
152
|
+
if (amount_used > 0 && new_amount_used === 0) {
|
|
153
|
+
element.val('0')
|
|
154
|
+
new_amount_used = 0
|
|
155
|
+
}
|
|
156
|
+
var $tds = element.parent().parent().siblings("td")
|
|
157
|
+
var $amount_used_inputs = $tds.find("form input[name='amount_used']")
|
|
158
|
+
var total_consumed = 0
|
|
159
|
+
$amount_used_inputs.each(function(index, amount_used_element) {
|
|
160
|
+
var value = parseInt($(amount_used_element).val()) || 0
|
|
161
|
+
total_consumed += value
|
|
162
|
+
});
|
|
163
|
+
if ((total_consumed + new_amount_used) > ingredient_quantity) {
|
|
164
|
+
var remaining_quantity = total_consumed < ingredient_quantity ? (ingredient_quantity - total_consumed) : 0
|
|
165
|
+
element.val(remaining_quantity)
|
|
166
|
+
new_amount_used = remaining_quantity
|
|
167
|
+
}
|
|
168
|
+
total_consumed = total_consumed + new_amount_used
|
|
169
|
+
var ingredient_id = element.closest("tr").data("ingredient_id")
|
|
170
|
+
$(`td[name='remaining_${ingredient_id}']`).text(`${ingredient_quantity}-${total_consumed}=${ingredient_quantity-total_consumed}`)
|
|
171
|
+
element.closest("tr").find('.ingredient-progress').css('width', `${parseInt((ingredient_quantity-total_consumed)*100/ingredient_quantity)}%`)
|
|
172
|
+
var date_of_using = element.closest("form").data("date_of_using")
|
|
173
|
+
update_header(date_of_using)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function update_header(date_of_using) {
|
|
177
|
+
var consumption_content_dated = date_of_using
|
|
178
|
+
$(meal_types).each(function(index, meal_type) {
|
|
179
|
+
var total_price_dated = 0.0
|
|
180
|
+
$(`form[data-date_of_using="${date_of_using}"][data-ingredient_meal_type="${meal_type}"]`).each(function(index, element) {
|
|
181
|
+
element = $(element)
|
|
182
|
+
var unit_price = parseFloat(element.data("ingredient_unit_price"))
|
|
183
|
+
var quantity = parseFloat(element.find("input[name='amount_used']").val()) || 0
|
|
184
|
+
total_price_dated += (unit_price * quantity)
|
|
185
|
+
});
|
|
186
|
+
total_price_dated = total_price_dated.toFixed(2)
|
|
187
|
+
consumption_content_dated += `<br />${meal_type}:${total_price_dated}`
|
|
188
|
+
});
|
|
189
|
+
$(`th[data-date_of_using="${date_of_using}"]`).html(consumption_content_dated)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function update_headers() {
|
|
193
|
+
|
|
194
|
+
$(date_range).each(function(index, date_h) {
|
|
195
|
+
update_header(date_h)
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
$(document).ready(function() {
|
|
202
|
+
var td1 = $(".table tr > :nth-child(1):first")
|
|
203
|
+
$(".table tr > :nth-child(2)").css("left", td1.width() * 1.05)
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
$(document).ready(function() {
|
|
207
|
+
dont_submit = true
|
|
208
|
+
var progress = 0
|
|
209
|
+
$.each(ingredient_ids, function(index, value) {
|
|
210
|
+
$.ajax({
|
|
211
|
+
url: "/canteen/create_consumption/" + value,
|
|
212
|
+
method: 'GET',
|
|
213
|
+
success: function(data) {
|
|
214
|
+
data = $(data)
|
|
215
|
+
var footer_progressbar = $('.progress-footer')
|
|
216
|
+
data.each(function(index, element) {
|
|
217
|
+
if (is_weekend(new Date($(element).data("date_of_using")))) {
|
|
218
|
+
$(element).find('[name="amount_used"]').addClass("weekend")
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
data.find('input[name="amount_used"]').blur(function() {
|
|
222
|
+
amount_used_input_blur(this)
|
|
223
|
+
});
|
|
224
|
+
$('#ingredient_num_' + value).append(data)
|
|
225
|
+
if (footer_progressbar) {
|
|
226
|
+
progress += 1
|
|
227
|
+
footer_progressbar.css('width', `${progress*100/ingredient_ids_length}%`)
|
|
228
|
+
if (progress >= ingredient_ids_length) {
|
|
229
|
+
footer_progressbar.css('width', "0%")
|
|
230
|
+
update_headers()
|
|
231
|
+
dont_submit = false
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
$(document).ready(function() {
|
|
242
|
+
$('.table-consumptions').on('keydown', 'input[name="amount_used"]', function(e) {
|
|
243
|
+
if ([9, 13, 37, 38, 39, 40].includes(e.keyCode)) {
|
|
244
|
+
e.preventDefault();
|
|
245
|
+
navigateToNextCell(
|
|
246
|
+
$(this),
|
|
247
|
+
e.keyCode === 9 ? "r" :
|
|
248
|
+
e.keyCode === 13 ? "d" :
|
|
249
|
+
e.keyCode === 37 ? "l" :
|
|
250
|
+
e.keyCode === 38 ? "u" :
|
|
251
|
+
e.keyCode === 39 ? "r" :
|
|
252
|
+
e.keyCode === 40 ? "d" : ""
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
if ((e.keyCode < 91 && e.keyCode > 64) || e.keyCode == 32) {
|
|
256
|
+
e.preventDefault()
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
function navigateToNextCell($currentInput, direction) {
|
|
262
|
+
var td = $currentInput.closest("form").closest('td');
|
|
263
|
+
var columnIndex = td.index();
|
|
264
|
+
|
|
265
|
+
var rowIndex = td.closest("tr").index()
|
|
266
|
+
if (direction == 'l') {
|
|
267
|
+
columnIndex = columnIndex - 1
|
|
268
|
+
rowIndex = rowIndex + 1
|
|
269
|
+
} else if (direction == 'r') {
|
|
270
|
+
columnIndex = columnIndex + 1
|
|
271
|
+
rowIndex = rowIndex + 1
|
|
272
|
+
} else if (direction == "u") {
|
|
273
|
+
rowIndex = rowIndex
|
|
274
|
+
} else if (direction == 'd') {
|
|
275
|
+
rowIndex = rowIndex + 2
|
|
276
|
+
}
|
|
277
|
+
var cell = $('.table-consumptions').find(`tr:eq(${rowIndex}) td:eq(${columnIndex})`);
|
|
278
|
+
var amount_used_input = cell.find('input[name="amount_used"]')
|
|
279
|
+
amount_used_input.first().focus()
|
|
280
|
+
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
function generate_spreadsheet() {
|
|
285
|
+
submit_consumptions(function() {
|
|
286
|
+
var month = $(".workbook-month-select").val()
|
|
287
|
+
window.open(`/canteen/generate_spreadsheet/${month}`, '_blank');
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function submit_consumptions(fn) {
|
|
293
|
+
if (dont_submit) {
|
|
294
|
+
return false
|
|
295
|
+
} else {
|
|
296
|
+
dont_submit = true
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
var consumption_forms = $('form[name="consumption_form"]')
|
|
300
|
+
var requests = [];
|
|
301
|
+
var progress = 0
|
|
302
|
+
consumption_forms_cp = []
|
|
303
|
+
consumption_forms.each(function(index, element) {
|
|
304
|
+
var form = $(element);
|
|
305
|
+
var amount_used_init = parseInt(form.data("amount_used")) || 0
|
|
306
|
+
var amount_used_new = parseInt(form.find("input[name='amount_used']").val()) || 0
|
|
307
|
+
if (form.data("is_disabled") == "True") {
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
if (form.find('input[name="amount_used"]').val().length < 1) {
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
if (amount_used_new == amount_used_init) {
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
316
|
+
consumption_forms_cp.push(form)
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
consumption_forms = consumption_forms_cp
|
|
320
|
+
var consumption_forms_length = consumption_forms.length
|
|
321
|
+
$(consumption_forms).each(function(index, element) {
|
|
322
|
+
form = $(element)
|
|
323
|
+
requests.push(
|
|
324
|
+
$.ajax({
|
|
325
|
+
url: form.attr('action'),
|
|
326
|
+
type: form.attr('method') || 'POST',
|
|
327
|
+
data: form.serialize(),
|
|
328
|
+
success: function(response) {
|
|
329
|
+
progress += 1
|
|
330
|
+
var footer_progressbar = $('.progress-footer')
|
|
331
|
+
if (footer_progressbar) {
|
|
332
|
+
var width = `${parseInt(progress*100/consumption_forms_length)}%`
|
|
333
|
+
$(footer_progressbar).css("width", width)
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}).catch(function(error) {
|
|
337
|
+
return erroe;
|
|
338
|
+
}));
|
|
339
|
+
});
|
|
340
|
+
$.when.apply($, requests)
|
|
341
|
+
.done(function() {
|
|
342
|
+
if (fn != undefined) {
|
|
343
|
+
fn()
|
|
344
|
+
}
|
|
345
|
+
location.reload();
|
|
346
|
+
})
|
|
347
|
+
.fail(function() {});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function set_consumptions_table_size() {
|
|
351
|
+
const submit_consumptions_btn = $(".btn-submit-consumptions")
|
|
352
|
+
const consumptions_table = $(".table-consumptions")
|
|
353
|
+
const header = $("header")
|
|
354
|
+
const footer = $("footer")
|
|
355
|
+
const height = Math.round((footer.offset().top - submit_consumptions_btn.height() - consumptions_table.offset().top) * 0.95)
|
|
356
|
+
consumptions_table.parent().height(height)
|
|
357
|
+
}
|
|
358
|
+
$(window).resize(function() {
|
|
359
|
+
set_consumptions_table_size()
|
|
360
|
+
});
|
|
361
|
+
$(document).ready(function() {
|
|
362
|
+
set_consumptions_table_size()
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
function list_consumptions() {
|
|
366
|
+
var storage_date_start = $('#storage_date_start').val()
|
|
367
|
+
var storage_date_end = $('#storage_date_end').val()
|
|
368
|
+
query = {}
|
|
369
|
+
if (storage_date_start) {
|
|
370
|
+
query["storage_date_start"] = storage_date_start
|
|
371
|
+
set_simple_cookie("storage_date_start", storage_date_start)
|
|
372
|
+
} else {
|
|
373
|
+
query["storage_date_start"] = ""
|
|
374
|
+
delete_cookie("storage_date_start")
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (storage_date_end) {
|
|
378
|
+
query["storage_date_end"] = storage_date_end
|
|
379
|
+
set_simple_cookie("storage_date_end", storage_date_end)
|
|
380
|
+
} else {
|
|
381
|
+
query["storage_date_end"] = ""
|
|
382
|
+
delete_cookie("storage_date_end")
|
|
383
|
+
}
|
|
384
|
+
update_href(query)
|
|
385
|
+
}
|
|
386
|
+
</script>
|
|
387
|
+
<style>
|
|
388
|
+
.ingredient-progress {
|
|
389
|
+
height: 2px;
|
|
390
|
+
background: green;
|
|
391
|
+
right: 9px;
|
|
392
|
+
position: absolute;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
#storage_date_start,
|
|
396
|
+
#storage_date_end {
|
|
397
|
+
text-align: center;
|
|
398
|
+
font-family: Mono;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
.weekend {
|
|
402
|
+
background-color: pink;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
.table-container {
|
|
406
|
+
overflow: auto;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
.table thead th {
|
|
410
|
+
position: -webkit-sticky;
|
|
411
|
+
position: sticky;
|
|
412
|
+
top: 0;
|
|
413
|
+
z-index: 1010;
|
|
414
|
+
white-space: nowrap;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.table tr {
|
|
418
|
+
font-size: 15px;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
.table tr> :nth-child(1) {
|
|
422
|
+
position: -webkit-sticky;
|
|
423
|
+
position: sticky;
|
|
424
|
+
left: 0;
|
|
425
|
+
z-index: 1010;
|
|
426
|
+
white-space: nowrap;
|
|
427
|
+
text-align: right;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
.table tr> :nth-child(2) {
|
|
431
|
+
position: -webkit-sticky;
|
|
432
|
+
position: sticky;
|
|
433
|
+
z-index: 1010;
|
|
434
|
+
font-family: Mono;
|
|
435
|
+
text-align: right;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
.table thead tr {
|
|
439
|
+
font-size: 15px;
|
|
440
|
+
font-family: Mono;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.table thead tr> :nth-child(1) {
|
|
444
|
+
z-index: 1020;
|
|
445
|
+
white-space: nowrap;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
.table thead tr> :nth-child(2) {
|
|
449
|
+
z-index: 1020;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
nav li {
|
|
453
|
+
z-index: 1030;
|
|
454
|
+
}
|
|
455
|
+
</style>
|
|
456
|
+
{% endblock %}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{% extends "base/content.html" %}
|
|
2
|
+
{% load crispy_forms_tags %}
|
|
3
|
+
{% block title %}
|
|
4
|
+
{% trans "Upload a Spreadsheet of Purchased Ingredients" %}
|
|
5
|
+
{% endblock %}
|
|
6
|
+
{% block content %}
|
|
7
|
+
<h2>{% trans "Please upload a spreadsheet of purchased ingredients." %}</h2>
|
|
8
|
+
<p>
|
|
9
|
+
{% trans "Need a template file?" %}
|
|
10
|
+
<a href="{% url 'canteen:get_template_workbook_of_purchased_ingredients' %}">{% trans "Download it." %}</a>
|
|
11
|
+
</p>
|
|
12
|
+
<form method="post" enctype="multipart/form-data">
|
|
13
|
+
{% csrf_token %} {{ form|crispy }}
|
|
14
|
+
<div class="py-3 fixed-bottom text-end bg-dark">
|
|
15
|
+
<button type="submit button" class="btn btn-outline-primary">{% trans "Upload" %}</button>
|
|
16
|
+
<button type="button" class="btn btn-danger" onclick="window.close();">{% trans "Cancel" %}</button>
|
|
17
|
+
</div>
|
|
18
|
+
</form>
|
|
19
|
+
{% endblock %}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{% extends "base/content.html" %}
|
|
2
|
+
{% load i18n %}
|
|
3
|
+
{% load crispy_forms_tags %}
|
|
4
|
+
{% block title %}
|
|
5
|
+
{% trans "New Ingredient" %}
|
|
6
|
+
{% endblock %}
|
|
7
|
+
{% block content %}
|
|
8
|
+
<h1>{% trans "Create new Ingredient" %}</h1>
|
|
9
|
+
<form method="post" action="{% url 'canteen:create_ingredient' %}">
|
|
10
|
+
{% csrf_token %}
|
|
11
|
+
{{ form|crispy }}
|
|
12
|
+
<div class="py-3 fixed-bottom text-end bg-dark">
|
|
13
|
+
<button type="submit" class="btn btn-primary">{% trans "Save" %}</button>
|
|
14
|
+
<button type="button" class="btn btn-danger" onclick="window.close();">{% trans "Cancel" %}</button>
|
|
15
|
+
</div>
|
|
16
|
+
</form>
|
|
17
|
+
{% endblock %}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{% extends "base/content.html" %}
|
|
2
|
+
{% load crispy_forms_tags %}
|
|
3
|
+
{% block title %}
|
|
4
|
+
{% blocktrans with instance_name=form.instance.name %}
|
|
5
|
+
Delete Ingredient {{ instance_name }}
|
|
6
|
+
{% endblocktrans %}
|
|
7
|
+
{% endblock %}
|
|
8
|
+
{% block content %}
|
|
9
|
+
<h5 class="">
|
|
10
|
+
{% blocktrans with instance_name=form.instance.name%}
|
|
11
|
+
Delete Ingredient {{ instance_name }} .
|
|
12
|
+
{% endblocktrans %}
|
|
13
|
+
</h5>
|
|
14
|
+
<p>
|
|
15
|
+
<dl>
|
|
16
|
+
{% for field in form %}
|
|
17
|
+
<dt>{{ field.label }}</dt>
|
|
18
|
+
<dd>
|
|
19
|
+
{{ field.value }}
|
|
20
|
+
</dd>
|
|
21
|
+
{% endfor %}
|
|
22
|
+
</dl>
|
|
23
|
+
</p>
|
|
24
|
+
<p class="text-danger">
|
|
25
|
+
{% blocktrans %}
|
|
26
|
+
Are you sure you want to delete this ingredient? This operation is irreversible.
|
|
27
|
+
{% endblocktrans%}
|
|
28
|
+
</p>
|
|
29
|
+
<div class="py-3 fixed-bottom text-end bg-dark">
|
|
30
|
+
<form method="post"
|
|
31
|
+
action="{% url 'canteen:delete_ingredient' form.instance.pk %}"
|
|
32
|
+
style="display: inline">
|
|
33
|
+
{% csrf_token %}
|
|
34
|
+
<button type="submit" class="btn btn-danger">{% trans 'Delete' %}</button>
|
|
35
|
+
<button type="button" class="btn btn-primary" onclick="window.close();">{% trans "Cancel" %}</button>
|
|
36
|
+
</form>
|
|
37
|
+
</div>
|
|
38
|
+
<script>
|
|
39
|
+
localize_content($("dd"))
|
|
40
|
+
</script>
|
|
41
|
+
{% endblock %}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
{% extends "base/header_content_footer.html" %}
|
|
2
|
+
{% load crispy_forms_tags %}
|
|
3
|
+
{% block title %}
|
|
4
|
+
{% trans "Ingredient List" %}
|
|
5
|
+
{% endblock %}
|
|
6
|
+
{% block content %}
|
|
7
|
+
<h1>{% trans "Ingredient List" %}</h1>
|
|
8
|
+
<form method="get"
|
|
9
|
+
action="{% url 'canteen:list_ingredients' %}"
|
|
10
|
+
class="d-flex justify-content-between align-items-center">
|
|
11
|
+
<input type="text"
|
|
12
|
+
name="q"
|
|
13
|
+
onkeydown="if(event.keyCode==13){submit_q();return false;}"
|
|
14
|
+
value="{{ search_query }}"
|
|
15
|
+
placeholder="{% trans 'Search ingredient ...' %}"
|
|
16
|
+
class="form-control" />
|
|
17
|
+
<button type="button"
|
|
18
|
+
onclick="submit_q();"
|
|
19
|
+
class="btn btn-primary text-nowrap">{% trans "Search" %}</button>
|
|
20
|
+
{% if search_query %}
|
|
21
|
+
<a onclick="clear_q();" class="text-nowrap">{% trans "Clear" %}</a>
|
|
22
|
+
{% endif %}
|
|
23
|
+
</form>
|
|
24
|
+
<div class="d-flex justify-content-end pt-2">
|
|
25
|
+
<a class="btn btn-primary mx-1"
|
|
26
|
+
href="{% url "canteen:list_meal_types" %}">{% trans "Ingredient Meal Types" %}</a>
|
|
27
|
+
<a class="btn btn-primary mx-1"
|
|
28
|
+
href="{% url "canteen:list_categories" %}">{% trans "Ingredient Categories" %}</a>
|
|
29
|
+
<a class="btn btn-warning mx-1"
|
|
30
|
+
href="{% url "canteen:create_consumptions" %}">{% trans "Consume" %}</a>
|
|
31
|
+
<a class="btn btn-primary mx-1"
|
|
32
|
+
onclick="open_small_window('{% url 'canteen:create_ingredients' %}')">{% trans "Add via template" %}</a>
|
|
33
|
+
<a class="btn btn-primary"
|
|
34
|
+
onclick="open_small_window('{% url 'canteen:create_ingredient' %}')">{% trans "Add one" %}</a>
|
|
35
|
+
</div>
|
|
36
|
+
<hr />
|
|
37
|
+
<table class="table table-bordered table-striped table-hover table-condensed">
|
|
38
|
+
<thead>
|
|
39
|
+
<tr>
|
|
40
|
+
<th scope="col">#</th>
|
|
41
|
+
{% for name,sort, header in headers %}
|
|
42
|
+
<th scope="col"
|
|
43
|
+
data-sort="sort_{{ name }} {{ sort }}"
|
|
44
|
+
onclick="sort_ingredients(this.dataset.sort);">
|
|
45
|
+
{{ header }}
|
|
46
|
+
{% if sort == "+" %}
|
|
47
|
+
↑
|
|
48
|
+
{% elif sort == "-" %}
|
|
49
|
+
↓
|
|
50
|
+
{% endif %}
|
|
51
|
+
</th>
|
|
52
|
+
{% endfor %}
|
|
53
|
+
<th scope="col"></th>
|
|
54
|
+
</tr>
|
|
55
|
+
</thead>
|
|
56
|
+
<tbody>
|
|
57
|
+
{% for ingredient in page_obj %}
|
|
58
|
+
<tr>
|
|
59
|
+
<th scope="row">{{ forloop.counter }}</th>
|
|
60
|
+
<td>{{ ingredient.storage_date }}</td>
|
|
61
|
+
<td>{{ ingredient.name }}</td>
|
|
62
|
+
<td>{{ ingredient.meal_type }}</td>
|
|
63
|
+
<td>{{ ingredient.category }}</td>
|
|
64
|
+
<td>{{ ingredient.quantity }}</td>
|
|
65
|
+
<td>{{ ingredient.quantity_unit_name }}</td>
|
|
66
|
+
<td>{{ ingredient.total_price }}</td>
|
|
67
|
+
<td>
|
|
68
|
+
{% if ingredient.is_ignorable %}
|
|
69
|
+
{% trans "Yes" %}
|
|
70
|
+
{% endif %}
|
|
71
|
+
</td>
|
|
72
|
+
<td>
|
|
73
|
+
{% if ingredient.is_disabled %}
|
|
74
|
+
{% trans "Yes" %}
|
|
75
|
+
{% endif %}
|
|
76
|
+
</td>
|
|
77
|
+
<td class="">
|
|
78
|
+
<a class=""
|
|
79
|
+
target="_blank"
|
|
80
|
+
onclick="open_small_window('{% url 'canteen:edit_ingredient' ingredient.id %}'); return false;">
|
|
81
|
+
{% trans "Edit" %}
|
|
82
|
+
</a>
|
|
83
|
+
|
|
|
84
|
+
<a class="text-danger"
|
|
85
|
+
target="_blank"
|
|
86
|
+
onclick="open_small_window('{% url 'canteen:delete_ingredient' ingredient.id %}'); return false;">
|
|
87
|
+
{% trans "Delete" %}
|
|
88
|
+
</a>
|
|
89
|
+
</td>
|
|
90
|
+
</tr>
|
|
91
|
+
{% empty %}
|
|
92
|
+
{% endfor %}
|
|
93
|
+
</tbody>
|
|
94
|
+
</table>
|
|
95
|
+
{% include 'includes/_paginator.html' %}
|
|
96
|
+
<script>
|
|
97
|
+
function clear_q() {
|
|
98
|
+
update_href({
|
|
99
|
+
"q": ""
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function submit_q() {
|
|
104
|
+
const q_value = document.querySelector('input[name="q"]').value;
|
|
105
|
+
update_href({
|
|
106
|
+
q: q_value
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function sort_ingredients(value) {
|
|
111
|
+
value = value.trim().split(/\s+/);
|
|
112
|
+
name = value[0];
|
|
113
|
+
value = value[1] || "";
|
|
114
|
+
const url = new URL(window.location.href);
|
|
115
|
+
const params = new URLSearchParams(url.search);
|
|
116
|
+
if (value == "-") {
|
|
117
|
+
value = "";
|
|
118
|
+
} else if (value == "") {
|
|
119
|
+
value = "+";
|
|
120
|
+
} else {
|
|
121
|
+
value = "-";
|
|
122
|
+
}
|
|
123
|
+
i_sort = {};
|
|
124
|
+
i_sort[name] = value;
|
|
125
|
+
update_href(i_sort);
|
|
126
|
+
}
|
|
127
|
+
</script>
|
|
128
|
+
{% endblock %}
|