<?php

namespace Api\Model;
use Think\Model;
use Common\Model\MemberModel;
use Common\Model\OrderGoodsModel;
use Org\Sms;
use Org\Mac;
use Org\Wechat;

/**
 * 订单模型
 */
class OrderModel extends Model{

    protected $_validate = array(
    	array('out_trade_no', 'require', '{%order_num_empty}', self::MUST_VALIDATE , 'regex', self::MODEL_BOTH),
    	array('out_trade_no', '', '{%order_num_exsit}', self::EXISTS_VALIDATE, 'unique'),
    );

    protected $_auto = array(
        array('createtime', NOW_TIME, self::MODEL_INSERT),
    	array('status', '1', self::MODEL_INSERT),
    );


    public function createOrder($data){
    	$data['userid'] = I('userid',0);
    	$data['out_trade_no'] = make_orderSn($data['userid']);
    	$data['total_fee'] = I('total_fee',0);
    	$data['credits'] = I('credits',0);
    	$data['body'] = '';
    	$data['mobile'] = I('mobile','');
    	$goods = I('goods','');

    	if(!$goods){
    		$this->error = L('select_laundry'); //请先选择衣物
    		return false;
    	}
    	$goods = explode('#', $goods);

    	$total_fee = 0;

    	$goods_arr = array();
    	foreach ($goods as $k=>$g){
    		$g_arr = explode(',', $g);
    		$info = M('Goods')->find($g_arr[0]);
    		$goods_arr[$k]['id'] = $g_arr[0];
    		$goods_arr[$k]['num'] = $g_arr[1];
    		$goods_arr[$k]['title'] = $info['title'];
    		$goods_arr[$k]['price'] = $info['price'];
    		$goods_arr[$k]['cate'] = $info['cate'];

    		$total_fee += $info['price']*$g_arr[1];
    	}
//     	$data['total_fee'] = $data['total_fee'];
//     	$msg = $total_fee."\n";
//     	$msg.= gettype($total_fee)."\n";
//     	file_put_contents('logs/aaa'.date('Y-m-d').'.log', $msg,FILE_APPEND);
//     	$msg = $data['total_fee']."\n";
//     	$msg.= gettype($data['total_fee'])."\n";
//     	file_put_contents('logs/aaa'.date('Y-m-d').'.log', $msg,FILE_APPEND);
//     	file_put_contents('logs/aaa'.date('Y-m-d').'.log', bccomp($data['total_fee'],$total_fee,2),FILE_APPEND);

    	if (bccomp($data['total_fee'],$total_fee,2)!=0) {
    		$this->error = L('order_amount_error'); //订单金额有误
    		return false;
    	}
    	$mem = new MemberModel();
    	if($data['credits']){
    		$memInfo = $mem->getInfoById($data['userid']);
    		if($memInfo['credits']<$data['credits']){
    			$this->error = L('points_not_enough'); //可用积分不足
    			return false;
    		}
    	}

    	$data['body'] = json_encode($goods_arr);
    	$ratio = C('jifen_ratio');
    	$data['pay_fee'] = $data['total_fee']-$data['credits']/$ratio;

    	if($order = $this->create($data)){
    		if($this->add($order)){
    		    //保存洗衣明细
    		    $obj_orderGoods = new OrderGoodsModel();
    		    $obj_orderGoods->saveGoods($order);

    			//更新用户积分
    			$mem->updateCredits($data['userid'], -$data['credits']);
    			$return['pay_fee'] = $data['pay_fee'];
    			$return['out_trade_no'] = $data['out_trade_no'];

    			return $return;
    		}
    		else{
    			$this->error = L('place_order_fail'); //创建订单失败
    			return false;
    		}
    	}else{
    		$this->error = L('place_order_fail'); //创建订单失败
    		return false;
    	}

    }




