<?php

use App\models\Logistic\Pri\PriPreData;

class Service_IntoArea
{
    const TYPE_TONCAR = 0; // 柜型类型，吨车
    const TYPE_CONTAINER = 1; // 柜型类型，集装箱
    const STATUS_DRAFT = 0; // 入区派车单状态，草稿
    const STATUS_CONFIRMED = 1; // 入区派车单状态，确认
    const ASN_IA_TAG = 0; // 能否用于创建入区派车单的ASN标识
    const ASN_PENDING = 3; // ANS状态，待审核
    const ASN_AUDITED = 4; // ASN状态，已审核

    private static $_intoArea = array();
    private static $_intoAreaDetail = array();
    private static $_asnCode = array();

    /**
     * 能创建入区派车单的ASN状态
     *
     * @return array
     */
    public static function getAllowedAsnStatus()
    {
        return array(
            self::ASN_PENDING,
            self::ASN_AUDITED,
        );
    }

    /**
     * 允许使用的柜型类型
     *
     * @return array
     */
    public static function getAllowedContainerType()
    {
        return array(
            self::TYPE_TONCAR,
            self::TYPE_CONTAINER,
        );
    }

    /**
     * 获取柜型类型
     *
     * @return array
     */
    public static function getContainer()
    {
        return array(
            self::TYPE_TONCAR => '吨车',
            self::TYPE_CONTAINER => '集装箱',
        );
    }

    /**
     * 获取入区派车单状态
     *
     * @return array
     */
    public static function getType()
    {
        return array(
            self::STATUS_DRAFT => '草稿',
            self::STATUS_CONFIRMED => '确认',
        );
    }

    /**
     * 验证接收的数据的有效性
     *
     * @param array $data 需要验证的数据
     * @return mixed         有效返回TRUE，否则返回错误信息数组
     */
    public static function valid($data)
    {
        $user = new Zend_Session_Namespace('userAuthorization');
        $default = array(
            'ia_code' => '',
            'car_number' => '',
            'telephone' => '',
            'container_type' => '',
            'asn_code' => array(),
        );
        $default = array_merge($default, $data);
        $detail = array();
        $error = array();

        if ('' !== $default['ia_code']) {
            $model = Table_IntoArea::getInstance();
            $intoArea = $model->getByCode($default['ia_code']);

            if (empty($intoArea)) {
                $error[] = '入区派车单【' . $default['ia_code'] . '】不存在';
                return $error;
            }

            if (self::STATUS_DRAFT !== (int)$intoArea['status']) {
                $error[] = '入区派车单【' . $default['ia_code'] . '】不是草稿状态';
                return $error;
            }

            self::$_intoArea = $intoArea;
            $intoAreaDetail = self::getDetailByCode($default['ia_code']);

            foreach ($intoAreaDetail as $item) {
                $detail[$item['iad_id']] = $item['receiving_code'];
            }

            self::$_intoAreaDetail = $detail;
        }

        if ('' === $default['car_number']) {
            $error[] = '车牌号不能为空';
        }

        if ('' === $default['telephone']) {
            $error[] = '联系电话不能为空';
        }

        if (!in_array($default['container_type'], self::getAllowedContainerType(), TRUE)) {
            $error[] = '柜型只能为吨车、集装箱';
        }

        $form_type = "";
        foreach ($default['asn_code'] as $code) {
            $asn = Service_Receiving::getByField($code, 'receiving_code');
            if($form_type==''){
                $form_type = $asn['form_type'];
            }
            if($form_type!=$asn['form_type']){
                $error[] = '不同业务类型入库单不能一块派车';
            }
            if (empty($asn)) {
                $error[] = 'ASN单【' . $code . '】不存在';
            } elseif ((int)$user->warehouseId !== (int)$asn['warehouse_id']) {
                $error[] = 'ASN单【' . $code . '】不属于当前仓库';
            } elseif (!in_array((int)$asn['receiving_status'], self::getAllowedAsnStatus(), TRUE)) {
                $error[] = 'ASN单【' . $code . '】状态不是待审核、已审核';
            } elseif (self::ASN_IA_TAG !== (int)$asn['into_area'] && !in_array($code, $detail, TRUE)) {
                $error[] = 'ASN单【' . $code . '】已创建过入区派车单';
            } else {
                self::$_asnCode[$code] = array(
                    'receiving_id' => (int)$asn['receiving_id'],
                    'receiving_code' => $asn['receiving_code'],
                    'customs_form_id' => $asn['refercence_form_id'],
                );
            }
        }

        return empty($error) ? TRUE : $error;
    }

