@@ -1111,7 +1111,8 @@ def get(self, request, *args, **kwargs):
1111
1111
):
1112
1112
kitchen_list [client_id ] = kitchen_item
1113
1113
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 )
1115
1116
if component_lines :
1116
1117
# we have orders on that date
1117
1118
num_pages = kcr_make_pages ( # kitchen count as PDF
@@ -1157,22 +1158,32 @@ def get(self, request, *args, **kwargs):
1157
1158
ComponentLine = collections .namedtuple ("ComponentLine" , component_line_fields [0 ::2 ])
1158
1159
1159
1160
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
1162
1165
"client" ,
1163
- "" , # String : Lastname and abbreviated first name
1166
+ "" ,
1167
+ # str: Quantity of regular size main dishes
1164
1168
"rqty" ,
1165
- "" , # String : Quantity of regular size main dishes
1169
+ "" ,
1170
+ # str: Quantity of large size main dishes
1166
1171
"lqty" ,
1167
- "" , # String : Quantity of large size main dishes
1172
+ "" ,
1173
+ # str: Ingredients that clashes
1168
1174
"ingr_clash" ,
1169
- "" , # String : Ingredients that clash
1175
+ "" ,
1176
+ # str: Other ingredients to avoid
1170
1177
"rest_ingr" ,
1171
- "" , # String : Other ingredients to avoid
1178
+ "" ,
1179
+ # str: Restricted items
1172
1180
"rest_item" ,
1173
- "" , # String : Restricted items
1181
+ "" ,
1174
1182
"span" ,
1175
1183
"1" ,
1184
+ # str: food preparation
1185
+ "food_prep" ,
1186
+ "" ,
1176
1187
] # Number of lines to "rowspan" in table
1177
1188
MealLine = collections .namedtuple ("MealLine" , meal_line_fields [0 ::2 ])
1178
1189
@@ -1190,7 +1201,7 @@ def meal_line(kititm):
1190
1201
A MealLine object
1191
1202
"""
1192
1203
return MealLine (
1193
- client = kititm .lastname + ", " + kititm .firstname [ 0 : 2 ] + "." ,
1204
+ client = format_client_name ( kititm .firstname , kititm .lastname ) ,
1194
1205
rqty = (str (kititm .meal_qty ) if kititm .meal_size == SIZE_CHOICES_REGULAR else "" ),
1195
1206
lqty = (str (kititm .meal_qty ) if kititm .meal_size == SIZE_CHOICES_LARGE else "" ),
1196
1207
ingr_clash = "" ,
@@ -1203,6 +1214,7 @@ def meal_line(kititm):
1203
1214
),
1204
1215
rest_item = ", " .join (kititm .restricted_items ),
1205
1216
span = "1" ,
1217
+ food_prep = ", " .join (sorted (kititm .preparation )),
1206
1218
)
1207
1219
1208
1220
@@ -1227,7 +1239,66 @@ def kcr_cumulate(regular, large, meal):
1227
1239
return (regular , large )
1228
1240
1229
1241
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 ):
1231
1302
"""Generate the sections and lines for the kitchen count report.
1232
1303
1233
1304
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):
1243
1314
meals will be delivered.
1244
1315
1245
1316
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.
1248
1318
"""
1249
1319
# Build component summary
1250
1320
component_lines = {}
@@ -1311,64 +1381,11 @@ def kcr_make_lines(kitchen_list, kcr_date):
1311
1381
else :
1312
1382
component_lines_sorted = []
1313
1383
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
1364
1385
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
- )
1370
1386
1371
- return (component_lines_sorted , meal_lines )
1387
+ def format_client_name (firstname , lastname ):
1388
+ return f"{ lastname } , { firstname [:2 ]} ."
1372
1389
1373
1390
1374
1391
def kcr_make_pages (kcr_date , component_lines , meal_lines ):
@@ -1509,7 +1526,7 @@ def go():
1509
1526
RLParagraph ("Regular" , styles ["NormalRight" ]),
1510
1527
RLParagraph ("Large" , styles ["NormalRight" ]),
1511
1528
"" ,
1512
- RLParagraph ("Client" , styles ["NormalLeft" ]),
1529
+ RLParagraph ("Client & Food Prep " , styles ["NormalLeft" ]),
1513
1530
RLParagraph ("Other restrictions" , styles ["NormalLeft" ]),
1514
1531
]
1515
1532
)
@@ -1522,7 +1539,7 @@ def go():
1522
1539
# Total line at the bottom
1523
1540
rows .append (
1524
1541
[
1525
- RLParagraph (ml .ingr_clash , styles ["NormalLeftBold" ]),
1542
+ RLParagraph (ml .ingr_clash or "∅" , styles ["NormalLeftBold" ]),
1526
1543
RLParagraph (ml .rqty , styles ["NormalRightBold" ]),
1527
1544
RLParagraph (ml .lqty , styles ["NormalRightBold" ]),
1528
1545
"" ,
@@ -1551,7 +1568,7 @@ def go():
1551
1568
None , # cap
1552
1569
[1 , 2 ],
1553
1570
) # dashes
1554
- value = RLParagraph (ml .ingr_clash , styles ["LargeBoldLeft" ])
1571
+ value = RLParagraph (ml .ingr_clash or "∅" , styles ["LargeBoldLeft" ])
1555
1572
else :
1556
1573
# span = -1 means clash data must be blanked out
1557
1574
# because it is the same as the initial spanned row
@@ -1563,13 +1580,17 @@ def go():
1563
1580
else :
1564
1581
client = ml .client
1565
1582
qty_style = "NormalRight"
1583
+ food_prep = f"({ ml .food_prep } )" if ml .food_prep else ""
1566
1584
rows .append (
1567
1585
[
1568
1586
value ,
1569
1587
RLParagraph (ml .rqty , styles [qty_style ]),
1570
1588
RLParagraph (ml .lqty , styles [qty_style ]),
1571
1589
"" ,
1572
- RLParagraph (client , styles ["NormalLeft" ]),
1590
+ [
1591
+ RLParagraph (client , styles ["NormalLeft" ]),
1592
+ RLParagraph (food_prep , styles ["NormalLeftBold" ]),
1593
+ ],
1573
1594
[
1574
1595
RLParagraph (
1575
1596
ml .rest_ingr
0 commit comments