3 if (isset($_POST['show_add_order'])) {
4 set_last_selected("area_id", $_POST['area_id']);
5 $area_id = $_POST['area_id'];
6 show_new_order_form($area_id);
8 else if (isset($_POST['add_order'])) {
9 set_last_selected("area_id", $_POST['area_id']);
12 echo "<p>Order placed.</p>\n";
13 $parameters = array("id", $id);
16 else if (isset($_POST['update_order'])) {
17 list($ignored, $id, $args) = parse_parameters($parameters);
19 $order = $q->findOneById($id);
21 if (update_order($order) !== false) {
22 echo "<p>Updated order.</p>\n";
23 $parameters = array("id", $order->getId());
27 echo "<p>No such contact!</p>\n";
30 else if ($_POST['show_in_area']) {
31 set_last_selected("area_id", $_POST['area_id']);
33 $area = $q->findOneById($_POST['area_id']);
34 header(sprintf("Location: http%s://%s/%s/in/area/%s/%d%s%s", ($_SERVER['HTTPS']) ? "s" : "", $_SERVER['HTTP_HOST'], $module, urlencode($area->getName()), $_POST['area_id'], get_order_state_query_uri(get_order_state_mask(), get_order_date_query_uri($_POST['from'], $_POST['to']))));
37 else if ($_POST['show_in_city']) {
38 set_last_selected("city_id", $_POST['city_id']);
40 $city = $q->findOneById($_POST['city_id']);
41 header(sprintf("Location: http%s://%s/%s/in/city/%s/%d%s%s", ($_SERVER['HTTPS']) ? "s" : "", $_SERVER['HTTP_HOST'], $module, urlencode($city->getName()), $_POST['city_id'], get_order_state_query_uri(get_order_state_mask()), get_order_date_query_uri($_POST['from'], $_POST['to'])));
45 function show_orders($city_id = null, $area_id = null, $requester_ids = null, $beneficiary_ids = null, $state_mask = null, $from = null, $to = null) {
46 list($first_page, $per_page) = pagination();
47 /* XXX: Use Propel methods. */
48 if (isset($state_mask)) $order_ids = get_order_ids_by_state($state_mask);
50 if (isset($requester_ids)) $q->filterByRequesterId($requester_ids);
51 if (isset($beneficiary_ids)) $q->filterByBeneficiaryId($beneficiary_ids);
53 #if (isset($state_mask)) $q->useOrderStateQuery()->addSelectQuery($latest_state, 'latestState')->where("order_id=latestState.order_id")->where("state & $state_mask")->endUse();
54 if (isset($city_id) || isset($area_id)) {
55 $q->joinWith('Order.Beneficiary');
56 $q->joinWith('Beneficiary.Address');
57 if (isset($area_id)) $q->where('Address.AreaId=?', $area_id);
58 if (isset($city_id)) {
59 $q->joinWith('Address.Area');
60 $q->where('Area.CityId=?', $city_id);
63 if (isset($state_mask)) $q->filterById($order_ids);
64 if (isset($from)) $q->where('Order.Date >= ?', $from);
65 if (isset($to)) $q->where('Order.Date <= ?', $to);
66 $orders = $q->orderByDate('desc')->orderById('desc')->paginate($first_page, $per_page);
68 foreach ($orders as $order) {
69 echo "<br>\n" . get_order_summary($order) . "<br>\n";
71 show_pagination($orders);
76 function show_city_orders($city_name, $city_id = null, $state_mask = null, $from = null, $to = null) {
77 if (isset($city_id)) $city = get_city_by_id($city_id);
78 else if ($city_name) $city = get_city_by_name($city_name);
80 echo "<p>Orders in city " . $city->getLink(get_city_displayname($city)) . ":";
81 return show_orders($city->getId(), null, null, null, $state_mask, $from, $to);
83 else echo "<p>No such city!</p>\n";
86 function show_requester_orders($contact_name, $contact_id = null, $state_mask = null, $from = null, $to = null) {
87 if (isset($contact_id)) $contact = get_contact_by_id($contact_id);
88 else if ($contact_name) $contact = get_contact_by_name($contact_name);
90 echo "<p>Orders from referrer " . $contact->getLink() . ":";
91 return show_orders(null, null, $contact->getId(), null, $state_mask, $from, $to);
93 else echo "<p>No such contact!</p>\n";
96 function show_beneficiary_orders($contact_name, $contact_id = null, $state_mask = null, $from = null, $to = null) {
97 if (isset($contact_id)) $contact = get_contact_by_id($contact_id);
98 else if ($contact_name) $contact = get_contact_by_name($contact_name);
100 echo "<p>Orders to beneficiary " . $contact->getLink() . ":";
101 return show_orders(null, null, null, $contact->getId(), $state_mask, $from, $to);
103 else echo "<p>No such contact!</p>\n";
106 function show_area_orders($area_name, $area_id = null, $state_mask = null, $from = null, $to = null) {
107 if (isset($area_id)) $area = get_area_by_id($area_id);
108 else if ($area_name) $area = get_area_by_name($area_name);
110 echo "<p>Orders in area " . $area->getLink() . ":";
111 return show_orders(null, $area->getId(), null, null, $state_mask, $from, $to);
113 else echo "<p>No such area!</p>\n";
116 function show_order_state_form($state_mask = null) {
117 global $states, $all_states;
119 if (is_null($state_mask)) $state_mask = $all_states;
121 echo "<p>Restrict to order states:\n";
122 for ($i = 0; $i < count($states); $i++) {
123 echo " <input type=\"checkbox\" id=\"state_$i\" name=\"state_$i\"";
124 if ($state_mask & (1 << $i)) echo " checked";
125 echo "><label for=\"state_$i\">$states[$i]</label>\n";
130 function get_order_state_mask($string = null) {
131 global $states, $all_states;
135 if (isset($string)) {
136 $selected = explode("+", $string);
137 for ($i = 0; $i < count($states); $i++) {
138 if (in_array($states[$i], $selected)) $mask |= (1 << $i);
142 for ($i = 0; $i < count($states); $i++) {
143 if ($_POST['state_' . $i] == "on") $mask |= (1 << $i);
147 if (! $mask) $mask = $all_states;
151 function get_order_state_query_string($mask) {
156 for ($i = 0; $i < count($states); $i++) {
157 if ($mask & (1 << $i)) $selected[] = $states[$i];
160 return implode("+", $selected);
163 function get_order_state_query_uri($mask) {
166 if (is_null($mask)) return "";
167 if ($mask == $all_states) return "";
169 return "/state/" . get_order_state_query_string($mask);
172 function get_order_date_query_uri($from, $to) {
174 if ($from) $uri .= "/from/$from";
175 if ($to) $uri .= "/to/$to";
177 if (! $uri) return "";
182 function show_order_areas_form($city_id = null) {
183 $areas = get_city_areas($city_id);
184 if (! count($areas)) {
185 echo "<p>No <a href=\"/area\">areas</a>!</p>\n";
189 $candidates = array();
190 foreach ($areas as $area) {
191 if (! count(get_area_contacts($area->getId()))) continue;
192 $candidates[] = $area;
194 if (! count($candidates)) return;
196 echo "<p>Show orders in area\n";
197 echo "<select name=\"area_id\">\n";
198 foreach ($candidates as $area) {
199 option("area_id", $area->getId(), get_area_displayname($area));
202 echo "<input type=\"submit\" name=\"show_in_area\" value=\"Show\">\n";
205 function show_order_cities_form($city_id = null) {
207 $cities = $q->orderByName()->find();
209 if (! count($cities)) {
210 echo "<p>No <a href=\"/city\">cities</a>!</p>\n";
214 $candidates = array();
215 foreach ($cities as $city) {
216 if (! count(get_city_contacts($city->getId()))) continue;
217 $candidates[] = $city;
219 if (! count($candidates)) return;
221 echo "<p>Show orders in city\n";
222 echo "<select name=\"city_id\">\n";
223 foreach ($candidates as $city) {
224 option("city_id", $city->getId(), get_city_displayname($city), $city_id);
227 echo "<input type=\"submit\" name=\"show_in_city\" value=\"Show\">\n";
230 function show_order_forms($city_id, $state_mask, $from = null, $to = null) {
231 form("noprint standout");
232 show_order_state_form($state_mask);
233 echo "<p>Restrict to orders for delivery between ";
234 datepicker("from", $from, true, null, false, "to");
236 datepicker("to", $to, true, "from", false);
237 show_order_areas_form($city_id);
238 show_order_cities_form($city_id);
242 function show_order_form($order = null, $area_id = null) {
243 global $states, $parcel_sizes, $parcel_contents;
246 $order_state = get_order_state($order);
248 $state = $order_state->getState();
249 $driver_id = $order_state->getDriverId();
252 else $order = new Order;
256 echo " <td>Delivery</td>\n";
257 /* XXX: Find suitable dates from area. */
259 show_date_form("date", $order->getDate());
260 if (! $order->getDate()) {
261 echo " and recur for <select name=\"recurrence\">\n";
262 for ($i = 0; $i < 4; $i++) option("recurrence", $i, $i);
263 echo "</select> weeks";
270 echo " <td>Referrer</td>\n";
271 echo " <td><select name=\"requester_id\">\n";
272 option("requester_id", null, "");
273 $contacts = get_area_requesters();
274 foreach ($contacts as $contact) {
275 option("requester_id", $contact->getId(), $contact->getDisplayname(), $order->getRequesterId());
278 $contact = get_contact_by_id($order->getRequesterId(), false);
279 if ($contact) echo " " . get_small_link($contact->getDisplayname(), $contact->getURL());
285 echo " <td>Beneficiary</td>\n";
286 echo " <td><select name=\"beneficiary_id\">\n";
287 option("beneficiary_id", null, "");
288 if (! $order->getId() && $order->getBeneficiaryId()) {
289 $contact = get_contact_by_id($order->getBeneficiaryId());
290 if ($contact) option("beneficiary_id", $order->getBeneficiaryId(), $contact->getDisplayname(), $order->getBeneficiaryId());
293 $contacts = get_area_beneficiaries($area_id);
294 foreach ($contacts as $contact) {
295 option("beneficiary_id", $contact->getId(), $contact->getDisplayname(), $order->getBeneficiaryId());
299 $contact = get_contact_by_id($order->getBeneficiaryId(), false);
300 if ($contact) echo " " . get_small_link($contact->getDisplayname(), $contact->getURL());
306 echo " <td>Hub</td>\n";
307 echo " <td><select name=\"hub_id\">\n";
308 option("hub_id", null, "");
309 $hubs = get_area_hubs();
310 foreach ($hubs as $hub) {
311 option("hub_id", $hub->getId(), $hub->getDisplayname(), $order->getHubId());
314 $hub = get_hub_by_id($order->getHubId(), false);
315 if ($hub) echo " " . get_small_link($hub->getDisplayname(), $hub->getURL());
321 echo " <td>Parcel size</td>\n";
322 echo " <td><select name=\"parcel_size\">\n";
323 $mask = 1 << count($parcel_sizes);
324 for ($i = 0; $i < count($parcel_sizes); $i++) {
325 option("parcel_size", 1 << $i, $parcel_sizes[$i], $order->getParcel() % $mask);
327 echo "</select></td>\n";
330 /* Parcel contents. */
332 echo " <td>Parcel contents</td>\n";
334 for ($i = count($parcel_sizes); $i < count($parcel_contents); $i++) {
335 echo " <input type=\"checkbox\" id=\"parcel_$i\" name=\"parcel_$i\"";
336 if ($order->getParcel() & (1 << $i)) echo " checked";
337 echo "><label for=\"parcel_$i\">$parcel_contents[$i]</label>\n";
344 echo " <td>Notes</td>\n";
345 echo " <td>"; textarea("notes", $order->getNotes()); echo "</td>\n";
350 echo " <td>Driver</td>\n";
351 $contacts = get_city_drivers();
352 if (count($contacts)) {
353 echo " <td><select name=\"driver_id\">\n";
354 option("driver_id", null, "");
355 foreach ($contacts as $contact) {
356 option("driver_id", $contact->getId(), $contact->getDisplayname(), $driver_id);
359 $contact = get_contact_by_id($driver_id, false);
360 if ($contact) echo " " . get_small_link($contact->getDisplayname(), $contact->getURL());
363 else echo " <td>No drivers!</td>\n";
367 if ($order->getId()) {
369 echo " <td>State</td>\n";
370 echo " <td><select name=\"state\">\n";
371 for ($i = 0; $i < count($states); $i++) {
372 option("state", 1 << $i, ucfirst($states[$i]), $state);
374 echo "</select></td>\n";
379 function show_new_order_form($area_id = null) {
380 if (! check_admin(1)) return;
382 $area = get_area_by_id($area_id);
383 if (! count($area)) {
384 echo "<p>No such <a href=\"/area\">area</a>!</p>\n";
389 echo "<p>Place an order:</p>\n";
392 show_order_form(null, $area_id);
395 echo " <td colspan=2>"; submit("add_order", "Order"); echo "</td></tr>\n";
401 function show_contact_order_form($contact) {
402 if (! check_admin(1)) return;
404 $area = get_contact_area($contact);
406 echo "<p>No valid <a href=\"/area\">area</a> for contact!</p>\n";
411 $order->setBeneficiaryId($contact->getId());
414 echo "<p>Placing order for " . $contact->getStrongLink() . ".";
415 $parcel = $contact->getParcel();
417 echo " Suggested parcel type is <span class=\"strong\">" . get_contact_parcel_string($contact) . "</span>";
418 $order->setParcel($parcel);
423 show_order_form($order, $area_id);
426 echo " <td colspan=2>"; submit("add_order", "Order"); echo "</td></tr>\n";
432 function show_add_new_order_form() {
433 if (! check_admin(1)) return;
435 /* We intentionally hide areas with no contacts. */
436 $areas = get_city_areas_with_contacts(null, $GLOBALS['ROLE_BENEFICIARY']);
437 if (! count($areas)) {
438 echo "<p>Can't place any orders until at least one <a href=\"/area\">area</a> has a <a href=\"/contact\">contact</a>!</p>\n";
442 form("noprint standout");
443 echo "<p>Place an order in <select name=\"area_id\">\n";
444 foreach ($areas as $area) {
445 option("area_id", $area->getId(), get_area_displayname($area));
448 submit("show_add_order", "Proceed");
453 function update_order(&$order, $new = false) {
454 global $user_id, $parcel_sizes, $parcel_contents;
456 #$date = ymd_to_iso8601("date");
457 $date = $_POST['date'];
458 $requester_id = $_POST['requester_id'];
459 $beneficiary_id = $_POST['beneficiary_id'];
460 $hub_id = $_POST['hub_id'];
461 $driver_id = $_POST['driver_id'];
462 if (! $driver_id) $driver_id = null;
463 $state = $_POST['state'];
464 if (! $state) $state = $GLOBALS['STATE_PLACED'];
465 $parcel = $_POST['parcel_size'];
466 for ($i = count($parcel_sizes); $i < count($parcel_contents); $i++) {
467 if ($_POST['parcel_' . $i] == "on") $parcel |= (1 << $i);
469 $notes = $_POST['notes'];
472 list($y, $m, $d) = explode('-', $date);
473 $then = mktime(0, 0, 0, $m, $d, $y);
476 /* XXX: check date */
478 $requester = get_contact_by_id($requester_id);
480 echo "<p>Invalid referrer!</p>\n";
484 $beneficiary = get_contact_by_id($beneficiary_id);
485 if (! $beneficiary) {
486 echo "<p>Invalid beneficiary!</p>\n";
491 $hub = get_hub_by_id($hub_id);
493 echo "<p>Invalid hub!</p>\n";
499 if ($new && isset($_POST['recurrence'])) $recurrence = $_POST['recurrence'];
500 if (! $recurrence) $recurrence = 0;
503 for ($i = 0; $i <= $recurrence; $i++) {
505 echo "<p>Creating recurrence $i.</p>\n";
509 $order->setDate($then + 7 * 86400 * $i);
510 $order->setRequesterId($requester_id);
511 $order->setBeneficiaryId($beneficiary_id);
512 $order->setHubId($hub_id);
513 $order->setParcel($parcel);
514 $order->setNotes($notes);
516 /* XXX: begin/commit */
520 $order_state = new OrderState;
521 $order_state->setUpdated($now);
522 $order_state->setOrderId($order->getId());
523 $order_state->setUserId($user_id);
524 $order_state->setDriverId($driver_id);
525 $order_state->setState($state);
527 $order_state->save();
529 catch (Exception $e) {
530 if ($new) echo "<p>Error placing order.</p>\n";
531 else echo "<p>Error updating order.</p>\n";
532 echo "<p>" . $e->getMessage() . "</p>\n";
540 function add_order() {
541 if (! check_admin(1, "place an order")) return;
544 if (! update_order($order, true)) return false;
545 return $order->getId();
548 function confirm_delete_order($id = null) {
549 if (! check_admin(1, "delete an order")) return;
551 if (isset($id)) $order = get_order_by_id($id);
552 if (! $order) return false;
554 echo "<h3>Confirm deletion</h3>\n";
555 echo "<p>You must confirm deletion of order $id: " . $order->getDeleteLink(true) . "</p>\n";
558 function delete_order($id = null) {
559 if (! check_admin(1, "delete an order")) return;
561 if (isset($id)) $order = get_order_by_id($id);
562 if (! $order) return false;
565 $q = new OrderStateQuery;
566 $order_states = $q->filterByOrderId($id)->find();
567 foreach ($order_states as $order_state) $order_state->delete();
569 echo "<p>Deleted order.</p>\n";
571 catch (Exception $e) {
572 echo "<p>Error deleting order $id!</p>\n";
579 function show_order_history($id) {
582 $q = new OrderStateQuery();
583 $order_states = $q->filterByOrderId($id)->orderById()->find();
585 if (! count($order_states)) return;
587 echo "<h3>Order history</h3>\n";
588 echo "<p class=\"history\">\n";
589 foreach ($order_states as $order_state) {
590 $date = $order_state->getUpdated();
592 $user = get_contact_by_id($order_state->getUserId());
593 if ($user) $username = $user->getDisplayname();
594 else $username = "unknown user";
596 $driver_id = $order_state->getDriverId();
597 if ($driver_id) $driver = get_contact_by_id($driver_id);
600 echo "<strong>$username</strong> changed order to state <strong>" . get_order_state_string($order_state) . "</strong>";
601 if ($driver) echo " for driver " . $driver->getDisplayname();
602 echo " on $date.<br>\n";
607 function show_order(&$id = null) {
608 if (isset($id)) $order = get_order_by_id($id);
609 if (! $order) return;
612 echo "<p>Order: <span class=\"strong\">" . $order->getId() . "</span>";
613 if (check_admin(1)) {
614 echo " " . $order->getDeleteLink();
620 show_order_form($order);
622 if (check_admin(1)) {
624 echo " <td colspan=2>";
625 submit("update_order", "Update");
633 show_order_history($order->getId());
637 if (count($parameters)) {
638 for ($i = 1; $i < count($parameters); $i++) {
639 if ($parameters[$i] == "state") {
640 /* /order/state/placed+picked */
641 $state_mask = get_order_state_mask($parameters[$i + 1]);
645 for ($i = 1; $i < count($parameters); $i++) {
646 if ($parameters[$i] == "dated") {
647 for ($j = $i + 1; $j < count($parameters) - 1; $j++) {
648 if ($parameters[$j] == "from") $from = $parameters[$j + 1];
649 if ($parameters[$j] == "to") $to = $parameters[$j + 1];
652 if ($from || $to) check_dates('order', $from, $to, false, false);
657 if ($parameters[0] == "in") {
658 /* /order/in/area/Romsey+Town/1 */
659 switch ($parameters[1]) {
662 $area_id = $parameters[3];
663 $_POST['area_id'] = $area_id;
665 $area = $q->findOneById($area_id);
666 $city = get_area_city($area);
667 if ($city) $city_id = $city->getId();
668 show_area_orders($parameters[2], $area_id, $state_mask, $from, $to);
672 $city_id = $parameters[3];
673 $_POST['city_id'] = $city_id;
675 $city = $q->findOneById($city_id);
676 show_city_orders($parameters[2], $city_id, $state_mask, $from, $to);
680 else if ($parameters[0] == "from") {
681 /* /order/from/referrer/Iain+Patterson/4 */
682 switch ($parameters[1]) {
684 $contact_id = $parameters[3];
685 $q = new ContactQuery;
686 $contact = $q->findOneById($contact_id);
687 show_requester_orders($parameters[2], $contact_id, $state_mask, $from, $to);
691 else if ($parameters[0] == "to") {
692 /* /order/to/beneficiary/Cambridge+Community+Church/1 */
693 switch ($parameters[1]) {
695 $contact_id = $parameters[3];
696 $q = new ContactQuery;
697 $hub = $q->findOneById($contact_id);
698 show_beneficiary_orders($parameters[2], $contact_id, $state_mask, $from, $to);
702 else if ($parameters[0] == "place") {
703 if ($parameters[1] == "for") {
704 if ($parameters[2] == "beneficiary") {
705 if ($parameters[4]) $contact = get_contact_by_id($parameters[4]);
706 if (! $contact) $contact = get_contact_by_name(urldecode($parameters[3]));
707 if ($contact) show_contact_order_form($contact);
712 list($ignored, $id, $args) = parse_parameters($parameters);
713 //echo "<p>$name($id) " . print_r($args, true) . "</p>\n";
717 confirm_delete_order($id);
720 case "confirmdelete":
725 else if (isset($id)) show_order($id);
726 else if ($state_mask) show_orders(null, null, null, null, $state_mask, $from, $to);
728 show_order_forms($city_id, $state_mask, $from, $to);
729 show_add_new_order_form($city_id);