Commit 4d6bd2e3 authored by Malcolm Blaney's avatar Malcolm Blaney

Invoice module now lists the pack size and number or packs in the

orders email. Manager module shows the current stock price next to
the price input for the selected row as a comparison. Purchase->Search
will display quantity if one product is given, and if a supplier is
given check for sales to removed users also. Payment module allows
navigating to previous imports, and exiting import mode by clicking
a row in the grid. Stock module will update the prices when the
pack size changes. Users in the "admin/admin" group can flag users
as removed.
parent 9c89b203
......@@ -771,15 +771,19 @@ class Invoice extends Base {
if (count($next_week) == 0) continue;
$email = $details["email"];
if ($email == "") {
if ($email === "") {
// Add a notification if no email address found for user.
$this->Notification("SendOrders: No email address for ".$user);
continue;
}
$first = $details["first"];
if ($first === "") {
$first = $user;
}
$message = "<html><head><title>".$subject."</title></head>\n".
"<body>\n".
"<p>Hello ".$user.",</p>\n".
"<p>Hello ".$first.",</p>\n".
"<p>".$roster->Description($user)."</p>\n".
"<p>Here is your order for this week:</p>\n".
'<table border="0" cellspacing="5">'."\n".
......@@ -1046,7 +1050,8 @@ class Invoice extends Base {
if (!is_array($data[$supplier])) $data[$supplier] = array();
if (!is_array($data[$supplier][$name])) {
$data[$supplier][$name] = array("quantity" => $quantity,
"price" => $price);
"price" => $price,
"size" => $products[$name]["size"]);
}
else {
$data[$supplier][$name]["quantity"] += $quantity;
......@@ -1145,12 +1150,14 @@ class Invoice extends Base {
$data[$supplier][] = array("name" => $name,
"group" => $group,
"quantity" => $quantity,
"price" => $price);
"price" => $price,
"size" => $products[$name]["size"]);
}
else {
if (!is_array($data[$supplier][$name])) {
$data[$supplier][$name] = array("price" => $price,
"group" => array());
"group" => array(),
"size" => $products[$name]["size"]);
// Initialise quantities to zero for each group for this item.
for ($i = 0; $i < count($group_list); $i++) {
$data[$supplier][$name]["group"][$group_list[$i]] = 0;
......@@ -1309,6 +1316,23 @@ class Invoice extends Base {
return $run_groups;
}
private function RoundPacks($packs) {
// Rounding is a value between zero and one, used to decide if the
// number of packs should be rounded up or down.
static $rounding;
if (!isset($rounding)) {
$rounding = $this->Substitute("invoice-order-rounding");
}
// If rounding is the empty string, leave packs as a fraction.
if ($rounding === "") {
return $packs;
}
// Otherwise find the fraction of the last pack to compare rounding to.
$fraction = $packs - floor($packs);
if ($fraction < (float)$rounding) return floor($packs);
return ceil($packs);
}
private function WriteData($data, $group_list = array()) {
// Format is either "horizontal", where group names are written as
// seperate columns and imply quantity per group (therefore wider
......@@ -1324,23 +1348,32 @@ class Invoice extends Base {
}
$files = array();
foreach ($data as $supplier => $product) {
foreach ($data as $supplier => $products) {
if (count($products) == 0) continue;
$content = "";
// If there's more than one group, orders can be displayed with group
// totals displayed either in their own columns (horizontally) or
// subtotaled under product groups (vertically).
if ($group_list) {
if ($format == "vertical") {
for ($i = 0; $i < count($product); $i++) {
// First add a title.
if ($i == 0) {
$content = "Product,Co-op,Quantity,Price".
$extra_column_title."\n";
// First add a title.
$content = "Product,Co-op,Quantity,Pack Size,Packs,Price".
$extra_column_title."\n";
for ($i = 0; $i < count($products); $i++) {
$quantity = $products[$i]["quantity"];
$size = $products[$i]["size"];
// When size is 1 it means it's not being used.
if ($size == 1) {
$size = "";
$packs = "";
}
else {
$packs = $this->RoundPacks($quantity / $size);
}
// Put the product name in double quotes in case it contains commas.
$content .= '"'.$product[$i]["name"].'",'.
$product[$i]["group"].','.$product[$i]["quantity"].','.
$product[$i]["price"].$extra_column."\n";
$content .= '"'.$products[$i]["name"].'",'.
$products[$i]["group"].",".$quantity.",".$size.",".$packs.",".
$products[$i]["price"].$extra_column."\n";
}
}
else {
......@@ -1349,46 +1382,65 @@ class Invoice extends Base {
for ($j = 0; $j < count($group_list); $j++) {
$content .= ucfirst($group_list[$j]).",";
}
$content .= "Total,Price".$extra_column_title."\n";
foreach ($product as $name => $details) {
$content .= "Total,Pack Size,Packs,Price".$extra_column_title."\n";
foreach ($products as $name => $details) {
$content .= '"'.$name.'",';
$total = 0;
for ($i = 0; $i < count($group_list); $i++) {
$content .= $details["group"][$group_list[$i]].",";
$total += (float)$details["group"][$group_list[$i]];
}
$content .= $total.",".$details["price"].$extra_column."\n";
$size = $details["size"];
// When size is 1 it means it's not being used.
if ($size == 1) {
$size = "";
$packs = "";
}
else {
$packs = $this->RoundPacks($total / $size);
}
$content .= $total.",".$size.",".$packs.",".$details["price"].
$extra_column."\n";
}
}
}
// When there is only one group, there is no format distinction.
else {
$content = "Product,Quantity,Price".$extra_column_title."\n";
foreach ($product as $name => $details) {
$content .= '"'.$name.'",'.$details["quantity"].','.
$content = "Product,Quantity,Pack Size,Packs,Price".
$extra_column_title."\n";
foreach ($products as $name => $details) {
$quantity = $details["quantity"];
$size = $details["size"];
// When size is 1 it means it's not being used.
if ($size == 1) {
$size = "";
$packs = "";
}
else {
$packs = $this->RoundPacks($quantity / $size);
}
$content .= '"'.$name.'",'.$quantity.",".$size.",".$packs.",".
$details["price"].$extra_column."\n";
}
}
if ($content != "") {
// Add ServerName to the path in case there are multiple installs
// on the same server.
$path = "/tmp/".$this->user->config->ServerName();
if (!is_dir($path)) {
mkdir($path);
}
$filename = $path."/".$supplier."-".date("j-F-Y").".csv";
$handle = fopen($filename, "w");
if (!$handle) {
$this->Log('Invoice->WriteData: Error opening file: '.$filename);
return;
}
else {
$files[] = $filename;
}
fwrite($handle, $content);
fclose($handle);
// Add ServerName to the path in case there are multiple installs
// on the same server.
$path = "/tmp/".$this->user->config->ServerName();
if (!is_dir($path)) {
mkdir($path);
}
$filename = $path."/".$supplier."-".date("j-F-Y").".csv";
$handle = fopen($filename, "w");
if (!$handle) {
$this->Log('Invoice->WriteData: Error opening file: '.$filename);
return;
}
else {
$files[] = $filename;
}
fwrite($handle, $content);
fclose($handle);
}
return $files;
}
......
......@@ -159,7 +159,7 @@ class Manager extends Base {
'<div class="form-spacing">'.
'<label for="manager-price-input">Price*:</label>'.
'<input id="manager-price-input" size="15" maxlength="50" '.
'readonly="true">'.
'readonly="true"><span class="manager-price-info"></span>'.
'</div>'.
'<div class="form-spacing">'.
'<label for="manager-date-input">Date:</label>'.
......
......@@ -309,6 +309,7 @@ class Payment extends Base {
'<div class="bank-details"></div>'.
'<div class="contact-details"></div>'.
'<button class="submit">submit</button>'.
'<button class="back hidden">go back</button>'.
'<button class="remove">remove</button>'.
'<button class="search hidden">search</button>'.
'</form>'.
......
......@@ -609,16 +609,6 @@ class Purchase 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..
$site_style = array('"","#purchase-quota-wrapper","border",'.
'"1px solid #777777"',
'"","#purchase-quota-wrapper","display","inline-block"',
'"","#purchase-quota-wrapper","height","10px"',
'"","#purchase-quota-wrapper","width","100px"',
'"","#purchase-quota-bar","display","block"',
'"","#purchase-quota-bar","height","100%"',
'"","#purchase-grower-info", "margin-left", "10px"',
'"","#purchase-quota-info", "margin-left", "10px"');
$this->AddSiteStyle($site_style);
}
public function UpdateScript($path) {
......@@ -1120,7 +1110,8 @@ class Purchase extends Base {
public function Search($user, $timestamp, $product, $supplier,
$quantity, $price, $start, $end, $group = false) {
$object = array();
$order = 'ORDER BY user, timestamp';
$order_query = 'ORDER BY user, timestamp';
$removed_query = "";
$search = "";
// Need to specify table for user query due to join.
if ($user !== "") {
......@@ -1147,7 +1138,10 @@ class Purchase extends Base {
$search .= 'supplier = "'.$supplier.'"';
// When supplier is not empty and grouping is requested, don't order by
// user because totals can't be calculated below.
if ($group) $order = 'ORDER BY timestamp';
if ($group) $order_query = 'ORDER BY timestamp';
// Also allow queries against removed users to give a an accurate
// result for the supplier.
$removed_query = ' OR users.system_group = "removed"';
}
if ($quantity !== "") {
if ($search !== "") {
......@@ -1179,6 +1173,7 @@ class Purchase extends Base {
}
$day_total = 0;
$day_quantity = "";
$prev_day = -1;
$prev_user = "";
$prev_timestamp = 0;
......@@ -1186,7 +1181,8 @@ class Purchase extends Base {
$mysqli = connect_db();
$query = 'SELECT purchase.user, timestamp, name, supplier, quantity, '.
'price FROM purchase LEFT JOIN users ON purchase.user = users.user '.
'WHERE ('.$organiser->GroupQuery().') AND '.$search.' '.$order;
'WHERE ('.$organiser->GroupQuery().$removed_query.') AND '.$search.' '.
$order_query;
if ($result = $mysqli->query($query)) {
while ($purchase = $result->fetch_assoc()) {
$quantity = (float)$purchase["quantity"];
......@@ -1197,8 +1193,8 @@ class Purchase extends Base {
$timestamp = (int)$purchase["timestamp"] * 1000;
if ($group) {
$day = date("z", (int)$purchase["timestamp"]);
// Only split totals on user change if not a supplier search.
if ($day != $prev_day ||
// Only split totals on user change if not a supplier search.
($supplier === "" && $purchase["user"] != $prev_user)) {
if ($day_total != 0) {
$day_total = number_format($day_total, 2, ".", "");
......@@ -1206,16 +1202,23 @@ class Purchase extends Base {
"user" => $supplier === "" ? $prev_user : "",
"name" => $product,
"supplier" => $supplier,
"quantity" => "",
"quantity" => $day_quantity,
"price" => "",
"total" => $day_total);
$day_total = 0;
if ($product !== "") {
$day_quantity = 0;
}
}
}
$prev_day = $day;
$prev_user = $purchase["user"];
$prev_timestamp = $timestamp;
$day_total += $quantity * $price;
// Tracking quantity only makes sense for one product.
if ($product !== "") {
$day_quantity += $quantity;
}
}
else {
$object[] = array("date" => $timestamp,
......@@ -1233,7 +1236,7 @@ class Purchase extends Base {
"user" => $supplier === "" ? $prev_user : "",
"name" => $product,
"supplier" => $supplier,
"quantity" => "",
"quantity" => $day_quantity,
"price" => "",
"total" => $day_total);
}
......
......@@ -93,8 +93,9 @@ class Stock extends Base {
'<button class="stock-add-supplier">add supplier</button>' : "";
return '<form id="stock-form">'.
'<div class="import">Use the form below to update individual stock, '.
'or import a file to update all stock for a supplier.<br><br>'.
'<a href="#" class="import-toggle">Show import form to update all '.
'stock for a supplier.</a>'.
'<div class="import hidden">'.
'<div class="form-spacing">'.
'<label for="stock-import-supplier">Supplier:</label>'.
'<input id="stock-import-supplier" size="15" maxlength="50">'.
......@@ -112,8 +113,8 @@ class Stock extends Base {
'<label for="stock-import-file">Import File:</label>'.
'<input id="stock-import-file" type="file" size="15">'.
'</div>'.
'<div class="info"></div><hr>'.
'</div>'.
'<div class="info"></div>'.
'</div><hr>'.
'<div class="form-spacing">'.
'<label for="stock-name-input">Product:</label>'.
'<input id="stock-name-input" type="text" size="15" maxlength="100">'.
......@@ -412,6 +413,9 @@ class Stock extends Base {
"grower" => $stock["grower"]);
}
else {
// Note here that even though product names aren't unique, we can
// still key off them because we make sure only one product is
// available at a time where the names are the same.
$object[$stock["name"]] =
array("user" => $stock["user"],
"unit" => $stock["unit"],
......
......@@ -52,28 +52,28 @@ function showUser(event,ui){var user=$("#manager-username-input").val();if(ui){u
resetForm();$("#manager-form .edit").button("option","disabled",true);$("#manager-form .details .fullname").html("");$("#manager-form .details .email").html("");if(user===""){return;}
if($.inArray(user,manager.users)===-1){alert("If an account was just created for "+user+" please reload the page.");$("#manager-username-input").val("");return;}
updateDetails();}
function showPurchase(row){var data=purchase[row];$("#manager-username-input").val(data.user);$("#manager-product-input").val(data.name);$("#manager-supplier-input").val(data.supplier);$("#manager-quantity-input").val(data.quantity);$("#manager-date-input").val(dobrado.formatDate(data.date));currentDate=data.date;var price=data.quantity*data.price;$.each(manager.products,function(index,item){if(item.name===data.name&&item.user===data.supplier){currentProduct=item;if(currentProduct.unit==="variable"){$("#manager-price-input").val(data.price).attr("readonly",false);$("#manager-quantity-input").spinner("disable");}
function showPurchase(row){var data=purchase[row];$("#manager-username-input").val(data.user);$("#manager-product-input").val(data.name);$("#manager-supplier-input").val(data.supplier);$("#manager-quantity-input").val(data.quantity);$("#manager-date-input").val(dobrado.formatDate(data.date));$(".manager-price-info").html("");currentDate=data.date;var price=data.quantity*data.price;$.each(manager.products,function(index,item){if(item.name===data.name&&item.user===data.supplier){currentProduct=item;if(currentProduct.unit==="variable"){$("#manager-price-input").val(data.price).attr("readonly",false);$("#manager-quantity-input").spinner("disable");}
else{$("#manager-price-input").val("$"+price.toFixed(2)+" @ ($"+data.price+"/"+
currentProduct.unit+")");$("#manager-price-input").attr("readonly",true);$("#manager-quantity-input").spinner("enable");}
currentProduct.unit+")");$("#manager-price-input").attr("readonly",true);var priceLevel=manager.buyerGroup[data.user];if(item[priceLevel].toFixed(2)!==data.price){$(".manager-price-info").html("Stock price now $"+
item[priceLevel].toFixed(2));}
$("#manager-quantity-input").spinner("enable");}
return false;}});updateDetails();}
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];}
function showProductFromMenu(event,ui){var user=$("#manager-username-input").val();var product=$("#manager-product-input").val();var supplier=$("#manager-supplier-input").val();var priceLevel="price";if(user!==""){priceLevel=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");}
$("#manager-quantity-input").val("");$("#manager-price-input").val("");$(".manager-price-info").html("");$.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[priceLevel].toFixed(2));$("#manager-price-input").attr("readonly",false);$("#manager-quantity-input").val("1").spinner("disable");}
else{$("#manager-price-input").val("($"+item[priceLevel].toFixed(2)+"/"+item.unit+")");$("#manager-price-input").attr("readonly",true);$("#manager-quantity-input").spinner("enable");}
return false;}});}
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];}
function showSupplierFromMenu(event,ui){var user=$("#manager-username-input").val();var supplier=$("#manager-supplier-input").val();var product=$("#manager-product-input").val();var priceLevel="price";if(user!==""){priceLevel=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);}
$("#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[priceLevel].toFixed(2));$("#manager-price-input").attr("readonly",false);}
else{$("#manager-price-input").val("($"+item[priceLevel].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 user=$("#manager-username-input").val();var price="price";if(user!==""){price=manager.buyerGroup[user];}
function setQuantity(event,ui){var user=$("#manager-username-input").val();var priceLevel="price";if(user!==""){priceLevel=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 total=quantity*currentProduct[price];$("#manager-price-input").val("$"+total.toFixed(2)+" @ ($"+
currentProduct[price].toFixed(2)+"/"+currentProduct.unit+")");}}
if(currentProduct&&currentProduct.unit!=="variable"){var total=quantity*currentProduct[priceLevel];$("#manager-price-input").val("$"+total.toFixed(2)+" @ ($"+
currentProduct[priceLevel].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;}
......@@ -106,4 +106,4 @@ else{purchase[i]=surcharge;}
return false;}});if(grid&&purchase.length!==0){grid.setData(purchase);grid.updateRowCount();grid.render();grid.setSelectedRows([]);}
else{$(".grid").hide();}
resetForm();});return false;}
function resetForm(){$("#manager-product-input").val("");$("#manager-supplier-input").val("");$("#manager-price-input").val("");$("#manager-quantity-input").val("");$("#manager-date-input").val("");currentProduct=null;currentDate=null;}})();
\ No newline at end of file
function resetForm(){$("#manager-product-input").val("");$("#manager-supplier-input").val("");$("#manager-price-input").val("");$(".manager-price-info").html("");$("#manager-quantity-input").val("");$("#manager-date-input").val("");currentProduct=null;currentDate=null;}})();
\ No newline at end of file
......@@ -280,6 +280,7 @@ if (!this.dobrado.manager) {
$("#manager-supplier-input").val(data.supplier);
$("#manager-quantity-input").val(data.quantity);
$("#manager-date-input").val(dobrado.formatDate(data.date));
$(".manager-price-info").html("");
currentDate = data.date;
var price = data.quantity * data.price;
// Set currentProduct and units.
......@@ -295,6 +296,15 @@ if (!this.dobrado.manager) {
" @ ($" + data.price + "/" +
currentProduct.unit + ")");
$("#manager-price-input").attr("readonly", true);
// Check if the price the user purchased at is different from the
// current stock price, and if so let ther user know the new price.
// Also data.price is given as a fixed two-decimal string, so
// convert the item's priceLevel to match the format.
var priceLevel = manager.buyerGroup[data.user];
if (item[priceLevel].toFixed(2) !== data.price) {
$(".manager-price-info").html("Stock price now $" +
item[priceLevel].toFixed(2));
}
$("#manager-quantity-input").spinner("enable");
}
return false;
......@@ -308,15 +318,16 @@ if (!this.dobrado.manager) {
var user = $("#manager-username-input").val();
var product = $("#manager-product-input").val();
var supplier = $("#manager-supplier-input").val();
var price = "price";
var priceLevel = "price";
if (user !== "") {
price = manager.buyerGroup[user];
priceLevel = manager.buyerGroup[user];
}
if (ui) {
product = ui.item.value;
}
$("#manager-quantity-input").val("");
$("#manager-price-input").val("");
$(".manager-price-info").html("");
$.each(manager.products, function(index, item) {
// If the supplier field is set, also use that here.
......@@ -327,13 +338,13 @@ 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[priceLevel].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").val("($" + item[priceLevel].toFixed(2) +
"/" + item.unit + ")");
$("#manager-price-input").attr("readonly", true);
$("#manager-quantity-input").spinner("enable");
}
......@@ -347,9 +358,9 @@ if (!this.dobrado.manager) {
var user = $("#manager-username-input").val();
var supplier = $("#manager-supplier-input").val();
var product = $("#manager-product-input").val();
var price = "price";
var priceLevel = "price";
if (user !== "") {
price = manager.buyerGroup[user];
priceLevel = manager.buyerGroup[user];
}
if (ui) {
supplier = ui.item.value;
......@@ -364,12 +375,12 @@ 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[priceLevel].toFixed(2));
$("#manager-price-input").attr("readonly", false);
}
else {
$("#manager-price-input").val("($" + item[price].toFixed(2) + "/" +
item.unit + ")");
$("#manager-price-input").val("($" + item[priceLevel].toFixed(2) +
"/" + item.unit + ")");
$("#manager-price-input").attr("readonly", true);
}
return false;
......@@ -402,9 +413,9 @@ 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";
var priceLevel = "price";
if (user !== "") {
price = manager.buyerGroup[user];
priceLevel = manager.buyerGroup[user];
}
var quantity = 0;
......@@ -423,9 +434,9 @@ if (!this.dobrado.manager) {
}
if (currentProduct && currentProduct.unit !== "variable") {
var total = quantity * currentProduct[price];
var total = quantity * currentProduct[priceLevel];
$("#manager-price-input").val("$" + total.toFixed(2) + " @ ($" +
currentProduct[price].toFixed(2) +
currentProduct[priceLevel].toFixed(2) +
"/" + currentProduct.unit + ")");
}
}
......@@ -688,6 +699,7 @@ if (!this.dobrado.manager) {
$("#manager-product-input").val("");
$("#manager-supplier-input").val("");
$("#manager-price-input").val("");
$(".manager-price-info").html("");
$("#manager-quantity-input").val("");
$("#manager-date-input").val("");
currentProduct = null;
......
This diff is collapsed.
......@@ -66,6 +66,7 @@ if (!this.dobrado.payment) {
$("#payment-details-form .submit").button().click(editBankDetails);
$(".payment .submit").button().click(savePayment);
$(".payment .remove").button().click(removePayment);
$(".payment .back").button().click(showPreviousImport);
$(".payment .edit").click(editSettings);
$("#payment-settings-form .submit").button().click(saveSettings);
$("#payment-username-input").val("");
......@@ -391,6 +392,10 @@ if (!this.dobrado.payment) {
}
function showPayment(item) {
// Exit import mode when the user clicks on an existing payment row.
if (currentImport !== 0) {
exitImport("");
}
currentPayment = item;
// Update the form based on the item given.
$("#payment-username-input").val(item.name);
......@@ -632,6 +637,8 @@ if (!this.dobrado.payment) {
"</b>:");
// Re-use the remove button to skip through imported transactions.
$(".payment .remove").button("option", "label", "skip");
// Also show a navigation button to go back through import data.
$(".payment .back").show();
showImportData();
}
};
......@@ -740,14 +747,20 @@ if (!this.dobrado.payment) {
});
}
function showPreviousImport() {
if (currentImport > 1) {
// showImportData always increments currentImport counter,
// so need to decrease by 2 to get back 1.
currentImport -= 2;
showImportData();
}
return false;
}
function showImportData() {
resetForm();
if (currentImport === importData.length) {
$(".import .info").html("Data processing complete.");
$("#payment-import-input").val("");
$(".payment .remove").button("option", "label", "remove");
importData = [];
currentImport = 0;
exitImport("Data processing complete.");
return;
}
var row = importData[currentImport++];
......@@ -796,4 +809,13 @@ if (!this.dobrado.payment) {
currentPayment = null;
}
function exitImport(message) {
$(".import .info").html(message);
$("#payment-import-input").val("");
$(".payment .remove").button("option", "label", "remove");
$(".payment .back").hide();
importData = [];
currentImport = 0;
}
})();
......@@ -32,7 +32,7 @@ if(index===2){allUserGridId="#"+$(this).attr("id");}});if($(".grid").length!==0)
if(value1===value2){return 0;}
if(value1>value2){return sign;}
else{return sign* -1;}});allAvailableGrid.invalidate();allAvailableGrid.render();});}
if($(".grid").length===3){var allUserColumns=[{id:"user",name:"Username",field:"user",width:210,sortable:true},{id:"date",name:"Date",field:"date",width:110,sortable:true,formatter:Slick.Formatters.Timestamp,editor:Slick.Editors.Date},{id:"quanity",name:"Quantity",field:"quantity",width:100,sortable:true,editor:Slick.Editors.Number},{id:"price",name:"Price",field:"price",width:100,sortable:true,formatter:Slick.Formatters.Units},{id:"total",name:"Total",field:"total",width:80,sortable:true,formatter:Slick.Formatters.Dollar}];var allUserOptions={editable:true,enableColumnReorder:false,forceFitColumns:true};$(allUserGridId).appendTo($(".purchase-all-users-dialog"));allUserGrid=dobrado.grid.instance(allUserGridId,[],allUserColumns,allUserOptions);allUserGrid.onCellChange.subscribe(updateUserPurchaseData);allUserGrid.onSort.subscribe(function(e,args){allUserData.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!=="user"){value1=parseFloat(value1);value2=parseFloat(value2);}
if($(".grid").length===3){var allUserColumns=[{id:"user",name:"Username",field:"user",width:210,sortable:true},{id:"date",name:"Date",field:"date",width:110,sortable:true,formatter:Slick.Formatters.Timestamp,editor:Slick.Editors.Date},{id:"quanity",name:"Quantity",field:"quantity",width:100,sortable:true,editor:Slick.Editors.Number},{id:"price",name:"Price",field:"price",width:100,sortable:true,formatter:Slick.Formatters.Units},{id:"total",name:"Total",field:"total",width:80,sortable:true,formatter:Slick.Formatters.Dollar}];var allUserOptions={editable:true,enableColumnReorder:false,forceFitColumns:true};$(allUserGridId).appendTo($(".purchase-all-users-dialog"));allUserGrid=dobrado.grid.instance(allUserGridId,[],allUserColumns,allUserOptions);allUserGrid.setSelectionModel(new Slick.RowSelectionModel());allUserGrid.onCellChange.subscribe(updateUserPurchaseData);allUserGrid.onSort.subscribe(function(e,args){allUserData.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!=="user"){value1=parseFloat(value1);value2=parseFloat(value2);}
if(value1===value2){return 0;}
if(value1>value2){return sign;}
else{return sign* -1;}});allUserGrid.invalidate();allUserGrid.render();});}}
......
......@@ -268,6 +268,7 @@ if (!this.dobrado.purchase) {
allUserGrid = dobrado.grid.instance(allUserGridId, [],
allUserColumns,
allUserOptions);
allUserGrid.setSelectionModel(new Slick.RowSelectionModel());
allUserGrid.onCellChange.subscribe(updateUserPurchaseData);
allUserGrid.onSort.subscribe(function (e, args) {
allUserData.sort(function(row1, row2) {
......
This diff is collapsed.
This diff is collapsed.
......@@ -53,7 +53,7 @@ else if(userExists){message="Updating user details.";}
else{message="Adding new user.";}
dobrado.log(message,"info");$.post("/php/request.php",{request:"account",action:"add-user",newUser:newUser,email:$("#email-input").val(),group:$("#system-group-input").val(),first:$("#new-details-first-input").val(),last:$("#new-details-last-input").val(),phone:$("#new-details-phone-input").val(),url:location.href,token:dobrado.token},function(response){if(dobrado.checkResponseError(response,"newUser request")){return false;}
$(".account").dialog("close");$("#register-form .username-info").html("");});return false;}
function removeUser(){dobrado.log("Removing user from system","info");$.post("/php/request.php",{request:"account",action:"remove-user-submit",removeUser:$("#remove-user-input").val(),url:location.href,token:dobrado.token},function(response){if(dobrado.checkResponseError(response,"removeUser")){return false;}
function removeUser(){dobrado.log("Removing user","info");$.post("/php/request.php",{request:"account",action:"remove-user-submit",removeUser:$("#remove-user-input").val(),url:location.href,token:dobrado.token},function(response){if(dobrado.checkResponseError(response,"removeUser")){return false;}
$(".account").dialog("close");});return false;}
function showGroup(group){dobrado.log("Loading group members.","info");$.post("/php/request.php",{request:"account",action:"show-group",group:group,url:location.href,token:dobrado.token},function(response){if(dobrado.checkResponseError(response,"group request")){return false;}
var account=JSON.parse(response);$(".group-user-list").html(account.content);$(".remove-group-member").button({icons:{primary:'ui-icon-closethick'},text:false}).click(removeGroupMember);});}
......
......@@ -60,16 +60,16 @@ function updateConfig(){var username=$("#site-config-form #user-input").val();do
var config=JSON.parse(response);$("#site-config-form :input").each(function(){var name=$(this).attr("name");if(config&&config[name]){$(this).val(config[name]);}
else{$(this).val("");}});});}
var template={};function showTemplateForLabel(event,ui){var label=$("#site-template-label-input").val();if(ui){label=ui.item.value;}
if(label===""){$("#site-template-content-textarea").val("");return;}
if(label===""){$("#site-template-content-textarea").val("");$("#site-template-description-textarea").val("");return;}
var group=$("#site-template-group-input").val();if(template.group[group]&&template.group[group][label]){var content=template.group[group][label];var description=template.description[label];$("#site-template-content-textarea").val(content);$("#site-template-description-textarea").val(description);}
else{$("#site-template-content-textarea").val("");$("#site-template-description-textarea").val("");}}
function showTemplateForGroup(event,ui){var label=$("#site-template-label-input").val();if(label===""){$("#site-template-content-textarea").val("");return;}
function showTemplateForGroup(event,ui){var label=$("#site-template-label-input").val();if(label===""){$("#site-template-content-textarea").val("");$("#site-template-description-textarea").val("");return;}
var group=$("#site-template-group-input").val();if(ui){group=ui.item.value;}
if(template.group[group]&&template.group[group][label]){var content=template.group[group][label];$("#site-template-content-textarea").val(content);}
else{$("#site-template-content-textarea").val("");}}
function updateTemplate(action){var label=$("#site-template-label-input").val();var group=$("#site-template-group-input").val();var content=$("#site-template-content-textarea").val();var description=$("#site-template-description-textarea").val();if(label===""){return;}
if(action==="saveTemplate"){dobrado.log("Saving template","info");if(!template.group[group]){template.group[group]={};}
template.group[group][label]=content;}
template.group[group][label]=content;template.description[label]=description;}
else if(action==="removeTemplate"){dobrado.log("Removing template","info");if(template.group[group]&&template.group[group][label]){delete template.group[group][label];}
if($.isEmptyObject(template.group[group])){delete template.group[group];}}
else{return;}
......
......@@ -244,7 +244,7 @@ if (!this.dobrado.account) {
}
function removeUser() {
dobrado.log("Removing user from system", "info");
dobrado.log("Removing user", "info");
$.post("/php/request.php", { request: "account",
action: "remove-user-submit",
removeUser: $("#remove-user-input").val(),
......
......@@ -350,6 +350,7 @@
}
if (label === "") {
$("#site-template-content-textarea").val("");