<?php
/*
 * shopping/order/Cart.class.php
 * 
 * CopyRight(C) 2010 Shopformer Development Team. All Right Reserved
 * URL: http://sourceforge.jp/projects/shopformer/
 * 
 * 
 * Mail: m_nakashima@users.sourceforge.jp
 * Auther: Masanori Nakashima
 * Last Update: 2010-09-21
 */
require_once( dirname(dirname(__FILE__))
.DIRECTORY_SEPARATOR.'PackageConfig.class.php' );
/**
 * 買い物かごに対して指定の処理をおこなうモジュール
 * 
 * postで渡されたcommandの入力文字列に応じて買い物かごを操作し、セッションに登録します。
 * 
 * <b>commandと動作の概要</b>
 * <ul>
 * <li><b>add</b><br />POST入力されたunit_idの販売単位を、同じくPOST入力されたorder_count個買い物かごに追加します。またaddress_orderをPOSTで指定することで複数の宛先を買い物かごに保存します。</li>
 * <li><b>drop</b><br />...</li>
 * <li><b>countup</b><br />...</li>
 * <li><b>countdown</b><br />...</li>
 * <li><b>clearall</b><br />...</li>
 * <li><b>addaddress</b><br />...</li>
 * <li><b>dropaddress</b><br />...</li>
 * <li><b>setprefecture</b><br />...</li>
 * <li><b>point</b><br />...</li>
 * </ul>
 * 
 * <b>spider_HttpRequestにsetAttributeするキーと値</b>
 * <ul>
 * <li><b>shopping.order.orderObject</b><br />買い物かごデータを保持する{@link shopping_DaoShoppingOrder shopping_DaoShoppingOrder}クラスインスタンス。</li>
 * </ul>
 * 
 * <b>セッションに保存するキーと値</b>
 * <ul>
 * <li><b>shopping.order.orderObject</b><br />買い物かごデータを保持する{@link shopping_DaoShoppingOrder shopping_DaoShoppingOrder}クラスインスタンス。</li>
 * </ul>
 * 
 * @package shopping
 * @category 
 * @version 1.2.01
 * @copyright Copyright(c)2011, Shopformer Development Team. <shopformer-dev@lists.sourceforge.jp>
 * @author Masanori Nakashima
 * @access public
 */
