CORE-POS/IS4C

View on GitHub
fannie/admin/LookupReceipt/ReprintReceiptPage.php

Summary

Maintainability
D
1 day
Test Coverage
F
50%
<?php
/*******************************************************************************

    Copyright 2009 Whole Foods Co-op

    This file is part of CORE-POS.

    CORE-POS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    CORE-POS is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    in the file license.txt along with IT CORE; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*********************************************************************************/

include(dirname(__FILE__) . '/../../config.php');
if (!class_exists('FannieAPI')) {
    include_once(__DIR__ . '/../../classlib2.0/FannieAPI.php');
}

class ReprintReceiptPage extends \COREPOS\Fannie\API\FannieReadOnlyPage 
{

    protected $title = 'Fannie :: Lookup Receipt';
    protected $header = 'Receipt Search - Fill in any information available';

    public $description  = '[Lookup Receipt] finds a POS transaction.';
    private $results = '';

    public function preprocess()
    {
        $this->addRoute('get<date>');
        return parent::preprocess();
    }

    function get_date_handler()
    {
        $date = $this->date;
        $date2 = FormLib::get('date2','');
        if ($date === '' && $date2 !== '') {
            // only one date is supplied and it's
            // via the secondary field, still use it
            $date = $date2;
        }
        $trans_num = FormLib::get('trans_num','');
        if (substr($trans_num, 0, 2) == 'CP' && is_numeric(substr($trans_num, 2))) {
            $pos = 2;
            $year = '20' . substr($trans_num, $pos, 2);
            $pos += 2;
            $month = substr($trans_num, $pos, 2);
            $pos += 2;
            $day = substr($trans_num, $pos, 2);
            $pos += 2;
            $emp = substr($trans_num, $pos, 5);
            $pos += 5;
            $reg = substr($trans_num, $pos, 3);
            $pos += 3;
            $trn = substr($trans_num, $pos, 4);
            $date = $year . '-' . $month . '-' . $day;
            $trans_num = ltrim($emp, '0') . '-' . ltrim($reg, '0') . '-' . ltrim($trn, '0');
        }
        $card_no = FormLib::get('card_no','');
        $emp_no = FormLib::get('emp_no','');
        $register_no = FormLib::get('register_no','');
        $trans_subtype = FormLib::get('trans_subtype','');
        $tenderTotal = FormLib::get('tenderTotal','');
        $department = FormLib::get('department','');
        $trans_no="";

        if ($trans_num !== "") {
            $temp = explode("-",$trans_num);
            if (count($temp) !== 3) {
                $emp_no=$reg_no=$trans_no=0;
            } else {
                $emp_no = $temp[0];
                $register_no=$temp[1];
                $trans_no=$temp[2];
            }
        }

        $dbc = $this->connection;
        $dbc->selectDB($this->config->get('OP_DB'));
        $dlog = $this->config->get('TRANS_DB') . $dbc->sep() . "transarchive";
        $query = "SELECT 
            year(datetime) AS year,
            month(datetime) AS month,
            day(datetime) AS day,
            emp_no,
            register_no,
            trans_no,
            MAX(card_no) AS card_no,
            MAX(datetime) AS ts
        FROM $dlog WHERE 1=1 ";
        $args = array();
        if ($date != "") {
            $date2 = ($date2 != "") ? $date2 : $date;
            $query .= ' AND datetime BETWEEN ? AND ? ';
            $args[] = $date.' 00:00:00';
            $args[] = $date2.' 23:59:59';
            $dlog = DTransactionsModel::selectDTrans($date, $date2);
            // update the table we're searching
            $query = str_replace($this->config->get('TRANS_DB') . $dbc->sep() . 'transarchive', $dlog, $query);
        } else {
            $query .= ' AND datetime >= ? ';
            $args[] = date('Y-m-d 00:00:00', strtotime('-15 days'));
        }
        if ($card_no != "") {
            $query .= " AND card_no=? ";
            $args[] = $card_no;
        }
        if ($emp_no != "") {
            $query .= " AND emp_no=? ";
            $args[] = $emp_no;
        }
        if ($register_no != "") {
            $query .= " AND register_no=? ";
            $args[] = $register_no;
        }
        if ($trans_no != "") {
            $query .= " AND trans_no=? ";
            $args[] = $trans_no;
        }
        if (FormLib::get('no-training') == '1') {
            $query .= ' AND emp_no <> 9999 AND register_no <> 99 ';
        }
        if (FormLib::get('no-canceled') == '1') {
            $query .= ' AND trans_status <> \'X\' ';
        }

        $tender_clause = "( 1=1";
        if ($trans_subtype != "") {
            $tender_clause .= " AND trans_subtype=? ";
            $args[] = $trans_subtype;
        }
        if ($tenderTotal != "") {
            $tender_clause .= " AND total=-1*? ";
            $args[] = $tenderTotal;
        } else {
            $tender_clause .= ' AND total <> 0 ';
        }
        $tender_clause .= ")";

        /**
          There is no tender restriction
          replace with a not-true statements
          otherwise the OR will match everything
        */
        if ($tender_clause == '( 1=1 AND total <> 0 )') {
            $tender_clause = '1=0';
        }

        $or_clause = '(' . $tender_clause;
        if ($department != "") {
            $or_clause .= " OR (department=? AND trans_type IN ('I','D')) ";
            $args[] = $department;
        }

        if (FormLib::get('is_refund', 0) == 1) {
            $or_clause .= ' OR trans_status=\'R\' ';
        }
        if (FormLib::get('mem_discount', 0) == 1) {
            $or_clause .= ' OR upc=\'DISCOUNT\' ';
        }

        $or_clause .= ")";
        if ($or_clause == "(1=0)") {
            $or_clause = "1=1";
        }
        $query .= ' AND '.$or_clause;

        $query .= " GROUP BY year(datetime),month(datetime),day(datetime),emp_no,register_no,trans_no ";
        $query .= " ORDER BY year(datetime),month(datetime),day(datetime),emp_no,register_no,trans_no ";

        $prep = $dbc->prepare($query);
        $result = $dbc->execute($prep,$args);
        if (!empty($trans_num) && !empty($date)) {
            header("Location: RenderReceiptPage.php?date=$date&receipt=$trans_num");
            return false;
        } elseif ($dbc->numRows($result) == 0) {
            $this->results = "<b>No receipts match the given criteria</b>";
        } elseif ($dbc->numRows($result) == 1){
            $row = $dbc->fetchRow($result);
            $trans_num = $row[3].'-'.$row[4].'-'.$row[5];
            header("Location: RenderReceiptPage.php?year={$row['year']}&month={$row['month']}&day={$row['day']}&receipt=$trans_num");
            return false;
        } else {
            $this->results = $this->toTable($dbc, $result, $dlog);
        }

        return true;
    }

