+<?php
+
+ if (isset($_POST['show_add_order'])) {
+ $area_id = $_POST['area_id'];
+ show_new_order_form($area_id);
+ }
+ else if (isset($_POST['add_order'])) {
+ $id = add_order();
+ if ($id !== false) {
+ echo "<p>Order placed.</p>\n";
+ $parameters = array("id", $id);
+ }
+ }
+ else if (isset($_POST['update_order'])) {
+ list($ignored, $id, $args) = parse_parameters($parameters);
+ $q = new OrderQuery;
+ $order = $q->findOneById($id);
+ if ($order) {
+ if (update_order($order) !== false) {
+ echo "<p>Updated order.</p>\n";
+ $parameters = array("id", $order->getId());
+ }
+ }
+ else {
+ echo "<p>No such contact!</p>\n";
+ }
+ }
+ else if ($_POST['show_in_area']) {
+ $q = new AreaQuery;
+ $area = $q->findOneById($_POST['area_id']);
+ header(sprintf("Location: http%s://%s/%s/in/area/%s/%d%s", ($_SERVER['HTTPS']) ? "s" : "", $_SERVER['HTTP_HOST'], $module, urlencode($area->getName()), $_POST['area_id'], get_order_state_uri(get_order_state_mask())));
+ exit;
+ }
+ else if ($_POST['show_in_city']) {
+ $q = new CityQuery;
+ $city = $q->findOneById($_POST['city_id']);
+ header(sprintf("Location: http%s://%s/%s/in/city/%s/%d%s", ($_SERVER['HTTPS']) ? "s" : "", $_SERVER['HTTP_HOST'], $module, urlencode($city->getName()), $_POST['city_id'], get_order_state_uri(get_order_state_mask())));
+ exit;
+ }
+
+ function show_orders($offset, $per_page, $requester_ids = null, $beneficiary_ids = null, $state_mask = null) {
+ /* XXX: Use Propel methods. */
+ if (isset($state_mask)) {
+ $order_ids = array();
+ $dbh = Propel::getConnection();
+ $sth = $dbh->prepare("select * from OrderState o where updated=(select max(updated) from OrderState where order_id=o.order_id) and state & $state_mask");
+ $sth->execute();
+ $order_states = OrderStatePeer::populateObjects($sth);
+ foreach ($order_states as $order_state) $order_ids[] = $order_state->getOrderId();
+ }
+ $q = new OrderQuery;
+ if (isset($requester_ids)) $q->filterByRequesterId($requester_ids);
+ if (isset($beneficiary_ids)) $q->filterByBeneficiaryId($beneficiary_ids);
+ # XXX: Doesn't work.
+ #if (isset($state_mask)) $q->useOrderStateQuery()->addSelectQuery($latest_state, 'latestState')->where("order_id=latestState.order_id")->where("state & $state_mask")->endUse();
+ if (isset($state_mask)) $q->filterById($order_ids);
+ $orders = $q->orderByDate()->find();
+ if (count($orders)) {
+ foreach ($orders as $order) {
+ echo "<br>\nOrder " . $order->getStrongLink($order->getId()) . ": " . get_order_displayname($order);
+ if (check_admin(1)) {
+ echo " " . $order->getDeleteLink();
+ }
+
+ /* XXX: Should pull from query. */
+ $q = new ContactQuery;
+ $contact = $q->findOneById($order->getBeneficiaryId());
+ if ($contact) {
+ echo " for " . $contact->getLink();
+ $area = get_contact_area($contact);
+ if ($area) echo " in " . $area->getLink();
+ }
+
+ if ($order->getHubId()) {
+ $q = new HubQuery;
+ $hub = $q->findOneById($order->getHubId());
+ if ($hub) echo " to hub " . $hub->getLink();
+ $area = get_hub_area($hub);
+ if ($area) echo " in " . $area->getLink();
+ }
+ }
+ }
+ else echo " none";
+ }
+
+ function show_city_orders($offset, $per_page, $city_name, $city_id = null, $state_mask = null) {
+ if (isset($city_id)) $city = get_city_by_id($city_id);
+ else if ($city_name) $city = get_city_by_name($city_name);
+ if ($city) {
+ $contacts = get_city_contacts($city->getId(), $GLOBALS['ROLE_BENEFICIARY']);
+ $beneficiary_ids = array();
+ foreach ($contacts as $contact) $beneficiary_ids[] = $contact->getId();
+
+ echo "<p>Orders in city " . $city->getLink(get_city_displayname($city)) . ":";
+ return show_orders($offset, $per_page, null, $beneficiary_ids, $state_mask);
+ }
+ else echo "<p>No such city!</p>\n";
+ }
+
+ function show_requester_orders($offset, $per_page, $contact_name, $contact_id = null, $state_mask = null) {
+ if (isset($contact_id)) $contact = get_contact_by_id($contact_id);
+ else if ($contact_name) $contact = get_contact_by_name($contact_name);
+ if ($contact) {
+ echo "<p>Orders from requester " . $contact->getLink() . ":";
+ return show_orders($offset, $per_page, $contact->getId(), null, $state_mask);
+ }
+ else echo "<p>No such contact!</p>\n";
+ }
+
+ function show_beneficiary_orders($offset, $per_page, $contact_name, $contact_id = null, $state_mask = null) {
+ if (isset($contact_id)) $contact = get_contact_by_id($contact_id);
+ else if ($contact_name) $contact = get_contact_by_name($contact_name);
+ if ($contact) {
+ echo "<p>Orders to beneficiary " . $contact->getLink() . ":";
+ return show_orders($offset, $per_page, null, $contact->getId(), $state_mask);
+ }
+ else echo "<p>No such contact!</p>\n";
+ }
+
+ function show_area_orders($offset, $per_page, $area_name, $area_id = null, $state_mask = null) {
+ if (isset($area_id)) $area = get_area_by_id($area_id);
+ else if ($area_name) $area = get_area_by_name($area_name);
+ if ($area) {
+ $contacts = get_area_contacts($area->getId(), $GLOBALS['ROLE_BENEFICIARY']);
+ $contact_ids = array();
+ foreach ($contacts as $contact) $contact_ids[] = $contact->getId();
+
+ echo "<p>Orders in area " . $area->getLink() . ":";
+ return show_orders($offset, $per_page, null, $contact_ids, $state_mask);
+ }
+ else echo "<p>No such area!</p>\n";
+ }
+
+ function show_order_state_form($state_mask = null) {
+ global $states, $all_states;
+
+ if (is_null($state_mask)) $state_mask = $all_states;
+
+ echo "<p>Restrict to order states:\n";
+ for ($i = 0; $i < count($states); $i++) {
+ echo " <input type=\"checkbox\" name=\"state_$i\"";
+ if ($state_mask & (1 << $i)) echo " checked";
+ echo ">$states[$i]\n";
+ }
+ echo "</p>\n";
+ }
+
+ function get_order_state_mask($string = null) {
+ global $states, $all_states;
+
+ $mask = 0;
+
+ if (isset($string)) {
+ $selected = explode("+", $string);
+ for ($i = 0; $i < count($states); $i++) {
+ if (in_array($states[$i], $selected)) $mask |= (1 << $i);
+ }
+ }
+ else {
+ for ($i = 0; $i < count($states); $i++) {
+ if ($_POST['state_' . $i] == "on") $mask |= (1 << $i);
+ }
+ }
+
+ if (! $mask) $mask = $all_states;
+ return $mask;
+ }
+
+ function get_order_state_string($mask) {
+ global $states;
+
+ $selected = array();
+
+ for ($i = 0; $i < count($states); $i++) {
+ if ($mask & (1 << $i)) $selected[] = $states[$i];
+ }
+
+ return implode("+", $selected);
+ }
+
+ function get_order_state_uri($mask) {
+ global $all_states;
+
+ if (is_null($mask)) return "";
+ if ($mask == $all_states) return "";
+
+ return "/state/" . get_order_state_string($mask);
+ }
+
+ function show_order_areas_form($city_id = null) {
+ $areas = get_city_areas($city_id);
+ if (! count($areas)) {
+ echo "<p>No <a href=\"/area\">areas</a>!</p>\n";
+ return;
+ }
+
+ echo "<p>Show orders in area\n";
+ echo "<select name=\"area_id\">\n";
+ foreach ($areas as $area) {
+ option("area_id", $area->getId(), get_area_displayname($area));
+ }
+ echo "</select>\n";
+ echo "<input type=\"submit\" name=\"show_in_area\" value=\"Show\">\n";
+ }
+
+ function show_order_cities_form($city_id = null) {
+ $q = new CityQuery;
+ $cities = $q->orderByName()->find();
+
+ if (! count($cities)) {
+ echo "<p>No <a href=\"/city\">cities</a>!</p>\n";
+ return;
+ }
+
+ echo "<p>Show orders in city\n";
+ echo "<select name=\"city_id\">\n";
+ foreach ($cities as $city) {
+ option("city_id", $city->getId(), get_city_displayname($city), $city_id);
+ }
+ echo "</select>\n";
+ echo "<input type=\"submit\" name=\"show_in_city\" value=\"Show\">\n";
+ }
+
+ function show_order_forms($city_id, $state_mask) {
+ echo "<form method=\"POST\" action=\"" . $_SERVER['REQUEST_URI'] . "\">\n";
+ show_order_state_form($state_mask);
+ show_order_areas_form($city_id);
+ show_order_cities_form($city_id);
+ echo "</form>\n";
+ }
+
+ function show_order_form($order = null, $area_id = null) {
+ global $states;
+
+ if ($order) {
+ $q = new OrderStateQuery;
+ $order_state = $q->filterByOrderId($order->getId())->orderByUpdated('desc')->limit(1)->findOne();
+ if ($order_state) $state = $order_state->getState();
+ }
+ else $order = new Order;
+
+
+ /* Date. */
+ echo "<tr>\n";
+ echo " <td>Delivery</td>\n";
+ /* XXX: Find suitable dates from area. */
+ echo " <td>"; show_date_form("date", $order->getDate()); echo "</td>\n";
+ echo "</tr>\n";
+
+ /* Requester. */
+ echo "<tr>\n";
+ echo " <td>Requester</td>\n";
+ echo " <td><select name=\"requester_id\">\n";
+ option("requester_id", null, "");
+ $contacts = get_area_requesters();
+ foreach ($contacts as $contact) {
+ option("requester_id", $contact->getId(), $contact->getDisplayname(), $order->getRequesterId());
+ }
+ echo "</select></td>\n";
+ echo "</tr>\n";
+
+ /* Beneficiary. */
+ echo "<tr>\n";
+ echo " <td>Beneficiary</td>\n";
+ echo " <td><select name=\"beneficiary_id\">\n";
+ option("beneficiary_id", null, "");
+ $contacts = get_area_beneficiaries($area_id);
+ foreach ($contacts as $contact) {
+ option("beneficiary_id", $contact->getId(), $contact->getDisplayname(), $order->getBeneficiaryId());
+ }
+ echo "</select></td>\n";
+ echo "</tr>\n";
+
+ /* Hub. */
+ echo "<tr>\n";
+ echo " <td>Hub</td>\n";
+ echo " <td><select name=\"hub_id\">\n";
+ option("hub_id", null, "");
+ $hubs = get_area_hubs();
+ foreach ($hubs as $hub) {
+ option("hub_id", $hub->getId(), $hub->getDisplayname(), $order->getHubId());
+ }
+ echo "</select></td>\n";
+ echo "</tr>\n";
+
+ /* Quantity. */
+ echo "<tr>\n";
+ echo " <td>Quantity (kg)</td>\n";
+ echo " <td>"; input("quantity", $order->getQuantity()); echo "</td>\n";
+ echo "</tr>\n";
+
+ /* Driver. */
+ echo "<tr>\n";
+ echo " <td>Driver</td>\n";
+ $contacts = get_city_drivers();
+ if (count($contacts)) {
+ echo " <td><select name=\"driver_id\">\n";
+ option("driver_id", null, "");
+ foreach ($contacts as $contact) {
+ option("driver_id", $contact->getId(), $contact->getDisplayname(), $driver_id);
+ }
+ echo "</select></td>\n";
+ }
+ else echo " <td>No drivers!</td>\n";
+ echo "</tr>\n";
+
+ /* State. */
+ if ($order->getId()) {
+ echo "<tr>\n";
+ echo " <td>State</td>\n";
+ echo " <td><select name=\"state\">\n";
+ for ($i = 0; $i < count($states); $i++) {
+ option("state", $i << 1, ucfirst($states[$i]), $state);
+ }
+ echo "</select></td>\n";
+ echo "</tr>\n";
+ }
+ }
+
+ function show_new_order_form($area_id = null) {
+ if (! check_admin(1)) return;
+
+ $area = get_area_by_id($area_id);
+ if (! count($area)) {
+ echo "<p>No such <a href=\"/area\">area</a>!</p>\n";
+ return;
+ }
+
+ echo "<form method=\"POST\" action=\"" . $_SERVER['REQUEST_URI'] . "\">\n";
+ echo "<p>Place an order:</p>\n";
+
+ echo "<table>\n";
+ show_order_form(null, $area_id);
+
+ echo "<tr>\n";
+ echo " <td colspan=2>"; submit("add_order", "Order"); echo "</td></tr>\n";
+ echo "</tr>\n";
+ echo "</table>\n";
+ echo "</form>\n";
+ }
+
+ function show_add_new_order_form() {
+ if (! check_admin(1)) return;
+
+ /* We intentionally hide areas with no contacts. */
+ $areas = get_city_areas_with_contacts(null, $GLOBALS['ROLE_BENEFICIARY']);
+ if (! count($areas)) {
+ 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";
+ return;
+ }
+
+ echo "<form method=\"POST\" action=\"" . $_SERVER['REQUEST_URI'] . "\">\n";
+ echo "<p>Place an order in <select name=\"area_id\">\n";
+ foreach ($areas as $area) {
+ option("area_id", $area->getId(), get_area_displayname($area));
+ }
+ echo "</select>";
+ submit("show_add_order", "Proceed");
+ echo "</p>\n";
+ echo "</form>\n";
+ }
+
+ function update_order(&$order, $new = false) {
+ global $user_id;
+
+ #$date = ymd_to_iso8601("date");
+ $date = $_POST['date'];
+ $requester_id = $_POST['requester_id'];
+ $beneficiary_id = $_POST['beneficiary_id'];
+ $hub_id = $_POST['hub_id'];
+ $quantity = $_POST['quantity'];
+ $driver_id = $_POST['driver_id'];
+ $state = $_POST['state'];
+ if (! $state) $state = $GLOBALS['STATE_PLACED'];
+
+ if (! $date) $date = time();
+ /* XXX: check date */
+
+ $requester = get_contact_by_id($requester_id);
+ if (! $requester) {
+ echo "<p>Invalid requester!</p>\n";
+ return false;
+ }
+
+ $beneficiary = get_contact_by_id($beneficiary_id);
+ if (! $beneficiary) {
+ echo "<p>Invalid beneficiary!</p>\n";
+ return false;
+ }
+
+ if ($hub_id) {
+ $hub = get_hub_by_id($hub_id);
+ if (! $hub) {
+ echo "<p>Invalid hub!</p>\n";
+ return false;
+ }
+ }
+
+ if (! is_numeric($quantity)) {
+ echo "<p>Invalid quantity!</p>\n";
+ return false;
+ }
+
+ $order->setDate($date);
+ $order->setRequesterId($requester_id);
+ $order->setBeneficiaryId($beneficiary_id);
+ $order->setHubId($hub_id);
+ $order->setQuantity($quantity);
+
+ try {
+ $order->save();
+
+ $order_state = new OrderState;
+ $order_state->setUpdated(time());
+ $order_state->setOrderId($order->getId());
+ $order_state->setUserId($user_id);
+ $order_state->setDriverId($driver_id);
+ $order_state->setState($state);
+
+ $order_state->save();
+ }
+ catch (Exception $e) {
+ if ($new) echo "<p>Error placing order.</p>\n";
+ else echo "<p>Error updating order.</p>\n";
+ return false;
+ }
+
+ return true;
+ }
+
+ function add_order() {
+ if (! check_admin(1, "place an order")) return;
+
+ $order = new Order;
+ if (! update_order($order, true)) return false;
+ return $order->getId();
+ }
+
+ function delete_order($id = null) {
+ if (! check_admin(1, "delete an order")) return;
+
+ if (isset($id)) $order = get_order_by_id($id);
+ if (! $order) return false;
+
+ try {
+ $q = new OrderStateQuery;
+ $order_states = $q->filterByOrderId($id)->find();
+ foreach ($order_states as $order_state) $order_state->delete();
+ $order->delete();
+ echo "<p>Deleted order.</p>\n";
+ }
+ catch (Exception $e) {
+ echo "<p>Error deleting order $id!</p>\n";
+ return false;
+ }
+
+ return true;
+ }
+
+ function show_order_history($id) {
+ global $states;
+
+ $q = new OrderStateQuery();
+ $order_states = $q->filterByOrderId($id)->orderById()->find();
+
+ if (! count($order_states)) return;
+
+ echo "<h3>Order history</h3>\n";
+ foreach ($order_states as $order_state) {
+ $date = $order_state->getUpdated();
+
+ $user = get_contact_by_id($order_state->getUserId());
+ if ($user) $username = $user->getDisplayname();
+ else $username = "unknown user";
+
+ $driver_id = $order_state->getDriverId();
+ if ($driver_id) $driver = get_contact_by_id($driver_id);
+
+ /* XXX */
+ $state = $order_state->getState();
+ for ($i = 0; $i < count($states); $i++) {
+ if ((1 << $i) == $state) {
+ $state = $states[$i];
+ break;
+ }
+ }
+ #$state = $states[$order_state->getState()];
+ echo "<p><strong>$username</strong> changed order to state <strong>$state</strong>";
+ if ($driver) echo " for driver " . $driver->getDisplayname();
+ echo " on $date.</p>\n";
+ }
+ }
+
+ function show_order(&$id = null) {
+ if (isset($id)) $order = get_order_by_id($id);
+ if (! $order) return;
+
+ echo "<form method=\"POST\" action=\"" . $_SERVER['REQUEST_URI'] . "\">\n";
+ echo "<p>Order: <span class=\"strong\">" . $order->getId() . "</span>";
+ if (check_admin(1)) {
+ echo " " . $order->getDeleteLink();
+ }
+ echo ": ";
+ echo "\n</p>";
+
+ echo "<table>\n";
+ show_order_form($order);
+
+ if (check_admin(1)) {
+ echo "<tr>\n";
+ echo " <td colspan=2>";
+ submit("update_order", "Update");
+ echo "</td>\n";
+ echo "</tr>\n";
+ }
+
+ echo "</table>\n";
+ echo "</form>\n";
+
+ show_order_history($order->getId());
+ }
+
+ $state_mask = null;
+ if (count($parameters)) {
+ for ($i = 1; $i < count($parameters); $i++) {
+ if ($parameters[$i] == "state") {
+ /* /order/state/placed+picked */
+ $state_mask = get_order_state_mask($parameters[$i + 1]);
+ }
+ }
+
+ if ($parameters[0] == "in") {
+ /* /order/in/area/Romsey+Town/1 */
+ switch ($parameters[1]) {
+ case "area":
+ case "area":
+ $area_id = $parameters[3];
+ $_POST['area_id'] = $area_id;
+ $q = new AreaQuery;
+ $area = $q->findOneById($area_id);
+ $city = get_area_city($area);
+ if ($city) $city_id = $city->getId();
+ show_area_orders(0, 10, $parameters[2], $area_id, $state_mask);
+ break;
+
+ case "city":
+ $city_id = $parameters[3];
+ $_POST['city_id'] = $city_id;
+ $q = new CityQuery;
+ $city = $q->findOneById($city_id);
+ show_city_orders(0, 10, $parameters[2], $city_id, $state_mask);
+ break;
+ }
+ }
+ else if ($parameters[0] == "from") {
+ /* /order/from/requester/Iain+Patterson/4 */
+ switch ($parameters[1]) {
+ case "requester":
+ $contact_id = $parameters[3];
+ $q = new ContactQuery;
+ $contact = $q->findOneById($contact_id);
+ show_requester_orders(0, 10, $parameters[2], $contact_id, $state_mask);
+ break;
+ }
+ }
+ else if ($parameters[0] == "to") {
+ /* /order/to/beneficiary/Cambridge+Community+Church/1 */
+ switch ($parameters[1]) {
+ case "beneficiary":
+ $contact_id = $parameters[3];
+ $q = new ContactQuery;
+ $hub = $q->findOneById($contact_id);
+ show_beneficiary_orders(0, 10, $parameters[2], $contact_id, $state_mask);
+ break;
+ }
+ }
+ }
+ list($ignored, $id, $args) = parse_parameters($parameters);
+ //echo "<p>$name($id) " . print_r($args, true) . "</p>\n";
+ if (count($args)) {
+ switch ($args[0]) {
+ case "delete":
+ delete_order($id);
+ break;
+ }
+ }
+ else if (isset($id)) show_order($id);
+ else if ($state_mask) show_orders(0, 10, null, null, $state_mask);
+ else {
+ /* XXX: Shown after adding. */
+ show_order_forms($city_id, $state_mask);
+ show_add_new_order_form($city_id);
+ }
+
+ if (count($parameters)) {
+ show_order_forms($city_id, $state_mask);
+ }
+
+
+?>