class shopping_order_Cart extends system_login_ModuleBase {
	function shopping_order_Cart() {
		array_push($this->require_module_array,'shopping.LoadConfig');
		array_push($this->require_module_array,'database2.Connect');
		array_push($this->require_module_array,'shopping.order.option.LoadList');
		array_push($this->require_module_array,'shopping.order.settlement.LoadList');
	}
	function execute( & $request ) {
		$dbo				= $request->getAttribute( 'dbo' );
		$redirect		= $request->getParam('redirect','post');
		if( isset($_GET[session_name()]) && strlen($_GET[session_name()]) > 0 ) {
			setcookie(session_name(),$_GET[session_name()]);
		}
		$shoppingOrderObject	= null;
		if( $request->existsSession(SHOPPING_SESSION_NAME_ORDER_OBJECT) ) {
			$shoppingOrderObject	= $request->getSession(SHOPPING_SESSION_NAME_ORDER_OBJECT);
		} else {
			$shoppingOrderObject	= $this->createNewShoppingOrderObject( $request );
		}
		
		// ログイン状態ごとの切り分け
		$this->_processLoginStatus( $request, $shoppingOrderObject );
		// コマンド分岐処理
		$execCommand	= $this->_processCommand( $request, $shoppingOrderObject );

		if( $execCommand ) {
			// コマンドを実行したらカラムごとのエラーメッセージは削除する
			$shoppingOrderObject->columnErrorHash	= array();
		}
		// プロモーション情報があるなら取得
		$shoppingPromotionObject	= $shoppingOrderObject->getRelatedPromotionObject( $request );
		$request->getAttribute('shopping.order.promotionInformation',$shoppingPromotionObject);

		if(preg_match('/^([fF](|[aA][lL][sS][eE])|[nN][oO](|[nN][eE]))$/',$redirect)>0){
		}else{
			if( !$request->isError() && $execCommand ) {
				$request->redirectTo(SPIDER_URI_REQUEST);
			}
		}
		// カート内を現在の情報で再計算
		$shoppingOrderObject->calculate( $request, true );
		// 表示用に属性登録
		$request->setAttribute('shopping.order.orderObject',	$shoppingOrderObject );
	}
	/**
	 * コマンド分岐処理
	 * @param $request spider_HttpRequestオブジェクト参照
	 * @param $shoppingOrderObject shopping_DaoShoppingOrderオブジェクト参照
	 * @return boolean コマンドを実行したらtrue
	 */
	function _processCommand( & $request, & $shoppingOrderObject ) {
		// コマンドごとの処理
		$command			= $request->getParam('command','post');
		$loginUserObject	= $this->getLoginUserObject( $request );
		$execCommand		= false;
		if( preg_match('/^[cC][lL][eE][aA][rR]$/',$command) > 0 ) {
			$execCommand	= true;
			// カートの商品を全て削除
			$shoppingOrderObject->clearAll();
		} else if( preg_match('/^[pP][oO][iI][nN][tT]$/',$command) > 0 ) {
			$execCommand	= true;
			// 妥当性検査:利用ポイント
			if( isset($_POST['point_use']) ) {
				$shoppingOrderObject->point_use		= mb_convert_kana(trim(stripslashes($_POST['point_use'])),'a');
				if( strlen($shoppingOrderObject->point_use) == 0 ) {
					$shoppingOrderObject->point_use	= 0;
				} else if( is_null($shoppingOrderObject->memberObject)
					|| strlen(trim($shoppingOrderObject->memberObject->member_id)) == 0
					|| strlen(trim($shoppingOrderObject->memberObject->member_number)) == 0
					|| $shoppingOrderObject->memberObject->member_class < 1 ) {
					$shoppingOrderObject->addColumnError($request,'point_use','shopping.error.cart.point.requiremember');
				} else if( preg_match('/^[0-9]{1,7}$/',$shoppingOrderObject->point_use) == 0 ) {
					$shoppingOrderObject->addColumnError($request,'point_use','shopping.error.cart.point.invalid');
				} else {
					$currentPoint	= $shoppingOrderObject->memberObject->pointCurrent( $request );
					if( false === $currentPoint ) {
						$shoppingOrderObject->addColumnError($request,'point_use','shopping.error.cart.point.confirm');
					} else if( $currentPoint < $shoppingOrderObject->point_use ) {
						$shoppingOrderObject->addColumnError($request,'point_use','shopping.error.cart.point.shortage',array($currentPoint));
					}
				}
			}
		} else if( preg_match('/^[cC][lL][eE][aA][rR][aA][dD][dD]$/',$command) > 0 ) {
			$execCommand	= true;
			// カートの商品を全て削除して追加
			$shoppingOrderObject->clearAll();
			// 商品を追加
			$this->addUnit2Cart( $request, $shoppingOrderObject );
		} else if( preg_match('/^[aA][dD][dD][aA][dD][dD][rR][eE][sS][sS]$/',$command) > 0 ) {
			$execCommand	= true;
			// 宛先を追加
			$shoppingOrderObject->addAddress( $request );
		} else if( preg_match('/^[dD][rR][oO][pP][aA][dD][dD][rR][eE][sS][sS]$/',$command) > 0 ) {
			$execCommand	= true;
			// 宛先を削除
			$addressOrder	= $this->getAddressOrder();
			$shoppingOrderObject->dropAddress( $request, $addressOrder );
		} else if( preg_match('/^[aA][dD][dD]$/',$command) > 0 ) {
			$execCommand	= true;
			// 商品を追加
			$this->addUnit2Cart( $request, $shoppingOrderObject );
		} else if( preg_match('/^[cC][oO][uU][nN][tT][uU][pP]$/',$command) > 0 ) {
			$execCommand	= true;
			// カウントアップ
			$addressOrder	= $this->getAddressOrder();
			$cartOrder		= $this->getCartOrder();
			if( $cartOrder !== false ) {
				$curCount	= $shoppingOrderObject->getItemCount( $request, $cartOrder, $addressOrder );
				$curCount++;
				$shoppingOrderObject->changeItemCount( $request, $cartOrder, $curCount, $addressOrder, $loginUserObject );
			}
		} else if( preg_match('/^[cC][oO][uU][nN][tT][dD][oO][wW][nN]$/',$command) > 0 ) {
			$execCommand	= true;
			// カウントダウン
			$addressOrder	= $this->getAddressOrder();
			$cartOrder		= $this->getCartOrder();
			if( $cartOrder !== false ) {
				$curCount	= $shoppingOrderObject->getItemCount( $request, $cartOrder, $addressOrder );
				$curCount--;
				if( $curCount <= 0 ) {
					$shoppingOrderObject->dropItem( $request, $cartOrder, $addressOrder );
				} else {
					$shoppingOrderObject->changeItemCount( $request, $cartOrder, $curCount, $addressOrder, $loginUserObject );
				}
			}
		} else if( preg_match('/^[dD][rR][oO][pP]$/',$command) > 0 ) {
			$execCommand	= true;
			// 商品選択解除
			$addressOrder	= $this->getAddressOrder();
			$cartOrder		= $this->getCartOrder();
			if( $cartOrder !== false ) {
				$shoppingOrderObject->dropItem( $request, $cartOrder, $addressOrder );
			}
		} else if( preg_match('/^[sS][eE][tT][pP][rR][eE][fF][eE][cC][tT][uU][rR][eE]$/',$command) > 0 ) {
			$execCommand	= true;
			// 指定の宛先に都道府県のみ設定する
			$addressOrder		= $this->getAddressOrder();
			$prefectureNumber	= $request->getParam('prefecture_number','post');
			if( strlen($prefectureNumber) > 0 && array_key_exists($prefectureNumber,$GLOBALS['PREFECTURE_HASH']) ) {
				$shoppingOrderObject->setPrefecture( $request, $prefectureNumber, $addressOrder );
			}
		}
		return $execCommand;
	}
	/**
	 * POST入力された宛先番号を取得
	 * @return int 宛先番号。指定がない場合は0
	 */
	function getAddressOrder(){
		if( isset($_POST['address_order']) ) {
			$addressOrder	= trim(stripslashes($_POST['address_order']));
			if( preg_match('/^[0-9]{1,2}$/',$addressOrder) == 0 ) {
				$addressOrder	= 0;
			}
			return $addressOrder;
		} else {
			return 0;
		}
	}
	/**
	 * POST入力されたカート内順序を取得
	 * @return int POST入力されたカート内順序.入力がない場合false
	 */
	function getCartOrder() {
		$cartOrder	= null;
		if( isset($_POST['cart_order']) ) {
			$cartOrder	= trim(stripslashes($_POST['cart_order']));
		} else if( isset($_POST['cart_number']) ) {
			$cartOrder	= trim(stripslashes($_POST['cart_number']));
		}
		if( preg_match('/^[0-9]{1,2}$/',$cartOrder) > 0 ) {
			return $cartOrder;
		}
		return false;
	}
	/**
	 * カートに商品を追加
	 * @param $request spider_HttpRequestオブジェクト参照
	 * @param $shoppingOrderObject shopping_DaoShoppingOrderオブジェクト参照
	 */
	function addUnit2Cart( & $request, & $shoppingOrderObject ) {
		$dbo				= $request->getAttribute('dbo');
		// 操作ユーザー
		$loginUserObject	= $this->getLoginUserObject( $request );
		// POST値の取得
		$addressOrder		= $request->getParam('address_order','post');
		$unitId				= $request->getParam('unit_id','post');
		$validate			= $request->getParam('validate','post');
		$orderCount			= $request->getParam('order_count','post');
		$prefectureNumber	= $request->getParam('prefecture_number','post');
		if( strlen($prefectureNumber) > 0
		&& array_key_exists($prefectureNumber,$GLOBALS['PREFECTURE_HASH']) ) {
			$shoppingOrderObject->setPrefecture( $request, $prefectureNumber, $addressOrder );
		}
		// オプションの整理
		$optionNameArray	= $request->getParam('option_names','post','array');
		$optionStringArray= $request->getParam('option_strings','post','array');
		// 入力調整
		if( preg_match('/^[0-9]{1,3}$/',$addressOrder) == 0 ) {
			$addressOrder	= 0;
		}
		// 指定販売単位オブジェクト
		$productUnitObject	= spider_Controller::createObject('shopping_DaoShoppingProductUnit');
		// 妥当性検査
		if( preg_match('/^[0-9]{1,7}$/',$orderCount) == 0 ) {
			$request->addLocaledError('shopping.error.cart.invalidordercount',SPIDER_LOG_LEVEL_ERROR,array());
			return false;
		} else if( strlen($unitId) == 0 ) {
			$request->addLocaledError('shopping.error.product.unit.invalidid',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		} else if( !$dbo->loadById($productUnitObject,$unitId) ) {
			$request->addLocaledError('shopping.error.product.unit.notfound',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		} else if( $productUnitObject->status_flag >= 200 ) {
			$request->addLocaledError('shopping.error.product.unit.notfound',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		} else if( SYSTEM_LOGIN_USER_ADMINISTRATORS != $loginUserObject->getLoginGroupLevel()
		&& $productUnitObject->status_flag < 100 ) {
			$request->addLocaledError('shopping.error.cart.closeditem',SPIDER_LOG_LEVEL_FATAL,array(''));
			return false;
		}
		// 商品情報を取得
		if( is_null($productUnitObject->shoppingProductObject) ) {
			$productUnitObject->loadParentProductObject( $dbo );
		}
		$shoppingOrderObject->search_data_id = $productUnitObject->shoppingProductObject->search_data_id;
		// 要求販売単位チェック
		$requireUnitId	= $productUnitObject->require_unit_id;
		$requireUnitObject	= null;
		if( strlen($requireUnitId) > 0 ) {
			// 要求販売単位がある場合既にカートに存在するか確認
			$requireUnitObject	= spider_Controller::createObject('shopping_DaoShoppingProductUnit');
			if( $dbo->loadById($requireUnitObject,$requireUnitId) ) {
				if( $shoppingOrderObject->getUnitOrderCount( $requireUnitId ) == 0 ) {
					$request->addLocaledError('shopping.error.cart.needrequireditem',SPIDER_LOG_LEVEL_FATAL,array($requireUnitObject->unit_name));
				}
			} else {
				$request->addLocaledError('shopping.error.cart.closeditem',SPIDER_LOG_LEVEL_FATAL,array(''));
			}
		}
		// 入力に問題がない場合
		$shoppingOrderItemObject	= spider_Controller::createObject('shopping_DaoShoppingOrderItem');
		$shoppingOrderItemObject->unit_id			= $unitId;
		$shoppingOrderItemObject->order_count	= $orderCount;
		$shoppingOrderItemObjectArray		= array();
		$firstItemObject	= null;
		$firstUnitObject	= null;
		// カートへの追加処理
		if( $productUnitObject->delivery_type < 200 ){
			// 通常商品の場合
			$shoppingOrderItemObject->setOrderOptionOnCartPost( $request );
			// 追加情報入力
			if( $this->setAdditionalItemPost( $request, $shoppingOrderItemObject ) ) {
				// カートに追加
				$shoppingOrderObject->addItem( $request, $shoppingOrderItemObject, $addressOrder );
				// 在庫数の確認
				if( preg_match('/^(false|no)$/',$validate) > 0 ){
				} else {
					if( $shoppingOrderObject->canExecuteOrder( $request ) ) {
						return true;
					} else {
						// 在庫がないなら現在追加した商品をカートから削除する
						array_pop($shoppingOrderObject->shoppingOrderAddressObjectArray[$addressOrder]->shoppingOrderItemObjectArray);
					return false;
					}
				}
			} else {
				return false;
			}
		} else{
			// 予約申込の場合
			$selectedDateHash	= $request->getSession('shopping.order.selectedDateHash',SPIDER_SESSION_SCOPE_GLOBAL);
			// 対象プランに対する日付選択を取得
			$selectedDateArray	= array();
			if( isset($_POST['term_unit_id']) && strlen($_POST['term_unit_id']) ) {
				$selectedDateArray	= array_unique($selectedDateHash[$request->getParam('term_unit_id','post')]);
			} else if( isset($selectedDateHash[$unitId]) && is_array($selectedDateHash[$unitId]) ){
				$selectedDateArray	= array_unique($selectedDateHash[$unitId]);
			}
			if( is_array($selectedDateArray) ){
				// 日時のフォーマットをそろえる
				foreach( $selectedDateArray as $key => $val ){
					if( preg_match('/^[0-9]{4}\\-[0-9]{1,2}\\-[0-9]{1,2}$/',$val) > 0 ){
						$selectedDateArray[$key] = date('Y-m-d',strtotime($val));
					} else {
						$selectedDateArray[$key] = date('Y-m-d H:i:s',strtotime($val));
					}
				}
				asort($selectedDateArray);
			}
			// 選択区間配列
			$termArray	= array();
			if( 900 == $productUnitObject->delivery_type ){
				// 宿泊予約の場合
				$termArray	= $this->createStayTermArray( $request, $selectedDateArray, $productUnitObject );
				if( !is_array($termArray) || count($termArray) == 0 ){
					$request->addLocaledError('shopping.error.cart.requiredate',SPIDER_LOG_LEVEL_FATAL,array(''));
					return false;
				}
			} else if( 200 == $productUnitObject->delivery_type ){
				// 時間予約の場合
				$termArray	= $this->createTimeTermArray( $request, $selectedDateArray, $productUnitObject );
				if( !is_array($termArray) || count($termArray) == 0 ){
					$request->addLocaledError('shopping.error.cart.requiredatetime',SPIDER_LOG_LEVEL_FATAL,array(''));
					return false;
				}
			} else if( 1700 == $productUnitObject->delivery_type || 1000 == $productUnitObject->delivery_type ){
				// 予約オプションの場合は一番最初に選択されているアイテムのタイプを確認
				$deliveryType		= 900;
				if( is_array($shoppingOrderObject->shoppingOrderAddressObjectArray) ){
					if( is_object($shoppingOrderObject->shoppingOrderAddressObjectArray[0]->shoppingOrderItemObjectArray[0]) ){
						$firstItemObject	= $shoppingOrderObject->shoppingOrderAddressObjectArray[0]->shoppingOrderItemObjectArray[0];
						$firstUnitObject	= $firstItemObject->getUnitObject( $request );
						$deliveryType		= $firstItemObject->delivery_type;
						if( 200 != $deliveryType && 900 != $deliveryType ) {
							$request->addLocaledError('shopping.error.cart.option.requirersv',SPIDER_LOG_LEVEL_FATAL,array(''));
							return false;
						}
					} else {
						$request->addLocaledError('shopping.error.cart.option.requirersv',SPIDER_LOG_LEVEL_FATAL,array(''));
						return false;
					}
				} else {
					$request->addLocaledError('shopping.error.cart.option.requirersv',SPIDER_LOG_LEVEL_FATAL,array(''));
					return false;
				}
				if( 1000 == $productUnitObject->delivery_type ){
					if( 200 == $deliveryType ) {
						$termArray	= $this->createTimeTermArray( $request, $selectedDateArray, $productUnitObject );
					} else if( 900 == $deliveryType ) {
						$termArray	= $this->createStayTermArray( $request, $selectedDateArray, $productUnitObject );
					}
				} else if( 1700 == $productUnitObject->delivery_type ) {
					if( 200 == $deliveryType ) {
						$termArray	= $this->createTimeTermArray( $request, $selectedDateArray, $firstUnitObject );
					} else if( 900 == $deliveryType ) {
						$termArray	= $this->createStayTermArray( $request, $selectedDateArray, $firstUnitObject );
					}
				}
				if( !is_array($termArray) || count($termArray) == 0 ){
					$selectedDateArray	= array_unique($selectedDateHash[$firstItemObject->unit_id]);
					if( 1000 == $productUnitObject->delivery_type ){
						if( 200 == $deliveryType ) {
							$termArray	= $this->createTimeTermArray( $request, $selectedDateArray, $productUnitObject );
						} else if( 900 == $deliveryType ) {
							$termArray	= $this->createStayTermArray( $request, $selectedDateArray, $productUnitObject );
						}
					} else if( 1700 == $productUnitObject->delivery_type ) {
						if( 200 == $deliveryType ) {
							$termArray	= $this->createTimeTermArray( $request, $selectedDateArray, $firstUnitObject );
						} else if( 900 == $deliveryType ) {
							$termArray	= $this->createStayTermArray( $request, $selectedDateArray, $firstUnitObject );
						}
					}
				}
				if( !is_array($termArray) || count($termArray) == 0 ){
					$request->addLocaledError('shopping.error.cart.option.requiredate',SPIDER_LOG_LEVEL_FATAL,array(''));
					return false;
				}
			}
			if( defined('SHOPPING_RSV_LIMIT_TERM_AT_ONCE')
			&& preg_match('/^[0-9]{1,2}$/',SHOPPING_RSV_LIMIT_TERM_AT_ONCE) > 0 ) {
				if( count($termArray) > SHOPPING_RSV_LIMIT_TERM_AT_ONCE ) {
					$request->addLocaledError('shopping.error.reserve.termlimitatonce',SPIDER_LOG_LEVEL_FATAL,array(''));
					return false;
				}
			}
			foreach( $termArray as $termInfoHash ) {
				$shoppingOrderItemObject	= spider_Controller::createObject('shopping_DaoShoppingOrderItem');
				$shoppingOrderItemObject->unit_id			= $unitId;
				$shoppingOrderItemObject->order_count		= $orderCount;
				$shoppingOrderItemObject->svc_start_date	= $termInfoHash['start'];
				$shoppingOrderItemObject->svc_limit_date	= $termInfoHash['limit'];
				$shoppingOrderItemObject->setOrderOptionOnCartPost( $request );
				if( 1700 == $productUnitObject->delivery_type ) {
					if( 900 == $firstUnitObject->delivery_type ){
						$shoppingOrderItemObject->service_term	= 60*60*24;
					} else {
						$shoppingOrderItemObject->service_term	= $firstUnitObject->service_term;
					}
				}
				// 追加情報入力
				if( $this->setAdditionalItemPost( $request, $shoppingOrderItemObject ) ) {
					// カートに追加
					$shoppingOrderObject->addItem( $request, $shoppingOrderItemObject, $addressOrder );
					// 在庫数の確認
					if( preg_match('/^(false|no)$/',$validate) > 0 ){
					} else {
						if( $shoppingOrderObject->canExecuteOrder( $request ) ) {
						} else {
							// 在庫がないなら現在追加した商品をカートから削除する
							array_pop($shoppingOrderObject->shoppingOrderAddressObjectArray[$addressOrder]->shoppingOrderItemObjectArray);
							return false;
						}
					}
				}
			}
			return true;
		}
	}
	/**
	 * 宿泊の場合の選択区間配列を日付配列から作成して取得
	 */
	function createStayTermArray( & $request, $selectedDateArray, $productUnitObject ){
		$termArray		= array();
		$currentTurm	= null;
		foreach( $selectedDateArray as $selectedDate ){
			if( strlen($selectedDate) > 0 ){
				$targetDayTime		= strtotime(date('Y-m-d 00:00:00',strtotime($selectedDate)));
				$tStartDateTime		= date('Y-m-d',$targetDayTime).' '.$productUnitObject->default_start_time;
				$tStartTime			= strtotime($tStartDateTime);
				$tLimitTime			= $tStartTime + $productUnitObject->service_term;
				$tLimitDateTime		= date('Y-m-d H:i:s',$tLimitTime);
				if( is_null($currentTurm) ){
					$currentTurm	= array('start'=>$tStartDateTime,'limit'=>$tLimitDateTime);
				} else if( $tStartTime - strtotime($currentTurm['limit']) > 60*60*24 ){
					// 24時間以上差がある場合は連続でないので選択日付に追加して新規区間
					array_push($termArray,$currentTurm);
					$currentTurm	= array('start'=>$tStartDateTime,'limit'=>$tLimitDateTime);
				} else {
					// 24時間以内の場合は連続区間の為終了時間を延ばす
					$currentTurm['limit']	= $tLimitDateTime;
				}
			}
		}
		if( !is_null($currentTurm) && is_array($currentTurm) ){
			array_push($termArray,$currentTurm);
		}
		return $termArray;
	}
	/**
	 * 日時予約の場合の選択区間配列を日付配列から作成して取得
	 */
	function createTimeTermArray( & $request, $selectedDateArray, $productUnitObject ){
		$termArray	= array();
			$currentTurm	= null;
			spider_Controller::loadClassDefinition('util_ValidateFunctions');
			foreach( $selectedDateArray as $selectedDate ){
				if( !util_ValidateFunctions::isAvailableDatetimeFormat($selectedDate) ){
					$request->addLocaledError('shopping.error.cart.invaliddatetime',SPIDER_LOG_LEVEL_FATAL,array(''));
					return false;
				} else {
					$tStartTime		= strtotime($selectedDate);
					$tLimitTime		= $tStartTime+$productUnitObject->service_term;
					$tLimitDateTime	= date('Y-m-d H:i:s',$tLimitTime);
					if( is_null($currentTurm) ){
						$currentTurm	= array('start'=>$selectedDate,'limit'=>$tLimitDateTime);
					} else if( $tStartTime - strtotime($currentTurm['limit']) > $productUnitObject->service_term ){
						// サービス提供時間以上差がある場合は連続でないので選択日付に追加して新規区間
						array_push($termArray,$currentTurm);
						$currentTurm	= array('start'=>$selectedDate,'limit'=>$tLimitDateTime);
					} else {
						// サービス提供時間以内の場合は連続区間の為終了時間を延ばす
						$currentTurm['limit']	= $tLimitDateTime;
					}
				}
			}
			if( !is_null($currentTurm) && is_array($currentTurm) ){
				array_push($termArray,$currentTurm);
			}
		return $termArray;
	}
	/**
	 * 
	 */
	function setAdditionalItemPost( & $request, & $shoppingOrderItemObject ) {
		$loginUserObject	= $this->getLoginUserObject( $request );
		if( $this->isLogin( $request )
		&& SYSTEM_LOGIN_USER_ADMINISTRATORS == $loginUserObject->getLoginGroupLevel() ) {
			// 管理者の場合は単価を変更入力可能に変更
			if( isset($_POST['price_unit']) ) {
				// 販売単価の入力がある場合
				$priceUnit	= $request->getParam('price_unit','post');
				if( preg_match('/^(|\\+|\\-)[0-9]{1,6}$/',$priceUnit) == 0 ) {
					$request->addLocaledError('shopping.error.product.unit.invalidpricesell',SPIDER_LOG_LEVEL_FATAL,array(''));
					return false;
				} else {
					$shoppingOrderItemObject->price_unit	= $priceUnit;
				}
			}
			if( isset($_POST['cost_unit']) ) {
				// 販売単位コストの入力がある場合
				$costUnit	= $request->getParam('cost_unit','post');
				if( preg_match('/^(|\\+|\\-)[0-9]{1,6}$/',$costUnit) == 0 ) {
					$request->addLocaledError('shopping.error.product.unit.invalidcost',SPIDER_LOG_LEVEL_FATAL,array(''));
					return false;
				} else {
					$shoppingOrderItemObject->cost_unit	= $costUnit;
				}
			}
			if( isset($_POST['point_unit']) ) {
				// 付与ポイントの入力がある場合
				$costUnit	= $request->getParam('point_unit','post');
				if( preg_match('/^(|\\+|\\-)[0-9]{1,6}$/',$costUnit) == 0 ) {
					$request->addLocaledError('shopping.error.product.unit.invalidpoint',SPIDER_LOG_LEVEL_FATAL,array(''));
					return false;
				} else {
					$shoppingOrderItemObject->point_unit	= $costUnit;
				}
			}
		}
		return true;
	}
	/**
	 * カートオブジェクトを新規に作成
	 * @param $request spider_HttpRequestオブジェクト参照
	 */
	function createNewShoppingOrderObject( & $request ) {
		$dbo					= $request->getAttribute( 'dbo' );
		$shoppingOrderObject	= spider_Controller::createObject('shopping_DaoShoppingOrder');
		// パラメータ付きのリンクか確認(プロモーションパラメータGETのafid)
		$shoppingOrderObject->promotion_code	= null;
		if( isset($_GET['afid']) ) {
			$shoppingOrderObject->promotion_code	= trim(stripslashes( $_GET['afid'] ));
		}
		// オプションを設定
		$optionHash	= $request->getAttribute('shopping.order.option.optionHash');
		$shoppingOrderObject->shoppingOrderOptionObjectArray	= $optionHash;
		
		// 参照サイト情報を取得する
		if( isset($_SERVER['HTTP_REFERER']) ) {
			$isFirstAccess	= true;
			// 自サイト範囲内なら最初のアクセスでない
			if( preg_match('/'.util_CharUtility::escapeRegxStr(SPIDER_URL_DOC).'/',$_SERVER['HTTP_REFERER']) > 0 ) {
				$isFirstAccess	= false;
			}
			if( $isFirstAccess ) {
				foreach( $GLOBALS['REV_PROXY_HASH'] as $hostName => $info ) {
					if( preg_match('/'.util_CharUtility::escapeRegxStr($hostName).'/',$_SERVER['HTTP_REFERER']) > 0 ) {
						$isFirstAccess	= false;
						break;
					}
				}
			}
			if( $isFirstAccess ) {
				$shoppingOrderObject->referrer_url	= $_SERVER['HTTP_REFERER'];
			}
		}
		$accessId	= '';
		if( strlen($shoppingOrderObject->promotion_code) == 0 ) {
			// プロモーションコードが指定されていない場合はcookieを確認
			if( isset($_COOKIE[SHOPPING_COOKIE_NAME_PROMOTION_ACCESS_CODE]) ) {
				$accessId	= $_COOKIE[SHOPPING_COOKIE_NAME_PROMOTION_ACCESS_CODE];
				if( strlen($accessId) > 0 ) {
					// アクセスIDが拾えたらアクセスログからプロモーションコードを取得
					$sql	= 'SELECT * FROM '.TABLE_NAME_SHOPPING_PROMOTION_ACCESS_LOG
					.' WHERE access_id='.$dbo->quote($accessId);
					$result	= $dbo->queryAll( $sql, 'hash' );
					if( false === $result ) {
						$request->addLocaledError('database2.error.common',SPIDER_LOG_LEVEL_FATAL,array($sql));
					} else if( count( $result ) == 0 ) {
						// アクセス情報がないならクッキーも削除
						$accessId	= '';
						setcookie(SHOPPING_COOKIE_NAME_PROMOTION_ACCESS_CODE, '', time()-3600);
					} else if( count( $result ) == 1 ) {
						$shoppingOrderObject->promotion_code	= $result[0]['promotion_code'];
						$shoppingOrderObject->access_param		= $result[0]['access_param'];
					} else {
						// アクセス情報が多数あるなら問題発生の為無視
						$accessId	= '';
						setcookie(SHOPPING_COOKIE_NAME_PROMOTION_ACCESS_CODE, '', time()-3600);
					}
				} else {
					// アクセスIDの長さが不正ならクッキー削除
					$accessId	= '';
					setcookie(SHOPPING_COOKIE_NAME_PROMOTION_ACCESS_CODE, '', time()-3600);
				}
			} else {
				$accessId	= '';
			}
		}
		
		// プロモーションコードが設定されている場合
		$shoppingPromotionObject	= $shoppingOrderObject->getRelatedPromotionObject( $request );
		if( $shoppingPromotionObject ) {
			// プロモーション情報を取得出来たら
			if( strlen($accessId) == 0 ) {
				// 初回アクセスならログを記録してアクセスIDを取得
				$shoppingOrderObject->access_param	= $shoppingPromotionObject->_getAccessParamStrings();
				$accessId	= $shoppingPromotionObject->writeAccessLog( $request );
				// アクセスIDをクッキーに記録
				if( strlen($accessId) > 0 ) {
					setcookie(SHOPPING_COOKIE_NAME_PROMOTION_ACCESS_CODE, $accessId, time()+3600*24*30);
				}
			}
		} else {
			// プロモーション情報を取得できなかったら
			$shoppingOrderObject->promotion_code	= '';
			$shoppingOrderObject->access_param		= '';
			setcookie(SHOPPING_COOKIE_NAME_PROMOTION_ACCESS_CODE, '', time()-3600);
		}
		
		// プロモーションに関係なく携帯電話の場合の端末IDが設定されていないなら取得しておく
		$agentClass	= $request->getAttribute('spider.access_agent_class');
		$mobileId	= '';
		if( 'docomo' == $agentClass || 'docomo2' == $agentClass ) {
			$iModeId	= trim($_SERVER['HTTP_X_DCMGUID']);
			if( isset($_SERVER['HTTP_X_DCMGUID']) && strlen($_SERVER['HTTP_X_DCMGUID']) > 0 ) {
				$mobileId	= $_SERVER['HTTP_X_DCMGUID'];
			}
		} else if( 'au' == $agentClass ) {
			if( isset($_SERVER['HTTP_X_UP_SUBNO']) && strlen($_SERVER['HTTP_X_UP_SUBNO']) > 0 ) {
				$mobileId	= $_SERVER['HTTP_X_UP_SUBNO'];
			}
		} else if( 'softbank' == $agentClass ) {
			if( isset($_SERVER['HTTP_X_JPHONE_UID']) && strlen($_SERVER['HTTP_X_JPHONE_UID']) > 0 ) {
				$mobileId	= $_SERVER['HTTP_X_JPHONE_UID'];
			}
		}
		$shoppingOrderObject->sim_id	= $mobileId;
		return $shoppingOrderObject;
	}
	/**
	 * ログイン状態によってプロモーションと会員オブジェクトを調整
	 * @param $request spider_HttpRequestオブジェクト参照
	 * @param $shoppingOrderObject shopping_DaoShoppingOrderオブジェクト参照
	 */
	function _processLoginStatus( & $request, & $shoppingOrderObject ) {
		$dbo					= $request->getAttribute( 'dbo' );
		$loginUserObject		= $this->getLoginUserObject( $request );
		if( $this->isLogin( $request )
			&& SYSTEM_LOGIN_USER_ADMINISTRATORS == $loginUserObject->getLoginGroupLevel() ) {
			// 管理者ログインの場合
			if( isset( $_POST['promotion_code'] ) ) {
				// プロモーションコードを入力可能
				$shoppingOrderObject->promotion_code	= trim(stripslashes($_POST['promotion_code']));
				// プロモーションオブジェクトの再読み込み
				$shoppingOrderObject->getRelatedPromotionObject( $request, true );
			}
			if( isset( $_POST['member_id'] ) ) {
				// 会員IDを入力可能
				$memberId	= mb_convert_kana(trim(stripslashes($_POST['member_id'])),'a');
				if( strlen($memberId) > 0 && $shoppingOrderObject->member_id != $memberId ) {
					$memberObject	= spider_Controller::createObject('member_DaoMember');
					if( $dbo->loadById($memberObject, $memberId) ) {
						if( !$shoppingOrderObject->setMemberObject( $memberObject ) ) {
							$request->addLocaledError('shopping.error.order.loadmember',SPIDER_LOG_LEVEL_ERROR,array(''));
						} else {
							// 会員情報を入れ替えて利用ポイントがセット済みの場合
							$currentPoint	= $memberObject->pointCurrent( $request );
							if( $shoppingOrderObject->point_use > $currentPoint ) {
								// ポイントオーバーしていたら最大値に変更
								$shoppingOrderObject->point_use	= $currentPoint;
							}
						}
					} else {
						$request->addLocaledError('shopping.error.order.loadmember',SPIDER_LOG_LEVEL_ERROR,array(''));
						$shoppingOrderObject->member_id		= null;
						$shoppingOrderObject->memberObject	= spider_Controller::createObject('member_DaoMember');
					}
				} else if( strlen($memberId) == 0 ) {
					$shoppingOrderObject->member_id		= null;
					$shoppingOrderObject->memberObject	= spider_Controller::createObject('member_DaoMember');
				}
			} else if( !is_a($shoppingOrderObject->memberObject,'member_DaoMember') ) {
				$shoppingOrderObject->memberObject	= spider_Controller::createObject('member_DaoMember');
			}
			// 卸販売の入力の調整
			if( isset( $_POST['buying_flag'] ) ) {
				if( is_object($shoppingOrderObject->memberObject) ) {
					if( '53' == $shoppingOrderObject->memberObject->member_class ) {
						$shoppingOrderObject->buying_flag	= trim(stripslashes($_POST['buying_flag']));
					} else {
						$shoppingOrderObject->buying_flag	= 0;
					}
				} else {
					$request->addLocaledError('shopping.error.cart.buying.requiremember',SPIDER_LOG_LEVEL_FATAL,array(''));
				}
			}
		} else if( $this->isLogin( $request ) ) {
			// 会員ログインの場合
			$shoppingOrderObject->promotion_code			= null;
			$shoppingOrderObject->shoppingPromotionObject	= null;
			if( !$shoppingOrderObject->setMemberObject( $loginUserObject ) ) {
				$request->addLocaledError('system.error.common.session.timeout',SPIDER_LOG_LEVEL_ERROR,array(''));
			} else {
				if( '53' == $loginUserObject->member_class ) {
					// '特別割引会員'の場合のみ卸販売フラグをセット可能
					if( isset( $_POST['buying_flag'] ) ) {
						if( '1' == $_POST['buying_flag'] ) {
							$shoppingOrderObject->buying_flag	= 1;
						} else {
							$shoppingOrderObject->buying_flag	= 0;
						}
					}
				} else {
					// '特別割引会員'以外の場合卸販売フラグは0
					$shoppingOrderObject->buying_flag	= 0;
				}
			}
		} else {
			// ログインしていない場合プロモーションコード初回アクセス時のまま
			// 卸販売フラグは0
			$shoppingOrderObject->buying_flag	= 0;
			// 関連プロモーション情報を読み込み
			if( strlen($shoppingOrderObject->promotion_code) > 0 ) {
				$shoppingOrderObject->getRelatedPromotionObject( $request );
			}
			// セットされていないなら新規member_DaoMemberオブジェクトをセット
			if( !is_a($shoppingOrderObject->memberObject,'member_DaoMember') ) {
				$shoppingOrderObject->member_id		= null;
				$shoppingOrderObject->memberObject	= spider_Controller::createObject('member_DaoMember');
				$shoppingOrderObject->memberObject->member_class	= 0;
			}
		}
	}
	/**
	 * モジュールの後処理を行います。
	 * @param $request spider_HttpRequestオブジェクト参照
	 */
	function post_process( & $request ) {
		$shoppingOrderObject	= $request->getAttribute('shopping.order.orderObject');
		$removeCart				= $request->getAttribute('shopping.order.removeCart');
		if( true !== $removeCart ){
			$removeCart	= false;
		}
		if( is_object($shoppingOrderObject) && !$removeCart ) {
			// カートオブジェクトから商品販売単位オブジェクトを削除
			$shoppingOrderObject->unsetAllUnitObject();
			// オプションの下位互換を削除
			unset($shoppingOrderObject->payOptionItems);
			unset($shoppingOrderObject->freeOptionItems);
			unset($shoppingOrderObject->option_names);
			unset($shoppingOrderObject->option_values);
			unset($shoppingOrderObject->dbo);
			unset($shoppingOrderObject->request);
			unset($shoppingOrderObject->shoppingPromotionObject);
			// セッションに登録
			$request->setSession(SHOPPING_SESSION_NAME_ORDER_OBJECT,$shoppingOrderObject,SPIDER_SESSION_SCOPE_GLOBAL);
		} else {
			// セッションを削除する
			$request->removeSession(SHOPPING_SESSION_NAME_ORDER_OBJECT,SPIDER_SESSION_SCOPE_GLOBAL);
			$request->removeSession(SHOPPING_SESSION_NAME_ORDER_OBJECT,SPIDER_SESSION_SCOPE_GLOBAL);
			$request->removeSession(SHOPPING_SESSION_NAME_ORDER_CONFIRM_PURCHASER,SPIDER_SESSION_SCOPE_GLOBAL);
			$request->removeSession(SHOPPING_SESSION_NAME_ORDER_CONFIRM_ADDRESS,SPIDER_SESSION_SCOPE_GLOBAL);
			$request->removeSession(SHOPPING_SESSION_NAME_ORDER_CONFIRM_ADDRESS_OPTION,SPIDER_SESSION_SCOPE_GLOBAL);
			$request->removeSession(SHOPPING_SESSION_NAME_ORDER_CONFIRM_SETTLEMENT,SPIDER_SESSION_SCOPE_GLOBAL);
			$request->removeSession(SHOPPING_SESSION_NAME_ORDER_CONFIRM_OPTIONS,SPIDER_SESSION_SCOPE_GLOBAL);
			$request->removeSession(SHOPPING_SESSION_NAME_ORDER_CONFIRM_ITEMOPTIONS,SPIDER_SESSION_SCOPE_GLOBAL);
			$request->removeSession(SHOPPING_SESSION_NAME_ORDER_CONFIRM_COMMENT,SPIDER_SESSION_SCOPE_GLOBAL);
			$request->removeSession(SHOPPING_SESSION_NAME_ORDER_CONFIRM_DELIVERY_OLD,SPIDER_SESSION_SCOPE_GLOBAL);
			$request->removeSession('shopping.order.selectedDateHash',SPIDER_SESSION_SCOPE_GLOBAL);
		}
	}
}
?>