/** Lots of options on this report. */ function fetch_report_data() { $dbc = $this->connection; $dbc->selectDB($this->config->get('OP_DB')); $date1 = $this->form->date1; $date2 = $this->form->date2; $deptStart = FormLib::get_form_value('deptStart', ''); $deptEnd = FormLib::get_form_value('deptEnd', ''); $deptMulti = FormLib::get('departments', array()); $buyer = FormLib::get_form_value('buyer', ''); $groupby = FormLib::get_form_value('sort', 'PLU'); $store = FormLib::get('store', 0); $superP = $dbc->prepare('SELECT dept_ID FROM superdepts WHERE superID=?'); /** Build a WHERE condition for later. Superdepartment (buyer) takes precedence over department and negative values have special meaning Extra lookup to write condition in terms of transaction.department seems to result in better index utilization and faster queries */ $filter_condition = 't.department BETWEEN ? AND ?'; $args = array($deptStart, $deptEnd); if (count($deptMulti) > 0) { $filter_condition = 't.department IN ('; $args = array(); foreach ($deptMulti as $d) { $filter_condition .= '?,'; $args[] = $d; } $filter_condition = substr($filter_condition, 0, strlen($filter_condition) - 1) . ')'; } if ($buyer !== "" && $buyer > 0) { $filter_condition .= ' AND s.superID=? '; $args[] = $buyer; /* $superR = $dbc->execute($superP, array($buyer)); $filter_condition = 't.department IN ('; $args = array(); while ($superW = $dbc->fetch_row($superR)) { $filter_condition .= '?,'; $args[] = $superW['dept_ID']; } $filter_condition = substr($filter_condition, 0, strlen($filter_condition)-1) . ')'; $filter_condition .= ' AND s.superID=?'; $args[] = $buyer; */ } else { if ($buyer !== "" && $buyer == -1) { $filter_condition = "1=1"; $args = array(); } else { if ($buyer !== "" && $buyer == -2) { $superR = $dbc->execute($superP, array(0)); $filter_condition = 't.department NOT IN (0,'; $args = array(); while ($superW = $dbc->fetch_row($superR)) { $filter_condition .= '?,'; $args[] = $superW['dept_ID']; } $filter_condition = substr($filter_condition, 0, strlen($filter_condition) - 1) . ')'; $filter_condition .= ' AND s.superID <> 0'; } } } /** * Provide more WHERE conditions to filter irrelevant * transaction records, as a stop-gap until this is * handled more uniformly across the application. */ $filter_transactions = "t.trans_status NOT IN ('D','X','Z')\n AND t.emp_no <> 9999\n AND t.register_no <> 99"; $filter_transactions = DTrans::isValid() . ' AND ' . DTrans::isNotTesting(); /** Select a summary table. For UPC results, per-unique-ring summary is needed. For date/dept/weekday results the per-department summary is fine (and a smaller table) */ $dlog = DTransactionsModel::selectDlog($date1, $date2); /** Build an appropriate query depending on the grouping option */ $query = ""; $superTable = $buyer !== "" && $buyer > 0 ? 'superdepts' : 'MasterSuperDepts'; $args[] = $date1 . ' 00:00:00'; $args[] = $date2 . ' 23:59:59'; $args[] = $store; switch ($groupby) { case 'PLU': $query = "SELECT t.upc,\n CASE WHEN p.description IS NULL THEN t.description ELSE p.description END as description, \n SUM(CASE WHEN trans_status IN('','0','R') THEN 1 WHEN trans_status='V' THEN -1 ELSE 0 END) as rings," . DTrans::sumQuantity('t') . " as qty,\n SUM(t.total) AS total,\n d.dept_no,d.dept_name,s.superID,\n COALESCE(v.vendorName,x.distributor) AS distributor\n FROM {$dlog} as t " . DTrans::joinProducts() . DTrans::joinDepartments() . "LEFT JOIN {$superTable} AS s ON t.department = s.dept_ID\n LEFT JOIN prodExtra as x on t.upc = x.upc\n LEFT JOIN vendors AS v ON p.default_vendor_id=v.vendorID\n WHERE {$filter_condition}\n AND t.trans_type IN ('I', 'D')\n AND tdate BETWEEN ? AND ?\n AND {$filter_transactions}\n AND " . DTrans::isStoreID($store, 't') . "\n GROUP BY t.upc,\n CASE WHEN p.description IS NULL THEN t.description ELSE p.description END,\n CASE WHEN t.trans_status = 'R' THEN 'Refund' ELSE 'Sale' END,\n d.dept_no,d.dept_name,s.superID,distributor ORDER BY SUM(t.total) DESC"; break; case 'Department': $query = "SELECT t.department,d.dept_name," . DTrans::sumQuantity('t') . " as qty,\n SUM(total) as Sales \n FROM {$dlog} as t " . DTrans::joinDepartments() . "LEFT JOIN {$superTable} AS s ON s.dept_ID = t.department \n WHERE {$filter_condition}\n AND tdate BETWEEN ? AND ?\n AND t.trans_type IN ('I', 'D')\n AND {$filter_transactions}\n AND " . DTrans::isStoreID($store, 't') . "\n GROUP BY t.department,d.dept_name ORDER BY SUM(total) DESC"; break; case 'Date': $query = "SELECT year(tdate),month(tdate),day(tdate)," . DTrans::sumQuantity('t') . " as qty,\n SUM(total) as Sales ,\n MAX(" . $dbc->dayofweek('tdate') . ") AS dow\n FROM {$dlog} as t " . DTrans::joinDepartments() . "LEFT JOIN {$superTable} AS s ON s.dept_ID = t.department\n WHERE {$filter_condition}\n AND tdate BETWEEN ? AND ?\n AND t.trans_type IN ('I', 'D')\n AND {$filter_transactions}\n AND " . DTrans::isStoreID($store, 't') . "\n GROUP BY year(tdate),month(tdate),day(tdate) \n ORDER BY year(tdate),month(tdate),day(tdate)"; break; case 'Weekday': $cols = $dbc->dayofweek("tdate") . ",CASE \n WHEN " . $dbc->dayofweek("tdate") . "=1 THEN 'Sun'\n WHEN " . $dbc->dayofweek("tdate") . "=2 THEN 'Mon'\n WHEN " . $dbc->dayofweek("tdate") . "=3 THEN 'Tue'\n WHEN " . $dbc->dayofweek("tdate") . "=4 THEN 'Wed'\n WHEN " . $dbc->dayofweek("tdate") . "=5 THEN 'Thu'\n WHEN " . $dbc->dayofweek("tdate") . "=6 THEN 'Fri'\n WHEN " . $dbc->dayofweek("tdate") . "=7 THEN 'Sat'\n ELSE 'Err' END"; $query = "SELECT {$cols}," . DTrans::sumQuantity('t') . " as qty,\n SUM(total) as Sales \n FROM {$dlog} as t " . DTrans::joinDepartments() . "LEFT JOIN {$superTable} AS s ON s.dept_ID = t.department \n WHERE {$filter_condition}\n AND tdate BETWEEN ? AND ?\n AND t.trans_type IN ('I', 'D')\n AND {$filter_transactions}\n AND " . DTrans::isStoreID($store, 't') . "\n GROUP BY {$cols}\n ORDER BY " . $dbc->dayofweek('tdate'); break; } /** Copy the results into an array. Date requires a special case to combine year, month, and day into a single field */ $prep = $dbc->prepare_statement($query); $result = $dbc->exec_statement($prep, $args); $ret = array(); while ($row = $dbc->fetch_array($result)) { $record = array(); if ($groupby == "Date") { $record[] = $row[1] . "/" . $row[2] . "/" . $row[0]; $record[] = date('l', strtotime($record[0])); $record[] = sprintf('%.2f', $row[3]); $record[] = sprintf('%.2f', $row[4]); } else { for ($i = 0; $i < $dbc->num_fields($result); $i++) { if (preg_match('/^\\d+\\.\\d+$/', $row[$i])) { $row[$i] = sprintf('%.2f', $row[$i]); } $record[] .= $row[$i]; } } $ret[] = $record; } return $ret; }