    private function toTable($dbc, $result, $dlog)
    {
        $this->addScript('../../src/javascript/tablesorter/jquery.tablesorter.js');
        $this->addOnloadCommand("\$('.tablesorter').tablesorter();\n");
        $ret = "<b>Matching receipts</b>:<br />";
        $ret .= '<table class="table tablesorter">
                <thead>
                    <tr>
                        <th>Date</th>
                        <th>Receipt</th>
                        <th>Employee</th>
                        <th>Lane</th>
                        <th>Owner</th>
                        <th>Subtotal</th>
                    </tr>
                </thead>
                <tbody>';
        $subTotalP = $dbc->prepare("
            SELECT SUM(-total) AS subtotal
            FROM {$dlog} AS d
            WHERE datetime BETWEEN ? AND ?
                AND trans_type='T'
                AND department = 0
                AND emp_no=?
                AND register_no=?
                AND trans_no=?
        ");
        $num_results = $dbc->numRows($result);
        while ($row = $dbc->fetchRow($result)) {
            $ret .= '<tr>';
            $ret .= '<td>' . $row['ts'] . '</td>';
            $trans_num = $row[3].'-'.$row[4].'-'.$row[5];
            $ret .= "<td><a href=\"RenderReceiptPage.php?year={$row['year']}&month={$row['month']}&day={$row['day']}&receipt=$trans_num\">";
            $ret .= "$trans_num</a></td>";
            $ret .= '<td>' . $row['emp_no'] . '</td>';
            $ret .= '<td>' . $row['register_no'] . '</td>';
            $ret .= '<td>' . $row['card_no'] . '</td>';
            if ($num_results < 50) {
                $subTotalArgs = array(
                    date('Y-m-d 00:00:00', strtotime($row['ts'])),
                    date('Y-m-d 23:59:59', strtotime($row['ts'])),
                    $row['emp_no'],
                    $row['register_no'],
                    $row['trans_no'],
                );
                $subTotal = $dbc->getValue($subTotalP, $subTotalArgs);
                $ret .= sprintf('<td>%.2f</td>', $subTotal);
            } else {
                $ret .= '<td>n/a</td>';
            }
            $ret .= '</tr>';
        }
        $ret .= '</tbody></table>';

        return $ret;
    }

    function css_content()
    {
        return '
        #mytable th {
            background: #330066;
            color: white;
            padding-left: 4px;
            padding-right: 4px;
        }
        .tablesorter thead th {
            cursor: hand;
            cursor: pointer;
        }
        .ui-datepicker {
            z-index: 100 !important;
        }
        ';
    }