    public function createOrder_new($data){

    	$goods = I('goods','');

    	if(!$goods){
    		$this->error = L('select_laundry'); //请先选择衣物
    		return false;
    	}
    	$goods = explode('#', $goods);


    	$goods_arr = array();
    	foreach ($goods as $k=>$g){
    		$g_arr = explode(',', $g);
    		$info = M('Goods')->find($g_arr[0]);
    		$goods_arr[$k]['id'] = $g_arr[0];
    		$goods_arr[$k]['num'] = $g_arr[1];
    		$goods_arr[$k]['title'] = $info['title'];
    		$goods_arr[$k]['amount'] = $info['price']*$goods_arr[$k]['num'];
    		$goods_arr[$k]['cate'] = $info['cate'];

    	}

    	if(empty($goods_arr)){
    		$this->error = L('select_laundry'); //请先选择衣物
    		return false;
    	}else{
    		$out_trade_no = make_orderSn($data['mac_id']);
    		S($out_trade_no.'_goods', $goods_arr);
    		S($out_trade_no.'_mac_id', $data['mac_id']);

    		return $out_trade_no;
    	}

    }


    public function getInfo($key,$value){
    	return $this->where(array($key=>$value))->find();
    }

    public function getPayStatus($out_trade_no){
    	$info = $this->where(array('out_trade_no'=>$out_trade_no))->field('pay_status')->find();
    	return $info['pay_status'];
    }


    public function getBox($out_trade_no){
    	$info = $this->where(array('out_trade_no'=>$out_trade_no))->find();
    	if(empty($info))
    		return '';
    	else
    		return $info['box'];
    }


    public function setBox($out_trade_no, $box, $mac_id){
    	$map['out_trade_no'] = $out_trade_no;
    	$data['box'] = $box;
    	$res = $this->where($map)->save($data);

    	if($res){
    		$where['mac_id'] = $mac_id;
    		$where['num'] = array('in',$box);
    		M('MachineBox')->where($where)->save(array('is_used'=>1));
    		return true;

    	}else{
    		return false;
    	}
    }




    //当前待取的订单
    public function macOrder($mac_id){
    	$map['status'] = 1;
    	$map['pay_status'] = 1;
    	$map['mac_id'] = $mac_id;
    	$map['yuyue'] = 0;
    	$fields = 'out_trade_no,box';
    	$lists = $this->where($map)->field($fields)->order('id asc')->select();
    	foreach ($lists as $k=>$v){
    		$lists[$k]['createtime'] = date('Y-m-d H:i:s',$v['createtime']);
    	}
    	return $lists;


    }


    //条码打印信息
    public function barcodeInfo($orderInfo){
    	$macInfo = M('Machine')->find($orderInfo['mac_id']);
    	$goods = "Order details：\n";
    	$body = json_decode($orderInfo['body'],true);
    	foreach ($body as $g){
    		$goods .=$g['title'].' '.$g['price'].' '.$g['num']."\n";
    	}

    	$params = array(
    			'id' => 'No.：'.$orderInfo['id'],
    			'out_trade_no' => 'Order：'.$orderInfo['out_trade_no'],
    			'addr' =>'Address：'.$macInfo['address'],
    			'door' =>'Box：'.$orderInfo['box'],
    			'createtime' => 'Createtime：'.date('Y-m-d H:i:s',$orderInfo['createtime']),
    			'mobile' => 'Mobile：'.$orderInfo['mobile'],
    			'amount' => 'Amount：'.$orderInfo['total_fee'],
    			'credits' => 'Points：'.$orderInfo['credits'],
    	        'note' => 'Note：'.$orderInfo['note'],
    			'goods' => $goods,
    	        'barcode' => str_replace('sn_', '', $orderInfo['out_trade_no'])

    	);
    	return $params;


    }

    //下单成功，关闭箱门
    public function succOrder($orderInfo){
    	if(!$orderInfo['pay_status']){
    		$this->error = L('order_not_paid'); //该订单还未支付
    		return false;
    	}else{
    	    write_order_log($orderInfo['out_trade_no'],L('place_order_succ').'，open box '.$orderInfo['box']);

    		setNewOrder($orderInfo['mid']);
    		$user_mobile = $orderInfo['mobile'];

    		$macInfo = M('Machine')->find($orderInfo['mac_id']);

    		$params = array();
    		$obj_sms = new Sms();
    		$status = $obj_sms->send($user_mobile, 'order_succ', $params);


//     		if (!$status) {
//     			$this->error = $obj_sms->error;
//     			return false;
//     		}else
    		{
    			$params2=array();

//     			print_pre($params2);
    			$status = $obj_sms->send($macInfo['mobile'], 'new_notify', $params2);
    			return true;
    		}

    	}
    		return true;
    }