    /**
     * 创建入区派车单
     *
     * @param array $row 入区派车单数据
     * @return mixed        创建成功返回入区派车单单号，否则返回错误信息数组
     */
    public static function create($row)
    {
        $error = array();
        $code = ''; // 入区派车单单号
        $user = new Zend_Session_Namespace('userAuthorization');
        $db = Common_Common::getAdapter();

        $db->beginTransaction(); // 开启事务

        try {
            $valid = self::valid($row); // 验证数据有效性

            if (TRUE !== $valid) {
                throw new Exception(join('；', $valid));
            }

            $code = Common_GetNumbers::getCode('INTO_AREA', '', 'ZHI');
            $intoAreaRow = array(
                'ia_code' => $code,
                'project_name' => 'CSCM-ECOWN',
                'car_number' => $row['car_number'],
                'container_type' => $row['container_type'],
                'telephone' => $row['telephone'],
                'warehouse_id' => (int)$user->warehouseId,
                'status' => self::STATUS_DRAFT,
                'created_time' => date('Y-m-d H:i:s'),
                'creator' => (int)$user->userId,
                'creator_ip' => Common_Common::getIP(),
            );

            if (!($iaId = self::insert($intoAreaRow))) {
                throw new Exception('数据库异常，无法入库into_area');
            }

            foreach (self::$_asnCode as $asn) {
                $intoAreaDetailRow = array(
                    'ia_id' => $iaId,
                    'ia_code' => $code,
                    'receiving_code' => $asn['receiving_code'],
                );

                if (!self::insertDetail($intoAreaDetailRow)) {
                    throw new Exception('数据库异常，无法入库into_area_detail');
                }

                if (!Service_Receiving::update(array('into_area' => 1), $asn['receiving_id'], 'receiving_id')) {
                    throw new Exception('数据库异常，无法更新receiving');
                }
            }

            $db->commit(); // 提交
        } catch (Exception $e) {
            $error[] = $e->getMessage();
            $db->rollBack(); // 异常回滚
        }

        return empty($error) ? $code : $error;
    }

    /**
     * 更新入区派车单
     *
     * @param array $row 入区派车单数据
     * @return mixed        成功返回TRUE，否则返回错误信息
     */
    public static function update($row)
    {
        $code = trim($row['ia_code']);
        $response = TRUE;
        $db = Common_Common::getAdapter();

        $db->beginTransaction(); // 开启事务

        try {
            if ('' === $code) {
                throw new Exception('入区派车单号不能为空');
            }

            $valid = self::valid($row); // 验证数据有效性

            if (TRUE !== $valid) {
                throw new Exception(join('；', $valid));
            }

            foreach (self::$_intoAreaDetail as $key => $val) { // 删除旧数据，释放ASN选择权
                self::deleteDetailById($key);
                Service_Receiving::update(array(
                    'into_area' => 0,
                ), $val, 'receiving_code');
            }

            foreach (self::$_asnCode as $asn) { // 新增详情，冻结选择权
                self::insertDetail(array(
                    'ia_id' => self::$_intoArea['ia_id'],
                    'ia_code' => self::$_intoArea['ia_code'],
                    'receiving_code' => $asn['receiving_code'],
                ));
                Service_Receiving::update(array(
                    'into_area' => 1,
                ), $asn['receiving_code'], 'receiving_code');
            }

            self::updateByCode(array(
                'car_number' => $row['car_number'],
                'telephone' => $row['telephone'],
                'container_type' => $row['container_type'],
                'updated_time' => date('Y-m-d H:i:s'),
            ), $code);

            $db->commit(); // 提交
        } catch (Exception $e) {
            $response = $e->getMessage();
            $db->rollBack(); // 异常回滚
        }

        return $response;
    }

