CORE-POS/IS4C

View on GitHub
fannie/modules/plugins2.0/CoreWarehouse/reports/CWMemberProfile.php

Summary

Maintainability
C
1 day
Test Coverage
<?php

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

class CWMemberProfile extends FannieRESTfulPage
{
    public $description = '[Shopper Profile] lists information about purchase history.
        Requires CoreWarehouse plugin.';
    protected $header = 'Shopper Profile';
    protected $title = 'Shopper Profile';

    protected function post_id_view()
    {
        return $this->get_id_view();
    }

    protected function get_id_view()
    {
        $doAvg = FormLib::get('doAvg', 1);
        $doTop = FormLib::get('doTop', 1);
        $ids = is_array($this->id) ? $this->id : explode("\n", $this->id);
        $ids = array_map('trim', $ids);
        $ids = array_filter($ids, 'is_numeric');
        list($inStr, $args) = $this->connection->safeInClause($ids);

        $maxP = $this->connection->prepare('SELECT MAX(yearTotalSpendingRank)
            FROM ' . FannieDB::fqn('MemberSummary', 'plugin:WarehouseDatabase') . '
            WHERE yearTotalSpending > 0');
        $max = $this->connection->getValue($maxP);
        $top25 = array();
        $allP = $this->connection->prepare('SELECT d.card_no
            FROM ' . FannieDB::fqn('MemberSummary', 'plugin:WarehouseDatabase') . ' AS d
                LEFT JOIN ' . FannieDB::fqn('custdata', 'op') . ' AS c ON d.card_no=c.CardNo AND c.personNum=1
            WHERE c.Type=\'PC\'
                AND d.yearTotalSpendingRank <= ?');
        $max = (int)($max*.25);
        $allR = $this->connection->execute($allP, array($max));
        while ($allW = $this->connection->fetchRow($allR)) {
            $top25[] = $allW['card_no'];
        }

        $endts = strtotime('last month');
        $startts = mktime(0, 0, 0, date('n', $endts)-11, 1, date('Y', $endts));
        $data = array();
        $prep = $this->connection->prepare('
            SELECT COUNT(DISTINCT card_no) AS shoppers,
                SUM(retailTotal) AS ttl,
                SUM(transCount) AS visits
            FROM ' . FannieDB::fqn('sumMemSalesByDay', 'plugin:WarehouseDatabase') . '
            WHERE date_id BETWEEN ? AND ?
                AND card_no IN (' . $inStr . ')');
        $avgQ = 'SELECT COUNT(DISTINCT card_no) AS shoppers,
                SUM(retailTotal) AS ttl,
                SUM(transCount) AS visits
            FROM ' . FannieDB::fqn('sumMemSalesByDay', 'plugin:WarehouseDatabase') . ' AS d
                LEFT JOIN ' . FannieDB::fqn('custdata', 'op') . ' AS c ON d.card_no=c.CardNo and c.personNum=1
            WHERE date_id BETWEEN ? AND ?
                AND c.Type=\'PC\'';
        $avgP = $this->connection->prepare($avgQ);
        list($in25, $args25) = $this->connection->safeInClause($top25);
        $topP = $this->connection->prepare('
            SELECT COUNT(DISTINCT card_no) AS shoppers,
                SUM(retailTotal) AS ttl,
                SUM(transCount) AS visits
            FROM ' . FannieDB::fqn('sumMemSalesByDay', 'plugin:WarehouseDatabase') . '
            WHERE date_id BETWEEN ? AND ?
                AND card_no IN (' . $in25 . ')');
        while ($startts < $endts) {
            $startID = date('Ymd', mktime(0,0,0,date('n',$startts),1,date('Y',$startts)));
            $endID = date('Ymt', mktime(0,0,0,date('n',$startts),1,date('Y',$startts)));
            $key = date('Y-m', $startts);

            $realArgs = $args;
            array_unshift($realArgs, $endID);
            array_unshift($realArgs, $startID);
            $row = $this->connection->getRow($prep, $realArgs);
            $top = array('ttl'=>0, 'visits'=>0, 'shoppers'=>1);
            $data[$key] = array(
                'ttl' => $row['ttl']/$row['shoppers'],
                'visits' => $row['visits']/$row['shoppers'],
                'basket' => $row['ttl'] / $row['visits'],
            );
            if ($doAvg) {
                $avg = $this->connection->getRow($avgP, array($startID, $endID));
                $data[$key]['avgTTL'] = $avg['ttl'] / $avg['shoppers'];
                $data[$key]['avgVisits'] = $avg['visits'] / $avg['shoppers'];
                $data[$key]['avgBasket'] = $avg['ttl'] / $avg['visits'];
            }
            if ($doTop) {
                $realArgs = $args25;
                array_unshift($realArgs, $endID);
                array_unshift($realArgs, $startID);
                $top = $this->connection->getRow($topP, $realArgs);
                $data[$key]['topTTL'] = $top['ttl'] / $top['shoppers'];
                $data[$key]['topVisits'] = $top['visits'] / $top['shoppers'];
                $data[$key]['topBasket'] = $top['ttl'] / $top['visits'];
            }

            $startts = mktime(0, 0, 0, date('n',$startts)+1, 1, date('Y',$startts));
        }

        $ret = '<table class="table table-bordered table-striped">
            <tr><th>Month</th><th>Spending ($)</th><th>Visits</th><th>Avg. Basket</th></tr>';
        foreach ($data as $month => $info) {
            $ret .= sprintf('<tr><th>%s</th><td>%.2f</td><td>%.2f</td><td>%.2f</td></tr>',
                $month, $info['ttl'], $info['visits'], $info['basket']);
        }
        $ret .= '</table>';

        $spend = array_map(function ($i) { return $i['ttl']; }, $data);
        $avgSpend = array_map(function ($i) { return $i['avgTTL']; }, $data);
        $spend25 = array_map(function ($i) { return $i['topTTL']; }, $data);
        $spendJSON = json_encode(array(
            'labels'=>array_keys($spend),
            'values'=>array_values($spend),
            'avg'=>array_values($avgSpend),
            'top'=>array_values($spend25),
        ));
        $visit = array_map(function ($i) { return $i['visits']; }, $data);
        $avgVisit = array_map(function ($i) { return $i['avgVisits']; }, $data);
        $topVisit = array_map(function ($i) { return $i['topVisits']; }, $data);
        $visitJSON = json_encode(array(
            'labels'=>array_keys($visit),
            'values'=>array_values($visit),
            'avg'=>array_values($avgVisit),
            'top'=>array_values($topVisit),
        ));
        $basket = array_map(function ($i) { return $i['basket']; }, $data);
        $avgBasket = array_map(function ($i) { return $i['avgBasket']; }, $data);
        $topBasket = array_map(function ($i) { return $i['topBasket']; }, $data);
        $basketJSON = json_encode(array(
            'labels'=>array_keys($basket),
            'values'=>array_values($basket),
            'avg'=>array_values($avgBasket),
            'top'=>array_values($topBasket),
        ));
        $this->addScript('../../../../src/javascript/Chart.min.js');
        $this->addScript('profile.js');
        $this->addOnloadCommand("cwProfile.drawChart({$spendJSON},{$visitJSON},{$basketJSON});");
        $ret .= <<<HTML
<div class="row">
    <div class="col-sm-6"><canvas id="spendCanvas"></canvas></div>
    <div class="col-sm-6"><canvas id="visitCanvas"></canvas></div>
</div>
<div class="row">
    <div class="col-sm-6"><canvas id="basketCanvas"></canvas></div>
</div>
HTML;

        return $ret;
    }

    protected function get_view()
    {
        return <<<HTML
<form method="get" action="CWMemberProfile.php">
    <div class="form-group">
        <label>Shopper #(s)</label>
        <textarea name="id" rows="10" class="form-control"></textarea>
    </div>
    <div class="form-group">
        <label><input type="checkbox" name="doAvg" value="0" /> Omit average owner</label>
    </div>
    <div class="form-group">
        <label><input type="checkbox" name="doTop" value="0" /> Omit top 25% owner</label>
    </div>
    <div class="form-group">
        <button type="submit" class="btn btn-default">Submit</button>
    </div>
</form>
HTML;
    }
}

FannieDispatch::conditionalExec();