    //衣物取走后，更新订单、格子状态
    public function fetchOrder($out_trade_no,$print=true){
    	$orderInfo = $this->getInfo('out_trade_no', $out_trade_no);
    	$map['out_trade_no'] = $out_trade_no;
    	$res = $this->where($map)->save(array('status'=>2,'box'=>'','updatetime'=>time()));
    	if($res){

    	    write_order_log($out_trade_no,'Distributor pick up');

    		$where['mac_id'] = $orderInfo['mac_id'];
    		$where['num'] = array('in',$orderInfo['box']);
    		M('MachineBox')->where($where)->save(array('is_used'=>0));



    		return true;
    	}else{
    		$this->error = L('update_order_fail'); //更新订单信息失败
    		return false;
    	}

    }

    //配送员存件，关闭箱门
    public function deposit($out_trade_no,$box){
    	$map['out_trade_no'] = $out_trade_no;
    	$orderInfo = $this->getInfo('out_trade_no', $out_trade_no);
    	if(!$orderInfo ){
    		$this->error = L('obtain_order_info_fail'); //获取订单信息失败1
    		return false;
    	}

    	$res = $this->where($map)->save(array('status'=>3,'box'=>$box));

    	if(!$res){
    		$this->error = L('obtain_order_info_fail'); //获取订单信息失败
    		return false;

    	}else{
    		//生成取件码
    		$code = make_fetchCode();
    		$data=array(
    				'out_trade_no' => str_replace('sn_', 'f', $out_trade_no),
    				'order_sn' => $out_trade_no,
    				'userid' => $orderInfo['userid'],
    				'code' => $code,
    				'createtime' => time(),
    				'mac_id' => $orderInfo['mac_id'],
    				'mid' => $orderInfo['mid'],
    				'box' => $orderInfo['box'],
    		);
    		if(M('Order_code')->add($data)){

    		    write_order_log($out_trade_no,'The dispatcher put the clothes in box '.$box.'，send fetch_code：'.$code);

    			$macInfo = M('Machine')->find($orderInfo['mac_id']);

    			//发送短信，通知用户取件
    			$params = array();
    			$params['code'] = $code;
    			$params['address'] = $macInfo['address'];
    			$obj_sms = new Sms();
    			$status = $obj_sms->send($orderInfo['mobile'], 'finish_notify', $params);
    			
    			
    			$memInfo = M('Member')->find($orderInfo['userid']);
    			if($memInfo['openid']){
    			    $options = array(
    			        'token'=>C('Weixin.token'),
    			        'encodingaeskey'=>C('Weixin.encodingaeskey'),
    			        'appid'=>C('Weixin.appid'),
    			        'appsecret'=>C('Weixin.appsecret')
    			    );
    			     
    			    $weObj = new Wechat($options);
    			    $tplMsg = array(
    			        "touser"=>$memInfo['openid'],
    			        "template_id"=>C('tpl_ids.qujian'),
    			        "url"=> C('ROOT_DOMAIN').'/Home/Index/order_detail/id/'.$orderInfo['id'],
    			        "topcolor"=>"#FF0000",
    			        "data"=>array(
    			            "first"=>array("value"=>'您好，您的衣物已清洗完毕', "color"=>"#173177"),
    			            "keyword1"=>array("value"=>$macInfo['address'].'洗衣柜', "color"=>"#173177"),
    			            "keyword2"=>array("value"=>$orderInfo['box'], "color"=>"#173177"),
    			            "keyword3"=>array("value"=>$code, "color"=>"#173177"),
    			            "remark"=>array("value"=>"请妥善保存取件码，并及时取件！超期将收取保管费用", "color"=>"#173177"),
    			        )
    			    );
    			    $weObj->sendTemplateMessage($tplMsg);
    			}
    			
    			
    			
    			return true;
    		}else{
    			$this->error = L('generate_fetch_code_fail'); //生成取件码失败
    			return false;
    		}
    	}
    }


