Commit 8ed3b27f authored by Malcolm Blaney's avatar Malcolm Blaney

New Report module. Last commit accidently included initial Detail

module changes for adding membership reminders, this commit adds
the full functionality. Groupwizard module now allows the 'co-op-day'
to be left unset and a date will be used that is one year away so
that buying can just stay open until quotas are met. The Groupwizard
will then update all timestamps when final dates are provided.
Invite module OpenBuyingGroups now uses a Purchase module method
OrderingAvailable which has been refactored. Organiser module checks
invite groups where required.
parent 165b1154
......@@ -21,6 +21,7 @@ php/modules/Post.php
php/modules/Purchase.php
php/modules/Reader.php
php/modules/Registration.php
php/modules/Report.php
php/modules/Roster.php
php/modules/Sell.php
php/modules/Slider.php
......@@ -52,6 +53,7 @@ js/dobrado.player.js
js/dobrado.purchase.js
js/dobrado.reader.js
js/dobrado.registration.js
js/dobrado.report.js
js/dobrado.roster.js
js/dobrado.sell.js
js/dobrado.slider.js
......@@ -82,6 +84,7 @@ js/source/dobrado.player.js
js/source/dobrado.purchase.js
js/source/dobrado.reader.js
js/source/dobrado.registration.js
js/source/dobrado.report.js
js/source/dobrado.roster.js
js/source/dobrado.sell.js
js/source/dobrado.slider.js
......
......@@ -34,9 +34,10 @@ class Detail extends Base {
$description = $mysqli->escape_string($_POST['description']);
$query = 'INSERT INTO user_detail VALUES ("'.$this->user->name.'", '.
'"'.$first.'", "'.$last.'", "'.$thumb.'", "'.$phone.'", "'.$address.'", '.
'"'.$description.'", 1) ON DUPLICATE KEY UPDATE first = "'.$first.'", '.
'last = "'.$last.'", thumbnail = "'.$thumb.'", phone = "'.$phone.'", '.
'address = "'.$address.'", description = "'.$description.'"';
'"'.$description.'", 1, 0, "") ON DUPLICATE KEY UPDATE '.
'first = "'.$first.'", last = "'.$last.'", thumbnail = "'.$thumb.'", '.
'phone = "'.$phone.'", address = "'.$address.'", '.
'description = "'.$description.'"';
if (!$mysqli->query($query)) {
$this->Log('Detail->Callback: '.$mysqli->error);
}
......@@ -144,18 +145,26 @@ class Detail extends Base {
public function Factory($fn, $p = NULL) {
if (is_array($p)) {
$count = count($p);
// Account module calls UpdateUser through module interface.
if ($fn == 'UpdateUser' && count($p) == 8) {
if ($fn == 'UpdateUser' && $count >= 8) {
$user = $p[0];
$first = $p[1];
$last = $p[2];
$phone = $p[3];
$address = $p[4];
$description = $p[5];
$display = $p[6];
$display = (int)$p[6];
$update_all = $p[7];
$reminder_time = 0;
$reminder_repeat = '';
if ($count == 10) {
$reminder_time = (int)$p[8];
$reminder_repeat = $p[9];
}
return $this->UpdateUser($user, $first, $last, $phone, $address,
$description, $display, $update_all);
$description, $display, $update_all,
$reminder_time, $reminder_repeat);
}
return;
}
......@@ -317,22 +326,23 @@ class Detail extends Base {
// Add the host group too.
$group_query .= ' OR users.system_group = "'.$this->user->group.'"';
$query = 'SELECT users.user, email, system_group, first, last, '.
'thumbnail, phone, description, display FROM users LEFT JOIN '.
'user_detail ON users.user = user_detail.user WHERE users.user '.
'NOT LIKE "buyer\_%" AND ('.$group_query.')';
'thumbnail, phone, description, display, reminder_time FROM users '.
'LEFT JOIN user_detail ON users.user = user_detail.user WHERE '.
'users.user NOT LIKE "buyer\_%" AND ('.$group_query.')';
}
else if ($organisation) {
$organiser = new Organiser($this->user, $this->owner);
$query = 'SELECT users.user, email, system_group, first, last, '.
'thumbnail, phone, description, display FROM users LEFT JOIN '.
'user_detail ON users.user = user_detail.user WHERE users.user '.
'NOT LIKE "buyer\_%" AND '.$organiser->GroupQuery();
'thumbnail, phone, description, display, reminder_time FROM users '.
'LEFT JOIN user_detail ON users.user = user_detail.user WHERE '.
'users.user NOT LIKE "buyer\_%" AND '.$organiser->GroupQuery();
}
else {
$query = 'SELECT users.user, email, system_group, first, last, '.
'thumbnail, phone, description, display FROM users LEFT JOIN '.
'user_detail ON users.user = user_detail.user WHERE users.user '.
'NOT LIKE "buyer\_%" AND users.system_group = "'.$this->user->group.'"';
'thumbnail, phone, description, display, reminder_time FROM users '.
'LEFT JOIN user_detail ON users.user = user_detail.user WHERE '.
'users.user NOT LIKE "buyer\_%" AND '.
'users.system_group = "'.$this->user->group.'"';
}
$mysqli = connect_db();
if ($result = $mysqli->query($query)) {
......@@ -352,6 +362,7 @@ class Detail extends Base {
'phone' => htmlspecialchars($detail['phone']),
'description' => htmlspecialchars($detail['description']),
'display' => $detail['display'] === '1',
'reminder_time' => $detail['reminder_time'],
'email' => htmlspecialchars($detail['email']),
'group' => $detail['system_group']);
}
......@@ -364,23 +375,71 @@ class Detail extends Base {
return $object;
}
public function MembershipReminder($user) {
$reminder_time = 0;
$reminder_repeat = '';
$mysqli = connect_db();
$query = 'SELECT reminder_time, reminder_repeat FROM user_detail '.
'WHERE user = "'.$user.'"';
if ($result = $mysqli->query($query)) {
if ($user_detail = $result->fetch_assoc()) {
$reminder_time = (int)$user_detail['reminder_time'];
$reminder_repeat = $user_detail['reminder_repeat'];
}
$result->close();
}
else {
$this->Log('Detail->MembershipReminder 1: '.$mysqli->error);
}
$mysqli->close();
// Return false if values aren't set for this user.
if ($reminder_time === 0 || $reminder_repeat === '') return false;
// Check if membership is due in the next two weeks.
if ($reminder_time < time() + (86400 * 14)) {
// Update the reminder time when less than one week.
if ($reminder_time < time() + (86400 * 7)) {
if ($reminder_repeat == '6 months') {
$reminder_time += (int)(86400 * 365.25 / 2);
}
else {
$reminder_time += (int)(86400 * 365.25);
}
$mysqli = connect_db();
$query = 'UPDATE user_detail SET reminder_time = '.$reminder_time.
' WHERE user = "'.$user.'"';
if (!$mysqli->query($query)) {
$this->Log('Detail->MembershipReminder 2: '.$mysqli->error);
}
$mysqli->close();
}
return true;
}
return false;
}
public function UpdateUser($user, $first, $last, $phone,
$address = '', $description = '',
$display = 1, $update_all = false) {
$display = 1, $update_all = false,
$reminder_time = 0, $reminder_repeat = '') {
$query = '';
$mysqli = connect_db();
if ($update_all) {
$query = 'INSERT INTO user_detail VALUES ("'.$user.'", "'.$first.'", '.
'"'.$last.'", "", "'.$phone.'", "'.$address.'", "'.$description.'", '.
$display.') ON DUPLICATE KEY UPDATE first = "'.$first.'", '.
'last = "'.$last.'", phone = "'.$phone.'", address = "'.$address.'", '.
'description = "'.$description.'", display = '.$display;
$display.', '.$reminder_time.', "'.$reminder_repeat.'") '.
'ON DUPLICATE KEY UPDATE first = "'.$first.'", last = "'.$last.'", '.
'phone = "'.$phone.'", address = "'.$address.'", '.
'description = "'.$description.'", display = '.$display.', '.
'reminder_time = '.$reminder_time.', '.
'reminder_repeat = "'.$reminder_repeat.'"';
}
else {
$query = 'INSERT INTO user_detail VALUES ("'.$user.'", "'.$first.'", '.
'"'.$last.'", "", "'.$phone.'", "'.$address.'", "'.$description.'", '.
$display.') ON DUPLICATE KEY UPDATE first = "'.$first.'", '.
'last = "'.$last.'", phone = "'.$phone.'"';
$display.', '.$reminder_time.', "'.$reminder_repeat.'") '.
'ON DUPLICATE KEY UPDATE first = "'.$first.'", last = "'.$last.'", '.
'phone = "'.$phone.'"';
}
if (!$mysqli->query($query)) {
$this->Log('Detail->UpdateUser: '.$mysqli->error);
......@@ -391,15 +450,17 @@ class Detail extends Base {
public function User($user = '') {
$object = array('email' => '', 'first' => '', 'last' => '',
'thumbnail' => '', 'phone' => '', 'address' => '',
'description' => '', 'display' => true);
'description' => '', 'display' => true,
'reminderTime' => 0, 'reminderRepeat' => '');
if ($user === '' || $user === NULL) {
$user = $this->user->name;
}
$mysqli = connect_db();
$query = 'SELECT email, first, last, thumbnail, phone, address, '.
'description, display FROM users LEFT JOIN user_detail ON '.
'users.user = user_detail.user WHERE users.user = "'.$user.'"';
'description, display, reminder_time, reminder_repeat FROM users '.
'LEFT JOIN user_detail ON users.user = user_detail.user WHERE '.
'users.user = "'.$user.'"';
if ($result = $mysqli->query($query)) {
if ($detail = $result->fetch_assoc()) {
$img = '<img class="thumb" src="/images/default_thumb.jpg">';
......@@ -418,7 +479,9 @@ class Detail extends Base {
'phone' => htmlspecialchars($detail['phone']),
'address' => htmlspecialchars($detail['address']),
'description' => htmlspecialchars($detail['description']),
'display' => $detail['display'] === '1');
'display' => $detail['display'] === '1',
'reminderTime' => $detail['reminder_time'],
'reminderRepeat' => $detail['reminder_repeat']);
}
$result->close();
}
......
......@@ -191,7 +191,7 @@ class Groupwizard extends Base {
'<button class="previous">previous</button>'.
'<button class="next">next</button>'.
'<div class="groupwizard-0"><p>This wizard will help you configure '.
'<div class="groupwizard-0"><p>This dialog will help you configure '.
'your group settings.</p>'.
'<p>Your changes will be automatically saved as you navigate through '.
'each section, and when this dialog is closed.</p>'.
......@@ -231,6 +231,9 @@ class Groupwizard extends Base {
'<div class="groupwizard-2 hidden"><b>Section 2:</b> Configure the '.
'days the group can purchase and order.'.
'<p>You can leave the purchase day blank if you\'re not sure when the '.
'order will close, for example you want to wait until quotas are '.
'full. Then when you\'re ready, come back and set the date here.</p>'.
'<div class="form-spacing">'.
'<label for="groupwizard-co-op-day">The day purchases are made:'.
'</label>'.
......@@ -282,8 +285,10 @@ class Groupwizard extends Base {
$this->Options('pre-order-open-time', $hours).
'</select>'.
'</div>'.
'If using calendar dates, the day orders close must be within '.
'a week of the purchase date.'.
'If you haven\'t set a purchase date above, leave the closing date '.
'for the order blank too, and set them both when you\'re ready. '.
'<i>If using calendar dates, the day orders close must be within '.
'a week of the purchase date.</i>'.
'<div class="form-spacing">'.
'<label for="groupwizard-pre-order-final-select">The day '.
'pre-order closes:</label>'.
......@@ -299,8 +304,8 @@ class Groupwizard extends Base {
$weekdays).'">'.
'</div>'.
'<div class="form-spacing">'.
'<label for="groupwizard-pre-order-final-date">I want to enter a '.
'date</label>'.
'<label for="groupwizard-pre-order-final-date">'.
'I want to enter a date</label>'.
'<input type="checkbox" id="groupwizard-pre-order-final-date">'.
'</div>'.
'<div class="form-spacing">'.
......@@ -686,7 +691,8 @@ class Groupwizard extends Base {
'"", "label[for=groupwizard-organiser-sender-name]", '.
'"width", "12em"');
$this->AddSiteStyle($site_style);
return $this->Dependencies(array('invite', 'organiser', 'stock'));
return $this->Dependencies(array('invite', 'organiser', 'purchase',
'stock'));
}
public function Placement() {
......@@ -727,7 +733,11 @@ class Groupwizard extends Base {
private function Options($label, $values) {
$text = '';
$current = $this->Substitute($label);
$current = '';
// co-op-day is a special case that needs to be checked.
if ($label !== 'co-op-day' || $this->PurchaseDate()) {
$current = $this->Substitute($label);
}
for ($i = 0; $i < count($values); $i++) {
$option = $values[$i];
if ($option === $current) {
......@@ -742,6 +752,10 @@ class Groupwizard extends Base {
}
private function Value($label, $excluded = null) {
// co-op-day is a special case that needs to be checked.
if ($label === 'co-op-day' && !$this->PurchaseDate()) {
return '';
}
$current = $this->Substitute($label);
if (isset($excluded) && in_array($current, $excluded)) {
return '';
......@@ -749,6 +763,36 @@ class Groupwizard extends Base {
return $current;
}
private function PurchaseDate() {
// This function is used to hide the date when co-op-day is more than
// 6 months away, which signifies that ordering will be closed later.
// It's also used to update the value when it's not currently set.
$co_op_day = $this->Substitute('co-op-day');
if ($co_op_day === '') {
// When co-op-day is not set, give it a default of one year away.
$twelve_months = time() + (86400 * 365);
$co_op_day = date('j M Y', $twelve_months);
$organiser = new Organiser($this->user, $this->owner);
$groups = $organiser->Siblings();
$mysqli = connect_db();
for ($i = 0; $i < count($groups); $i++) {
$query = 'INSERT INTO template VALUES ("co-op-day", '.
'"'.$groups[$i].'", "'.$co_op_day.'") ON DUPLICATE KEY UPDATE '.
'content = "'.$co_op_day.'"';
if (!$mysqli->query($query)) {
$this->Log('Groupwizard->PurchaseDate: '.$mysqli->error);
}
}
$mysqli->close();
return false;
}
$six_months = time() + (86400 * 182);
if (strtotime($co_op_day) > $six_months) {
return false;
}
return true;
}
private function ExtraSettings($string) {
return $this->user->canEditSite ? $string : '';
}
......@@ -761,6 +805,33 @@ class Groupwizard extends Base {
$mysqli = connect_db();
$label = $mysqli->escape_string($_POST['label']);
$value = $mysqli->escape_string($_POST['value']);
// Special case for co-op-day, update existing orders to new date.
if ($label === 'co-op-day') {
$weekdays = array('Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday');
$co_op_day = $this->Substitute('co-op-day');
if (in_array($co_op_day, $weekdays)) {
$co_op_day = 'next '.$co_op_day;
}
$old_timestamp = strtotime($co_op_day);
$new_timestamp = false;
if ($value === '') {
// When a new value for co-op-day isn't given update the template and
// also the order to one year away.
$new_timestamp = time() + (86400 * 365);
$value = date('j M Y', $new_timestamp);
}
else if (in_array($value, $weekdays)) {
$new_timestamp = strtotime('next '.$value);
}
else {
$new_timestamp = strtotime($value);
}
if ($old_timestamp && $new_timestamp) {
$purchase = new Purchase($this->user, $this->owner);
$purchase->UpdateTimestamp($old_timestamp, $new_timestamp);
}
}
if ($_SESSION['groupwizard-all-groups']) {
$organiser = new Organiser($this->user, $this->owner);
$groups = $organiser->Siblings();
......
......@@ -369,7 +369,7 @@ class Invite extends Base {
$this->Log('Invite->Install: '.$mysqli->error);
}
$mysqli->close();
return $this->Dependencies(array('detail', 'notification'));
return $this->Dependencies(array('detail', 'notification', 'purchase'));
}
public function Placement() {
......@@ -417,6 +417,7 @@ class Invite extends Base {
}
public function OpenBuyingGroups() {
$purchase = new Purchase($this->user, $this->owner);
$default_group = $this->user->group;
$groups = array();
$mysqli = connect_db();
......@@ -425,19 +426,7 @@ class Invite extends Base {
if ($result = $mysqli->query($query)) {
while ($invite = $result->fetch_assoc()) {
$this->user->group = $invite['name'];
// Only add this group to the list if it's currently open.
$pre_order_final = $this->Substitute('pre-order-final');
$pre_order_final_time = $this->Substitute('pre-order-final-time');
if ($pre_order_final !== '' && $pre_order_final_time !== '') {
$pre_order_final .= ', '.$pre_order_final_time;
}
$final = strtotime($pre_order_final);
// If $final is less than the current time, use the next timestamp
// for this day and time.
if ($final && $final < time()) {
$final = strtotime('next '.$pre_order_final);
}
if ($final) {
if ($purchase->OrderingAvailable()) {
$groups[] = $this->user->group;
}
}
......
......@@ -22,10 +22,8 @@ class Invoice extends Base {
}
public function Callback() {
$object = array();
if (!$this->user->canViewPage) {
$object['error'] = 'You don\'t have permission to view invoices.';
return $object;
return array('error' => 'You don\'t have permission to view invoices.');
}
$mysqli = connect_db();
......@@ -33,21 +31,20 @@ class Invoice extends Base {
$mysqli->close();
if ($action == 'list') {
$object = $this->Data(true, true);
return $this->Data(true, true);
}
else if ($action == 'listInvoices') {
$object = $this->ListInvoices();
if ($action == 'listInvoices') {
return $this->ListInvoices();
}
else if ($action == 'sendOldInvoice') {
$object = $this->SendOldInvoice();
if ($action == 'sendOldInvoice') {
return $this->SendOldInvoice();
}
else if ($action == 'exportMemberHistory') {
$object = $this->ExportMemberHistory();
if ($action == 'exportMemberHistory') {
return $this->ExportMemberHistory();
}
else if ($action == 'exportData') {
$object = $this->ExportData();
if ($action == 'exportData') {
return $this->ExportData();
}
return $object;
}
public function CanAdd($page) {
......@@ -329,7 +326,9 @@ class Invoice extends Base {
'"invoice-organisation-sender","","noreply@!host"',
'"invoice-organisation-email","","(organisation email)"',
'"invoice-organisation-subject","",'.
'"Orders for next week"');
'"Orders for next week"',
'"invoice-membership-reminder","","<b>Reminder:</b> '.
'Your membership is due."');
$this->AddTemplate($template);
$site_style = array('"",".invoice .export-data","float","right"',
......@@ -392,6 +391,7 @@ class Invoice extends Base {
// included in the total.
$start = strtotime('-'.$this->Substitute('invoice-day-count').' days');
$end = time();
// TODO: Check if tax should be shown for the group and call AllTaxable.
$purchase_totals = $purchase->AllTotals($start, $end, $organisation);
$sold_totals = $purchase->AllSold($start, $end);
// Check if any surcharges have already been calculated.
......@@ -1036,6 +1036,10 @@ class Invoice extends Base {
}
$message .= '</table>'."\n";
}
if ($this->Substitute('display-membership-reminder') == 'true' &&
$detail->MembershipReminder($user)) {
$message .= '<p>'.$this->Substitute('invoice-membership-reminder').'</p>';
}
// Lastly format the balance via substitutions for the group.
$message .= $this->FormatInvoiceAfterSold($balance, $credit);
$message .= '</body></html>';
......@@ -1739,7 +1743,7 @@ class Invoice extends Base {
$purchase->Search($username, 0, '', '', '', '', 0, time(), true);
$sold_data = $purchase->Search('', 0, '', $username,
'', '', 0, time(), true);
$payment_data = $payment->Search($username, 0, 0, 0, true, false);
$payment_data = $payment->Search($username);
$total_purchase = 0;
$total_sold = 0;
$total_payments = 0;
......
......@@ -62,42 +62,7 @@ class Organiser extends Base {
}
else if ($action == 'add-member') {
if ($this->user->canEditSite) {
$name = '';
$member = strtolower($mysqli->escape_string($_POST['member']));
// Member groups need to be unique across all organisations.
$query = 'SELECT name FROM organisation WHERE '.
'system_group = "'.$member.'"';
if ($result = $mysqli->query($query)) {
if ($organisation = $result->fetch_assoc()) {
$name = $organisation['name'];
}
}
else {
$this->Log('Organiser->Callback 1: '.$mysqli->error);
}
if ($name !== '') {
$object['error'] = $member.' is already a member of '.$name;
}
else {
// Can't add invite groups to an organisation. (Note that avoiding
// adding invite module as a dependency here because organiser is a
// default module.)
$invite = new Module($this->user, $this->owner, 'invite');
if ($invite->IsInstalled() && $invite->Factory('Exists', $member)) {
$object['error'] = 'Can\'t add an invite group.';
}
else {
$organisation =
strtolower($mysqli->escape_string($_POST['organisation']));
$query = 'INSERT INTO organisation VALUES ("'.$organisation.'", '.
'"'.$member.'")';
if (!$mysqli->query($query)) {
$this->Log('Organiser->Callback 2: '.$mysqli->error);
}
$object['members'] = $this->ShowMembers($organisation);
$object['list'] = $this->ShowOrganisations();
}
}
$object = $this->AddMember();
}
else {
$object['error'] = 'Permission denied adding organisation member.';
......@@ -300,7 +265,7 @@ class Organiser extends Base {
'</div>'.
'<div class="form-spacing">'.
'<label for="organiser-email-to-input">To:</label>'.
'<input id="organiser-email-to-input" type="email" size="50">'.
'<input id="organiser-email-to-input" size="50">'.
'</div>'.
'<div class="form-spacing">'.
'<label for="organiser-email-subject-input">Subject:</label>'.
......@@ -511,7 +476,7 @@ class Organiser extends Base {
return $filtered;
}
public function MatchUser($user) {
public function MatchUser($user, $invite_groups = false) {
$match = false;
$mysqli = connect_db();
$query = 'SELECT user FROM users WHERE user = "'.$user.'" '.
......@@ -521,7 +486,20 @@ class Organiser extends Base {
$result->close();
}
else {
$this->Log('Organiser->MatchUser: '.$mysqli->error);
$this->Log('Organiser->MatchUser 1: '.$mysqli->error);
}
// If not a match, check if invite_groups array was provided.
if (!$match && $invite_groups) {
$query = 'SELECT system_group FROM users WHERE user = "'.$user.'"';
if ($result = $mysqli->query($query)) {
if ($users = $result->fetch_assoc()) {
$match = in_array($users['system_group'], $invite_groups);
}
$result->close();
}
else {
$this->Log('Organiser->MatchUser 2: '.$mysqli->error);
}
}
$mysqli->close();
return $match;
......@@ -607,6 +585,68 @@ class Organiser extends Base {
// Private functions below here ////////////////////////////////////////////
private function AddMember() {
$mysqli = connect_db();
$name = '';
$member = strtolower($mysqli->escape_string($_POST['member']));
// Member groups need to be unique across all organisations.
$query = 'SELECT name FROM organisation WHERE '.
'system_group = "'.$member.'"';
if ($result = $mysqli->query($query)) {
if ($organisation = $result->fetch_assoc()) {
$name = $organisation['name'];
}
}
else {
$this->Log('Organiser->AddMember 1: '.$mysqli->error);
}
if ($name !== '') {
$mysqli->close();
return array('error' => $member.' is already a member of '.$name);
}
$name = '';
// Member groups can't have the same name as an organisation either.
$query = 'SELECT name FROM organisation WHERE name = "'.$member.'"';
if ($result = $mysqli->query($query)) {
if ($organisation = $result->fetch_assoc()) {
$name = $organisation['name'];
}
}
else {
$this->Log('Organiser->AddMember 2: '.$mysqli->error);
}
if ($name !== '') {
$mysqli->close();
return array('error' => $member.' is the name of an organisation.');
}
// Can't add invite groups to an organisation. (Note that avoiding
// adding invite module as a dependency here because organiser is a
// default module.)
$invite = new Module($this->user, $this->owner, 'invite');
if ($invite->IsInstalled() && $invite->Factory('Exists', $member)) {
$mysqli->close();
return array('error' => 'Can\'t add an invite group.');
}
$organisation = strtolower($mysqli->escape_string($_POST['organisation']));
if ($organisation == $member) {
$mysqli->close();
return array('error' => 'Organisation and member group can\'t have '.
'the same name.');
}
$query = 'INSERT INTO organisation VALUES ("'.$organisation.'", '.
'"'.$member.'")';
if (!$mysqli->query($query)) {
$this->Log('Organiser->AddMember 3: '.$mysqli->error);
}
$mysqli->close();
return array('members' => $this->ShowMembers($organisation),
'list' => $this->ShowOrganisations());
}
private function ShowContacts($organisation) {
$content = '';
$server_name = $this->user->config->ServerName();
......@@ -641,15 +681,17 @@ class Organiser extends Base {
return $content;
}
private function ShowUsers($group, $array = true) {
private function ShowUsers($group = '', $array = true) {
$user_list = $array ? array() : '';
$mysqli = connect_db();
$query = '';
if ($group != '') {
$query = 'SELECT user, email FROM users WHERE system_group="'.$group.'"';
$query = 'SELECT user, email FROM users WHERE active = 1 AND '.
'system_group = "'.$group.'"';
}
else {
$query = 'SELECT user, email FROM users WHERE '.$this->GroupQuery();
$query = 'SELECT user, email FROM users WHERE active = 1 AND '.
$this->GroupQuery();
}
if ($result = $mysqli->query($query)) {
while ($users = $result->fetch_assoc()) {
......
......@@ -42,8 +42,8 @@ class Payment extends Base {
$group = (bool)$mysqli->escape_string($_POST["group"]);
$exportData = (bool)$mysqli->escape_string($_POST["exportData"]);
$mysqli->close();
return $this->Search($username, $timestamp, $start, $end,
$group, $exportData);
return $this->Search($username, $timestamp, $start, $end, $group,
$exportData);
}
if ($action == "details") {
$banking = new Banking($this->user, $this->owner);
......@@ -548,8 +548,8 @@ class Payment extends Base {
$mysqli->close();
}
public function Search($username, $timestamp,
$start, $end, $group, $exportData) {
public function Search($username, $timestamp = 0, $start = 0,
$end = 0, $group = true, $exportData = false) {
$mysqli = connect_db();
$object = array("search" => array());
$search = "";
......@@ -645,6 +645,34 @@ class Payment extends Base {
return $object;
}
public function SearchTotal($start, $end, $organisation) {
$total = 0;
$group_query = '';
if ($organisation) {
$organiser = new Organiser($this->user, $this->owner);
$group_query = $organiser->GroupQuery();
}
else {
$group_query = 'users.system_group = "'.$this->user->group.'"';
}
$mysqli = connect_db();
$query = 'SELECT SUM(amount) AS total FROM payments LEFT JOIN users '.
'ON payments.user = users.user WHERE '.$group_query.' AND '.
'timestamp >= '.$start.' AND timestamp <= '.$end;
if ($result = $mysqli->query($query)) {
if ($payments = $result->fetch_assoc()) {
$total = (float)$payments['total'];
}
$result->close();
}
else {
$this->Log('Payment->SearchTotal: '.$mysqli->error);
}
$mysqli->close();
return $total;
}
public function Surcharge($purchases) {
if ($purchases == 0) return 0;
......
This diff is collapsed.
This diff is collapsed.
......@@ -604,6 +604,37 @@ class Stock extends Base {
return $object;
}
public function AllTaxable() {
$object = array();
$organiser = new Organiser($this->user, $this->owner);