    /**
     * 确认入区派车单
     *
     * @param string $code 入区派车单号
     * @return mixed          成功返回TRUE，否则返回错误信息
     */
    public static function confirm($code, $bg_company)
    {
        $code = trim($code);
        $response = TRUE;
        $db = Common_Common::getAdapter();

        $db->beginTransaction(); // 开启事务

        try {
            if ('' === $code) {
                throw new Exception('入区派车单号不能为空');
            }

            $intoArea = self::getByCode($code);

            if (empty($intoArea)) {
                throw new Exception('入区派车单【' . $code . '】不存在');
            }

            if (self::STATUS_DRAFT !== (int)$intoArea['status']) {
                throw new Exception('入区派车单【' . $code . '】不是草稿状态');
            }

            $intoAreaDetail = self::getDetailByCode($code);

            if (empty($intoAreaDetail)) {
                throw new Exception('入区派车单【' . $code . '】不存在ASN单');
            }
            $preEnter = new PriPreData();
            $params = [
                'ref_no' => $code,
                'ie_flag' => 'I',
                'ie_port' => '',
                'platenumber' => $intoArea['car_number'],
                'bg_company' => $bg_company
            ];
            $preEnter->setCompanyCode($bg_company);
            foreach ($intoAreaDetail as $detail) {
                $preEnter->addReceivingCode($detail['receiving_code']);
                $receivingInfo = $preEnter->getReceivingInfo($detail['receiving_code']);
                $params['ie_port'] = $receivingInfo['ie_port'];
                $params['pt_code'] = $receivingInfo['form_type'];
            }
            $preEnter->setParams($params);
            $preEnter->makePriEnter();
            // 确认的时候，读取receiving_xml表确认ASN单存在性及海关单号
//      foreach ($intoAreaDetail as $detail) {
//        $subAsn = Service_ReceivingXml::getByCondition(array('receiving_code' => $detail['receiving_code']));
//
//        if (empty($subAsn)) {
//          throw new Exception('ASN单【' . $detail['receiving_code'] . '】缺乏必要数据');
//        }
//        else {
//          foreach ($subAsn as $item) {
//            if ('' === trim($item['refercence_form_id'])) {
//              throw new Exception('ASN单【' . $detail['receiving_code'] . '】子单【' . $item['sub_receiving_code'] . '】海关单号为空');
//            }
//          }
//        }
//      }

            // 更新入区派车单状态为确认
            self::updateByCode(array(
                'status' => self::STATUS_CONFIRMED,
                'confirmed_time' => date('Y-m-d H:i:s'),
            ), $code);

            $db->commit(); // 提交
            //$db->rollBack(); // 异常回滚
        } catch (Exception $e) {
            $response = $e->getMessage();
            $db->rollBack(); // 异常回滚
        }

        return $response;
    }

    /**
     * 根据指定条件检索数据
     *
     * @param array $condition 检索条件
     * @param array $option 附件条件
     * @return mixed
     */
    public static function getByCondition($condition, $option = array())
    {
        $model = Table_IntoArea::getInstance();

        return $model->getByCondition($condition, $option);
    }

    /**
     * 根据入区派车单单号检索数据
     *
     * @param array $code 入区派车单单号
     * @return mixed
     */
    public static function getByCode($code)
    {
        $model = Table_IntoArea::getInstance();

        return $model->getByCode($code);
    }

    /**
     * 新增入区派车单
     *
     * @param array $row 入区派车单数据
     * @return integer
     */
    public static function insert($row)
    {
        $model = Table_IntoArea::getInstance();

        return $model->insert($row);
    }

    /**
     * 新增入区派车单详情
     *
     * @param array $row 详情数据
     * @return integer
     */
    public static function insertDetail($row)
    {
        $model = Table_IntoAreaDetail::getInstance();

        return $model->insert($row);
    }

    /**
     * 根据入区派车单单号检索入区派车单ASN数据
     *
     * @param array $code 入区派车单单号
     * @return mixed
     */
    public static function getDetailByCode($code)
    {
        $model = Table_IntoAreaDetail::getInstance();

        return $model->getByParentCode($code);
    }

    /**
     * 根据入区派车单单号更新数据
     *
     * @param array $code 入区派车单单号
     * @return mixed
     */
    public static function updateByCode($data, $code)
    {
        $model = Table_IntoArea::getInstance();

        return $model->updateByCode($data, $code);
    }

    /**
     * 根据入区派车单详情ID更新数据
     *
     * @param array $data 需要更新的字段，键值对
     * @param array $id 入区派车单详情ID
     * @return integer
     */
    public static function updateDetailById($data, $id)
    {
        $model = Table_IntoAreaDetail::getInstance();

        return $model->updateById($data, $id);
    }

    /**
     * 根据入区派车单详情ID删除数据
     *
     * @param array $id 入区派车单详情ID
     * @return integer
     */
    public static function deleteDetailById($id)
    {
        $model = Table_IntoAreaDetail::getInstance();

        return $model->deleteById($id);
    }
}