    //检查订单是否过期
    public function checkOrderIsOverdue($mac_id, $code){
    	$data = array();
    	$map['mac_id'] = $mac_id;
    	$map['code'] = $code;
    	$map['status'] = 0;
    	$pay_fee = 0;
    	$pay_plus = 0;
    	$pay_overdue = 0;

    	$row = M('OrderCode')->where($map)->find();
    	if(!$row){
    		$this->error = L('fetch_code_error'); //取件码有误
    		return false;
    	}

    	$orderInfo = $this->getInfo('out_trade_no', $row['order_sn']);
    	if(!$orderInfo ){
    		$this->error = L('obtain_order_info_fail'); //获取订单信息失败
    		return false;
    	}
    	if($orderInfo['status']!=3 ){
    		$this->error = L('order_status_not_allow'); //当前订单状态不允许此操作
    		return false;
    	}
    	if($orderInfo['pay_plus']){
    		$pay_plus = $orderInfo['pay_plus'];
    	}

    	//已经存在pay_fee时，不在计算，防止客户第一次未付款，下次再取时更新订单失败
    	if($row['pay_fee']>0){
    		$data['pay_fee'] = $row['pay_fee'];
    		$data['box'] = '';
    		$data['out_trade_no'] = $row['out_trade_no'];
    		return $data;
    	}

    	if($pay_plus==0 || $row['pay_status']==1){
    	    $data['pay_fee'] = 0;
    	    $data['box'] = $orderInfo['box'];
    	    $data['out_trade_no'] = $orderInfo['out_trade_no'];
    	}else{
    	    $data['pay_fee'] = $pay_plus;
    	    $data['box'] = '';
    	    $data['out_trade_no'] = $row['out_trade_no'];

    	    $res = M('OrderCode')->where($map)->save(array('pay_fee'=>$pay_plus,'pay_plus'=>$pay_plus));
    	    if(!$res){
    	        $this->error = L('update_order_fail'); //更新订单失败
    	        return false;
    	    }
    	}
    	return $data;

    	exit;


    	$data = array();


	    $now = time();
	    $times = $now - $row['createtime'];
	    if($times<3600*24 || $row['pay_status']){//不超期
	    	if($pay_plus!='0.00'){
	    		$data['pay_fee'] = $pay_plus;
	    		$data['box'] = '';
	    		$data['out_trade_no'] = $row['out_trade_no'];
	    	}else{
	    		$data['pay_fee'] = 0;
	    		$data['box'] = $orderInfo['box'];
	    		$data['out_trade_no'] = $orderInfo['out_trade_no'];
	    	}
	    	return $data;
	    }else{

	    	$day = $times/(3600*24);
	    	$pay_overdue = floor(1*$day);
// 	    	$data['pay_overdue'] = $pay_overdue;
// 	    	$data['pay_plus'] = $pay_plus;
	    	$data['pay_fee'] = $pay_overdue+$pay_plus;
	    	$data['out_trade_no'] = $row['out_trade_no'];
	    	$data['box'] = '';
	    	if($pay_fee!=$row['pay_fee']){
		    	$res = M('OrderCode')->where($map)->save(array('pay_fee'=>$pay_fee));
		    	if(!$res){
		    		$this->error = L('obtain_order_info_fail'); //获取订单信息失败
		    		return false;
		    	}
	    	}
	    	return $data;

	    }

    }


    //订单完成
    public function finish($out_trade_no){
    	$orderInfo = $this->getInfo('out_trade_no', $out_trade_no);
    	if(!$orderInfo ){
    		$this->error = L('obtain_order_info_fail'); //获取订单信息失败
    		return false;
    	}

    	M('OrderCode')->where(array('order_sn'=>$out_trade_no))->save(array('status'=>1,'updatetime'=>time()));
    	$this->where(array('out_trade_no'=>$out_trade_no))->save(array('status'=>10,'box'=>'','updatetime'=>time()));

    	$where['mac_id'] = $orderInfo['mac_id'];
    	$where['num'] = array('in',$orderInfo['box']);
    	M('MachineBox')->where($where)->save(array('is_used'=>0));

    	$obj_orderFinish = new OrderFinishModel();
    	$obj_orderFinish->insert($orderInfo);

    	write_order_log($out_trade_no,'Customer pick up, order complete');

    	return true;

    }

