<?php
/*
 * shopping/order/Status.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-06-18
 */
require_once( dirname(dirname(__FILE__))
.DIRECTORY_SEPARATOR.'PackageConfig.class.php' );
class shopping_order_Status extends system_login_ModuleBase {
	function shopping_order_Status() {
		array_push($this->require_module_array,'system.login.Require');
		array_push($this->require_module_array,'database2.Transaction');
		array_push($this->require_module_array,'shopping.order.settlement.LoadList');
		array_push($this->require_module_array,'shopping.order.settlement.LoadListExists');
	}
	function execute( & $request ) {
		
		$dbo					= $request->getAttribute( 'dbo' );
		$orderNumber			= $request->getParam('shpon','get');
		$orderId				= $request->getParam('shpoi','get');
		$shoppingOrderObject	= spider_Controller::createObject('shopping_DaoShoppingOrder');
		$loginUserObject		= $this->getLoginUserObject( $request );
		$targetStatus	= $request->getParam('target_status','post');
		$statusNumber	= $request->getParam('status_number','post');
		$isNotify		= $request->getParam('is_notify','post');

		if( preg_match('/^[0-9]+$/',$orderNumber) > 0 ) {
			// 番号があるなら読み込み
			if( $dbo->loadByNumber( $shoppingOrderObject, $orderNumber, true ) ) {
			} else {
				$request->addLocaledError('shopping.error.order.notfound',SPIDER_LOG_LEVEL_FATAL,array(''));
			}
		} else if( preg_match('/^[0-9a-zA-Z\\-\\_\\.]+$/',$orderId) > 0 ) {
			// IDがあるなら読み込み
			if( $dbo->loadById( $shoppingOrderObject, $orderId, true ) ) {
			} else {
				$request->addLocaledError('shopping.error.order.notfound',SPIDER_LOG_LEVEL_FATAL,array(''));
			}
		} else {
			$request->addLocaledError('shopping.error.order.notfound',SPIDER_LOG_LEVEL_FATAL,array(''));
		}
		// 入力値を先にチェック
		if( preg_match('/^[0-9]{1,3}$/',$statusNumber) == 0 ) {
			$request->addLocaledError('shopping.error.common.invalidstatus',SPIDER_LOG_LEVEL_ERROR,array(''));
		} else if( preg_match('/^[sS][eE][tT][tT][lL][eE]$/',$targetStatus) > 0 ) {
			$targetStatus	= 'settle';
			if( !isset($GLOBALS['SHOPPING_ORDER_STATUS_SETTLE_HASH'][$statusNumber]) ) {
				$request->addLocaledError('shopping.error.common.invalidstatus',SPIDER_LOG_LEVEL_ERROR,array(''));
			}
		} else if( preg_match('/^[pP][rR][oO][mM][oO][tT][iI][oO][nN]$/',$targetStatus) > 0 ) {
			$targetStatus	= 'promotion';
			if( !isset($GLOBALS['SHOPPING_ORDER_STATUS_PROMOTION_HASH'][$statusNumber]) ) {
				$request->addLocaledError('shopping.error.common.invalidstatus',SPIDER_LOG_LEVEL_ERROR,array(''));
			}
		} else if( preg_match('/^[fF][lL][aA][gG]$/',$targetStatus) > 0 ) {
			$targetStatus	= 'flag';
			if( !isset($GLOBALS['SHOPPING_ORDER_STATUS_HASH'][$statusNumber]) ) {
				$request->addLocaledError('shopping.error.common.invalidstatus',SPIDER_LOG_LEVEL_ERROR,array(''));
			}
		} else {
			$request->addLocaledError('shopping.error.cart.admin.invalidtargetst',SPIDER_LOG_LEVEL_ERROR,array(''));
		}
		// 操作しようとしているログイン者がこの申し込みにどうかかわっているか確認
		$operationType	= 0;
		if( !$request->isError() ) {
			$operationType	= $shoppingOrderObject->confirmModifyPermittion( $request, $loginUserObject );
		}
		if( $operationType == 0 ) {
			$request->addLocaledError('system.error.login.user.noauthexec',SPIDER_LOG_LEVEL_ERROR,array());
		} else if( $operationType == 2 ) {
			// 申し込み者本人の場合はstatus_flagをキャンセル申請にしかできない
			if( 'flag' != $targetStatus ) {
				$request->addLocaledError('system.error.login.user.noauthexec',SPIDER_LOG_LEVEL_ERROR,array());
			} else if( 191 != $statusNumber ) {
				$request->addLocaledError('system.error.login.user.noauthexec',SPIDER_LOG_LEVEL_ERROR,array());
			}
		}
		// 読み込みでエラーがないなら申し込み状態を変更
		if( !$request->isError() ) {
			// エラーがないなら状態と履歴ノートのみ変更
			$newHistoryNote	= '';
			if( 'settle'==$targetStatus ){
				$newHistoryNote	.= date('Y-m-d H:i:s').' [決済状態変更]';
			} else if( 'promotion'==$targetStatus ){
				$newHistoryNote	.= date('Y-m-d H:i:s').' [プロモ状態変更]';
			} else {
				$newHistoryNote	.= date('Y-m-d H:i:s').' [状態変更]';
			}
			if( 1 == $operationType ){
				$newHistoryNote	.= '[管理者操作]';
			} else if( 2 == $operationType ){
				$newHistoryNote	.= '[申込者操作]';
			} else if( 3 == $operationType ){
				$newHistoryNote	.= '[提供者操作]';
			}
			if( 'settle'==$targetStatus ){
				$newHistoryNote	.= $GLOBALS['SHOPPING_ORDER_STATUS_SETTLE_HASH'][$shoppingOrderObject->status_settle];
				$newHistoryNote	.= ' -> '.$GLOBALS['SHOPPING_ORDER_STATUS_SETTLE_HASH'][$statusNumber];
			} else if( 'promotion'==$targetStatus ){
				$newHistoryNote	.= $GLOBALS['SHOPPING_ORDER_STATUS_PROMOTION_HASH'][$shoppingOrderObject->status_promotion];
				$newHistoryNote	.= ' -> '.$GLOBALS['SHOPPING_ORDER_STATUS_PROMOTION_HASH'][$statusNumber];
			} else {
				$newHistoryNote	.= $GLOBALS['SHOPPING_ORDER_STATUS_HASH'][$shoppingOrderObject->status_flag];
				$newHistoryNote	.= ' -> '.$GLOBALS['SHOPPING_ORDER_STATUS_HASH'][$statusNumber];
			}
			$newHistoryNote	.= "\n";
			$shoppingOrderObject->history_note	= $newHistoryNote.$shoppingOrderObject->history_note;
			// 変更を実行
			$targetColumnName	= 'status_'.$targetStatus;
			$shoppingOrderObject->$targetColumnName	= $statusNumber;
			$sql	= 'UPDATE '.TABLE_NAME_SHOPPING_ORDER
			.' SET '.$targetColumnName.'='.$statusNumber
			.', history_note='.$dbo->quote($shoppingOrderObject->history_note)
			.', updated_date=NOW()'
			.' WHERE order_number='.$shoppingOrderObject->order_number;
			if( $dbo->query($sql ) ){
				// アップデートに成功したら決済処理連動
				// 利用可能な決済方法の読み込み
				$settleMethodObjectArray	= $request->getAttribute('shopping.order.settlement.methodExistsObjectArray');
				if( is_array($settleMethodObjectArray) ) {
					foreach( $settleMethodObjectArray as $settleMethodObject ) {
						if( $shoppingOrderObject->settle_method == $settleMethodObject->getMethodNumber() ) {
							$settleMethodObject->modify( $request, $shoppingOrderObject );
							break;
						}
					}
					// 決済連動に成功してエラーがないなら
					if( !$request->isError() ) {
						if( $shoppingOrderObject->point_total > 0 && $shoppingOrderObject->memberObject->member_class > 0 ) {
							// 会員登録かつポイント付与が存在する申し込み情報の場合
							if( $targetStatus == 'settle' ) {
								// 対象が決済ステータス
								if( $shoppingOrderObject->status_settle_org != 101 && $statusNumber == 101 ) {
									// 支払済み以外から支払済みに変更した場合ポイントを加算する
									$addPoint	= '+'.$shoppingOrderObject->point_total;
									if( $shoppingOrderObject->memberObject->pointChange( $request,
										$addPoint,$GLOBALS['SHOPPING_LABEL_ORDER'].$GLOBALS['SHOPPING_LABEL_ORDER'].':'.$shoppingOrderObject->order_id.':'.$shoppingOrderObject->payment_total.'円') ){
									} else {
										$request->addLocaledError('shopping.error.point.failtosave',SPIDER_LOG_LEVEL_ERROR,array());
									}
								} else if( $shoppingOrderObject->status_settle_org == 101 && $statusNumber != 101 ) {
									// 支払済みから支払済み以外に変更した場合ポイントを減算する
									$usePoint	= '-'.$shoppingOrderObject->point_total;
									if( $shoppingOrderObject->memberObject->pointChange( $request,
										$usePoint, $GLOBALS['SHOPPING_LABEL_ORDER'].'決済ロールバック:'.$shoppingOrderObject->order_id.':'.$shoppingOrderObject->payment_total.'円') ){
									} else {
										$request->addLocaledError('shopping.error.point.failtosave',SPIDER_LOG_LEVEL_ERROR,array());
									}
								}
							} else if( $targetStatus == 'flag' ) {
								if( $shoppingOrderObject->status_flag_org < 200 && $statusNumber > 200 ) {
									// キャンセルや無効の場合はポイント減
									$usePoint	= '-'.$shoppingOrderObject->point_total;
									if( $shoppingOrderObject->memberObject->pointChange( $request,
										$usePoint, ''.$GLOBALS['SHOPPING_LABEL_ORDER'].'キャンセル:'.$shoppingOrderObject->order_id.':'.$shoppingOrderObject->payment_total.'円') ){
									} else {
										$request->addLocaledError('shopping.error.point.failtosave',SPIDER_LOG_LEVEL_ERROR,array());
									}
								} if( $shoppingOrderObject->status_flag_org >= 200 && $statusNumber < 200 ) {
									// 申し込みが無効状態から復帰した場合
									if( $shoppingOrderObject->status_settle == 101 ) {
										// 決済状態が決済済みならポイントを追加
										$addPoint	= '+'.$shoppingOrderObject->point_total;
										if( $shoppingOrderObject->memberObject->pointChange( $request,
											$addPoint,''.$GLOBALS['SHOPPING_LABEL_ORDER'].'復活:'.$shoppingOrderObject->order_id.':'.$shoppingOrderObject->payment_total.'円') ){
										} else {
											$request->addLocaledError('shopping.error.point.failtosave',SPIDER_LOG_LEVEL_ERROR,array());
										}
									}
								}
							}
						}
					}
				} else {
					$request->addLocaledError('shopping.error.order.failtoloadplugin',SPIDER_LOG_LEVEL_ERROR,array());
				}
			} else {
				$request->addLocaledError('database2.error.update',SPIDER_LOG_LEVEL_ERROR,array($sql));
			}
		}
		// エラーがなく最後の変更前保存ファイルが残っていたら削除する
		if( !$request->isError() && $shoppingOrderObject->status_flag > 5 ){
			$shoppingOrderObject->deleteSerialized( $request );
		}
		// メール通知の判断
		$needSendMail	= false;
		if( 2 == $operationType ) {
			$needSendMail	= true;
		} else if( preg_match('/^([tT](|[rR][uU][eE])|[yY](|[eE][sS]))$/',$isNotify) > 0 ){
			$needSendMail	= true;
		}
		// メール通知
		if( !$request->isError() && 'flag' == $targetStatus && $needSendMail ) {
			// 送信情報の整形
			require_once(dirname(__FILE__).'/Optimize.class.php');
			shopping_order_Optimize::_setEnvironmentFor11x( $request, $shoppingOrderObject );
			// 状態が変更されたことを申し込み者に通知
			if( isset($GLOBALS['SHOPPING_ORDER_STATUS_MAIL'])
			&& isset($GLOBALS['SHOPPING_ORDER_STATUS_MAIL'][$statusNumber])
			&& strlen($GLOBALS['SHOPPING_ORDER_STATUS_MAIL'][$statusNumber]) > 0 ) {
				// メールテンプレートがあるなら通知
				$mailTemplateId	= $GLOBALS['SHOPPING_ORDER_STATUS_MAIL'][$statusNumber];
				$memberObject	= & $shoppingOrderObject->memberObject;
				$targetMail		= null;
				if( ( $shoppingOrderObject->mail_flag == 2 || $shoppingOrderObject->mail_flag == 12 )
				&& strlen($memberObject->mb_mail) > 0 ) {
					$targetMail	= $memberObject->mb_mail;
				} else if( strlen($memberObject->pc_mail) > 0 ) {
					$targetMail	= $memberObject->pc_mail;
				}
				if( is_null($targetMail) ) {
					$request->addLocaledError('shopping.error.order.invalidmail',SPIDER_LOG_LEVEL_FATAL,array(''));
				} else {
					$bcc	= null;
					// 通知メール
					if(defined('SHOPPING_MAIL_ADDRESS_BCC') && strlen(SHOPPING_MAIL_ADDRESS_BCC) > 0 ) {
						$bcc	= SHOPPING_MAIL_ADDRESS_BCC;
					}
					if( $shoppingOrderObject->sendInformationMail( $request, $targetMail, $mailTemplateId, $bcc, '', array(), $loginUserObject ) ) {
					} else {
						$request->addLocaledError('shopping.error.order.failtonotifymail',SPIDER_LOG_LEVEL_FATAL,array(''));
					}
				}
			}
			// オーナー・管理者のメールテンプレート確認
			if( !$request->isError() && isset($GLOBALS['SHOPPING_ORDER_STATUS_OWNER_MAIL'])
			&& isset($GLOBALS['SHOPPING_ORDER_STATUS_OWNER_MAIL'][$statusNumber])
			&& strlen($GLOBALS['SHOPPING_ORDER_STATUS_OWNER_MAIL'][$statusNumber]) > 0 ) {
				// メールテンプレートがあるなら
				$mailTemplateId	= $GLOBALS['SHOPPING_ORDER_STATUS_OWNER_MAIL'][$statusNumber];
				// オーナーに通知
				$ownerMemberObjectArray	= $shoppingOrderObject->getProducerMemberObjectArray( $request );
				foreach( $ownerMemberObjectArray as $ownerMemberObject ) {
					// オーナーへのメールはＰＣを優先
					$email	= $ownerMemberObject->pc_mail;
					if( strlen($email) == 0 && strlen($ownerMemberObject->mb_mail) > 0 ) {
						$email	= $ownerMemberObject->mb_mail;
					}
					if( strlen($email) > 0 ) {
						if($shoppingOrderObject->sendInformationMail( $request, $email, $mailTemplateId, null, '', array(), $loginUserObject ) ) {
						} else {
							$request->addLocaledError('shopping.error.order.failtoownermail',SPIDER_LOG_LEVEL_FATAL,array(''));
							break;
						}
					}
				}
				// 管理者宛てに通知
				if( !$request->isError() && defined('SHOPPING_MAIL_ADDRESS_NOTIFY') && strlen(SHOPPING_MAIL_ADDRESS_NOTIFY) > 0 ) {
					spider_Controller::loadClassDefinition('util_Mail');
					$mailAddressArray	= util_Mail::divideCsvEmail( SHOPPING_MAIL_ADDRESS_NOTIFY );
					foreach( $mailAddressArray as $addNum => $address ) {
						if( $shoppingOrderObject->sendInformationMail( $request, $address, $mailTemplateId, null, '', array(), $loginUserObject ) ) {
						} else {
							$request->addLocaledError('shopping.error.order.failtoadminmail',SPIDER_LOG_LEVEL_FATAL,array(''));
							break;
						}
					}
				}
			}
		}
		$request->setAttribute('shopping.order.orderObject',	$shoppingOrderObject );
	}
}
?>