fnschool 20251018.81021.825__py3-none-any.whl → 20251020.82239.858__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 +1 -1
- fnschoo1/canteen/forms.py +1 -1
- fnschoo1/canteen/migrations/0017_ingredient_updated_at_alter_category_created_at_and_more.py +30 -0
- fnschoo1/canteen/models.py +14 -2
- fnschoo1/canteen/templates/canteen/consumption/create.html +5 -4
- fnschoo1/canteen/templates/canteen/ingredient/list.html +101 -69
- fnschoo1/canteen/views.py +51 -2
- fnschoo1/canteen/workbook/generate.py +172 -174
- fnschoo1/fnschool/_settings.py +3 -0
- fnschoo1/fnschool/settings.py +12 -1
- fnschoo1/locale/zh_Hans/LC_MESSAGES/django.mo +0 -0
- fnschoo1/static/css/fnschool.css +6 -0
- fnschoo1/static/js/fnschool.js +24 -0
- {fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/METADATA +1 -1
- {fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/RECORD +24 -22
- {fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/SOURCES.txt.py +0 -0
- {fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/WHEEL +0 -0
- {fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/dependency_links.txt.py +0 -0
- {fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/entry_points.txt +0 -0
- {fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/entry_points.txt.py +0 -0
- {fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/licenses/LICENSE +0 -0
- {fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/requires.txt.py +0 -0
- {fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/top_level.txt +0 -0
- {fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/top_level.txt.py +0 -0
fnschoo1/__init__.py
CHANGED
fnschoo1/canteen/forms.py
CHANGED
|
@@ -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
|
+
]
|
fnschoo1/canteen/models.py
CHANGED
|
@@ -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() {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
{% extends "base/header_content_footer.html" %}
|
|
2
|
+
{% load tz %}
|
|
2
3
|
{% load crispy_forms_tags %}
|
|
3
4
|
{% block title %}
|
|
4
5
|
{% trans "Ingredient List" %}
|
|
@@ -34,77 +35,97 @@
|
|
|
34
35
|
onclick="open_small_window('{% url 'canteen:create_ingredient' %}')">{% trans "Add one" %}</a>
|
|
35
36
|
</div>
|
|
36
37
|
<hr />
|
|
37
|
-
<
|
|
38
|
-
<
|
|
39
|
-
<
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
<
|
|
59
|
-
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
{
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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>
|
|
106
113
|
{% include 'includes/_paginator.html' %}
|
|
107
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
|
+
|
|
108
129
|
function clear_q() {
|
|
109
130
|
update_href({
|
|
110
131
|
"q": ""
|
|
@@ -136,4 +157,15 @@
|
|
|
136
157
|
update_href(i_sort);
|
|
137
158
|
}
|
|
138
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
|
+
|
|
139
171
|
{% endblock %}
|
fnschoo1/canteen/views.py
CHANGED
|
@@ -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
|
|
|
@@ -20,6 +20,7 @@ from django.db.models import (
|
|
|
20
20
|
DecimalField,
|
|
21
21
|
ExpressionWrapper,
|
|
22
22
|
F,
|
|
23
|
+
IntegerField,
|
|
23
24
|
Q,
|
|
24
25
|
Sum,
|
|
25
26
|
Value,
|
|
@@ -185,8 +186,16 @@ def set_row_height_in_inches(worksheet, row, inches):
|
|
|
185
186
|
worksheet.row_dimensions[row].height = points
|
|
186
187
|
|
|
187
188
|
|
|
188
|
-
class
|
|
189
|
-
def __init__(
|
|
189
|
+
class MealTypeWorkbook:
|
|
190
|
+
def __init__(
|
|
191
|
+
self,
|
|
192
|
+
request,
|
|
193
|
+
year=None,
|
|
194
|
+
month=None,
|
|
195
|
+
ingredients=None,
|
|
196
|
+
meal_type=None,
|
|
197
|
+
categories=None,
|
|
198
|
+
):
|
|
190
199
|
self.wb = Workbook()
|
|
191
200
|
self.wb[self.wb.sheetnames[0]].sheet_state = "hidden"
|
|
192
201
|
self.cover_sheet = self.wb.create_sheet(title=_("Sheet Cover"))
|
|
@@ -227,15 +236,27 @@ class CanteenWorkBook:
|
|
|
227
236
|
self.font_18_bold = Font(size=18, bold=True)
|
|
228
237
|
self.font_20_bold = Font(size=20, bold=True)
|
|
229
238
|
|
|
239
|
+
self.year = year or datetime().now().year
|
|
240
|
+
self.month = month or datetime().now().month
|
|
241
|
+
|
|
242
|
+
self.first_date_of_month = datetime(self.year, self.month, 1).date()
|
|
243
|
+
self.last_date_of_month = datetime(
|
|
244
|
+
self.year, self.month, calendar.monthrange(self.year, self.month)[1]
|
|
245
|
+
).date()
|
|
246
|
+
self.first_date_of_year = datetime(self.year, 1, 1)
|
|
247
|
+
self.last_date_of_year = datetime(self.year, 12, 31)
|
|
248
|
+
|
|
230
249
|
self.request = request
|
|
231
250
|
self.user = self.request.user
|
|
251
|
+
self.ingredients = ingredients
|
|
252
|
+
self.ignorable_ingredients = self.ingredients.filter(
|
|
253
|
+
Q(is_ignorable=True)
|
|
254
|
+
).all()
|
|
255
|
+
self.storage_ingredients = self.ingredients.filter(
|
|
256
|
+
Q(is_ignorable=False)
|
|
257
|
+
).all()
|
|
232
258
|
self.meal_type = meal_type
|
|
233
|
-
self.
|
|
234
|
-
self.month = int(month.split("-")[1])
|
|
235
|
-
self.date_start = datetime(self.year, self.month, 1).date()
|
|
236
|
-
self.date_end = datetime(
|
|
237
|
-
self.year, self.month, calendar.monthrange(self.year, self.month)[1]
|
|
238
|
-
).date()
|
|
259
|
+
self.categories = categories
|
|
239
260
|
self.is_zh_CN = is_zh_CN()
|
|
240
261
|
|
|
241
262
|
self._is_school = None
|
|
@@ -294,7 +315,7 @@ class CanteenWorkBook:
|
|
|
294
315
|
affiliation=user.affiliation,
|
|
295
316
|
year=self.year,
|
|
296
317
|
month=self.month,
|
|
297
|
-
day=self.
|
|
318
|
+
day=self.last_date_of_month.day,
|
|
298
319
|
)
|
|
299
320
|
|
|
300
321
|
header_row_num = 3
|
|
@@ -318,10 +339,7 @@ class CanteenWorkBook:
|
|
|
318
339
|
cell.alignment = self.center_alignment
|
|
319
340
|
cell.border = self.thin_border
|
|
320
341
|
|
|
321
|
-
categories =
|
|
322
|
-
Q(user=user) & Q(is_disabled=False)
|
|
323
|
-
).all()
|
|
324
|
-
|
|
342
|
+
categories = self.categories
|
|
325
343
|
set_row_height_in_inches(sheet, 1, 0.38)
|
|
326
344
|
set_row_height_in_inches(sheet, 2, 0.22)
|
|
327
345
|
set_row_height_in_inches(sheet, 3, 0.32)
|
|
@@ -334,14 +352,10 @@ class CanteenWorkBook:
|
|
|
334
352
|
category_cell = sheet.cell(row_num, 1)
|
|
335
353
|
category_cell.value = category.name
|
|
336
354
|
|
|
337
|
-
ingredients =
|
|
338
|
-
Q(
|
|
339
|
-
& Q(
|
|
340
|
-
& Q(
|
|
341
|
-
& Q(storage_date__lte=self.date_end)
|
|
342
|
-
& Q(meal_type=self.meal_type)
|
|
343
|
-
& Q(is_disabled=False)
|
|
344
|
-
& Q(is_ignorable=True)
|
|
355
|
+
ingredients = self.ignorable_ingredients.filter(
|
|
356
|
+
Q(category=category)
|
|
357
|
+
& Q(storage_date__gte=self.first_date_of_month)
|
|
358
|
+
& Q(storage_date__lte=self.last_date_of_month)
|
|
345
359
|
).all()
|
|
346
360
|
total_price_cell = sheet.cell(row_num, 2)
|
|
347
361
|
total_price_cell.value = sum([i.total_price for i in ingredients])
|
|
@@ -353,13 +367,9 @@ class CanteenWorkBook:
|
|
|
353
367
|
cell.alignment = self.center_alignment
|
|
354
368
|
cell.border = self.thin_border
|
|
355
369
|
|
|
356
|
-
ingredients =
|
|
357
|
-
Q(
|
|
358
|
-
& Q(
|
|
359
|
-
& Q(storage_date__lte=self.date_end)
|
|
360
|
-
& Q(meal_type=self.meal_type)
|
|
361
|
-
& Q(is_disabled=False)
|
|
362
|
-
& Q(is_ignorable=True)
|
|
370
|
+
ingredients = self.ignorable_ingredients.filter(
|
|
371
|
+
Q(storage_date__gte=self.first_date_of_month)
|
|
372
|
+
& Q(storage_date__lte=self.last_date_of_month)
|
|
363
373
|
).all()
|
|
364
374
|
|
|
365
375
|
summary_row_num = len(categories) + header_row_num + 1
|
|
@@ -464,7 +474,7 @@ class CanteenWorkBook:
|
|
|
464
474
|
affiliation=user.affiliation,
|
|
465
475
|
year=self.year,
|
|
466
476
|
month=self.month,
|
|
467
|
-
day=self.
|
|
477
|
+
day=self.last_date_of_month.day,
|
|
468
478
|
)
|
|
469
479
|
|
|
470
480
|
header_row_num = 3
|
|
@@ -490,10 +500,7 @@ class CanteenWorkBook:
|
|
|
490
500
|
cell.alignment = self.center_alignment
|
|
491
501
|
cell.border = self.thin_border
|
|
492
502
|
|
|
493
|
-
categories =
|
|
494
|
-
Q(user=user) & Q(is_disabled=False)
|
|
495
|
-
).all()
|
|
496
|
-
|
|
503
|
+
categories = self.categories
|
|
497
504
|
set_row_height_in_inches(sheet, 1, 0.38)
|
|
498
505
|
set_row_height_in_inches(sheet, 2, 0.22)
|
|
499
506
|
set_row_height_in_inches(sheet, 3, 0.32)
|
|
@@ -506,19 +513,14 @@ class CanteenWorkBook:
|
|
|
506
513
|
category_cell = sheet.cell(row_num, 1)
|
|
507
514
|
category_cell.value = category.name
|
|
508
515
|
|
|
509
|
-
ingredients =
|
|
510
|
-
Q(
|
|
511
|
-
& Q(category=category)
|
|
516
|
+
ingredients = self.storage_ingredients.filter(
|
|
517
|
+
Q(category=category)
|
|
512
518
|
& Q(
|
|
513
519
|
consumptions__date_of_using__range=(
|
|
514
|
-
self.
|
|
515
|
-
self.
|
|
520
|
+
self.first_date_of_month,
|
|
521
|
+
self.last_date_of_month,
|
|
516
522
|
)
|
|
517
523
|
)
|
|
518
|
-
& Q(meal_type=self.meal_type)
|
|
519
|
-
& Q(category__is_disabled=False)
|
|
520
|
-
& Q(is_disabled=False)
|
|
521
|
-
& Q(is_ignorable=False)
|
|
522
524
|
).distinct()
|
|
523
525
|
|
|
524
526
|
total_price_cell = sheet.cell(row_num, 2)
|
|
@@ -526,8 +528,8 @@ class CanteenWorkBook:
|
|
|
526
528
|
for i in ingredients:
|
|
527
529
|
consumptions = i.consumptions.filter(
|
|
528
530
|
Q(is_disabled=False)
|
|
529
|
-
& Q(date_of_using__lte=self.
|
|
530
|
-
& Q(date_of_using__gte=self.
|
|
531
|
+
& Q(date_of_using__lte=self.last_date_of_month)
|
|
532
|
+
& Q(date_of_using__gte=self.first_date_of_month)
|
|
531
533
|
).all()
|
|
532
534
|
total_price_consumed += sum(
|
|
533
535
|
[c.amount_used * i.unit_price for c in consumptions]
|
|
@@ -541,18 +543,13 @@ class CanteenWorkBook:
|
|
|
541
543
|
cell.alignment = self.center_alignment
|
|
542
544
|
cell.border = self.thin_border
|
|
543
545
|
|
|
544
|
-
ingredients =
|
|
545
|
-
Q(
|
|
546
|
-
& Q(
|
|
546
|
+
ingredients = self.storage_ingredients.filter(
|
|
547
|
+
Q(
|
|
547
548
|
consumptions__date_of_using__range=(
|
|
548
|
-
self.
|
|
549
|
-
self.
|
|
549
|
+
self.first_date_of_month,
|
|
550
|
+
self.last_date_of_month,
|
|
550
551
|
)
|
|
551
552
|
)
|
|
552
|
-
& Q(meal_type=self.meal_type)
|
|
553
|
-
& Q(category__is_disabled=False)
|
|
554
|
-
& Q(is_disabled=False)
|
|
555
|
-
& Q(is_ignorable=False)
|
|
556
553
|
).distinct()
|
|
557
554
|
|
|
558
555
|
summary_row_num = len(categories) + header_row_num + 1
|
|
@@ -560,8 +557,8 @@ class CanteenWorkBook:
|
|
|
560
557
|
for i in ingredients:
|
|
561
558
|
consumptions = i.consumptions.filter(
|
|
562
559
|
Q(is_disabled=False)
|
|
563
|
-
& Q(date_of_using__lte=self.
|
|
564
|
-
& Q(date_of_using__gte=self.
|
|
560
|
+
& Q(date_of_using__lte=self.last_date_of_month)
|
|
561
|
+
& Q(date_of_using__gte=self.first_date_of_month)
|
|
565
562
|
).all()
|
|
566
563
|
summary_total_price += sum(
|
|
567
564
|
[c.amount_used * i.unit_price for c in consumptions]
|
|
@@ -666,7 +663,7 @@ class CanteenWorkBook:
|
|
|
666
663
|
affiliation=user.affiliation,
|
|
667
664
|
year=self.year,
|
|
668
665
|
month=self.month,
|
|
669
|
-
day=self.
|
|
666
|
+
day=self.last_date_of_month.day,
|
|
670
667
|
)
|
|
671
668
|
|
|
672
669
|
header_row_num = 3
|
|
@@ -690,10 +687,7 @@ class CanteenWorkBook:
|
|
|
690
687
|
cell.alignment = self.center_alignment
|
|
691
688
|
cell.border = self.thin_border
|
|
692
689
|
|
|
693
|
-
categories =
|
|
694
|
-
Q(user=user) & Q(is_disabled=False)
|
|
695
|
-
).all()
|
|
696
|
-
|
|
690
|
+
categories = self.categories
|
|
697
691
|
set_row_height_in_inches(sheet, 1, 0.38)
|
|
698
692
|
set_row_height_in_inches(sheet, 2, 0.22)
|
|
699
693
|
set_row_height_in_inches(sheet, 3, 0.32)
|
|
@@ -706,15 +700,12 @@ class CanteenWorkBook:
|
|
|
706
700
|
category_cell = sheet.cell(row_num, 1)
|
|
707
701
|
category_cell.value = category.name
|
|
708
702
|
|
|
709
|
-
ingredients =
|
|
710
|
-
Q(
|
|
703
|
+
ingredients = self.storage_ingredients.filter(
|
|
704
|
+
Q(storage_date__gte=self.first_date_of_month)
|
|
705
|
+
& Q(storage_date__lte=self.last_date_of_month)
|
|
711
706
|
& Q(category=category)
|
|
712
|
-
& Q(storage_date__gte=self.date_start)
|
|
713
|
-
& Q(storage_date__lte=self.date_end)
|
|
714
|
-
& Q(meal_type=self.meal_type)
|
|
715
|
-
& Q(is_disabled=False)
|
|
716
|
-
& Q(is_ignorable=False)
|
|
717
707
|
).all()
|
|
708
|
+
|
|
718
709
|
total_price_cell = sheet.cell(row_num, 2)
|
|
719
710
|
total_price_cell.value = sum([i.total_price for i in ingredients])
|
|
720
711
|
|
|
@@ -725,13 +716,9 @@ class CanteenWorkBook:
|
|
|
725
716
|
cell.alignment = self.center_alignment
|
|
726
717
|
cell.border = self.thin_border
|
|
727
718
|
|
|
728
|
-
ingredients =
|
|
729
|
-
Q(
|
|
730
|
-
& Q(
|
|
731
|
-
& Q(storage_date__lte=self.date_end)
|
|
732
|
-
& Q(meal_type=self.meal_type)
|
|
733
|
-
& Q(is_disabled=False)
|
|
734
|
-
& Q(is_ignorable=False)
|
|
719
|
+
ingredients = self.storage_ingredients.filter(
|
|
720
|
+
Q(storage_date__gte=self.first_date_of_month)
|
|
721
|
+
& Q(storage_date__lte=self.last_date_of_month)
|
|
735
722
|
).all()
|
|
736
723
|
|
|
737
724
|
summary_row_num = len(categories) + header_row_num + 1
|
|
@@ -811,16 +798,10 @@ class CanteenWorkBook:
|
|
|
811
798
|
sheet.sheet_properties.tabColor = "ff9e16"
|
|
812
799
|
user = self.user
|
|
813
800
|
consumption_rows_count = 21
|
|
814
|
-
categories =
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
Q(is_disabled=False)
|
|
819
|
-
& Q(ingredient__meal_type=self.meal_type)
|
|
820
|
-
& Q(ingredient__user=user)
|
|
821
|
-
& Q(date_of_using__gte=self.date_start)
|
|
822
|
-
& Q(date_of_using__lte=self.date_end)
|
|
823
|
-
).all()
|
|
801
|
+
categories = self.categories
|
|
802
|
+
consumptions = []
|
|
803
|
+
for i in self.storage_ingredients:
|
|
804
|
+
consumptions += i.consumptions.filter(Q(is_disabled=False)).all()
|
|
824
805
|
consumption_row_height = 0.18
|
|
825
806
|
consumption_rows_height = consumption_rows_count * 0.18
|
|
826
807
|
|
|
@@ -880,7 +861,7 @@ class CanteenWorkBook:
|
|
|
880
861
|
Ingredient(
|
|
881
862
|
user=user,
|
|
882
863
|
name="",
|
|
883
|
-
storage_date=self.
|
|
864
|
+
storage_date=self.first_date_of_month,
|
|
884
865
|
meal_type=split_dated_consumption.ingredient.meal_type,
|
|
885
866
|
category=c,
|
|
886
867
|
quantity=0.0,
|
|
@@ -1204,22 +1185,16 @@ class CanteenWorkBook:
|
|
|
1204
1185
|
sheet.sheet_properties.tabColor = "16b1ff"
|
|
1205
1186
|
user = self.user
|
|
1206
1187
|
ingredient_rows_count = 21
|
|
1207
|
-
ingredients =
|
|
1208
|
-
Q(
|
|
1209
|
-
& Q(
|
|
1210
|
-
& Q(is_ignorable=False)
|
|
1211
|
-
& Q(storage_date__gte=self.date_start)
|
|
1212
|
-
& Q(storage_date__lte=self.date_end)
|
|
1213
|
-
& Q(meal_type=self.meal_type)
|
|
1214
|
-
).all()
|
|
1215
|
-
categories = Category.objects.filter(
|
|
1216
|
-
Q(user=user) & Q(is_disabled=False)
|
|
1188
|
+
ingredients = self.storage_ingredients.filter(
|
|
1189
|
+
Q(storage_date__gte=self.first_date_of_month)
|
|
1190
|
+
& Q(storage_date__lte=self.last_date_of_month)
|
|
1217
1191
|
).all()
|
|
1192
|
+
categories = self.categories
|
|
1218
1193
|
ingredient_row_height = 0.18
|
|
1219
1194
|
ingredient_rows_height = ingredient_rows_count * 0.18
|
|
1220
1195
|
storage_dates = sorted(list(set([i.storage_date for i in ingredients])))
|
|
1221
1196
|
|
|
1222
|
-
|
|
1197
|
+
formed_ingredients = []
|
|
1223
1198
|
for storage_date in storage_dates:
|
|
1224
1199
|
dated_ingredients = [
|
|
1225
1200
|
i for i in ingredients if i.storage_date == storage_date
|
|
@@ -1282,7 +1257,7 @@ class CanteenWorkBook:
|
|
|
1282
1257
|
)
|
|
1283
1258
|
|
|
1284
1259
|
storage_date_index = sub_storage_num
|
|
1285
|
-
|
|
1260
|
+
formed_ingredients.append(
|
|
1286
1261
|
[storage_date, storage_date_index, split_dated_ingredients]
|
|
1287
1262
|
)
|
|
1288
1263
|
|
|
@@ -1293,7 +1268,7 @@ class CanteenWorkBook:
|
|
|
1293
1268
|
storage_date,
|
|
1294
1269
|
storage_date_index,
|
|
1295
1270
|
dated_ingredients,
|
|
1296
|
-
) in enumerate(
|
|
1271
|
+
) in enumerate(formed_ingredients):
|
|
1297
1272
|
row_num = (ingredient_rows_count + 6) * index + 1
|
|
1298
1273
|
|
|
1299
1274
|
title_cell_row_num = row_num
|
|
@@ -1327,13 +1302,13 @@ class CanteenWorkBook:
|
|
|
1327
1302
|
storage_num += 1
|
|
1328
1303
|
|
|
1329
1304
|
prev_storage_date = (
|
|
1330
|
-
|
|
1331
|
-
if 0 <= index - 1 < len(
|
|
1305
|
+
formed_ingredients[index - 1][0]
|
|
1306
|
+
if 0 <= index - 1 < len(formed_ingredients)
|
|
1332
1307
|
else None
|
|
1333
1308
|
)
|
|
1334
1309
|
next_storage_date = (
|
|
1335
|
-
|
|
1336
|
-
if 0 < index + 1 < (len(
|
|
1310
|
+
formed_ingredients[index + 1][0]
|
|
1311
|
+
if 0 < index + 1 < (len(formed_ingredients) - 1)
|
|
1337
1312
|
else None
|
|
1338
1313
|
)
|
|
1339
1314
|
sub_title_num_cell_row_num = title_cell_row_num + 1
|
|
@@ -1563,10 +1538,7 @@ class CanteenWorkBook:
|
|
|
1563
1538
|
cell.border = self.thin_border
|
|
1564
1539
|
cell.font = self.font_12_bold
|
|
1565
1540
|
|
|
1566
|
-
categories =
|
|
1567
|
-
Q(user=user) & Q(is_disabled=False)
|
|
1568
|
-
).all()
|
|
1569
|
-
|
|
1541
|
+
categories = self.categories
|
|
1570
1542
|
set_row_height_in_inches(sheet, 1, 0.60)
|
|
1571
1543
|
set_row_height_in_inches(sheet, 2, 0.44)
|
|
1572
1544
|
|
|
@@ -1578,13 +1550,10 @@ class CanteenWorkBook:
|
|
|
1578
1550
|
category_cell = sheet.cell(row_num, 1)
|
|
1579
1551
|
category_cell.value = category.name
|
|
1580
1552
|
|
|
1581
|
-
ingredients =
|
|
1582
|
-
Q(
|
|
1583
|
-
& Q(
|
|
1584
|
-
& Q(
|
|
1585
|
-
& Q(storage_date__lte=self.date_end)
|
|
1586
|
-
& Q(meal_type=self.meal_type)
|
|
1587
|
-
& Q(is_disabled=False)
|
|
1553
|
+
ingredients = self.ingredients.filter(
|
|
1554
|
+
Q(category=category)
|
|
1555
|
+
& Q(storage_date__gte=self.first_date_of_month)
|
|
1556
|
+
& Q(storage_date__lte=self.last_date_of_month)
|
|
1588
1557
|
).all()
|
|
1589
1558
|
total_price_cell = sheet.cell(row_num, 2)
|
|
1590
1559
|
total_price_cell.value = sum([i.total_price for i in ingredients])
|
|
@@ -1602,12 +1571,9 @@ class CanteenWorkBook:
|
|
|
1602
1571
|
cell.alignment = self.center_alignment
|
|
1603
1572
|
cell.border = self.thin_border
|
|
1604
1573
|
|
|
1605
|
-
ingredients =
|
|
1606
|
-
Q(
|
|
1607
|
-
& Q(
|
|
1608
|
-
& Q(storage_date__lte=self.date_end)
|
|
1609
|
-
& Q(meal_type=self.meal_type)
|
|
1610
|
-
& Q(is_disabled=False)
|
|
1574
|
+
ingredients = self.ingredients.filter(
|
|
1575
|
+
Q(storage_date__gte=self.first_date_of_month)
|
|
1576
|
+
& Q(storage_date__lte=self.last_date_of_month)
|
|
1611
1577
|
).all()
|
|
1612
1578
|
|
|
1613
1579
|
summary_row_num = len(categories) + header_row_num + 1
|
|
@@ -1644,12 +1610,8 @@ class CanteenWorkBook:
|
|
|
1644
1610
|
user = self.user
|
|
1645
1611
|
ingredient_rows_count = 17
|
|
1646
1612
|
|
|
1647
|
-
ingredients =
|
|
1648
|
-
Q(
|
|
1649
|
-
& Q(storage_date__lte=self.date_end)
|
|
1650
|
-
& Q(meal_type=self.meal_type)
|
|
1651
|
-
& Q(is_disabled=False)
|
|
1652
|
-
& Q(is_ignorable=False)
|
|
1613
|
+
ingredients = self.storage_ingredients.filter(
|
|
1614
|
+
Q(storage_date__lte=self.last_date_of_month)
|
|
1653
1615
|
).all()
|
|
1654
1616
|
|
|
1655
1617
|
consumptions = []
|
|
@@ -1657,7 +1619,8 @@ class CanteenWorkBook:
|
|
|
1657
1619
|
consumptions += [
|
|
1658
1620
|
c
|
|
1659
1621
|
for c in ingredient.consumptions.filter(
|
|
1660
|
-
Q(date_of_using__lte=self.
|
|
1622
|
+
Q(date_of_using__lte=self.last_date_of_month)
|
|
1623
|
+
& Q(is_disabled=False)
|
|
1661
1624
|
).all()
|
|
1662
1625
|
]
|
|
1663
1626
|
|
|
@@ -1673,11 +1636,9 @@ class CanteenWorkBook:
|
|
|
1673
1636
|
inventory_days.append(date_of_using)
|
|
1674
1637
|
|
|
1675
1638
|
if len(inventory_days) < 1:
|
|
1676
|
-
inventory_days.insert(-1, self.
|
|
1639
|
+
inventory_days.insert(-1, self.last_date_of_month)
|
|
1677
1640
|
|
|
1678
|
-
inventory_days.insert(
|
|
1679
|
-
0, (self.date_start.replace(day=1) - timedelta(days=1))
|
|
1680
|
-
)
|
|
1641
|
+
inventory_days.insert(0, (self.first_date_of_month - timedelta(days=1)))
|
|
1681
1642
|
formed_ingredients = []
|
|
1682
1643
|
for inventory_day in inventory_days:
|
|
1683
1644
|
inventory_day_ingredients = []
|
|
@@ -1716,7 +1677,7 @@ class CanteenWorkBook:
|
|
|
1716
1677
|
inventory_day_ingredients += [
|
|
1717
1678
|
Ingredient(
|
|
1718
1679
|
user=user,
|
|
1719
|
-
storage_date=self.
|
|
1680
|
+
storage_date=self.first_date_of_month,
|
|
1720
1681
|
name="",
|
|
1721
1682
|
meal_type=self.meal_type,
|
|
1722
1683
|
category=s_ingredient0.category,
|
|
@@ -1973,13 +1934,9 @@ class CanteenWorkBook:
|
|
|
1973
1934
|
user = self.user
|
|
1974
1935
|
ingredient_rows_count = 11
|
|
1975
1936
|
|
|
1976
|
-
ingredients =
|
|
1977
|
-
Q(
|
|
1978
|
-
& Q(
|
|
1979
|
-
& Q(storage_date__lte=self.date_end)
|
|
1980
|
-
& Q(meal_type=self.meal_type)
|
|
1981
|
-
& Q(is_disabled=False)
|
|
1982
|
-
& Q(is_ignorable=True)
|
|
1937
|
+
ingredients = self.ignorable_ingredients.filter(
|
|
1938
|
+
Q(storage_date__gte=self.first_date_of_month)
|
|
1939
|
+
& Q(storage_date__lte=self.last_date_of_month)
|
|
1983
1940
|
).all()
|
|
1984
1941
|
|
|
1985
1942
|
categories = list(set([i.category for i in ingredients]))
|
|
@@ -1996,7 +1953,7 @@ class CanteenWorkBook:
|
|
|
1996
1953
|
_split_ingredients += [
|
|
1997
1954
|
Ingredient(
|
|
1998
1955
|
user=user,
|
|
1999
|
-
storage_date=self.
|
|
1956
|
+
storage_date=self.last_date_of_month,
|
|
2000
1957
|
name="",
|
|
2001
1958
|
meal_type=_split_ingredient0.meal_type,
|
|
2002
1959
|
category=_split_ingredient0.category,
|
|
@@ -2036,7 +1993,11 @@ class CanteenWorkBook:
|
|
|
2036
1993
|
sub_title_date_cell = sheet.cell(sub_title_row_num, 4)
|
|
2037
1994
|
sub_title_date_cell.value = _(
|
|
2038
1995
|
"{year}.{month:0>2}.{day:0>2} (Non-storage list sheet)"
|
|
2039
|
-
).format(
|
|
1996
|
+
).format(
|
|
1997
|
+
year=self.year,
|
|
1998
|
+
month=self.month,
|
|
1999
|
+
day=self.last_date_of_month.day,
|
|
2000
|
+
)
|
|
2040
2001
|
|
|
2041
2002
|
for cell in [sub_title_affiliation_cell, sub_title_date_cell]:
|
|
2042
2003
|
cell.font = self.font_14
|
|
@@ -2170,29 +2131,7 @@ class CanteenWorkBook:
|
|
|
2170
2131
|
date_end = date(year, 12, 31)
|
|
2171
2132
|
meal_type = self.meal_type
|
|
2172
2133
|
|
|
2173
|
-
ingredients =
|
|
2174
|
-
Ingredient.objects.filter(
|
|
2175
|
-
Q(is_disabled=False)
|
|
2176
|
-
& Q(is_ignorable=False)
|
|
2177
|
-
& Q(user=user)
|
|
2178
|
-
& Q(meal_type=meal_type)
|
|
2179
|
-
)
|
|
2180
|
-
.prefetch_related("consumptions")
|
|
2181
|
-
.all()
|
|
2182
|
-
)
|
|
2183
|
-
ingredients = [
|
|
2184
|
-
i
|
|
2185
|
-
for i in ingredients
|
|
2186
|
-
if date_start <= i.storage_date <= date_end
|
|
2187
|
-
or any(
|
|
2188
|
-
[
|
|
2189
|
-
date_start <= c.date_of_using <= date_end
|
|
2190
|
-
for c in i.consumptions.all()
|
|
2191
|
-
if c.is_disabled == False
|
|
2192
|
-
]
|
|
2193
|
-
)
|
|
2194
|
-
]
|
|
2195
|
-
|
|
2134
|
+
ingredients = self.storage_ingredients
|
|
2196
2135
|
ingredient_names = list(set([i.name for i in ingredients]))
|
|
2197
2136
|
for ingredient_name_index, ingredient_name in enumerate(
|
|
2198
2137
|
ingredient_names
|
|
@@ -2417,16 +2356,16 @@ class CanteenWorkBook:
|
|
|
2417
2356
|
|
|
2418
2357
|
sheet.cell(
|
|
2419
2358
|
month_surplus_header_row_num,
|
|
2420
|
-
|
|
2359
|
+
10,
|
|
2421
2360
|
remaining_quantity_last_month,
|
|
2422
2361
|
)
|
|
2423
2362
|
sheet.cell(
|
|
2424
2363
|
month_surplus_header_row_num,
|
|
2425
|
-
|
|
2364
|
+
12,
|
|
2426
2365
|
remaining_total_price_last_month,
|
|
2427
2366
|
)
|
|
2428
2367
|
sheet.cell(
|
|
2429
|
-
month_surplus_header_row_num,
|
|
2368
|
+
month_surplus_header_row_num, 11, unit_price.normalize()
|
|
2430
2369
|
)
|
|
2431
2370
|
|
|
2432
2371
|
month_ingredients = []
|
|
@@ -2680,7 +2619,7 @@ class CanteenWorkBook:
|
|
|
2680
2619
|
self.fill_in_consumption_sheet()
|
|
2681
2620
|
self.fill_in_consumption_list_sheet()
|
|
2682
2621
|
self.fill_in_surplus_sheet()
|
|
2683
|
-
if self.request.GET.get("include_food_sheets","") == "true":
|
|
2622
|
+
if self.request.GET.get("include_food_sheets", "") == "true":
|
|
2684
2623
|
self.fill_in_food_sheets()
|
|
2685
2624
|
|
|
2686
2625
|
return self.wb
|
|
@@ -2689,10 +2628,59 @@ class CanteenWorkBook:
|
|
|
2689
2628
|
def get_workbook_zip(request, month):
|
|
2690
2629
|
from ..views import meal_type_name_0
|
|
2691
2630
|
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
).
|
|
2695
|
-
|
|
2631
|
+
year, month = [int(v) for v in month.split("-")]
|
|
2632
|
+
first_date_of_year = datetime(year, 1, 1).date()
|
|
2633
|
+
last_date_of_year = datetime(year, 12, 31).date()
|
|
2634
|
+
|
|
2635
|
+
meal_types = (
|
|
2636
|
+
MealType.objects.annotate(ingredients_count=Count("ingredients"))
|
|
2637
|
+
.filter(
|
|
2638
|
+
Q(user=request.user)
|
|
2639
|
+
& Q(is_disabled=False)
|
|
2640
|
+
& Q(ingredients_count__gt=0)
|
|
2641
|
+
)
|
|
2642
|
+
.all()
|
|
2643
|
+
)
|
|
2644
|
+
|
|
2645
|
+
categories = (
|
|
2646
|
+
Category.objects.annotate(ingredients_count=Count("ingredients"))
|
|
2647
|
+
.filter(
|
|
2648
|
+
Q(user=request.user)
|
|
2649
|
+
& Q(is_disabled=False)
|
|
2650
|
+
& Q(ingredients_count__gt=0)
|
|
2651
|
+
)
|
|
2652
|
+
.order_by("priority")
|
|
2653
|
+
.all()
|
|
2654
|
+
)
|
|
2655
|
+
|
|
2656
|
+
user_ingredients = (
|
|
2657
|
+
Ingredient.objects.annotate(
|
|
2658
|
+
total_consumed=Coalesce(
|
|
2659
|
+
Sum("consumptions__amount_used"), 0, output_field=IntegerField()
|
|
2660
|
+
)
|
|
2661
|
+
)
|
|
2662
|
+
.filter(
|
|
2663
|
+
Q(is_disabled=False)
|
|
2664
|
+
& (
|
|
2665
|
+
Q(
|
|
2666
|
+
consumptions__date_of_using__range=(
|
|
2667
|
+
first_date_of_year,
|
|
2668
|
+
last_date_of_year,
|
|
2669
|
+
)
|
|
2670
|
+
)
|
|
2671
|
+
| Q(quantity__gt=F("total_consumed"))
|
|
2672
|
+
| (
|
|
2673
|
+
Q(storage_date__gte=first_date_of_year)
|
|
2674
|
+
& Q(storage_date__lte=last_date_of_year)
|
|
2675
|
+
)
|
|
2676
|
+
)
|
|
2677
|
+
& Q(user=request.user)
|
|
2678
|
+
& Q(category__is_disabled=False)
|
|
2679
|
+
& Q(meal_type__is_disabled=False)
|
|
2680
|
+
)
|
|
2681
|
+
.select_related("meal_type", "category")
|
|
2682
|
+
.prefetch_related("consumptions")
|
|
2683
|
+
.distinct()
|
|
2696
2684
|
)
|
|
2697
2685
|
|
|
2698
2686
|
zip_buffer = io.BytesIO()
|
|
@@ -2707,13 +2695,20 @@ def get_workbook_zip(request, month):
|
|
|
2707
2695
|
if not meal_type.name == meal_type_name_0
|
|
2708
2696
|
else ""
|
|
2709
2697
|
),
|
|
2710
|
-
month=month
|
|
2698
|
+
month=f"{year}{month:0>2}",
|
|
2711
2699
|
affiliation=request.user.affiliation,
|
|
2712
2700
|
)
|
|
2713
2701
|
+ ".xlsx"
|
|
2714
2702
|
)
|
|
2715
|
-
|
|
2716
|
-
wb =
|
|
2703
|
+
__ingredients = user_ingredients.filter(meal_type=meal_type).all()
|
|
2704
|
+
wb = MealTypeWorkbook(
|
|
2705
|
+
request,
|
|
2706
|
+
year=year,
|
|
2707
|
+
month=month,
|
|
2708
|
+
ingredients=__ingredients,
|
|
2709
|
+
meal_type=meal_type,
|
|
2710
|
+
categories=categories,
|
|
2711
|
+
).fill_in()
|
|
2717
2712
|
excel_buffer = io.BytesIO()
|
|
2718
2713
|
wb.save(excel_buffer)
|
|
2719
2714
|
excel_buffer.seek(0)
|
|
@@ -2722,3 +2717,6 @@ def get_workbook_zip(request, month):
|
|
|
2722
2717
|
|
|
2723
2718
|
zip_buffer.seek(0)
|
|
2724
2719
|
return zip_buffer
|
|
2720
|
+
|
|
2721
|
+
|
|
2722
|
+
# The end.
|
fnschoo1/fnschool/settings.py
CHANGED
|
@@ -126,7 +126,8 @@ AUTH_PASSWORD_VALIDATORS = [
|
|
|
126
126
|
# Internationalization
|
|
127
127
|
# https://docs.djangoproject.com/en/4.2/topics/i18n/
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
USE_TZ = True
|
|
130
|
+
TIME_ZONE = "Asia/Shanghai"
|
|
130
131
|
|
|
131
132
|
USE_I18N = True
|
|
132
133
|
USE_L10N = True
|
|
@@ -164,4 +165,14 @@ MEDIA_URL = "/media/"
|
|
|
164
165
|
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
|
|
165
166
|
|
|
166
167
|
LOGIN_URL = reverse_lazy("profiles:log_in")
|
|
168
|
+
|
|
169
|
+
_settings_path = Path(__file__).parent / "_settings.py"
|
|
170
|
+
if _settings_path.exists():
|
|
171
|
+
print(
|
|
172
|
+
('Custom configuration "{_settings_path}" has been used.').format(
|
|
173
|
+
_settings_path=_settings_path.as_posix()
|
|
174
|
+
)
|
|
175
|
+
)
|
|
176
|
+
from ._settings import *
|
|
177
|
+
|
|
167
178
|
# The end.
|
|
Binary file
|
fnschoo1/static/css/fnschool.css
CHANGED
fnschoo1/static/js/fnschool.js
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
function make_highlight(query, time_data) {
|
|
2
|
+
var highlight_elements = $(query)
|
|
3
|
+
var highlight_elements_toggled = []
|
|
4
|
+
highlight_elements.each(function (index, element) {
|
|
5
|
+
var element = $(element)
|
|
6
|
+
var time_value = element.data(time_data)
|
|
7
|
+
var seconds_diff = Math.floor((new Date() - new Date(time_value)) / 1000)
|
|
8
|
+
if (seconds_diff < 46) {
|
|
9
|
+
highlight_elements_toggled.push(element)
|
|
10
|
+
element.toggleClass('fn-highlight')
|
|
11
|
+
$('html,body').animate({ scrollTop: element.offset().top }, 1)
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
setTimeout(function () {
|
|
16
|
+
$(highlight_elements_toggled).each(function (index, element) {
|
|
17
|
+
element = $(element)
|
|
18
|
+
element.toggleClass('fn-highlight')
|
|
19
|
+
})
|
|
20
|
+
}, 10 * 1000)
|
|
21
|
+
}
|
|
22
|
+
|
|
1
23
|
function get_cookie(name) {
|
|
2
24
|
const cookies = document.cookie.split(';')
|
|
3
25
|
for (const cookie of cookies) {
|
|
@@ -89,3 +111,5 @@ $(document).ready(function () {
|
|
|
89
111
|
function set_page(num) {
|
|
90
112
|
update_href({ page: num })
|
|
91
113
|
}
|
|
114
|
+
|
|
115
|
+
// The end.
|
|
@@ -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>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
fnschoo1/__init__.py,sha256=
|
|
1
|
+
fnschoo1/__init__.py,sha256=rT-4fDJu76Ag8U4PoXAAd-4nAnLc2YFqPkwnObEVhqc,197
|
|
2
2
|
fnschoo1/manage.py,sha256=VZIol9q_Dhg81_KJ9Jfq-L5O8ubQelShkA-cZVJ1S6E,1539
|
|
3
3
|
fnschoo1/canteen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
fnschoo1/canteen/admin.py,sha256=suMo4x8I3JBxAFBVIdE-5qnqZ6JAZV0FESABHOSc-vg,63
|
|
5
5
|
fnschoo1/canteen/apps.py,sha256=zUjM0ZJwHW4i72vOm87QewRlvFQORQo5yb053u4YIGs,146
|
|
6
|
-
fnschoo1/canteen/forms.py,sha256=
|
|
7
|
-
fnschoo1/canteen/models.py,sha256=
|
|
6
|
+
fnschoo1/canteen/forms.py,sha256=JaN6SX9KIrJeUKRfTMf6bA0Op3mEGCc6xqUE6yWC8TU,2596
|
|
7
|
+
fnschoo1/canteen/models.py,sha256=44GtfJbp6kiQYdcBmSXqHiW6JLLcmiRydf7DC6EToWY,6331
|
|
8
8
|
fnschoo1/canteen/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2nk6VY-g,60
|
|
9
9
|
fnschoo1/canteen/urls.py,sha256=4GtrqC9L59c8zopfjRgqhbcvA5iPnGcAUVuM6CrKWpk,2797
|
|
10
|
-
fnschoo1/canteen/views.py,sha256=
|
|
10
|
+
fnschoo1/canteen/views.py,sha256=9qsNiCM4sUEUpV_8g874msSamrp-dqTb5mdUtyWvZmQ,29171
|
|
11
11
|
fnschoo1/canteen/migrations/0001_initial.py,sha256=IHlyfT9sNc-kRQZy7NyjgWzp4EGus405QCAUw4oNdAQ,3943
|
|
12
12
|
fnschoo1/canteen/migrations/0002_ingredient_is_disabled.py,sha256=j8oGWb2b99YwsEk-uwESLA_JRITEcz6b35ekoYOUGGc,444
|
|
13
13
|
fnschoo1/canteen/migrations/0003_consumption_is_disabled_alter_ingredient_is_disabled.py,sha256=9RB5SHjINgrrqtDpcVIUXEBa3C_MTcR_keXLGG_PcOs,619
|
|
@@ -24,6 +24,7 @@ fnschoo1/canteen/migrations/0013_alter_consumption_options_alter_ingredient_opti
|
|
|
24
24
|
fnschoo1/canteen/migrations/0014_category_priority.py,sha256=AywjPQhwtwm8xttEEOGQ3yyQ8j890hL5J-wCUNEwbkE,677
|
|
25
25
|
fnschoo1/canteen/migrations/0015_alter_category_options_alter_category_priority.py,sha256=l8WVVTaDDbB3-xBMdU402gsQo3mhfeUUEcIp_hYVEPk,720
|
|
26
26
|
fnschoo1/canteen/migrations/0016_consumption_unique_ingredient_date_of_using.py,sha256=kiNr4ISVoy99U7LuJMItJYtNyE4BPYR_jSdnKoXxWt4,520
|
|
27
|
+
fnschoo1/canteen/migrations/0017_ingredient_updated_at_alter_category_created_at_and_more.py,sha256=fvbJV9uf8lUrqASwPO2EsyW3ApXkFk4zBE1vlT2UV0o,872
|
|
27
28
|
fnschoo1/canteen/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
29
|
fnschoo1/canteen/templates/canteen/close.html,sha256=pLYeJmGaOEJKMUJdZmYzz_n--l28IRDQ4fXvetP_Vsc,200
|
|
29
30
|
fnschoo1/canteen/templates/canteen/category/create.html,sha256=T33zbHRYUrWlLYSLAYZ14Y03Gw2tGMoYzBWUVv-I8pk,609
|
|
@@ -31,29 +32,30 @@ fnschoo1/canteen/templates/canteen/category/delete.html,sha256=iPmGAB2r8K9DqBTp9
|
|
|
31
32
|
fnschoo1/canteen/templates/canteen/category/list.html,sha256=QLO2GA13Co48Ijd0DCCN4lcMm1fgJqT2CprH5VdLZPw,2148
|
|
32
33
|
fnschoo1/canteen/templates/canteen/category/update.html,sha256=UnCI95eqsQXfdUMdJXWUf1qNVWM9ZgsP03ayZ_Nrak8,831
|
|
33
34
|
fnschoo1/canteen/templates/canteen/consumption/_create.html,sha256=tXlJcd566D9sYbsnj5KN-m0lyobT2AwwYt9oxUHbn4M,1026
|
|
34
|
-
fnschoo1/canteen/templates/canteen/consumption/create.html,sha256=
|
|
35
|
+
fnschoo1/canteen/templates/canteen/consumption/create.html,sha256=LSxyYQZfQLAekD84AQaJp_JRYge8I4IBF7DkTGLIGEI,16744
|
|
35
36
|
fnschoo1/canteen/templates/canteen/ingredient/close.html,sha256=pLYeJmGaOEJKMUJdZmYzz_n--l28IRDQ4fXvetP_Vsc,200
|
|
36
37
|
fnschoo1/canteen/templates/canteen/ingredient/create.html,sha256=i4ajPDpXBTUp08lIiwn0wZoNEohyXlX3G64zG1lmIcs,839
|
|
37
38
|
fnschoo1/canteen/templates/canteen/ingredient/create_one.html,sha256=y9EAKXmyIrlp5-DxHd86l1rMtB16KuOjPMbPiLAN_ag,615
|
|
38
39
|
fnschoo1/canteen/templates/canteen/ingredient/delete.html,sha256=npUtDGV7KK2jvc2AkiNlK6F2wUsKwLB5DQuBULm1pW8,1227
|
|
39
|
-
fnschoo1/canteen/templates/canteen/ingredient/list.html,sha256=
|
|
40
|
+
fnschoo1/canteen/templates/canteen/ingredient/list.html,sha256=QqPvNbfQCv74jOWpgMX9I-m-Omg3HR_k51XlDFMv3YE,5900
|
|
40
41
|
fnschoo1/canteen/templates/canteen/ingredient/update.html,sha256=JwW8dVQ1fzvxjA32RvRSSqrYzPPaajObvy7D45gz5pc,835
|
|
41
42
|
fnschoo1/canteen/templates/canteen/meal_type/create.html,sha256=OIxOcAa3Pp3OPT-Z0PRLINfZ08CO61ulNDU-YJA6EKI,612
|
|
42
43
|
fnschoo1/canteen/templates/canteen/meal_type/delete.html,sha256=i9PBX3ShXU4Az62MEawAuDWM5jwOmKByywizhdvuSTI,1567
|
|
43
44
|
fnschoo1/canteen/templates/canteen/meal_type/list.html,sha256=c5kJUE1OgpRtSrMV4wFwL_gbRSaX_XMM4Zt1JTx34_g,1907
|
|
44
45
|
fnschoo1/canteen/templates/canteen/meal_type/update.html,sha256=vqqyuC1m2CnPd3KrcjA8t4hbJslT001s4XvcYpkQmO0,834
|
|
45
46
|
fnschoo1/canteen/workbook/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
46
|
-
fnschoo1/canteen/workbook/generate.py,sha256=
|
|
47
|
+
fnschoo1/canteen/workbook/generate.py,sha256=wmqt5eFxmZRZdasMTsuc1AbntwOpUN4uVOtjfpM2j1k,109350
|
|
47
48
|
fnschoo1/fnschool/__init__.py,sha256=TmHhzykpKNMoMf6eD-EKvbvmnlzs1XGHtvD55ae1sXs,287
|
|
49
|
+
fnschoo1/fnschool/_settings.py,sha256=ajz1GSNU9xYVrFEDSz6Xwg7amWQ_yvW75tQa1ZvRIWc,3
|
|
48
50
|
fnschoo1/fnschool/asgi.py,sha256=kzkqosS10uBlyBX53EXcsATcvEZmac6nsPzyOHCuucE,393
|
|
49
|
-
fnschoo1/fnschool/settings.py,sha256=
|
|
51
|
+
fnschoo1/fnschool/settings.py,sha256=4etVUGXK6YNv7xmNi95N4serk9JEr93kG8LsL0O3r5Y,4651
|
|
50
52
|
fnschoo1/fnschool/urls.py,sha256=8WPemtCUuStd0R9gDP70c-NRQ5k7G4ksq6dYGH6xCDM,1036
|
|
51
53
|
fnschoo1/fnschool/views.py,sha256=MfujMhFkRLxT-saID1xTU16v0khzIl6ceDl7_JgrgFs,152
|
|
52
54
|
fnschoo1/fnschool/wsgi.py,sha256=dQq4S0vZWCz8w5R9KooJeLYTVFXvEgJRYe7NFZwVxU8,393
|
|
53
55
|
fnschoo1/fnschool/templatetags/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
54
56
|
fnschoo1/fnschool/templatetags/fnschool_tags.py,sha256=l5Zov4VlQKpz-69SFftP4kXyMymz-a0D5F_ss_eiFc4,568
|
|
55
57
|
fnschoo1/locale/en/LC_MESSAGES/django.mo,sha256=M8AB6fmjwlEd761iFlasNWdiEYfE-2nIwBoioGtEVUo,404
|
|
56
|
-
fnschoo1/locale/zh_Hans/LC_MESSAGES/django.mo,sha256=
|
|
58
|
+
fnschoo1/locale/zh_Hans/LC_MESSAGES/django.mo,sha256=a70R8-JrOVyLEYOxZGLsqn7Q0DzKQkwi09-5p05Dlbc,22621
|
|
57
59
|
fnschoo1/profiles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
58
60
|
fnschoo1/profiles/admin.py,sha256=93UCvdODI63KzCDfFFnKmfvCMGCp6FCG9WErE91i79Y,522
|
|
59
61
|
fnschoo1/profiles/apps.py,sha256=WDu6eceFnDkBFMqquAolMZMo7XPb0ah6l2q2AruTrl4,215
|
|
@@ -75,11 +77,11 @@ fnschoo1/profiles/templates/profiles/edit.html,sha256=49afyNH7OsqEKfD9TFrDKbRZ7r
|
|
|
75
77
|
fnschoo1/profiles/templates/profiles/log_in.html,sha256=9hcuxdxAUHdFBxrJTJ_X6IVwKC_Jw6mfA5Sqx9a4bZA,736
|
|
76
78
|
fnschoo1/profiles/templates/profiles/log_out.html,sha256=RRb6K-0G1Jm4RhfY9VwftJgNwgI8jsKb_N5Gvp5XtiE,320
|
|
77
79
|
fnschoo1/static/css/bootstrap.min.css,sha256=eGY1FwN6FhXUvbmXraT1t_q2vcNlQa8g5xQDwg8mG6w,280591
|
|
78
|
-
fnschoo1/static/css/fnschool.css,sha256=
|
|
80
|
+
fnschoo1/static/css/fnschool.css,sha256=k71DBJi4EwUQSOPyXX6G-15m8HN_z4_Ac72Du0Zf9Co,476
|
|
79
81
|
fnschoo1/static/images/favicon.ico,sha256=S8Tf0NsUdHnoYO0SEn-sig6YjB0atIpEtSlm7p1HxjY,5014
|
|
80
82
|
fnschoo1/static/js/bootstrap.bundle.min.js,sha256=6kw84LCFc4QJzifgkle0FsvQrpt2NVRNPNjSSc9caiM,125881
|
|
81
83
|
fnschoo1/static/js/bootstrap.min.js,sha256=0SHpZTHghUOz_BNedMzuH00z5lgwOSRKP_KI9G5Ogbk,88597
|
|
82
|
-
fnschoo1/static/js/fnschool.js,sha256=
|
|
84
|
+
fnschoo1/static/js/fnschool.js,sha256=M2hdpT_g6f77bDLzN3zWxjPybcfrWHRSpo6deNSxkH4,3684
|
|
83
85
|
fnschoo1/static/js/jquery.min.js,sha256=np_WnfpAmUmEO_iheFAJKf6mbm0_laW3Ns4x7kjSlt4,162505
|
|
84
86
|
fnschoo1/static/js/jquery.slim.min.js,sha256=p5YkbOjgHxX3hTadKlGuDW58NvJ1ldjjokDuDQ_5yXs,129962
|
|
85
87
|
fnschoo1/static/js/popper.min.js,sha256=O2xdmtEow7gq3I7-0lKjshvxHkBe0hTWrMkbX2fy0XQ,36887
|
|
@@ -96,14 +98,14 @@ fnschoo1/templates/includes/_navigation.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRk
|
|
|
96
98
|
fnschoo1/templates/includes/_paginator.html,sha256=Q-FRCODFNlETjn2yX18IfhctRWfqEgEnIc5LcdHzKSo,1262
|
|
97
99
|
fnschoo1/templates/registration/logged_out.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
98
100
|
fnschoo1/templates/registration/login.html,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
99
|
-
fnschool-
|
|
100
|
-
fnschool-
|
|
101
|
-
fnschool-
|
|
102
|
-
fnschool-
|
|
103
|
-
fnschool-
|
|
104
|
-
fnschool-
|
|
105
|
-
fnschool-
|
|
106
|
-
fnschool-
|
|
107
|
-
fnschool-
|
|
108
|
-
fnschool-
|
|
109
|
-
fnschool-
|
|
101
|
+
fnschool-20251020.82239.858.dist-info/licenses/LICENSE,sha256=2n6rt7r999OuXp8iOqW9we7ORaxWncIbOwN1ILRGR2g,7651
|
|
102
|
+
fnschool-20251020.82239.858.dist-info/METADATA,sha256=_e8pXoy9CHrKNnLPpki1a7kt3BWuBlOO5ZSwhX7HVZo,4752
|
|
103
|
+
fnschool-20251020.82239.858.dist-info/SOURCES.txt.py,sha256=2LY2mshgNtxI3ICB-oBjyMYgJk2bQqeGFM5J5ay5TQs,4954
|
|
104
|
+
fnschool-20251020.82239.858.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
105
|
+
fnschool-20251020.82239.858.dist-info/dependency_links.txt.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
106
|
+
fnschool-20251020.82239.858.dist-info/entry_points.txt,sha256=Ow5nChVFJY3O4TJAIE1ZydMev1MUtgRsT1b8eFP6728,54
|
|
107
|
+
fnschool-20251020.82239.858.dist-info/entry_points.txt.py,sha256=7iOwIx_m9Y6xJt___BZHWJh27LV5hqWnUjmj77MoRys,47
|
|
108
|
+
fnschool-20251020.82239.858.dist-info/requires.txt.py,sha256=PqRcHIQSMPUb271hacYrlSDHwB1WDZmlWUkh6RnBz_g,113
|
|
109
|
+
fnschool-20251020.82239.858.dist-info/top_level.txt,sha256=s6ZKnNm94Q0-247a50eI7jDK98uPF6P2kC9Ovd3LUlM,9
|
|
110
|
+
fnschool-20251020.82239.858.dist-info/top_level.txt.py,sha256=_7CbrSihm0dzBn_tTy2ass_Y2VlkVNT2eylE8mcfwHY,9
|
|
111
|
+
fnschool-20251020.82239.858.dist-info/RECORD,,
|
{fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/SOURCES.txt.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/entry_points.txt.py
RENAMED
|
File without changes
|
{fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/requires.txt.py
RENAMED
|
File without changes
|
{fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/top_level.txt
RENAMED
|
File without changes
|
{fnschool-20251018.81021.825.dist-info → fnschool-20251020.82239.858.dist-info}/top_level.txt.py
RENAMED
|
File without changes
|