    //订单完成--未使用
    public function finish2($mac_id, $code){
    	$map['mac_id'] = $mac_id;
    	$map['code'] = $code;
    	$map['status'] = 0;

    	$row = M('OrderCode')->where($map)->find();
    	if(!$row){
    		$this->error = L('fetch_code_error'); //取件码有误
    		return false;
    	}

    	$orderInfo = $this->getInfo('out_trade_no', $row['order_sn']);
    	if(!$orderInfo ){
    		$this->error = L('obtain_order_info_fail'); //获取订单信息失败
    		return false;
    	}

    	M('OrderCode')->where($map)->save(array('status'=>1));
    	$this->where(array('out_trade_no'=>$row['order_sn']))->save(array('status'=>10));
    	return true;

    }


    //检查预约码
    public function checkYuyueCode($mac_id, $code){
    	$map['mac_id'] = $mac_id;
    	$map['yuyue_code'] = $code;
    	$map['yuyue'] = 1;
    	$map['pay_status'] = 1;
    	$map['status'] = 1;


    	$row = M('Order')->where($map)->find();
    	if(!$row){
    		$this->error = L('yuyue_code_error'); //预约码有误
    		return false;
    	}
//     	if($row['status']==-1){
//     		$this->error = '预约码已过期，请联系客服退款';
//     		return false;
//     	}
    	$box = $row['box'];
    	if(empty($box)){
    	    $box = getAvlBox($row['out_trade_no'],'member'); //分配格子
    	    if(empty($box)){
    	        $this->error = L('no_available_box'); //当前没有可用的格子，请联系客服
    	        return false;
    	    }
    	    write_order_log($row['out_trade_no'],' Booking order，occupy box'.$box);

    	}

    	$data = array();
    	$data['box'] = $box;
    	$data['out_trade_no'] = $row['out_trade_no'];
    	return $data;
    }


    //修改小票打印状态
    public function setPrintStatus($out_trade_no,$succ){
        $map['out_trade_no'] = $out_trade_no;

        $data['print_status'] = $succ;
        if($this->where($map)->save($data))
            return true;
        else
            return false;

    }



    //获取微信支付二维码
    public function wxpayQrcode($orderInfo){
    	require_once VENDOR_PATH.'Wxpay/lib/WxPay.Api.php';
    	require_once VENDOR_PATH.'Wxpay/example/WxPay.NativePay.php';

    	$input = new \WxPayUnifiedOrder();
    	$notify = new \NativePay();

    	$input->SetBody("Self-service laundry service");
    	$input->SetAttach("yichao");
    	$input->SetOut_trade_no($orderInfo['out_trade_no']);
    	if(C('is_develop')==0) //非测试，使用正常价格
    		$input->SetTotal_fee($orderInfo['pay_fee']*100);
    	else
    		$input->SetTotal_fee(1);


    	$input->SetTime_start(date("YmdHis"));
    	$input->SetTime_expire(date("YmdHis", time() + 300));
    	$input->SetGoods_tag("test");
    	$input->SetNotify_url(\WxPayConfig::NOTIFY_URL);
    	$input->SetTrade_type("NATIVE");
    	$input->SetProduct_id("123456789");
    	$res = $notify->GetPayUrl($input);

    	//     	print_pre($res);
    	//     	exit;
    	if($res && $res['return_code']=='SUCCESS' && $res['result_code']=='SUCCESS'){
    		$url = $res["code_url"];
//     		$code_url = U('Public/qrcode','','',true).'?data='.urlencode($url);
    		return $url;
    	}else{
    		$this->error = L('qrcode_generation_failure'); //生成二维码失败
    		return false;
    	}
    }


