has('report_access_codes', ["AND" => ['code' => $VARS['code'], 'expires[>]' => $date]])) { dieifnotloggedin(); $requester = $_SESSION['uid']; } else { $requester = $database->get('report_access_codes', 'uid', ['code' => $VARS['code']]); } } else { dieifnotloggedin(); $requester = $_SESSION['uid']; } if (account_has_permission($_SESSION['username'], "ADMIN")) { $allowed_users = true; } else { if (account_has_permission($_SESSION['username'], "QWIKCLOCK_MANAGE")) { $allowed_users = getManagedUIDs($requester); } if (account_has_permission($_SESSION['username'], "QWIKCLOCK_EDITSELF")) { $allowed_users[] = $_SESSION['uid']; } } // Delete old DB entries $database->delete('report_access_codes', ['expires[<=]' => $date]); if (LOADED) { $user = null; if (isset($VARS['type']) && isset($VARS['format'])) { generateReport($VARS['type'], $VARS['format'], $VARS['register'], $VARS['startdate'], $VARS['enddate']); die(); } else { lang("invalid parameters"); die(); } } function getCashFlowReport($register = null, $start = null, $end = null) { global $database; $where = []; if (!is_null($register) && $database->has('registers', ['registerid' => $register])) { $where["registers.registerid"] = $register; } if ((bool) strtotime($start) == TRUE) { $where["OR #open"] = [ "open[>=]" => date("Y-m-d", strtotime($start)), "close[>=]" => date("Y-m-d", strtotime($start)) ]; } if ((bool) strtotime($end) == TRUE) { // Make the date be the end of the day, not the start $where["close[<=]"] = date("Y-m-d", strtotime($end)) . " 23:59:59"; } if (count($where) > 1) { $where = ["AND" => $where]; } $cash = $database->select( "cash_drawer", [ '[>]registers' => ['cash_drawer.registerid' => 'registerid'], '[>]transactions' => ['cash_drawer.cashid' => 'cashid'], '[>]payments' => ['transactions.txid' => 'txid'], '[>]payment_types' => ['payments.type' => 'typeid'] ], [ "cash_drawer.cashid", "registers.registername", "cash_drawer.registerid", "open", "close", "payments.type", "payments.amount", "payment_types.typename" ], $where ); $header = [lang("register", false), lang("open", false), lang("close", false), lang("cash", false), lang("card", false), lang("check", false), lang("crypto", false), lang("gift card", false), lang("free", false)]; $out = [$header]; $registers = []; foreach ($cash as $c) { $registers[$c['registerid']]['name'] = $c['registername']; $registers[$c['registerid']]['id'] = $c['registerid']; $registers[$c['registerid']]['open'] = date(DATETIME_FORMAT, strtotime($c['open'])); if (is_null($c['close'])) { $registers[$c['registerid']]['close'] = date(DATETIME_FORMAT); } else { $registers[$c['registerid']]['close'] = date(DATETIME_FORMAT, strtotime($c['close'])); } if (!isset($registers[$c['registerid']][$c['typename']])) { $registers[$c['registerid']][$c['typename']] = 0.0; } $registers[$c['registerid']][$c['typename']] += $c['amount']; } foreach ($registers as $r) { $types = $database->select('payment_types', 'typename'); foreach ($types as $t) { if (!isset($r[$t])) { $r[$t] = 0.0; } } $out[] = [ $r['name'], $r['open'], $r['close'], $r['cash'] . "", $r['card'] . "", $r['check'] . "", $r['crypto'] . "", $r['giftcard'] . "", $r['free'] . "" ]; } return $out; } function getReportData($type, $register = null, $start = null, $end = null) { switch ($type) { case "cashflow": return getCashFlowReport($register, $start, $end); default: return [["error"]]; } } function dataToCSV($data, $name = "report", $register = null, $start = null, $end = null) { $csv = Writer::createFromString(''); $usernotice = ""; $usertitle = ""; $datetitle = ""; if ($start != null && (bool) strtotime($start)) { $datenotice = lang2("report filtered to start date", ["date" => date(DATE_FORMAT, strtotime($start))], false); $datetitle = "_" . date(DATE_FORMAT, strtotime($start)); $csv->insertOne([$datenotice]); } if ($end != null && (bool) strtotime($end)) { $datenotice = lang2("report filtered to end date", ["date" => date(DATE_FORMAT, strtotime($end))], false); $datetitle .= ($datetitle == "" ? "_" : "-") . date(DATE_FORMAT, strtotime($end)); $csv->insertOne([$datenotice]); } $csv->insertAll($data); header('Content-type: text/csv'); header('Content-Disposition: attachment; filename="' . $name . $usertitle . $datetitle . "_" . date("Y-m-d_Hi") . ".csv" . '"'); echo $csv; die(); } function dataToODS($data, $name = "report", $register = null, $start = null, $end = null) { $ods = new ods(); $styleColumn = new odsStyleTableColumn(); $styleColumn->setUseOptimalColumnWidth(true); $headerstyle = new odsStyleTableCell(); $headerstyle->setFontWeight("bold"); $table = new odsTable($name); for ($i = 0; $i < count($data[0]); $i++) { $table->addTableColumn(new odsTableColumn($styleColumn)); } $usernotice = ""; $usertitle = ""; $datetitle = ""; if ($user != null && array_key_exists('username', $user) && array_key_exists('name', $user)) { $usernotice = lang2("report filtered to user", ["name" => $user['name'], "username" => $user['username']], false); $usertitle = "_" . $user['username']; $row = new odsTableRow(); $row->addCell(new odsTableCellString($usernotice)); $table->addRow($row); } if ($start != null && (bool) strtotime($start)) { $datenotice = lang2("report filtered to start date", ["date" => date(DATE_FORMAT, strtotime($start))], false); $datetitle = "_" . date(DATE_FORMAT, strtotime($start)); $row = new odsTableRow(); $row->addCell(new odsTableCellString($datenotice)); $table->addRow($row); } if ($end != null && (bool) strtotime($end)) { $datenotice = lang2("report filtered to end date", ["date" => date(DATE_FORMAT, strtotime($end))], false); $datetitle .= ($datetitle == "" ? "_" : "-") . date(DATE_FORMAT, strtotime($end)); $row = new odsTableRow(); $row->addCell(new odsTableCellString($datenotice)); $table->addRow($row); } $rowid = 0; foreach ($data as $datarow) { $row = new odsTableRow(); foreach ($datarow as $cell) { if ($rowid == 0) { $row->addCell(new odsTableCellString($cell, $headerstyle)); } else { $row->addCell(new odsTableCellString($cell)); } } $table->addRow($row); $rowid++; } $ods->addTable($table); $ods->downloadOdsFile($name . $usertitle . $datetitle . "_" . date("Y-m-d_Hi") . ".ods"); } function dataToHTML($data, $name = "report", $register = null, $start = null, $end = null) { global $SECURE_NONCE; // HTML exporter doesn't like null values for ($i = 0; $i < count($data); $i++) { for ($j = 0; $j < count($data[$i]); $j++) { if (is_null($data[$i][$j])) { $data[$i][$j] = ''; } } } $datenotice = ""; $datetitle = ""; if ($start != null && (bool) strtotime($start)) { $datenotice = "" . lang2("report filtered to start date", ["date" => date(DATE_FORMAT, strtotime($start))], false) . "
"; $datetitle = "_" . date(DATE_FORMAT, strtotime($start)); } if ($end != null && (bool) strtotime($end)) { $datenotice .= "" . lang2("report filtered to end date", ["date" => date(DATE_FORMAT, strtotime($end))], false) . "
"; $datetitle .= ($datetitle == "" ? "_" : "-") . date(DATE_FORMAT, strtotime($end)); } header('Content-type: text/html'); $converter = new HTMLConverter(); $out = "\n" . "\n" . "\n" . "" . $name . $datetitle . "_" . date("Y-m-d_Hi") . "\n" . << STYLE . $datenotice . $converter->convert($data); echo $out; } function generateReport($type, $format, $register = null, $start = null, $end = null, $deleted = true) { $data = getReportData($type, $register, $start, $end, $deleted); switch ($format) { case "ods": dataToODS($data, $type, $register, $start, $end); break; case "html": dataToHTML($data, $type, $register, $start, $end); break; case "csv": default: echo dataToCSV($data, $type, $register, $start, $end); break; } }