Commit 9db49b13 authored by Malcolm Blaney's avatar Malcolm Blaney

Added buyer_group to banking table and UpdateUser method so that

all bank details can be updated from the payment module. Invoice
module now checks if the current user is in admin's "backup"
group before creating a backup. Invoice module also checks if a
surcharge should be added, or if pre-order is being used before
showing in ui. Manager module looks up buyer groups for all users
so that new purchases can be added with the correct price.
Payment module now has a callback action for editing bank details.
Purchase module looks up buyer groups for all users so that
purchases can be added with the correct price.
parent 76a572b0
......@@ -22,24 +22,25 @@ class Banking extends Base {
}
public function Callback() {
$callback = array();
if ($this->user->name != $this->owner) {
$object["error"] = "Username doesn't match";
return $object;
$callback["error"] = "Username doesn't match";
return $callback;
}
$mysqli = connect_db();
$name = $mysqli->escape_string($_POST["name"]);
$number = $mysqli->escape_string($_POST["number"]);
$bsb = $mysqli->escape_string($_POST["bsb"]);
$credit = $mysqli->escape_string($_POST["credit"]);
$query = 'UPDATE banking SET name="'.$name.'", number="'.$number.
'", bsb="'.$bsb.'", credit="'.$credit.'" WHERE user="'.
$this->user->name.'"';
$query = 'UPDATE banking SET name = "'.$name.'", number = "'.$number.'", '.
'bsb = "'.$bsb.'", credit = '.$credit.
' WHERE user = "'.$this->user->name.'"';
if (!$mysqli->query($query)) {
$this->Log('Banking->Callback: '.$mysqli->error);
$this->Log("Banking->Callback: ".$mysqli->error);
}
$object["done"] = true;
$callback["done"] = true;
$mysqli->close();
return $object;
return $callback;
}
public function CanAdd($page) {
......@@ -80,7 +81,7 @@ class Banking extends Base {
$result->close();
}
else {
$this->Log('Banking->Content: '.$mysqli->error);
$this->Log("Banking->Content: ".$mysqli->error);
}
$mysqli->close();
......@@ -135,16 +136,17 @@ class Banking extends Base {
$result->close();
}
else {
$this->Log('Banking->Copy 1: '.$mysqli->error);
$this->Log("Banking->Copy 1: ".$mysqli->error);
}
}
// This query does the insert without needing to check for an existing
// user. (The duplicate key update doesn't do anything).
$query = 'INSERT INTO banking VALUES ("'.$this->user->name.'", "'.
$reference.'", "", "", "", "1", "1", "0") ON DUPLICATE KEY UPDATE user="'.
$this->user->name.'"';
$query = 'INSERT INTO banking VALUES ("'.$this->user->name.'", '.
'"'.$reference.'", "", "", "", "1", "1", "0", '.
'"'.$this->Substitute("banking-default-group").'") '.
'ON DUPLICATE KEY UPDATE user = "'.$this->user->name.'"';
if (!$mysqli->query($query)) {
$this->Log('Banking->Copy 2: '.$mysqli->error);
$this->Log("Banking->Copy 2: ".$mysqli->error);
}
$mysqli->close();
}
......@@ -179,10 +181,11 @@ class Banking extends Base {
'credit TINYINT(1),'.
'surcharge TINYINT(1),'.
'next_week INT(10) UNSIGNED NOT NULL,'.
'buyer_group VARCHAR(50),'.
'PRIMARY KEY(user)'.
') ENGINE=MyISAM';
if (!$mysqli->query($query)) {
$this->Log('Banking->Install: '.$mysqli->error);
$this->Log("Banking->Install: ".$mysqli->error);
}
$mysqli->close();
$site_style = array('"",".banking .edit a","color","#222222"',
......@@ -209,9 +212,9 @@ class Banking extends Base {
if (isset($id)) return;
$mysqli = connect_db();
$query = 'DELETE FROM banking WHERE user="'.$this->owner.'"';
$query = 'DELETE FROM banking WHERE user = "'.$this->owner.'"';
if (!$mysqli->query($query)) {
$this->Log('Banking->Remove: '.$mysqli->error);
$this->Log("Banking->Remove: ".$mysqli->error);
}
$mysqli->close();
}
......@@ -223,6 +226,13 @@ class Banking extends Base {
public function Update() {
// This is called when the version of the module is updated,
// to provide a way to update or modify tables etc..
$mysqli = connect_db();
$query = 'ALTER TABLE banking ADD COLUMN buyer_group VARCHAR(50) AFTER '.
'next_week';
if (!$mysqli->query($query)) {
$this->Log("Banking->Update: ".$mysqli->error);
}
$mysqli->close();
}
public function UpdateScript($path) {
......@@ -232,14 +242,45 @@ class Banking extends Base {
// Public functions that aren't part of interface here /////////////////////
public function AllBuyers($organisation = false) {
$users = array();
$buyer_groups = array();
$mysqli = connect_db();
$query = "";
if ($organisation) {
$organiser = new Organiser($this->user, $this->owner, $this->config);
$query = 'SELECT banking.user, buyer_group FROM banking LEFT JOIN '.
'users ON banking.user = users.user WHERE '.
$organiser->GroupQuery();
}
else {
$query = 'SELECT banking.user, buyer_group FROM banking LEFT JOIN '.
'users ON banking.user = users.user WHERE '.
'users.system_group = "'.$this->user->group.'"';
}
if ($result = $mysqli->query($query)) {
while ($banking = $result->fetch_assoc()) {
$users[] = $banking["user"];
// If the buyer_group for a user is empty, the default used is "price".
$buyer_groups[$banking["user"]] = $banking["buyer_group"] == "" ?
"price" : $banking["buyer_group"];
}
$result->close();
}
else {
$this->Log("Banking->AllBuyers: ".$mysqli->error);
}
return array($users, $buyer_groups);
}
public function AllSettings() {
$settings = array();
$organiser = new Organiser($this->user, $this->owner, $this->config);
$mysqli = connect_db();
$query = 'SELECT banking.user, reference, name, number, bsb, credit, '.
'surcharge FROM banking LEFT JOIN users ON banking.user=users.user '.
'WHERE '.$organiser->GroupQuery();
'surcharge, buyer_group FROM banking LEFT JOIN users ON banking.user = '.
'users.user WHERE '.$organiser->GroupQuery();
if ($result = $mysqli->query($query)) {
while ($banking = $result->fetch_assoc()) {
$settings[$banking["user"]] =
......@@ -248,17 +289,50 @@ class Banking extends Base {
"number" => $banking["number"],
"bsb" => $banking["bsb"],
"credit" => (int)$banking["credit"],
"surcharge" => (int)$banking["surcharge"]);
"surcharge" => (int)$banking["surcharge"],
"buyerGroup" => $banking["buyer_group"]);
}
$result->close();
}
else {
$this->Log('Banking->AllSettings: '.$mysqli->error);
$this->Log("Banking->AllSettings: ".$mysqli->error);
}
$mysqli->close();
return $settings;
}
public function UpdateUser($username, $reference, $name, $number,
$bsb, $credit, $surcharge, $buyer_group) {
$count = -1;
$organiser = new Organiser($this->user, $this->owner, $this->config);
$mysqli = connect_db();
// The banking reference needs to be unique so check if it already exists.
$query = 'SELECT reference FROM banking LEFT JOIN users ON '.
'banking.user = users.user WHERE reference = "'.$reference.'" '.
'AND banking.user != "'.$username.'" AND ('.$organiser->GroupQuery().')';
if ($result = $mysqli->query($query)) {
$count = $result->num_rows;
}
else {
$this->Log("Banking->UpdateUser 1: ".$mysqli->error);
}
if ($count != 0) {
$mysqli->close();
return array("error" => "Bank reference already exists");
}
$query = 'UPDATE banking SET reference = "'.$reference.'", '.
'name = "'.$name.'", number = "'.$number.'", bsb = "'.$bsb.'", '.
'credit = '.$credit.', surcharge = '.$surcharge.', buyer_group = '.
'"'.$buyer_group.'" WHERE user = "'.$username.'"';
if (!$mysqli->query($query)) {
$this->Log("Banking->UpdateUser 2: ".$mysqli->error);
}
$mysqli->close();
return array("done" => true);
}
public function SaveNextWeek($us_next_week) {
// Use the configured day of the week for the co-op to find the next time
// the co-op will be held. Due to the way relative dates work, need to
......@@ -276,12 +350,12 @@ class Banking extends Base {
if ($user_query != "") {
$user_query .= ' OR ';
}
$user_query .= 'user="'.$mysqli->escape_string($us_next_week[$i]).'"';
$user_query .= 'user = "'.$mysqli->escape_string($us_next_week[$i]).'"';
}
if ($user_query != "") {
$query = 'UPDATE banking SET next_week='.$timestamp.' WHERE '.$user_query;
if (!$mysqli->query($query)) {
$this->Log('Banking->SaveNextWeek: '.$mysqli->error);
$this->Log("Banking->SaveNextWeek: ".$mysqli->error);
}
}
$mysqli->close();
......@@ -304,7 +378,7 @@ class Banking extends Base {
$count = $result->num_rows;
}
else {
$this->Log('Banking->CountNextWeek: '.$mysqli->error);
$this->Log("Banking->CountNextWeek: ".$mysqli->error);
}
$mysqli->close();
return array($count, $timestamp);
......@@ -319,7 +393,7 @@ class Banking extends Base {
$result->close();
}
else {
$this->Log('Banking->Settings: '.$mysqli->error);
$this->Log("Banking->Settings: ".$mysqli->error);
}
$mysqli->close();
return $banking;
......
......@@ -36,15 +36,23 @@ class Invoice extends Base {
$object = $this->Data(true);
}
else if ($action == "backup") {
$control = new Control($this->user, $this->owner, $this->config);
// Creates a backup file if one doesn't already exist, returns the
// name of the newest backup file.
$file = $control->Backup();
if ($file === false) {
$object["error"] = "Could not create a backup file.";
// The current user must be a member of the backup group to create
// backup's of the database.
if ($this->GroupMember("backup", "admin")) {
$object["allowed"] = true;
$control = new Control($this->user, $this->owner, $this->config);
// Creates a backup file if one doesn't already exist, returns the
// name of the newest backup file.
$file = $control->Backup();
if ($file === false) {
$object["error"] = "Could not create a backup file.";
}
else {
$object["content"] = $file;
}
}
else {
$object["content"] = $file;
$object["allowed"] = false;
}
}
else if ($action == "addSurcharge") {
......@@ -77,11 +85,23 @@ class Invoice extends Base {
}
public function Content($id) {
return '<button class="add-surcharge">add surcharge</button>'.
$surcharge = $this->Substitute("surcharge") == "true" ? true : false;
$pre_order = $this->Substitute("pre-order") == "true" ? true : false;
// Showing the surcharge button depends on whether a surcharge is added for
// the current group, but there's also no point showing it if pre-order is
// used, because that means the surcharge is added automatically.
$add_surcharge = $surcharge && !$pre_order ?
'<button class="add-surcharge">add surcharge</button>' : "";
// Don't offer to send order when pre-order is used, they are sent
// automatically.
$send_orders = $pre_order ?
"" : '<input type="checkbox" id="invoice-extra-email-input"> '.
'Send email for next weeks orders<br>';
return $add_surcharge.
'<button class="send-invoice">send invoices</button>'.
'<input type="checkbox" id="invoice-extra-email-input"> '.
'Send email for next weeks orders<br>'.
'<div class="backup"></div>'.
$send_orders.'<div class="backup"></div>'.
'<div class="user-details"></div>';
}
......@@ -101,7 +121,10 @@ class Invoice extends Base {
$run_groups = $this->RunGroups("co-op-day", $time);
for ($i = 0; $i < count($run_groups); $i++) {
$this->user = new User($this->config, $this->owner, $run_groups[$i]);
$data = $this->AddSurcharge(false);
// Check if a surcharge is being added for this group, otherwise can just
// skip straight to getting the current purchase data.
$surcharge = $this->Substitute("surcharge") == "true" ? true : false;
$data = $surcharge ? $this->AddSurcharge(false) : $this->Data(false);
$total = count($data["grid"]);
if ($total == 0) continue;
......@@ -376,8 +399,8 @@ class Invoice extends Base {
if ($surcharge != 0) {
$total_surcharge += $surcharge;
$purchase->AddPurchase($user, time(), "surcharge",
$stock->SurchargeSupplier(),
1, $surcharge, $this->user->name);
$stock->SurchargeSupplier(), 1,
$surcharge, $surcharge, $this->user->name);
}
}
}
......@@ -401,8 +424,8 @@ class Invoice extends Base {
if ($surcharge != 0) {
$total_surcharge += $surcharge;
$purchase->AddPurchase($user, time(), "surcharge",
$stock->SurchargeSupplier(),
1, $surcharge, $this->user->name);
$stock->SurchargeSupplier(), 1,
$surcharge, $surcharge, $this->user->name);
}
}
}
......@@ -546,13 +569,20 @@ class Invoice extends Base {
'/'.$products[$name]["unit"].'</td><td>$'.$data[$i]["total"].
'</td></tr>'."\n";
}
$message .= '<tr><td></td><td></td><td></td><td>Subtotal</td><td>$'.
number_format($purchase_value, 2, ".", "").'</td></tr>'."\n".
'<tr><td></td><td></td><td></td><td>Surcharge</td><td>$'.
number_format($surcharge, 2, ".", "").'</td></tr>'."\n".
'<tr><td></td><td></td><td></td><td><b>Total</b></td><td><b>$'.
number_format($purchase_value + $surcharge, 2, ".", "").
'</b></td></tr></table>'."\n";
if ($this->Substitute("surcharge") == "true") {
$message .= '<tr><td></td><td></td><td></td><td>Subtotal</td><td>$'.
number_format($purchase_value, 2, ".", "").'</td></tr>'."\n".
'<tr><td></td><td></td><td></td><td>Surcharge</td><td>$'.
number_format($surcharge, 2, ".", "").'</td></tr>'."\n".
'<tr><td></td><td></td><td></td><td><b>Total</b></td><td><b>$'.
number_format($purchase_value + $surcharge, 2, ".", "").
'</b></td></tr></table>'."\n";
}
else {
$message .= '<tr><td></td><td></td><td></td><td><b>Total</b></td><td>'.
'<b>$'.number_format($purchase_value, 2, ".", "").'</b></td></tr>'.
'</table>'."\n";
}
}
if ($sold != 0) {
$message .= '<p>Your sold items for this week:</p>'."\n";
......@@ -560,13 +590,20 @@ class Invoice extends Base {
$message .= '<table border="0" cellspacing="5"><tr><td '.$cell_style.
'>Name</td><td '.$cell_style.'>Quantity</td><td '.$cell_style.
'>Price</td><td '.$cell_style.'>Total</td></tr>'."\n";
$total = 0;
for ($i = 0; $i < count($data); $i++) {
$name = $data[$i]["name"];
$total += (float)$data[$i]["price"];
$message .= '<tr><td>'.$name.'</td><td>'.
$data[$i]["quantity"].'</td><td>$'.$data[$i]["price"].'/'.
$products[$name]["unit"].'</td><td>$'.
$data[$i]["total"].'</td></tr>'."\n";
}
// Only show the title if there's more than one product sold.
if (count($data) > 1) {
$message .= '<tr><td></td><td></td><td><b>Total</b></td><td>'.
$total.'</td></tr>';
}
$message .= '</table>'."\n";
}
$message .= '</body></html>';
......@@ -818,7 +855,7 @@ class Invoice extends Base {
$supplier = $details["supplier"];
$quantity = $details["quantity"];
$price = "$".number_format($details["price"], 2, ".", "")."/".
$price = "$".number_format($details["basePrice"], 2, ".", "")."/".
$products[$name]["unit"];
$message .= '<tr><td>'.$user.'</td><td>'.$name.'</td><td>'.
$supplier.'</td><td>'.$quantity.'</td><td>'.$price.'</td></tr>'."\n";
......@@ -908,7 +945,7 @@ class Invoice extends Base {
$supplier = $details["supplier"];
$quantity = $details["quantity"];
$price = "$".number_format($details["price"], 2, ".", "")."/".
$price = "$".number_format($details["basePrice"], 2, ".", "")."/".
$products[$name]["unit"];
$previous_name = $name;
$total_quantity += $quantity;
......
......@@ -33,17 +33,10 @@ class Manager extends Base {
$organiser = new Organiser($this->user, $this->owner, $this->config);
if ($action == "list") {
// Autocomplete users and products.
$query = 'SELECT user FROM users WHERE '.$organiser->GroupQuery();
if ($result = $mysqli->query($query)) {
while ($users = $result->fetch_assoc()) {
$object["users"][] = $users["user"];
}
$result->close();
}
else {
$this->Log('Manager->Callback: '.$mysqli->error);
}
// Lists of users and products are made to autocomplete and verify input.
$banking = new Banking($this->user, $this->owner, $this->config);
list($object["users"], $object["buyerGroup"]) = $banking->AllBuyers(true);
$detail = new Detail($this->user, $this->owner, $this->config);
$object["details"] = $detail->AllUsers(true);
......@@ -76,10 +69,11 @@ class Manager extends Base {
$supplier = $mysqli->escape_string($_POST["supplier"]);
$quantity = $mysqli->escape_string($_POST["quantity"]);
$price = $mysqli->escape_string($_POST["price"]);
$base_price = $mysqli->escape_string($_POST["basePrice"]);
$purchase = new Purchase($this->user, $this->owner, $this->config);
$object = $purchase->AddPurchase($username, $timestamp, $product,
$supplier, $quantity, $price,
$this->user->name);
$base_price, $this->user->name);
}
else {
$object["error"] = "User not found";
......@@ -123,7 +117,7 @@ class Manager extends Base {
}
public function CanEdit($id) {
return true;
return false;
}
public function CanRemove($id) {
......@@ -163,7 +157,7 @@ class Manager extends Base {
'<label for="manager-date-input">Date:</label>'.
'<input id="manager-date-input" size="15" maxlength="50">'.
'</div>'.
'*Price and Quantity are not currently searchable.'.
'*Price and Quantity are not searchable.'.
'<hr>'.
'<div>Search between start and end dates (leave above date blank):'.
'</div>'.
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -40,7 +40,7 @@ function addSurcharge(){if(!grid){return;}
var selected=grid.getSelectedRows();var data=[];for(var i=0;i<selected.length;i++){var row=selected[i];data.push({name:users.grid[row].name,purchases:users.grid[row].purchases,surcharge:users.grid[row].surcharge});}
dobrado.log("Adding surcharge...","info");$.post("/php/request.php",{request:"invoice",action:"addSurcharge",data:JSON.stringify(data),url:location.href,token:dobrado.token},function(response){if(dobrado.checkResponseError(response,"invoice addSurcharge")){return;}
surchargeAdded=true;users=JSON.parse(response);grid.setData(users.grid);grid.updateRowCount();grid.render();grid.setSelectedRows([]);dobrado.log("Checking backup...","info");$.post("/php/request.php",{request:"invoice",action:"backup",url:location.href,token:dobrado.token},function(response){if(dobrado.checkResponseError(response,"invoice backup")){return;}
var backup=JSON.parse(response);$(".invoice .backup").html('Please download the backup file: '+'<a href="php/'+backup.content+'">'+backup.content+'</a>');});});}
var backup=JSON.parse(response);if(backup.allowed){$(".invoice .backup").html('Please download the backup file: '+'<a href="php/'+backup.content+'">'+backup.content+'</a>');}});});}
function sendInvoice(){function send(response){if(dobrado.checkResponseError(response,"sendInvoice")){return;}
if(invoiceCount===invoiceData.length){if(!$("#invoice-extra-email-input").is(":checked")){return;}
invoiceData=[];invoiceCount=0;dobrado.log("Checking orders for next week.","info");$.post("/php/request.php",{request:"invoice",action:"nextWeekOrders",url:location.href,token:dobrado.token},function(response){if(dobrado.checkResponseError(response,"nextWeek")){return;}
......@@ -48,6 +48,6 @@ dobrado.log("Checking user attendance.","info");$.post("/php/request.php",{reque
var data=JSON.stringify(invoiceData[invoiceCount++]);dobrado.log("Sending invoice "+invoiceCount+" of "+
invoiceData.length,"info");$.post("/php/request.php",{request:"invoice",action:"sendInvoice",data:data,url:location.href,token:dobrado.token},send);}
if(!grid){return;}
if(!surchargeAdded&&!confirm("The surcharge hasn't just been added... coninute?")){return;}
if(!surchargeAdded&&$(".add-surcharge").length!==0&&!confirm("The surcharge hasn't just been added... coninute?")){return;}
var selected=grid.getSelectedRows();for(var i=0;i<selected.length;i++){var row=selected[i];invoiceData.push({name:users.grid[row].name,purchases:users.grid[row].purchases,surcharge:users.grid[row].surcharge,sold:users.grid[row].sold,balance:users.grid[row].balance,credit:users.grid[row].credit});}
send(JSON.stringify({done:true}));}})();
\ No newline at end of file
......@@ -192,9 +192,11 @@ if (!this.dobrado.invoice) {
return;
}
var backup = JSON.parse(response);
$(".invoice .backup").html('Please download the backup file: ' +
'<a href="php/' + backup.content +
'">' + backup.content + '</a>');
if (backup.allowed) {
$(".invoice .backup").html('Please download the backup file: ' +
'<a href="php/' + backup.content +
'">' + backup.content + '</a>');
}
});
});
}
......@@ -249,7 +251,7 @@ if (!this.dobrado.invoice) {
if (!grid) {
return;
}
if (!surchargeAdded &&
if (!surchargeAdded && $(".add-surcharge").length !== 0 &&
!confirm("The surcharge hasn't just been added... coninute?")) {
return;
}
......
......@@ -54,30 +54,33 @@ function showPurchase(row){var data=purchase[row];$("#manager-username-input").v
else{$("#manager-price-input").val("$"+price.toFixed(2)+" @ ($"+data.price+"/"+
currentProduct.unit+")");$("#manager-price-input").attr("readonly",true);$("#manager-quantity-input").spinner("enable");}
return false;}});updateDetails();}
function showProductFromMenu(event,ui){var product=$("#manager-product-input").val();var supplier=$("#manager-supplier-input").val();if(ui){product=ui.item.value;}
$("#manager-quantity-input").val("");$("#manager-price-input").val("");$.each(manager.products,function(index,item){if(item.name===product&&(supplier===""||supplier===item.user)){currentProduct=item;$("#manager-supplier-input").val(item.user);if(item.unit==="variable"){$("#manager-price-input").val(item.price.toFixed(2));$("#manager-price-input").attr("readonly",false);$("#manager-quantity-input").val("1").spinner("disable");}
else{$("#manager-price-input").val("($"+item.price.toFixed(2)+"/"+
function showProductFromMenu(event,ui){var user=$("#manager-username-input").val();var product=$("#manager-product-input").val();var supplier=$("#manager-supplier-input").val();var price="price";if(user!==""){price=manager.buyerGroup[user];}
if(ui){product=ui.item.value;}
$("#manager-quantity-input").val("");$("#manager-price-input").val("");$.each(manager.products,function(index,item){if(item.name===product&&(supplier===""||supplier===item.user)){currentProduct=item;$("#manager-supplier-input").val(item.user);if(item.unit==="variable"){$("#manager-price-input").val(item[price].toFixed(2));$("#manager-price-input").attr("readonly",false);$("#manager-quantity-input").val("1").spinner("disable");}
else{$("#manager-price-input").val("($"+item[price].toFixed(2)+"/"+
item.unit+")");$("#manager-price-input").attr("readonly",true);$("#manager-quantity-input").spinner("enable");}
return false;}});}
function showSupplierFromMenu(event,ui){var supplier=$("#manager-supplier-input").val();var product=$("#manager-product-input").val();if(ui){supplier=ui.item.value;}
$("#manager-quantity-input").val("");$("#manager-price-input").val("");$.each(manager.products,function(index,item){if(item.user===supplier&&product===item.name){currentProduct=item;if(item.unit==="variable"){$("#manager-price-input").val(item.price.toFixed(2));$("#manager-price-input").attr("readonly",false);}
else{$("#manager-price-input").val("($"+item.price.toFixed(2)+"/"+
function showSupplierFromMenu(event,ui){var user=$("#manager-username-input").val();var supplier=$("#manager-supplier-input").val();var product=$("#manager-product-input").val();var price="price";if(user!==""){price=manager.buyerGroup[user];}
if(ui){supplier=ui.item.value;}
$("#manager-quantity-input").val("");$("#manager-price-input").val("");$.each(manager.products,function(index,item){if(item.user===supplier&&product===item.name){currentProduct=item;if(item.unit==="variable"){$("#manager-price-input").val(item[price].toFixed(2));$("#manager-price-input").attr("readonly",false);}
else{$("#manager-price-input").val("($"+item[price].toFixed(2)+"/"+
item.unit+")");$("#manager-price-input").attr("readonly",true);}
return false;}});}
function updateProducts(){var products=[];$.each(manager.products,function(index,item){if($.inArray(item.name,products)===-1){products.push(item.name);}});$("#manager-product-input").autocomplete({source:products,select:showProductFromMenu});var suppliers=[];$.each(manager.products,function(index,item){if($.inArray(item.user,suppliers)===-1){suppliers.push(item.user);}});$("#manager-supplier-input").autocomplete({source:suppliers,select:showSupplierFromMenu});}
function setQuantity(event,ui){var quantity=0;if("value"in ui){quantity=ui.value;}
function setQuantity(event,ui){var user=$("#manager-username-input").val();var price="price";if(user!==""){price=manager.buyerGroup[user];}
var quantity=0;if("value"in ui){quantity=ui.value;}
else{quantity=parseFloat($(this).val());if(!quantity||quantity<0){quantity=0;$(this).val("0");}}
if(currentProduct&&currentProduct.unit!=="variable"){var price=quantity*currentProduct.price;$("#manager-price-input").val("$"+price.toFixed(2)+" @ ($"+
currentProduct.price.toFixed(2)+"/"+currentProduct.unit+")");}}
if(currentProduct&&currentProduct.unit!=="variable"){var total=quantity*currentProduct[price];$("#manager-price-input").val("$"+total.toFixed(2)+" @ ($"+
currentProduct[price].toFixed(2)+"/"+currentProduct.unit+")");}}
function submit(){var user=$("#manager-username-input").val();if(user===""||!currentProduct){return false;}
var product=currentProduct.name;if(product!==$("#manager-product-input").val()){alert("Product not found.");resetForm();return false;}
var supplier=currentProduct.user;if(supplier!==$("#manager-supplier-input").val()){alert("Supplier not found.");resetForm();return false;}
var price=currentProduct.price.toFixed(2);if(currentProduct.unit==="variable"){price=$("#manager-price-input").val();}
var price=currentProduct[manager.buyerGroup[user]].toFixed(2);if(currentProduct.unit==="variable"){price=$("#manager-price-input").val();}
var quantity=parseFloat($("#manager-quantity-input").val());if(!quantity||quantity<0){alert("Quantity required.");return false;}
var total=(quantity*price).toFixed(2);var timestamp=parseInt($.datepicker.formatDate("@",$("#manager-date-input").datepicker("getDate")),10);if(!timestamp){alert("Date required.");return false;}
if(currentDate&&timestamp>currentDate-oneDay&&timestamp<currentDate+oneDay){timestamp=currentDate;}
else{currentDate=null;}
dobrado.log("Saving purchase...","info");$.post("/php/request.php",{request:"manager",username:user,timestamp:timestamp,product:product,supplier:supplier,quantity:quantity,price:price,action:"submit",url:location.href,token:dobrado.token},function(response){if(dobrado.checkResponseError(response,"manager submit")){return;}
dobrado.log("Saving purchase...","info");$.post("/php/request.php",{request:"manager",username:user,timestamp:timestamp,product:product,supplier:supplier,quantity:quantity,price:price,basePrice:currentProduct.price.toFixed(2),action:"submit",url:location.href,token:dobrado.token},function(response){if(dobrado.checkResponseError(response,"manager submit")){return;}
var surcharge=JSON.parse(response);var selectedRow=0;var newItem=true;if(currentDate){$.each(purchase,function(i,item){if(item.name===product&&item.date===currentDate&&item.user===user){purchase[i].supplier=supplier;purchase[i].quantity=quantity;purchase[i].price=price;purchase[i].total=total;if(grid){selectedRow=i;}
newItem=false;}
else if(!surcharge.done&&item.user===user&&item.name==="surcharge"&&item.date===surcharge.date){purchase[i]=surcharge;}});}
......
......@@ -295,9 +295,14 @@ if (!this.dobrado.manager) {
}
function showProductFromMenu(event, ui) {
// Price shown for the product depends on selected user's buyerGroup.
var user = $("#manager-username-input").val();
var product = $("#manager-product-input").val();
var supplier = $("#manager-supplier-input").val();
var price = "price";
if (user !== "") {
price = manager.buyerGroup[user];
}
if (ui) {
product = ui.item.value;
}
......@@ -313,12 +318,12 @@ if (!this.dobrado.manager) {
$("#manager-supplier-input").val(item.user);
// Update the price input when the product changes.
if (item.unit === "variable") {
$("#manager-price-input").val(item.price.toFixed(2));
$("#manager-price-input").val(item[price].toFixed(2));
$("#manager-price-input").attr("readonly", false);
$("#manager-quantity-input").val("1").spinner("disable");
}
else {
$("#manager-price-input").val("($" + item.price.toFixed(2) + "/" +
$("#manager-price-input").val("($" + item[price].toFixed(2) + "/" +
item.unit + ")");
$("#manager-price-input").attr("readonly", true);
$("#manager-quantity-input").spinner("enable");
......@@ -329,9 +334,14 @@ if (!this.dobrado.manager) {
}
function showSupplierFromMenu(event, ui) {
// Price shown for the product depends on selected user's buyerGroup.
var user = $("#manager-username-input").val();
var supplier = $("#manager-supplier-input").val();
var product = $("#manager-product-input").val();
var price = "price";
if (user !== "") {
price = manager.buyerGroup[user];
}
if (ui) {
supplier = ui.item.value;
}
......@@ -345,11 +355,11 @@ if (!this.dobrado.manager) {
currentProduct = item;
// Update the price input when the product changes.
if (item.unit === "variable") {
$("#manager-price-input").val(item.price.toFixed(2));
$("#manager-price-input").val(item[price].toFixed(2));
$("#manager-price-input").attr("readonly", false);
}
else {
$("#manager-price-input").val("($" + item.price.toFixed(2) + "/" +
$("#manager-price-input").val("($" + item[price].toFixed(2) + "/" +
item.unit + ")");
$("#manager-price-input").attr("readonly", true);
}
......@@ -381,6 +391,13 @@ if (!this.dobrado.manager) {
}
function setQuantity(event, ui) {
// Price shown for the product depends on selected user's buyerGroup.
var user = $("#manager-username-input").val();
var price = "price";
if (user !== "") {
price = manager.buyerGroup[user];
}
var quantity = 0;
if ("value" in ui) {
// value is set for the 'spin' event, before the input field is updated.
......@@ -397,9 +414,9 @@ if (!this.dobrado.manager) {
}
if (currentProduct && currentProduct.unit !== "variable") {
var price = quantity * currentProduct.price;
$("#manager-price-input").val("$" + price.toFixed(2) + " @ ($" +
currentProduct.price.toFixed(2) +
var total = quantity * currentProduct[price];
$("#manager-price-input").val("$" + total.toFixed(2) + " @ ($" +
currentProduct[price].toFixed(2) +
"/" + currentProduct.unit + ")");
}
}
......@@ -424,7 +441,7 @@ if (!this.dobrado.manager) {
resetForm();
return false;
}
var price = currentProduct.price.toFixed(2);
var price = currentProduct[manager.buyerGroup[user]].toFixed(2);
if (currentProduct.unit === "variable") {
price = $("#manager-price-input").val();
}
......@@ -460,6 +477,7 @@ if (!this.dobrado.manager) {
supplier: supplier,
quantity: quantity,
price: price,
basePrice: currentProduct.price.toFixed(2),
action: "submit",
url: location.href,
token: dobrado.token },
......
......@@ -26,18 +26,26 @@
if(!this.dobrado.payment){dobrado.payment={};}
(function(){'use strict';var payments=[];var grid=null;var currentPayment=null;var allNames=[];var allReferences=[];var details={};var importData=[];var currentImport=0;$(function(){if($(".payment").length===0){return;}
$("#payment-settings-form").dialog({autoOpen:false,title:"Edit your payment settings",width:400});$(".payment .submit").button().click(savePayment);$(".payment .remove").button().click(removePayment);$(".payment .edit").click(editSettings);$("#payment-settings-form .submit").button().click(saveSettings);$("#payment-username-input").val("");$("#payment-fullname-input").val("");$("#payment-date-input").val(dobrado.formatDate()).datepicker({dateFormat:dobrado.dateFormat});$("#payment-reference-input").val("");$("#payment-import-input").change(loadImportData);dobrado.log("Loading payments...","info");$.post("/php/request.php",{request:"payment",action:"list",url:location.href,token:dobrado.token},function(response){if(dobrado.checkResponseError(response,"payment list request")){return;}
$("#payment-settings-form").dialog({autoOpen:false,title:"Edit your payment settings",width:400});$("#payment-details-form").dialog({autoOpen:false,position:{my:"top",at:"top+50",of:"body"},title:"Edit Bank Details",width:450});$("#payment-details-form .submit").button().click(editBankDetails);$(".payment .submit").button().click(savePayment);$(".payment .remove").button().click(removePayment);$(".payment .edit").click(editSettings);$("#payment-settings-form .submit").button().click(saveSettings);$("#payment-username-input").val("");$("#payment-fullname-input").val("");$("#payment-date-input").val(dobrado.formatDate()).datepicker({dateFormat:dobrado.dateFormat});$("#payment-reference-input").val("");$("#payment-import-input").change(loadImportData);dobrado.log("Loading payments...","info");$.post("/php/request.php",{request:"payment",action:"list",url:location.href,token:dobrado.token},function(response){if(dobrado.checkResponseError(response,"payment list request")){return;}
payments=JSON.parse(response);if($(".grid").length!==0){var id="#"+$(".grid").attr("id");var columns=[{id:"date",name:"Date",field:"date",width:110,sortable:true,formatter:Slick.Formatters.Timestamp},{id:"name",name:"Username",field:"name",width:120,sortable:true},{id:"reference",name:"Reference",field:"reference",width:100,sortable:true},{id:"comment",name:"Comment",field:"comment",width:250,sortable:true},{id:"amount",name:"Amount",field:"amount",width:80,sortable:true,formatter:Slick.Formatters.Dollar}];var options={enableColumnReorder:false,forceFitColumns:true};grid=dobrado.grid.instance(id,payments,columns,options);grid.setSelectionModel(new Slick.RowSelectionModel());grid.onClick.subscribe(function(e,item){showPayment(payments[item.row]);});grid.onSort.subscribe(function(e,args){payments.sort(function(row1,row2){var field=args.sortCol.field;var sign=args.sortAsc?1:-1;var value1=row1[field];var value2=row2[field];if(field==="amount"){value1=parseFloat(value1);value2=parseFloat(value2);}
if(value1===value2){return 0;}
if(value1>value2){return sign;}
else{return sign* -1;}});grid.invalidate();grid.render();});}
loadUserDetails();});});function showDetails(user){var bank=details.bank[user];var contact=details.contact[user];if(bank&&bank.name&&bank.number&&bank.bsb){$(".payment .bank-details").html("<b>Bank Details:</b><br>"+"Account Name: "+bank.name+", Account Number: "+bank.number+", BSB: "+bank.bsb+"<br>");}
else{$(".payment .bank-details").html("");}
loadUserDetails();});});function showDetails(user){var bank=details.bank[user];var contact=details.contact[user];if(bank&&bank.name&&bank.number&&bank.bsb){$(".payment .bank-details").html('<b>Bank Details:</b>'+'<button class="edit">edit</button>'+'<br>Account Name: '+bank.name+', Account Number: '+bank.number+', BSB: '+bank.bsb+'<br>');$(".payment .bank-details .edit").button().click(openDialog);}
else if(user){$(".payment .bank-details").html('<b>Bank Details:</b>'+'<button class="edit">edit</button>');$(".payment .bank-details .edit").button().click(openDialog);}
else{$(".payment .bank-details").html('');}
if(contact&&contact.email){var description="";if(contact.phone){description+="Phone: "+contact.phone;}
if(description!==""){description+=