    //获取微信支付二维码
    public function alipayQrcode($orderInfo){
    	require_once VENDOR_PATH.'Alipay/f2fpay/model/builder/AlipayTradePrecreateContentBuilder.php';
    	require_once VENDOR_PATH.'Alipay/f2fpay/service/AlipayTradeService.php';

    	// (必填) 商户网站订单系统中唯一订单号，64个字符以内，只能包含字母、数字、下划线，
    	// 需保证商户系统端不能重复，建议通过数据库sequence生成，
    	//$outTradeNo = "qrpay".date('Ymdhis').mt_rand(100,1000);
    	$outTradeNo = $orderInfo['out_trade_no'];

    	// (必填) 订单标题，粗略描述用户的支付目的。如“xxx品牌xxx门店当面付扫码消费”
    	$subject = "Self-service laundry service";

    	// (必填) 订单总金额，单位为元，不能超过1亿元
    	// 如果同时传入了【打折金额】,【不可打折金额】,【订单总金额】三者,则必须满足如下条件:【订单总金额】=【打折金额】+【不可打折金额】
    	if(C('is_develop')==0) //非测试，使用正常价格
    		$totalAmount = $orderInfo['pay_fee'];
    	else
    		$totalAmount = 0.01;


    	// (不推荐使用) 订单可打折金额，可以配合商家平台配置折扣活动，如果订单部分商品参与打折，可以将部分商品总价填写至此字段，默认全部商品可打折
    	// 如果该值未传入,但传入了【订单总金额】,【不可打折金额】 则该值默认为【订单总金额】- 【不可打折金额】
    	//String discountableAmount = "1.00"; //

    	// (可选) 订单不可打折金额，可以配合商家平台配置折扣活动，如果酒水不参与打折，则将对应金额填写至此字段
    	// 如果该值未传入,但传入了【订单总金额】,【打折金额】,则该值默认为【订单总金额】-【打折金额】
    	$undiscountableAmount = "";

    	// 卖家支付宝账号ID，用于支持一个签约账号下支持打款到不同的收款账号，(打款到sellerId对应的支付宝账号)
    	// 如果该字段为空，则默认为与支付宝签约的商户的PID，也就是appid对应的PID
    	//$sellerId = "2088721541558970";

    	// 订单描述，可以对交易或商品进行一个详细地描述，比如填写"购买商品2件共15.00元"
    	$body = "laundry service";

    	//商户操作员编号，添加此参数可以为商户操作员做销售统计
    	//$operatorId = "999999";

    	// (可选) 商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息，详询支付宝技术支持
    	//$storeId = "";

    	// 支付宝的店铺编号
    	//$alipayStoreId= "";

    	// 业务扩展参数，目前可添加由支付宝分配的系统商编号(通过setSysServiceProviderId方法)，系统商开发使用,详情请咨询支付宝技术支持
    	$providerId = ""; //系统商pid,作为系统商返佣数据提取的依据
    	$extendParams = new \ExtendParams();
    	$extendParams->setSysServiceProviderId($providerId);
    	$extendParamsArr = $extendParams->getExtendParams();

    	// 支付超时，线下扫码交易定义为5分钟
    	$timeExpress = "5m";

    	// 商品明细列表，需填写购买商品详细信息，
    	$goodsDetailList = array();


    	//第三方应用授权令牌,商户授权系统商开发模式下使用
    	$appAuthToken = "";//根据真实值填写

    	// 创建请求builder，设置请求参数
    	$qrPayRequestBuilder = new \AlipayTradePrecreateContentBuilder();
    	$qrPayRequestBuilder->setOutTradeNo($outTradeNo);
    	$qrPayRequestBuilder->setTotalAmount($totalAmount);
    	$qrPayRequestBuilder->setTimeExpress($timeExpress);
    	$qrPayRequestBuilder->setSubject($subject);
    	$qrPayRequestBuilder->setBody($body);
    	$qrPayRequestBuilder->setUndiscountableAmount($undiscountableAmount);
    	$qrPayRequestBuilder->setExtendParams($extendParamsArr);
    	//$qrPayRequestBuilder->setGoodsDetailList($goodsDetailList);
    	//$qrPayRequestBuilder->setStoreId($storeId);
    	//$qrPayRequestBuilder->setOperatorId($operatorId);
    	//$qrPayRequestBuilder->setAlipayStoreId($alipayStoreId);

    	$qrPayRequestBuilder->setAppAuthToken($appAuthToken);


    	// 调用qrPay方法获取当面付应答
    	$qrPay = new \AlipayTradeService($config);
    	$qrPayResult = $qrPay->qrPay($qrPayRequestBuilder);

    	//	根据状态值进行业务处理
    	if($qrPayResult->getTradeStatus()=="SUCCESS"){
    		$response = $qrPayResult->getResponse();
    		$qrcode = $response->qr_code;
//     		$code_url = U('Public/qrcode','','',true).'?data='.urlencode($qrcode);
    		return $qrcode;
    	}else{
    		$this->error = $qrPayResult->getResponse()->sub_msg;
    		return false;
    	}
    }

}
