<?php
class GetNumber
{
    private $applicationCode, $customerCode, $time, $prefix, $rule;
	
	public function __construct($applicationCode = '', $customerCode = '', $prefix = 'E', $rule=1, $isFullYear=false)
    {
        $this->prefix = $prefix;
        $this->time = $this->timeSlice($isFullYear);
        $this->customerCode = $customerCode;
        $this->applicationCode = $applicationCode;
        $this->rule = $rule;
    }
    
    public function getCode()
    {
        $string = $this->rule ? $this->customerCode : str_pad(rand(0, 9999), 4, '0', STR_PAD_LEFT);
        return strtoupper($this->prefix . $string . $this->time . $this->getSequence());
    }
    
    public function getOnlyCode() {
        return strtoupper($this->prefix . date('y') . sprintf('%07s', $this->getSerialNumber()));
    }

    public function getOnlyNumberCode($length) {
    	return strtoupper($this->prefix . sprintf("%0{$length}s", $this->getSerialNumber()));
    }

    private function getOrderCnt()
    {
        $condition = array(
            'application_code' => $this->applicationCode,
        );
        if ($this->customerCode != '') {
            $condition['customer_code'] = $this->customerCode;
        }
        $application = Service_Application::getByCondition($condition, '*');
        $date = date('Ymd');
        $time = date('Y-m-d H:i:s');
        if (empty($application)) {
            $row = array(
                'application_code' => $this->applicationCode,
                'current_number' => $date . '-1',
                'app_add_time' => $time,
                'customer_code' => $this->customerCode,
            );
            Service_Application::add($row);
            return '1';
        } else {
            if (!empty($application[0]['current_number']) && isset($application[0]['current_number'])) {
                $arr = explode('-', $application[0]['current_number']);
                if ($date == $arr[0]) {
                    $count = $arr[1] + 1;
                } else {
                    $count = 1;
                }
            } else {
                $count = 1;
            }
            $update = array('current_number' => $date . '-' . $count, 'app_update_time' => $time);
            Service_Application::update($update, $application[0]['application_id']);
        }
        return $count;
    }
    
    private function getSerialNumber() {
    	$serialNumber = '1';
    	$application = Service_Application::getByField($this->applicationCode, 'application_code');
    	$time = date('Y-m-d H:i:s');
    	if (empty($application)) {
    		$row = array(
    				'application_code' => $this->applicationCode,
    				'current_number' => $serialNumber,
    				'app_add_time' => $time
    		);
    		Service_Application::add($row);
    	} else {
    		$application = Service_Application::getForUpdate($application['application_id']);
    		$serialNumber = $application['current_number'] + 1;
    		$update = array('current_number' => $serialNumber, 'app_update_time' => $time);
    		Service_Application::update($update, $application['application_id']);
    	}
    	return $serialNumber;
    }

    private function getSequence()
    {
        return sprintf('%04s', $this->getOrderCnt());
    }

    public function timeSlice($isFullYear)
    {
    	if($isFullYear === false) return date('ymd');
    	else return date('Ymd');
    }


}

class Common_GetNumbers
{
    /**
     * @param string $applicationCode
     * @param string $customerCode/跟客户无关就传$warehouseId
     * @param string $prefix
     * @param string $rule 1:单号带客户代码 0:四位随机
     * @return string
     */
    public static function getCode($applicationCode = '', $customerCode = '', $prefix = 'DO', $rule = 1, $isFullYear=false)
    {
        $obj = new GetNumber($applicationCode, $customerCode, $prefix, $rule, $isFullYear);
        return $obj->getCode();
    }
    
    public static function getOnlyCode($applicationCode, $prefix)
    {
        $obj = new GetNumber($applicationCode, '', $prefix, false);
        return $obj->getOnlyCode();
    }

    public static function getOnlyNumberCode($applicationCode, $prefix ,$length)
    {
    	$obj = new GetNumber($applicationCode, '', $prefix, false);
    	return $obj->getOnlyNumberCode($length);
    }
}