Commit cf0df620 authored by Mal's avatar Mal

New Manager module to search and update purchases. Purchase

module now provides extra Search and RemovePurchase methods.
Stock module now also provides a list of all products.
Removed creating purchase query from Invoice module, now calls
AddPurchase for each surcharge entry.
parent 89839f18
......@@ -217,7 +217,7 @@ class Invoice extends Base {
if (file_exists($file)) return $file;
// Otherwise check recent dates before creating a new backup.
for ($i = 1; $i < 7; $i++) {
for ($i = 1; $i < 5; $i++) {
$date = date("Y-m-d", strtotime("-".$i." days"));
$recent = "backup-".$date.".sql.gz";
if (file_exists($recent)) return $recent;
......@@ -229,6 +229,8 @@ class Invoice extends Base {
}
private function AddSurcharge() {
$purchase = new Module($this->user, $this->owner, "purchase",
$this->config);
$banking = new Module($this->user, $this->owner, "banking",
$this->config);
$payment = new Module($this->user, $this->owner, "payment",
......@@ -247,22 +249,13 @@ class Invoice extends Base {
if ($surcharge == 0) {
$surcharge = $payment->Factory(array("Surcharge", $purchases));
if ($surcharge != 0) {
if ($query !== "") {
$query .= ", ";
}
$query .= '("'.$user.'", '.time().', "surcharge", 1, '.
$surcharge.', "'.$this->user->name.'")';
$purchase->Factory(array("AddPurchase", $user, time(), "surcharge",
1, $surcharge, $this->user->name));
}
}
}
}
$mysqli->close();
if ($query !== "") {
$purchase = new Module($this->user, $this->owner, "purchase",
$this->config);
$purchase->Factory(array("AddPurchase", $query));
}
return $this->Data();
}
......
<?php
// Dobrado Content Management System
// Copyright (C) 2012 Malcolm Blaney
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
class Manager extends Base {
public function Add($id) {
}
public function Callback() {
$object = array();
if (!$this->user->canEditPage) {
$object["error"] = "You don't have permission to access manager.";
return $object;
}
$mysqli = connect_db();
$action = $mysqli->escape_string($_POST["action"]);
if ($action == "list") {
// Autocomplete users and products.
$query = 'SELECT user FROM users';
if ($result = $mysqli->query($query)) {
while ($users = $result->fetch_assoc()) {
$object["users"][] = $users["user"];
}
$result->close();
}
else {
$this->Log('Manager->Callback: '.$mysqli->error);
}
$detail = new Module($this->user, $this->owner, "detail", $this->config);
$object["details"] = $detail->Factory("AllUsers");
$stock = new Module($this->user, $this->owner, "stock", $this->config);
$object["products"] = $stock->Factory("AllProducts");
}
else if ($action == "search") {
$username = $mysqli->escape_string($_POST["username"]);
$timestamp = (int)$mysqli->escape_string($_POST["timestamp"]) / 1000;
$product = $mysqli->escape_string($_POST["product"]);
$quantity = $mysqli->escape_string($_POST["quantity"]);
$price = $mysqli->escape_string($_POST["price"]);
$start = (int)$mysqli->escape_string($_POST["start"]) / 1000;
$end = (int)$mysqli->escape_string($_POST["end"]) / 1000;
$purchase = new Module($this->user, $this->owner, "purchase",
$this->config);
$object = $purchase->Factory(array("Search", $username, $timestamp,
$product, $quantity, $price, $start,
$end));
}
else if ($action == "submit") {
$username = $mysqli->escape_string($_POST["username"]);
$timestamp = (int)$mysqli->escape_string($_POST["timestamp"]) / 1000;
$product = $mysqli->escape_string($_POST["product"]);
$quantity = $mysqli->escape_string($_POST["quantity"]);
$price = $mysqli->escape_string($_POST["price"]);
$purchase = new Module($this->user, $this->owner, "purchase",
$this->config);
$purchase->Factory(array("AddPurchase", $username, $timestamp, $product,
$quantity, $price, $this->user->name));
$object["done"] = true;
}
else if ($action == "remove") {
$username = $mysqli->escape_string($_POST["username"]);
$product = $mysqli->escape_string($_POST["product"]);
$timestamp = (int)$mysqli->escape_string($_POST["timestamp"]) / 1000;
$purchase = new Module($this->user, $this->owner, "purchase",
$this->config);
$purchase->Factory(array("RemovePurchase", $username, $timestamp,
$product));
$object["done"] = true;
}
else if ($action == "editDetails") {
$username = $mysqli->escape_string($_POST["username"]);
$first = $mysqli->escape_string($_POST["first"]);
$last = $mysqli->escape_string($_POST["last"]);
$phone = $mysqli->escape_string($_POST["phone"]);
$detail = new Module($this->user, $this->owner, "detail", $this->config);
$detail->Factory(array("UpdateUser", $username, $first, $last, $phone));
$object["done"] = true;
}
$mysqli->close();
return $object;
}
public function CanAdd($page) {
return true;
}
public function CanEdit($id) {
return true;
}
public function CanRemove($id) {
return true;
}
public function Content($id) {
return '<form id="manager-form">'.
'<div class="form-spacing">'.
'<label for="manager-username-input">Username:</label>'.
'<input id="manager-username-input" size="15" maxlength="50">'.
'</div>'.
'<div class="details"><b>Contact details:</b> '.
'<button class="edit">edit</button><br>'.
'<span class="fullname"></span> '.
'<span class="email"></span>'.
'</div>'.
'<hr>'.
'<div class="form-spacing">'.
'<label for="manager-product-input">Product:</label>'.
'<input id="manager-product-input" size="15" maxlength="100">'.
'</div>'.
'<div class="form-spacing">'.
'<label for="manager-quantity-input">Quantity*:</label>'.
'<input id="manager-quantity-input" size="6" maxlength="8">'.
'</div>'.
'<div class="form-spacing">'.
'<label for="manager-price-input">Price*:</label>'.
'<input id="manager-price-input" size="15" maxlength="50" '.
'readonly="true">'.
'</div>'.
'<div class="form-spacing">'.
'<label for="manager-date-input">Date:</label>'.
'<input id="manager-date-input" size="15" maxlength="50">'.
'</div>'.
'*Price and Quantity are not currently searchable.'.
'<hr>'.
'<div>Search between start and end dates (leave above date blank):'.
'</div>'.
'<div class="form-spacing">'.
'<label for="manager-start-date-input">Start:</label>'.
'<input id="manager-start-date-input" size="15" maxlength="50">'.
'</div>'.
'<div class="form-spacing">'.
'<label for="manager-end-date-input">End:</label>'.
'<input id="manager-end-date-input" size="15" maxlength="50">'.
'</div>'.
'<button class="submit">submit</button>'.
'<button class="search">search</button>'.
'<button class="remove">remove</button>'.
'</form>'.
'<div class="search-info"></div>'.
'<form id="manager-details-form" class="hidden">'.
'<div class="form-spacing">'.
'<label for="manager-details-first-input">First Name:</label>'.
'<input id="manager-details-first-input" size="15" maxlength="50">'.
'</div>'.
'<div class="form-spacing">'.
'<label for="manager-details-last-input">Last Name:</label>'.
'<input id="manager-details-last-input" size="15" maxlength="50">'.
'</div>'.
'<div class="form-spacing">'.
'<label for="manager-details-phone-input">Phone Number:</label>'.
'<input id="manager-details-phone-input" size="15" maxlength="50">'.
'</div><br>'.
'<div id="manager-details-info"></div>'.
'<button class="submit">submit</button>'.
'</form>';
}
public function Copy($id, $old_owner, $old_id) {
}
public function Factory($fn) {
}
public function Group() {
}
public function IncludeScript() {
return true;
}
public function Install($path) {
// Append dobrado.purchase.js to the existing dobrado.js file.
// Note that the module is only available when logged in.
$this->AppendScript($path, "dobrado.manager.js", false);
$site_style = array('"","#manager-form","background-color","#eeeeee"',
'"","#manager-form","border","1px solid #aaaaaa"',
'"","#manager-form","border-radius","2px"',
'"","#manager-form","padding","5px"',
'"","#manager-form label","width","6em"',
'"","#manager-details-form label","width","7.5em"',
'"","#manager-details-form .submit","margin-left",'.
'"8em"',
'"","#manager-form .submit","float","right"',
'"","#manager-form .search","float","right"',
'"","#manager-form .search","margin-right","10px"');
$this->AddSiteStyle($site_style);
}
public function Placement() {
return "middle";
}
public function Remove($id) {
}
public function SetContent($id, $us_content) {
}
public function Update() {
// This is called when the version of the module is updated,
// to provide a way to update or modify tables etc..
}
public function UpdateScript($path) {
$this->AppendScript($path, "dobrado.manager.js", false);
}
// Private functions below here ////////////////////////////////////////////
}
?>
\ No newline at end of file
......@@ -44,7 +44,7 @@ class Purchase extends Base {
$result->close();
}
else {
$this->Log('Purchase->Callback: '.$mysqli->error);
$this->Log('Purchase->Callback 1: '.$mysqli->error);
}
$detail = new Module($this->user, $this->owner, "detail", $this->config);
$object["details"] = $detail->Factory("AllUsers");
......@@ -133,17 +133,17 @@ class Purchase extends Base {
($timestamp+1).' AND timestamp>='.($timestamp-1).' AND name="'.
$name.'"';
if (!$mysqli->query($query)) {
$this->Log('Purchase->Callback: '.$mysqli->error);
$this->Log('Purchase->Callback 2: '.$mysqli->error);
}
$object["done"] = true;
}
else if ($action == "saveDetails") {
$user = $mysqli->escape_string($_POST["user"]);
$username = $mysqli->escape_string($_POST["username"]);
$first = $mysqli->escape_string($_POST["first"]);
$last = $mysqli->escape_string($_POST["last"]);
$phone = $mysqli->escape_string($_POST["phone"]);
$detail = new Module($this->user, $this->owner, "detail", $this->config);
$detail->Factory(array("UpdateUser", $user, $first, $last, $phone));
$detail->Factory(array("UpdateUser", $username, $first, $last, $phone));
$object["done"] = true;
}
$mysqli->close();
......@@ -325,14 +325,37 @@ class Purchase extends Base {
$timestamp = $fn[2];
return $this->AllOutstanding($payment_totals, $timestamp);
}
if ($name == "AddPurchase" && count($fn) == 2) {
$query = $fn[1];
return $this->AddPurchase($query);
if ($name == "AddPurchase" && count($fn) == 7) {
$user = $fn[1];
$timestamp = $fn[2];
$product = $fn[3];
$quantity = $fn[4];
$price = $fn[5];
$volunteer = $fn[6];
return $this->AddPurchase($user, $timestamp, $product, $quantity,
$price, $volunteer);
}
if ($name == "RemovePurchase" && count($fn) == 4) {
$user = $fn[1];
$timestamp = $fn[2];
$product = $fn[3];
return $this->RemovePurchase($user, $timestamp, $product);
}
if ($name == "AllMostRecent" && count($fn) == 2) {
$timestamp = $fn[1];
return $this->AllMostRecent($timestamp);
}
if ($name == "Search" && count($fn) == 8) {
$user = $fn[1];
$timestamp = $fn[2];
$product = $fn[3];
$quantity = $fn[4];
$price = $fn[5];
$start = $fn[6];
$end = $fn[7];
return $this->Search($user, $timestamp, $product, $quantity, $price,
$start, $end);
}
return;
}
if ($fn == "Total") return $this->Total();
......@@ -789,15 +812,30 @@ class Purchase extends Base {
return $outstanding;
}
private function AddPurchase($query) {
if ($query === "") return;
private function AddPurchase($user, $timestamp, $product, $quantity, $price,
$volunteer) {
if ($user === "" || $timestamp === "" || $product === "" ||
$quantity === "" || $price === "") return;
$mysqli = connect_db();
if (!$mysqli->query('INSERT INTO purchase VALUES '.$query)) {
$query = 'INSERT INTO purchase VALUES ("'.$user.'" ,'.$timestamp.', "'.
$product.'", '.$quantity.', '.$price.', "'.$volunteer.'") '.
'ON DUPLICATE KEY UPDATE quantity='.$quantity.', price='.$price;
if (!$mysqli->query($query)) {
$this->Log('Purchase->AddPurchase: '.$mysqli->error);
}
$mysqli->close();
}
private function RemovePurchase($user, $timestamp, $product) {
$mysqli = connect_db();
$query = 'DELETE FROM purchase WHERE user="'.$user.'" AND name="'.
$product.'" AND timestamp='.$timestamp;
if (!$mysqli->query($query)) {
$this->Log('Purchase->RemovePurchase: '.$mysqli->error);
}
$mysqli->close();
}
private function NewUser() {
$mysqli = connect_db();
$query = 'INSERT INTO purchase_totals VALUES ("'.$this->user->name.'", 0)';
......@@ -828,6 +866,81 @@ class Purchase extends Base {
return $recent;
}
private function Search($user, $timestamp, $product, $quantity, $price,
$start, $end) {
$object = array();
$search = "";
if ($user !== "") {
$search .= 'user="'.$user.'"';
}
if ($timestamp !== 0) {
if ($search !== "") {
$search .= ' AND ';
}
$search .= 'timestamp='.$timestamp;
}
if ($product !== "") {
if ($search !== "") {
$search .= ' AND ';
}
$search .= 'name="'.$product.'"';
}
if ($quantity !== "") {
if ($search !== "") {
$search .= ' AND ';
}
$search .= 'quantity='.$quantity;
}
if ($price !== "") {
if ($search !== "") {
$search .= ' AND ';
}
$search .= 'price='.$price;
}
if ($start !== 0) {
if ($search !== "") {
$search .= ' AND ';
}
$search .= 'timestamp>='.$start;
}
if ($end !== 0) {
if ($search !== "") {
$search .= ' AND ';
}
$search .= 'timestamp<='.$end;
}
if ($search === "") {
return $object;
}
$mysqli = connect_db();
$query = 'SELECT user, timestamp, name, quantity, price FROM '.
'purchase WHERE '.$search;
if ($result = $mysqli->query($query)) {
while ($purchase = $result->fetch_assoc()) {
$quantity = (float)$purchase["quantity"];
$price = (float)$purchase["price"];
$total = $quantity * $price;
$total = number_format($total, 2, ".", "");
$price = number_format($price, 2, ".", "");
$timestamp = (int)$purchase["timestamp"] * 1000;
$object[] = array("date" => $timestamp,
"user" => $purchase["user"],
"name" => $purchase["name"],
"quantity" => $quantity,
"price" => $price,
"total" => $total);
}
$result->close();
}
else {
$this->Log('Purchase->Search: '.$mysqli->error);
}
$mysqli->close();
return $object;
}
}
?>
\ No newline at end of file
......@@ -167,6 +167,7 @@ class Stock extends Base {
return;
}
if ($fn == "AvailableProducts") return $this->AvailableProducts();
if ($fn == "AllProducts") return $this->AllProducts();
if ($fn == "LastUpdate") return $this->LastUpdate();
if ($fn == "AllSuppliers") return $this->AllSuppliers();
if ($fn == "Supplier") return $this->Supplier();
......@@ -295,6 +296,26 @@ class Stock extends Base {
return $object;
}
private function AllProducts() {
$object = array();
$mysqli = connect_db();
$query = 'SELECT name, user, unit, price, category FROM stock '.
'ORDER BY name';
if ($result = $mysqli->query($query)) {
while ($stock = $result->fetch_assoc()) {
$object[] = array("name" => $stock["name"],
"unit" => $stock["unit"],
"price" => (float)$stock["price"]);
}
$result->close();
}
else {
$this->Log('Stock->AllProducts: '.$mysqli->error);
}
$mysqli->close();
return $object;
}
private function LastUpdate() {
$mysqli = connect_db();
$timestamp = "";
......
This diff is collapsed.
......@@ -295,7 +295,7 @@ if (!this.dobrado.purchase) {
$("#purchase-quantity-input").val(data.quantity);
$("#purchase-date-input").val(dobrado.formatDate(data.date));
var price = data.quantity * data.price;
// Set currentProduct to updateFormControls and get units.
// Set currentProduct before calling setFormControls and get units.
$.each(purchase.products, function(index, item) {
if (item.name === data.name) {
currentProduct = item;
......@@ -633,7 +633,7 @@ if (!this.dobrado.purchase) {
dobrado.log("Saving user details...", "info");
$.post("/php/request.php", { request: "purchase",
user: user,
username: user,
first: first,
last: last,
phone: phone,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment