CORE-POS/IS4C

View on GitHub
fannie/modules/plugins2.0/CpwInvoiceImport/FileToOrder.php

Summary

Maintainability
B
4 hrs
Test Coverage
<?php

namespace COREPOS\Fannie\Plugin\CpwInvoiceImport;
use COREPOS\Fannie\API\data\FileData;

class FileToOrder
{
    public function read($filename)
    {
        $arr = FileData::fileToArray($filename);
        if (!is_array($arr)) {
            throw new \Exception('Invalid file');
        }
        $log = new \FannieLogger();
        $inv = $this->getHeaderField($arr, 'Invoice');
        $oDate = $this->getHeaderField($arr, 'Order Date');
        $sDate = $this->getHeaderField($arr, 'Ship Date');
        $addr = $this->getShippingAddress($arr);

        $items = $this->getItemLines($arr);
        $log->debug('Line count: ' . count($arr));
        $log->debug('Item count: ' . count($items));
        if (count($items) == 0) {
            throw new \Exception('Order is empty');
        }
        $fixed = array();
        foreach ($items as $i) {
            $fixed[] = $this->normalizeItemLine($i);
        }

        return array(
            'invoiceNo' => $inv,
            'orderDate' => FileData::excelFloatToDate($oDate),
            'shipDate' => FileData::excelFloatToDate($sDate),
            'shipTo' => $addr,
            'items' => $fixed,
        );
    }

    private function getShippingAddress($arr)
    {
        $ret = array();
        for ($i=0; $i<count($arr); $i++) {
            if (stristr($arr[$i][0], 'Ship To')) {
                $i++;
                while ($arr[$i][1] !== null) {
                    $ret[] = $arr[$i][1];
                    $i++;
                }
                break;
            }
        }

        return $ret;
    }

    private function getHeaderField($arr, $name)
    {
        foreach ($arr as $line) {
            if (stristr($line[4], $name)) {
                return $line[6];
            }
        }

        return false;
    }

    private function getItemLines($arr)
    {
        return array_filter($arr, function($i) {
            return (is_numeric($i[7]) && (is_numeric($i[5]) || stristr($i[2], 'charge')));
        });
    }

    private function normalizeItemLine($item)
    {
        list($case, $unit) = $this->parseSize($item[2]);
        $ret = array(
            'description' => $item[2],
            'orderedQty' => $item[0] === null ? 0 : $item[0],
            'shippedQty' => $item[1] === null ? 0 : $item[1],
            'sku' => $item[5] === null ? $item[2] : $item[5],
            'casePrice' => $item[7] / $case,
            'total' => $item[7],
            'caseSize' => $case,
            'unitSize' => $unit,
        );
        //fixup for data oddities
        switch ($ret['sku']) {
            case '9228':
                $ret['caseSize'] = 33;
                $ret['unitSize'] = 'LB';
                break;
        }

        return $ret;
    }

    private function parseSize($item)
    {
        $item = strtoupper($item);
        if (preg_match('/([0-9\.]+)\s*-\s*([0-9\.]+)\s*LB/', $item, $matches)) {
            $avg = ($matches[1] + $matches[2]) / 2;
            return array($avg, 'LB');
        } elseif (preg_match('/([0-9]+)\/([0-9\.]+)\s*LB/', $item, $matches)) {
            return array($matches[1] * $matches[2], 'LB');
        } elseif (preg_match('/([0-9\.]+)\s*LB/', $item, $matches)) {
            return array($matches[1], 'LB');
        } elseif (preg_match('/([0-9\.]+)\s*-\s*([0-9\.]+)\s*CT/', $item, $matches)) {
            $avg = ($matches[1] + $matches[2]) / 2;
            return array($avg, 'CT');
        } elseif (preg_match('/([0-9]+)\s*CT/', $item, $matches)) {
            return array($matches[1], 'CT');
        } elseif (preg_match('/([0-9]+)\s*DOZ/', $item, $matches)) {
            return array($matches[1], 'DOZ');
        } elseif (preg_match('/\s([0-9\.]+)\s*GAL/', $item, $matches)) {
            return array($matches[1], 'GAL');
        } elseif (preg_match('/([0-9]+)\/([0-9\.]+)\s*OZ/', $item, $matches)) {
            return array($matches[1] * $matches[2], 'OZ');
        }

        return array(1, 'CASE');
    }

}