    function get_date_view()
    {
        if (!empty($this->results)) {
            $str = filter_input(INPUT_SERVER, 'QUERY_STRING');
            $json = FormLib::queryStringToJSON($str);
            $this->results .= '
                <p>
                    <button type="button" class="btn btn-default"
                        onclick="location=\'ReprintReceiptPage.php\';">New Search</button>
                    <a href="?json=' . base64_encode($json) . '" class="btn btn-default btn-reset">
                        Adjust Search</a>
                </p>';
            return $this->results;
        } else {
            return $this->get_view();
        }
    }

    function get_view()
    {
        $dbc = $this->connection;
        $depts = "<option value=\"\">Select one...</option>";
        $res = $dbc->query("SELECT dept_no,dept_name from " . FannieDB::fqn('departments', 'op') . " order by dept_name");
        while ($row = $dbc->fetchRow($res)) {
            $depts .= sprintf("<option value=%d>%s</option>",$row[0],$row[1]);
        }
        $numsR = $dbc->query("SELECT TenderCode,TenderName FROM " . FannieDB::fqn('tenders', 'op') . " ORDER BY TenderName");
        $tenders = '';
        while ($numsW = $dbc->fetchRow($numsR)) {
            $tenders .= sprintf("<option value=%s>%s</option>",$numsW[0],$numsW[1]); 
        }
        if (FormLib::get('json') !== '') {
            $init = FormLib::fieldJSONtoJavascript(base64_decode(FormLib::get('json')));
            $this->addOnloadCommand($init);
        }

        return include(__DIR__ . '/lookup.template.html');
    }

    public function helpContent()
    {
        return '<p>Find a receipt from a previous transaction. All fields are theoretically optional
            but that will give a very long list of transactions. Fill in a couple values to narrow
            down the list.</p>
            <ul>
                <li>If no date is given, all matching receipts from the past 15 days will be returned</li>
                <li>A date and a receipt number is sufficient to find any receipt</li>
                <li>If you have a receipt number, you don\'t need to specify a lane or cashier number</li>
                <li>ALL fields are optional. You can specify a tender type without an amount (or vice versa)</li>
            </ul>';
    }

    public function unitTest($phpunit)
    {
        $phpunit->assertNotEquals(0, strlen($this->get_view()));
        $phpunit->assertNotEquals(0, strlen($this->css_content()));
        $phpunit->assertNotEquals(0, strlen($this->get_date_view()));
        $this->date = date('Y-m-d');
        $phpunit->assertEquals(true, $this->preprocess());
        $phpunit->assertInternalType('boolean', $this->get_date_handler());
        // other code path after handler runs
        $phpunit->assertNotEquals(0, strlen($this->get_date_view()));
    }
}

FannieDispatch::conditionalExec();