Skip to content

Commit fe9aa64

Browse files
committed
Add food preparation table in kitchen count (#93)
1 parent e0c24b3 commit fe9aa64

File tree

1 file changed

+94
-73
lines changed

1 file changed

+94
-73
lines changed

souschef/delivery/views.py

+94-73
Original file line numberDiff line numberDiff line change
@@ -1111,7 +1111,8 @@ def get(self, request, *args, **kwargs):
11111111
):
11121112
kitchen_list[client_id] = kitchen_item
11131113

1114-
component_lines, meal_lines = kcr_make_lines(kitchen_list, delivery_date)
1114+
component_lines = kcr_make_component_lines(kitchen_list, delivery_date)
1115+
meal_lines = kcr_make_meal_lines(kitchen_list)
11151116
if component_lines:
11161117
# we have orders on that date
11171118
num_pages = kcr_make_pages( # kitchen count as PDF
@@ -1157,22 +1158,32 @@ def get(self, request, *args, **kwargs):
11571158
ComponentLine = collections.namedtuple("ComponentLine", component_line_fields[0::2])
11581159

11591160

1160-
meal_line_fields = [ # Special Meal Line on Kitchen Count.
1161-
# field name default value
1161+
# Special Meal Line on Kitchen Count.
1162+
# structure: first line = field name, second line = default value
1163+
meal_line_fields = [
1164+
# str: Lastname and abbreviated first name
11621165
"client",
1163-
"", # String : Lastname and abbreviated first name
1166+
"",
1167+
# str: Quantity of regular size main dishes
11641168
"rqty",
1165-
"", # String : Quantity of regular size main dishes
1169+
"",
1170+
# str: Quantity of large size main dishes
11661171
"lqty",
1167-
"", # String : Quantity of large size main dishes
1172+
"",
1173+
# str: Ingredients that clashes
11681174
"ingr_clash",
1169-
"", # String : Ingredients that clash
1175+
"",
1176+
# str: Other ingredients to avoid
11701177
"rest_ingr",
1171-
"", # String : Other ingredients to avoid
1178+
"",
1179+
# str: Restricted items
11721180
"rest_item",
1173-
"", # String : Restricted items
1181+
"",
11741182
"span",
11751183
"1",
1184+
# str: food preparation
1185+
"food_prep",
1186+
"",
11761187
] # Number of lines to "rowspan" in table
11771188
MealLine = collections.namedtuple("MealLine", meal_line_fields[0::2])
11781189

@@ -1190,7 +1201,7 @@ def meal_line(kititm):
11901201
A MealLine object
11911202
"""
11921203
return MealLine(
1193-
client=kititm.lastname + ", " + kititm.firstname[0:2] + ".",
1204+
client=format_client_name(kititm.firstname, kititm.lastname),
11941205
rqty=(str(kititm.meal_qty) if kititm.meal_size == SIZE_CHOICES_REGULAR else ""),
11951206
lqty=(str(kititm.meal_qty) if kititm.meal_size == SIZE_CHOICES_LARGE else ""),
11961207
ingr_clash="",
@@ -1203,6 +1214,7 @@ def meal_line(kititm):
12031214
),
12041215
rest_item=", ".join(kititm.restricted_items),
12051216
span="1",
1217+
food_prep=", ".join(sorted(kititm.preparation)),
12061218
)
12071219

12081220

@@ -1227,7 +1239,66 @@ def kcr_cumulate(regular, large, meal):
12271239
return (regular, large)
12281240

12291241

1230-
def kcr_make_lines(kitchen_list, kcr_date):
1242+
def kcr_make_meal_lines(kitchen_list):
1243+
meal_lines = []
1244+
rtotal, ltotal = (0, 0)
1245+
# Ingredients clashes (and other columns)
1246+
rsubtotal, lsubtotal = (0, 0)
1247+
clients = iter(
1248+
sorted(
1249+
[
1250+
(client_id, kitchen_item)
1251+
for client_id, kitchen_item in kitchen_list.items()
1252+
if kitchen_item.incompatible_ingredients or kitchen_item.preparation
1253+
],
1254+
key=lambda item: item[1].incompatible_ingredients,
1255+
)
1256+
)
1257+
1258+
# first line of a combination of ingredients
1259+
line_start = 0
1260+
rsubtotal, lsubtotal = (0, 0)
1261+
client_id, kitchen_item = next(clients, (0, 0)) # has end sentinel
1262+
while client_id > 0:
1263+
if rsubtotal == 0 and lsubtotal == 0:
1264+
# add line for subtotal at top of combination
1265+
meal_lines.append(MealLine(*meal_line_fields[1::2]))
1266+
combination = kitchen_item.incompatible_ingredients
1267+
meal_lines.append(meal_line(kitchen_item))
1268+
rsubtotal, lsubtotal = kcr_cumulate(rsubtotal, lsubtotal, kitchen_item)
1269+
client_id, kitchen_item = next(clients, (0, 0))
1270+
if client_id == 0 or combination != kitchen_item.incompatible_ingredients:
1271+
# last line of this combination of ingredients
1272+
line_end = len(meal_lines)
1273+
# set rowspan to total number of lines for this combination
1274+
meal_lines[line_start] = meal_lines[line_start]._replace(
1275+
client="SUBTOTAL",
1276+
rqty=str(rsubtotal),
1277+
lqty=str(lsubtotal),
1278+
ingr_clash=", ".join(combination),
1279+
span=str(line_end - line_start),
1280+
)
1281+
rtotal, ltotal = (rtotal + rsubtotal, ltotal + lsubtotal)
1282+
rsubtotal, lsubtotal = (0, 0)
1283+
# hide ingredients for lines following the first
1284+
for j in range(line_start + 1, line_end):
1285+
meal_lines[j] = meal_lines[j]._replace(span="-1")
1286+
# Add a blank line as separator
1287+
meal_lines.append(MealLine(*meal_line_fields[1::2]))
1288+
# first line of next combination of ingredients
1289+
line_start = len(meal_lines)
1290+
# END WHILE
1291+
1292+
meal_lines.append(
1293+
MealLine(*meal_line_fields[1::2])._replace(
1294+
rqty=str(rtotal), lqty=str(ltotal), ingr_clash="TOTAL SPECIALS"
1295+
)
1296+
)
1297+
1298+
return meal_lines
1299+
1300+
1301+
def kcr_make_component_lines(kitchen_list, kcr_date):
12311302
"""Generate the sections and lines for the kitchen count report.
12321303
12331304
Count all the dishes that have to be prepared and identify all the
@@ -1243,8 +1314,7 @@ def kcr_make_lines(kitchen_list, kcr_date):
12431314
meals will be delivered.
12441315
12451316
Returns:
1246-
A tuple. First value is the component (dishes) summary lines. The
1247-
second value is the special meals lines.
1317+
Component (dishes) summary lines.
12481318
"""
12491319
# Build component summary
12501320
component_lines = {}
@@ -1311,64 +1381,11 @@ def kcr_make_lines(kitchen_list, kcr_date):
13111381
else:
13121382
component_lines_sorted = []
13131383

1314-
# Build special meal lines
1315-
1316-
meal_lines = []
1317-
rtotal, ltotal = (0, 0)
1318-
# Ingredients clashes (and other columns)
1319-
rsubtotal, lsubtotal = (0, 0)
1320-
clients = iter(
1321-
sorted(
1322-
[
1323-
(ke, val)
1324-
for ke, val in kitchen_list.items()
1325-
if val.incompatible_ingredients
1326-
],
1327-
key=lambda x: x[1].incompatible_ingredients,
1328-
)
1329-
)
1330-
1331-
# first line of a combination of ingredients
1332-
line_start = 0
1333-
rsubtotal, lsubtotal = (0, 0)
1334-
k, v = next(clients, (0, 0)) # has end sentinel
1335-
while k > 0:
1336-
if rsubtotal == 0 and lsubtotal == 0:
1337-
# add line for subtotal at top of combination
1338-
meal_lines.append(MealLine(*meal_line_fields[1::2]))
1339-
combination = v.incompatible_ingredients
1340-
meal_lines.append(meal_line(v))
1341-
rsubtotal, lsubtotal = kcr_cumulate(rsubtotal, lsubtotal, v)
1342-
k, v = next(clients, (0, 0))
1343-
if k == 0 or combination != v.incompatible_ingredients:
1344-
# last line of this combination of ingredients
1345-
line_end = len(meal_lines)
1346-
# set rowspan to total number of lines for this combination
1347-
meal_lines[line_start] = meal_lines[line_start]._replace(
1348-
client="SUBTOTAL",
1349-
rqty=str(rsubtotal),
1350-
lqty=str(lsubtotal),
1351-
ingr_clash=", ".join(combination),
1352-
span=str(line_end - line_start),
1353-
)
1354-
rtotal, ltotal = (rtotal + rsubtotal, ltotal + lsubtotal)
1355-
rsubtotal, lsubtotal = (0, 0)
1356-
# hide ingredients for lines following the first
1357-
for j in range(line_start + 1, line_end):
1358-
meal_lines[j] = meal_lines[j]._replace(span="-1")
1359-
# Add a blank line as separator
1360-
meal_lines.append(MealLine(*meal_line_fields[1::2]))
1361-
# first line of next combination of ingredients
1362-
line_start = len(meal_lines)
1363-
# END WHILE
1384+
return component_lines_sorted
13641385

1365-
meal_lines.append(
1366-
MealLine(*meal_line_fields[1::2])._replace(
1367-
rqty=str(rtotal), lqty=str(ltotal), ingr_clash="TOTAL SPECIALS"
1368-
)
1369-
)
13701386

1371-
return (component_lines_sorted, meal_lines)
1387+
def format_client_name(firstname, lastname):
1388+
return f"{lastname}, {firstname[:2]}."
13721389

13731390

13741391
def kcr_make_pages(kcr_date, component_lines, meal_lines):
@@ -1509,7 +1526,7 @@ def go():
15091526
RLParagraph("Regular", styles["NormalRight"]),
15101527
RLParagraph("Large", styles["NormalRight"]),
15111528
"",
1512-
RLParagraph("Client", styles["NormalLeft"]),
1529+
RLParagraph("Client & Food Prep", styles["NormalLeft"]),
15131530
RLParagraph("Other restrictions", styles["NormalLeft"]),
15141531
]
15151532
)
@@ -1522,7 +1539,7 @@ def go():
15221539
# Total line at the bottom
15231540
rows.append(
15241541
[
1525-
RLParagraph(ml.ingr_clash, styles["NormalLeftBold"]),
1542+
RLParagraph(ml.ingr_clash or "∅", styles["NormalLeftBold"]),
15261543
RLParagraph(ml.rqty, styles["NormalRightBold"]),
15271544
RLParagraph(ml.lqty, styles["NormalRightBold"]),
15281545
"",
@@ -1551,7 +1568,7 @@ def go():
15511568
None, # cap
15521569
[1, 2],
15531570
) # dashes
1554-
value = RLParagraph(ml.ingr_clash, styles["LargeBoldLeft"])
1571+
value = RLParagraph(ml.ingr_clash or "∅", styles["LargeBoldLeft"])
15551572
else:
15561573
# span = -1 means clash data must be blanked out
15571574
# because it is the same as the initial spanned row
@@ -1563,13 +1580,17 @@ def go():
15631580
else:
15641581
client = ml.client
15651582
qty_style = "NormalRight"
1583+
food_prep = f"({ml.food_prep})" if ml.food_prep else ""
15661584
rows.append(
15671585
[
15681586
value,
15691587
RLParagraph(ml.rqty, styles[qty_style]),
15701588
RLParagraph(ml.lqty, styles[qty_style]),
15711589
"",
1572-
RLParagraph(client, styles["NormalLeft"]),
1590+
[
1591+
RLParagraph(client, styles["NormalLeft"]),
1592+
RLParagraph(food_prep, styles["NormalLeftBold"]),
1593+
],
15731594
[
15741595
RLParagraph(
15751596
ml.rest_ingr

0 commit comments

Comments
 (0)