PageRenderTime 56ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/controllers/orders.php

https://bitbucket.org/cpoppema/stockpiler
PHP | 402 lines | 352 code | 40 blank | 10 comment | 44 complexity | eca977c62bc01f8e89f2a6e072c0a88f MD5 | raw file
  1. <?php
  2. const MSG_SUCCESS_ADD_ORDER = 'Your order was added successfully!';
  3. const MSG_SUCCESS_EDIT_ORDER = 'Your order was updated successfully!';
  4. const MSG_UNAUTHORIZED_ADD_ORDER = 'You are not authorized to add an order!';
  5. const MSG_UNAUTHORIZED_EDIT_ORDER = 'You are not authorized to edit an order!';
  6. function orders_history()
  7. {
  8. Security_Authorize();
  9. $orders = R::findAll('order', 'order by id desc');
  10. $index = R::$adapter->getAffectedRows();
  11. R::preload($orders, array('product'));
  12. foreach($orders as $order)
  13. {
  14. // Calculate progress
  15. $progress_current = 0;
  16. $deliveries = R::find('stock', 'order_id = ? and (iscanceled = 0 or iscanceled is null)', array($order->id));
  17. foreach($deliveries as $delivery)
  18. {
  19. $progress_current += $delivery->amount;
  20. }
  21. $progress_total = $order['amount'];
  22. $progress_perc = 1;
  23. $progress_class = 'danger';
  24. if ($progress_current > 0)
  25. {
  26. $progress_class = 'warning';
  27. $progress_perc = floor(($progress_current / $progress_total) * 100);
  28. }
  29. elseif ($progress_current == $progress_total)
  30. {
  31. $progress_class = 'success';
  32. $progress_perc = 100;
  33. }
  34. if ($progress_class != 'danger')
  35. {
  36. if ($progress_current == $progress_total)
  37. {
  38. $progress_bar = "<div class='progress progress-success'><div class='bar' style='width: 100%'>{$progress_total}</div></div>";
  39. } else {
  40. $progress_bar = "<div class='progress'><div class='bar bar-{$progress_class}' style='width: {$progress_perc}%'>{$progress_current}</div><div class='bar bar-danger' style='width: ". (100 - $progress_perc) . "%'>{$progress_total}</div></div>";
  41. }
  42. } else {
  43. $progress_bar = "<div class='progress'><div class='bar bar-success' style='width: 2%'></div><div class='bar bar-danger' style='width: 98%'>0 / {$progress_total}</div></div>";
  44. }
  45. $css_class = 'error';
  46. if ($order['hasarrived'] == 1)
  47. {
  48. $css_class = 'success';
  49. }
  50. if ($order['iscanceled'] == 1)
  51. {
  52. $css_class = 'warning';
  53. }
  54. if ($order['iscanceled'] == 1 && $_SESSION['CurrentUser_HideInacitve'])
  55. {
  56. $css_class .= ' hide';
  57. }
  58. $body .= "<tr class='" . $css_class . "'>\n";
  59. $body .= "<th>\n";
  60. $body .= $index;
  61. $body .= "</th>\n";
  62. $body .= "<td class='name'>\n";
  63. $body .= $order['product']['name'];
  64. $body .= "</td>\n";
  65. $body .= "<td class='code'>\n";
  66. $body .= $order['product']['code'];
  67. $body .= "</td>\n";
  68. $body .= "<td>\n";
  69. $body .= $progress_bar;
  70. $body .= "</td>\n";
  71. if ($_SESSION["CurrentUser_IsReadOnly"] != "1")
  72. {
  73. $body .= "<td>\n";
  74. $body .= "<a href='" . option('base_uri') . "orders/" . $order['id'] . "'>Edit</a>\n";
  75. $body .= "</td>\n";
  76. }
  77. $body .= "</tr>\n";
  78. $index--;
  79. }
  80. if (count($orders) == 0)
  81. {
  82. $body .= "<tr>\n";
  83. $body .= "<td colspan='5'>You're an order.</td>\n";
  84. $body .= "</tr>\n";
  85. }
  86. // Get typeahead data
  87. $names = array();
  88. $codes = array();
  89. $products = R::findAll('product', 'order by name asc, code asc');
  90. foreach ($products as $product) {
  91. $names[] = $product['name'];
  92. $codes[] = $product['code'];
  93. }
  94. set("names", $names);
  95. set("codes", $codes);
  96. set("title", "Order History");
  97. set("body", $body);
  98. return html("orders/history.php");
  99. }
  100. function orders_add()
  101. {
  102. Security_Authorize();
  103. if ($_SESSION['CurrentUser_IsReadOnly'] == "1")
  104. {
  105. header("Location: " . option('base_uri') . "&error=" . MSG_UNAUTHORIZED_ADD_ORDER);
  106. exit;
  107. }
  108. // Get typeahead data
  109. $names = array();
  110. $codes = array();
  111. $products = R::find('product', 'isdeleted = 0 or isdeleted is null order by name asc, code asc');
  112. foreach ($products as $product) {
  113. $names[] = $product['name'];
  114. $codes[] = $product['code'];
  115. }
  116. set("names", $names);
  117. set("codes", $codes);
  118. set("title", "New Order");
  119. return html("orders/add.php");
  120. }
  121. function orders_add_post()
  122. {
  123. Security_Authorize();
  124. if ($_SESSION['CurrentUser_IsReadOnly'] == "1")
  125. {
  126. header("Location: " . option('base_uri') . "&error=" . MSG_UNAUTHORIZED_ADD_ORDER);
  127. exit;
  128. }
  129. if (empty($_POST['name']) || strlen(trim($_POST['name'])) == 0)
  130. {
  131. $_GET['error'] = "You need to provide at least the product's name!";
  132. }
  133. if ( !isset($_POST['amount']) || $_POST['amount'] <= 0)
  134. {
  135. $_GET['error'] = "Care to tell us how much you really want to order?!";
  136. } else {
  137. $product = R::findOne('product', 'name = ? and (isdeleted = 0 or isdeleted is null)', array($_POST['name']));
  138. if (R::$adapter->getAffectedRows() < 1)
  139. {
  140. $_GET['error'] = "The name you provided was not found! Did you tried to order a previous deleted product perhaps?";
  141. } else {
  142. // Add Order
  143. $order = R::dispense('order');
  144. $order->product = $product;
  145. $order->amount = $_POST['amount'];
  146. $order->hasarrived = false;
  147. $order->iscanceled = false;
  148. $order->reason = null;
  149. $id = R::store($order);
  150. // Log adding order
  151. $entry = R::dispense('log');
  152. $entry->action = 'created';
  153. $entry->object = $order->getID();
  154. $entry->object_type = $order->getMeta('type');
  155. $entry->user_id = $_SESSION['CurrentUser_ID'];
  156. $entry->date = R::isoDateTime();
  157. R::store($entry);
  158. // Order added, go to list
  159. header("Location: " . option('base_uri') . "orders&success=" . MSG_SUCCESS_ADD_ORDER);
  160. exit;
  161. }
  162. }
  163. // Get typeahead data
  164. $names = array();
  165. $codes = array();
  166. $products = R::find('product', 'isdeleted = 0 or isdeleted is null order by name asc, code asc');
  167. foreach ($products as $product) {
  168. $names[] = $product['name'];
  169. $codes[] = $product['code'];
  170. }
  171. set("names", $names);
  172. set("codes", $codes);
  173. // Errors, go to form
  174. set("title", "New Order");
  175. return html("orders/add.php");
  176. }
  177. function orders_edit()
  178. {
  179. Security_Authorize();
  180. if ($_SESSION['CurrentUser_IsReadOnly'] == "1")
  181. {
  182. header("Location: " . option('base_uri') . "&error=" . MSG_UNAUTHORIZED_EDIT_ORDER);
  183. exit;
  184. }
  185. $order = R::load('order', params('id'));
  186. if (!$order->id)
  187. {
  188. set("title", "Not Found");
  189. set("type", "order");
  190. return html("error/notfound.php");
  191. }
  192. // Find partial deliveries
  193. $deliveries = R::find('stock', 'order_id = ? and (iscanceled = 0 or iscanceled is null) order by id asc', array($order->id));
  194. $progress_total = $order->amount;
  195. $index = 1;
  196. $has_all_products = false;
  197. $progress_current = 0;
  198. $partial_deliveries_body = "";
  199. foreach($deliveries as $delivery)
  200. {
  201. $progress_current += $delivery->amount;
  202. $progress_perc = floor(($progress_current / $progress_total) * 100);
  203. $partial_deliveries_body .= "<tr>";
  204. $partial_deliveries_body .= "<th>" . $index . "</th>";
  205. $partial_deliveries_body .= "<td>&plus;" . $delivery->amount . "</td>";
  206. $partial_deliveries_body .= "<td>";
  207. if ($progress_current == $progress_total)
  208. {
  209. $has_all_products = true;
  210. $partial_deliveries_body .= "<div class='progress progress-success'><div class='bar' style='width: 100%'>{$progress_total}</div></div>";
  211. } else {
  212. $partial_deliveries_body .= "<div class='progress'><div class='bar bar-warning' style='width: {$progress_perc}%'>{$progress_current}</div><div class='bar bar-danger' style='width: " . (100 - $progress_perc) . "%'>{$progress_total}</div></div>";
  213. }
  214. $partial_deliveries_body .= "</td>";
  215. if ($_SESSION["CurrentUser_IsReadOnly"] != "1")
  216. {
  217. $partial_deliveries_body .= "<td style='width: 100px;'>";
  218. $partial_deliveries_body .= "<a href='" . url_for('stock') . "/" . $delivery->getID() . "'>Edit</a>";
  219. $partial_deliveries_body .= "</td>";
  220. }
  221. $partial_deliveries_body .= "</tr>";
  222. $index++;
  223. }
  224. // Update has_arrived (in light of partial delivery or maybe canceled deliveries)
  225. $order->hasarrived = $progress_current == $progress_total;
  226. R::store($order);
  227. $max_partial_amount = $progress_total - $progress_current;
  228. R::preload($order, array('product'));
  229. set("title", "Edit Order");
  230. set("order", $order);
  231. set("has_all_products", $has_all_products);
  232. set("max_partial_amount", $max_partial_amount);
  233. set("partial_deliveries_body", $partial_deliveries_body);
  234. return html("orders/edit.php");
  235. }
  236. function orders_edit_post()
  237. {
  238. Security_Authorize();
  239. if ($_SESSION['CurrentUser_IsReadOnly'] == "1")
  240. {
  241. header("Location: " . option('base_uri') . "&error=" . MSG_UNAUTHORIZED_EDIT_ORDER);
  242. exit;
  243. }
  244. $order = R::load('order', params('id'));
  245. if (!$order->id)
  246. {
  247. set("title", "Not Found");
  248. set("type", "order");
  249. return html("error/notfound.php");
  250. }
  251. // Log editing order
  252. $entry = R::dispense('log');
  253. $entry->action = 'modified';
  254. if ($_POST['iscanceled'] == 1)
  255. {
  256. if ($order->iscanceled != 1)
  257. {
  258. $entry->action = 'canceled';
  259. } else {
  260. $entry->action = 'modified when canceled';
  261. }
  262. }
  263. elseif ($order->iscanceled == 1)
  264. {
  265. $entry->action = 'uncanceled';
  266. }
  267. // Add partial delivery
  268. if (isset($_POST['partial-delivery']))
  269. {
  270. $progress_current = R::getCol('SELECT SUM(amount) as amount FROM stock WHERE order_id = ? and (iscanceled = 0 or iscanceled is null)', array($order->id));
  271. if ((int) $progress_current[0]['amount'] + (int) $_POST['partial-amount'] > (int) $order->amount)
  272. {
  273. header("Location: " . option('base_uri') . "orders/" . $order->getID() . "&error=You cannot add more than you've initially ordered.");
  274. exit;
  275. }
  276. // Add Partal Delivery
  277. $stock = R::dispense('stock');
  278. R::preload($order, array('product'));
  279. $stock->product = R::load('product', $order->product->getID());
  280. $stock->type = 'delivery';
  281. $stock->amount = $_POST['partial-amount'];
  282. $stock->reason = null;
  283. $stock->iscanceled = false;
  284. $stock->order = $order;
  285. $id = R::store($stock);
  286. // Log editing order
  287. $entry = R::dispense('log');
  288. $entry->action = 'modified';
  289. $entry->object = $order->getID();
  290. $entry->object_type = $order->getMeta('type');
  291. $entry->user_id = $_SESSION['CurrentUser_ID'];
  292. $entry->date = R::isoDateTime();
  293. R::store($entry);
  294. // Log adding delivery
  295. $new_entry = R::dispense('log');
  296. $new_entry->action = 'created';
  297. $new_entry->object = $stock->getID();
  298. $new_entry->object_type = $stock->getMeta('type');
  299. $new_entry->user_id = $_SESSION['CurrentUser_ID'];
  300. // Use same timestamp
  301. $new_entry->date = $entry->date;
  302. R::store($new_entry);
  303. header("Location: " . option('base_uri') . "orders/" . $order->getID());
  304. exit;
  305. } else {
  306. // Edit order
  307. $order->amount = $_POST['amount'];
  308. $order->hasarrived = (int) $_POST['hasarrived'];
  309. $order->iscanceled = (int) $_POST['iscanceled'];
  310. R::store($order);
  311. // Continue log entry editing order
  312. $entry->object = $order->getID();
  313. $entry->object_type = $order->getMeta('type');
  314. $entry->user_id = $_SESSION['CurrentUser_ID'];
  315. $entry->date = R::isoDateTime();
  316. R::store($entry);
  317. // Check if order is marked as arrived
  318. if ($order->hasarrived == 1)
  319. {
  320. // Calculate amount of products delivered
  321. $progress_current = R::getCol('SELECT SUM(amount) as amount FROM stock WHERE order_id = ? and (iscanceled = 0 or iscanceled is null)', array($order->id));
  322. $amount = (int) $order->amount - (int) $progress_current[0]['amount'];
  323. // Add Delivery
  324. $stock = R::dispense('stock');
  325. R::preload($order, array('product'));
  326. $stock->product = R::load('product', $order->product->getID());
  327. $stock->type = 'delivery';
  328. $stock->amount = $amount;
  329. $stock->reason = null;
  330. $stock->iscanceled = false;
  331. $stock->order = $order;
  332. $id = R::store($stock);
  333. // Log adding delivery
  334. $new_entry = R::dispense('log');
  335. $new_entry->action = 'created';
  336. $new_entry->object = $stock->getID();
  337. $new_entry->object_type = $stock->getMeta('type');
  338. $new_entry->user_id = $_SESSION['CurrentUser_ID'];
  339. // Use same timestamp
  340. $new_entry->date = $entry->date;
  341. R::store($new_entry);
  342. }
  343. header("Location: " . option('base_uri') . "orders/&success=" . MSG_SUCCESS_EDIT_ORDER);
  344. exit;
  345. }
  346. }