CORE-POS/IS4C

View on GitHub
fannie/modules/plugins2.0/RP/RpForecast.php

Summary

Maintainability
C
7 hrs
Test Coverage
<?php

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

class RpForecast extends FannieRESTfulPage
{
    protected $header = 'Order Forecast';
    protected $title = 'Order Forecast';
    protected $must_authenticate = true;

    protected function get_id_view()
    {
        $parP = $this->connection->prepare("
            SELECT SUM(movement)
            FROM " . FannieDB::fqn('Smoothed', 'plugin:WarehouseDatabase') . "
            WHERE 1=1
                " . ($this->id > 0 ? ' AND storeID=? ' : '') . "
                AND upc=?"); 

        $priceP = $this->connection->prepare("
            SELECT CASE WHEN p.special_price > 0 THEN p.special_price ELSE p.normal_price END AS price
            FROM upcLike AS u
                INNER JOIN products AS p ON p.upc=u.upc
            WHERE u.likeCode=?");

        $prep = $this->connection->prepare("
            SELECT r.upc,
                r.categoryID,
                c.name,
                v.vendorName AS vendorName,
                b.vendorName AS backupVendor,
                r.vendorSKU,
                r.vendorItem,
                r.backupSKU,
                r.backupItem,
                r.caseSize,
                r.vendorID,
                r.backupID,
                r.cost
            FROM RpOrderItems AS r
                LEFT JOIN RpOrderCategories AS c ON r.categoryID=c.rpOrderCategoryID
                LEFT JOIN vendors AS v ON r.vendorID=v.vendorID
                LEFT JOIN vendors AS b ON r.backupID=b.vendorID
            WHERE 
                r.deleted=0
                " . ($this->id > 0 ? ' AND r.storeID=? ' : '') . "
            ORDER BY r.vendorID, c.seq, c.name, r.vendorItem");
        $args = $this->id > 0 ? array($this->id) : array();
        $res = $this->connection->execute($prep, $args);
        $vendorID = false;
        $dailySales = 0;
        $seen = array();
        $ret = '';
        $optStr = '<option value="">Move to...</option>';
        while ($row = $this->connection->fetchRow($res)) {
            if (isset($seen[$row['upc']])) {
                continue;
            }
            $seen[$row['upc']] = true;
            if ($row['vendorID'] != $vendorID) {
                if ($vendorID !== false) {
                    $ret .= '</table>';
                }
                $ret .= '<h3>' . $row['vendorName'] . '</h3>';
                $vendorID = $row['vendorID'];
                $ret .= '<table class="table" id="table' . $vendorID . '">';
                $optStr .= sprintf('<option value="%d">%s</option>',
                    $row['vendorID'], $row['vendorName']);

            }
            $lc = str_replace('LC', '', $row['upc']);
            $parArgs = $this->id > 0 ? array($this->id, $row['upc']) : array($row['upc']);
            $par = $this->connection->getValue($parP, $parArgs);
            if ($row['caseSize'] != 0 && ($par / $row['caseSize']) < 0.1) {
                $par = 0.1 * $row['caseSize'];
            }
            $price = $this->connection->getValue($priceP, array(substr($row['upc'], 2)));
            $ret .= sprintf('<tr><td class="par-cell">%.2f</td><td>%s
                <span class="v-select collapse"><select></select></span></td></tr>',
                $par / $row['caseSize'], $row['vendorItem']);

            $dailySales += ($par * $price);
        }
        $ret .= '</table>';

        $ret .= '<p>Daily Sales: ' . $dailySales . '</p>';

        $dt1 = new DateTime(FormLib::get('date1'));
        $dt2 = new DateTime(FormLib::get('date2'));
        $diff = $dt1->diff($dt2, true);
        $days = $diff->days + 1;

        $ret .= '<p>Period Sales: ' . $dailySales * $days . '</p>';

        $segP = $this->connection->prepare("SELECT SUM(sales)
            FROM RpSegments
            WHERE 1=1
                " . ($this->id > 0 ? ' AND storeID=? ' : '') . "
                AND startDate BETWEEN ? AND ?");
        $segArgs = array();
        if ($this->id > 0) {
            $segArgs[] = $this->id;
        }
        $segArgs[] = $dt1->format('Y-m-d');
        $segArgs[] = $dt2->format('Y-m-d');
        $segSales = $this->connection->getValue($segP, $segArgs);
        $ret .= '<p>Projected Sales: ' . $segSales . '</p>';

        if ($segSales) {
            $adj = $segSales / ($dailySales * $days);
            $ret .= sprintf('<p>Adjustment factor: %.2f%%</p>', $adj * 100);
        }

        $this->addOnloadCommand("scalePars({$days});");
        if (isset($adj) && $adj) {
            $this->addOnloadCommand("scalePars({$adj});");
        }
        $this->addOnloadCommand('roundAll();');
        $this->addOnloadCommand("setupMenus('{$optStr}');");

        return $ret;
    }

    protected function get_view()
    {
        $stores = FormLib::storePicker('id');
        $dates = FormLib::standardDateFields();
        $this->addOnloadCommand("\$('select[name=id]').val(0);");

        return <<<HTML
<form method="get" action="RpForecast.php">
    <div class="col-sm-5">
        <div class="form-group">
            <label>Store</label>
            {$stores['html']}
        </div>
        <div class="form-group">
            <button type="submit" class="btn btn-default">Get Forecast</button>
        </div>
    </div>
    {$dates}
</form>
HTML;
    }

    protected function javascriptContent()
    {
        return <<<SCRIPT
function scalePars(factor) {
    $('td.par-cell').each(function () {
        var cur = $(this).html() * 1;
        cur = Math.round(cur * factor * 100) / 100;
        $(this).html(cur);
    });
}
function roundAll() {
    $('td.par-cell').each(function () {
        var cur = $(this).html() * 1;
        cur = Math.round(cur);
        $(this).html(cur);
    });
}
function setupMenus(optStr) {
    $('span.v-select select').html(optStr);
    $('tr').contextmenu(showMenu);
    $('span.v-select select').change(moveRow);
}
function showMenu(event) {
    event.preventDefault();
    $(event.target).find('span.v-select').toggle();
}
function moveRow(event) {
    var targetID = $(event.target).val(); 
    $(event.target).parent().hide();
    var curTable = $(event.target).closest('table');
    if ('table' + targetID == curTable.attr('id')) {
        return;
    }
    var row = $(event.target).closest('tr').remove().clone();
    row.contextmenu(showMenu);
    row.find('select').change(moveRow);
    $('#table' + targetID).append(row);
}
SCRIPT;
    }
}

FannieDispatch::conditionalExec();