#!/usr/bin/perl
#--NetShopOwner-CGI-version:4.2.5.5--

;#
;# order1.cgi
;# [PC]注文者情報入力画面
;# Copyright (c) 2004- Increment P Corp. All rights reserved.
;#
;# 2009/09/30 NSO4対応
;# 2010/05/11 Y.motai SBPS決済対応
;# last modified 2011/11/24 Y.motai 楽天カード決済対応
;#

use strict;
use uselib;
use defnsopath_shop;
use NsoVersionPC 1.00;
use Design::TemplOrder1;
use Lib::SiteStatus;
use Lib::ExpensesGoods;
use Lib::StockUtil;
use Digest::MD5 'md5_hex';

&ReadParse();
my %in    = %main::in;
my %incfn = %main::incfn;
my %inct  = %main::inct;

# 2010/05/12 T.Hinohara start
# SBPSから呼ばれた場合、POSTとなるが、
# 一部パラメータはURLに付加されているため、
# 別途取得する必要がある
if ($ENV{REQUEST_METHOD} eq 'POST'){
	# 環境変数からCGIURLに付加されているGETパラメータを取得する。
	my $buffer = $ENV{QUERY_STRING};
	# [&]を区切りにID名とIDを分割
	my @pairs = split( /&/, $buffer );
	foreach my $pair ( @pairs ) {
		my ( $name, $value ) = split( /=/, $pair );
		%in->{$name} = $value;
	}
}
# 2010/05/12 T.Hinohara end

# インスタンス定義
my $objConfigSystem = Config::NsoSystem->newShop();
my $objConfigMaster = Config::NsoMaster->new();
my $NsoMisc       = NsoMisc->new();
my $LibStockUtil = Lib::StockUtil->new();
my $ExpensesGoods;

my $SamePeriodID    = "";	# 同期ID
my $PossessionPoint = 0;	# 保有ポイント数
my $PointExpireDate = "";	# ポイント有効期限

# コンフィグレーションのキャッシュ
my %ConfigSystem = $objConfigSystem->cache_config();
my %ConfigMaster = $objConfigMaster->cache_config();

my $status_err;

FUNC:{
	my $func = $in{func} || 'main';
	my %function = (
		main       => \&main,
		login      => \&login,
		logged_in  => \&logged_in,
	);
	&check_order_finish;
	&check_closing();
	
	if ($function{$func}){
		$function{$func}->();
	}else{
		&main();
	}
}
exit();

;#
;# 開店・閉店状態検査
;#
sub check_closing {
	my $SiteStatus = Lib::SiteStatus->new({ ConfigSystem=>\%ConfigSystem });
	$SiteStatus->CheckClosing();
}

;#
;# メイン処理
;#
sub main {
	if ( $SamePeriodID eq "" ) {
		# 会員機能使用有無/会員制設定を取得
		my $memberUseFlag      = $ConfigMaster{adm_member_master}{member}{UseFlag};
		my $memberSubscription = $ConfigMaster{adm_member_master}{member}{Subscription};
		# 会員機能使用 かつ 会員のみ購入可能な場合、カート画面へ
		if ( $memberUseFlag == 1 and $memberSubscription == 1 ) {
			&redirectBasketUrl({ ErrorStatus=>'only_member_service' });
		}
	}

	# 商品代金・諸経費演算
	my $isMember = ( $SamePeriodID eq "" )? 0: 1;
	$ExpensesGoods = Lib::ExpensesGoods->new({ ConfigSystem=>\%ConfigSystem, ConfigMaster=>\%ConfigMaster,
                                               IsMember=>$isMember, 					# 会員フラグ
                                               PossessionPoint=>$PossessionPoint,		# 保有ポイント
                                               PointExpireDate=>$PointExpireDate });	# ポイント有効期限

	my $eg_err = $ExpensesGoods->ParseBasket();

	# エラーメッセージを取得
	$status_err = &error_message( $in{ErrorStatus} );

	if($eg_err ne ""){
		$status_err .= $eg_err;
	}

	# システムテンプレートクラスインスタンス
	my $TemplOrder1 = Design::TemplOrder1->new({ ConfigSystem=>\%ConfigSystem, ConfigMaster=>\%ConfigMaster, KickBack=>$in{KickBack}, ExpensesGoods=>$ExpensesGoods, status_err=>$status_err, Query=>\%in, SamePeriodID=>$SamePeriodID });
	
	# 置換内容
	my $contents = $TemplOrder1->RelpaceSystemTempl();
	
	# システムテンプレート置換
	print $NsoMisc->print_header();
	print $contents;
	exit();
}

;#
;# iPCOSSチェック処理
;#
sub check_order_finish {

	# 注文IDクッキー読み取り
	require DB::NsoOrderIDDB;
	my $OrderIdDB = NsoOrderIDDB->new();
	my $OrderID   = $OrderIdDB->Read_OrderID();

	# 注文IDクッキーが残っていた場合
	if ($OrderID ne ""){
		require Lib::IpcossCheck;
		my $IpcossCheck = Lib::IpcossCheck->new( {ConfigSystem=>\%ConfigSystem, ConfigMaster=>\%ConfigMaster, ExpensesGoods=>$ExpensesGoods} );
		# ipcoss Checkを行う。
		my $IpcCheckFlag = $IpcossCheck->check_ipcoss();
		# okとngの場合の処理
		if ($IpcCheckFlag eq 0){
			# ngだったときの処理
			$IpcossCheck->ipcoss_ng();
		} else {
			# ok だったときの処理
			my $contents = $IpcossCheck->RelpaceSystemTempl();
			print $NsoMisc->print_header();
			print $contents;
			exit ();
		}
	}
}

;#
;# ログインを行って会員購入
;#
sub login {

	# 会員機能使用有無を取得
	my $memberUseFlag = $ConfigMaster{adm_member_master}{member}{UseFlag};

	# 会員機能未使用の場合、カート画面へ
	if ( $memberUseFlag == 0 ) {
		&redirectBasketUrl({ ErrorStatus=>'no_member_service' });
	}

	# 会員情報を取得 (MailAddress,Password)
	my $mailAddress = $in{MailAddress};
	my $passWord    = $in{PassWord};
	
	# パスワードをMD5ハッシュ化
	$passWord = md5_hex $passWord;
	
	require DB::NsoMemberDB;
	my $MemberDB = NsoMemberDB->new({ ConfigSystem=>\%ConfigSystem, ConfigMaster=>\%ConfigMaster });
	if ( $MemberDB->{resultDbConnect} ne "" ) {
		&redirectBasketUrl({ ErrorStatus=>'db_access_error101' });
	}
	my %resultMemberDB = $MemberDB->Member_Select_Mail_Pwd_Query({ MailAddress=>$mailAddress , Password=>$passWord });
	if ( $resultMemberDB{status_err} ne "" ) {
		&redirectBasketUrl({ ErrorStatus=>'db_access_error102' });
	}
	
	# 会員情報が存在しない場合、カート画面へ
	if ( $resultMemberDB{RecordCount} == 0 ) {
		&redirectBasketUrl({ ErrorStatus=>'login_error' });
	}
	my %recMember = %{$resultMemberDB{RecordList}};

	# 会員区分＝承認待ちの場合、カート画面へ
	unless ( $recMember{MemberFlag} == 3 ) {
		&redirectBasketUrl({ ErrorStatus=>'no_approval_member' });
	}

	my $samePeriodID = $recMember{SamePeriodID};
	
	# ログイン情報を取得
	require DB::NsoLoginTempDB;
	my %where   = ( LoginTempID=>1 );
	my %records = ( SamePeriodID=>$samePeriodID );
	my $LoginTempDB = NsoLoginTempDB->new();
	$LoginTempDB->load_data_no_lock({ where=>\%where });
	if ( $LoginTempDB->{RecordCount} > 0 ) {
		# ログイン情報を更新
		$LoginTempDB->update_no_lock({ records=>\%records });
	} else {
		# ログイン情報を追加
		$LoginTempDB->insert_no_lock({ records=>\%records });
	}
	
	&logged_in();
};

;#
;# 現在ログイン中の会員で会員購入
;#
sub logged_in {
	my $samePeriodID = "";
	
	# 会員機能使用有無を取得
	my $memberUseFlag = $ConfigMaster{adm_member_master}{member}{UseFlag};

	# 会員機能未使用の場合、カート画面へ
	if ( $memberUseFlag == 0 ) {
		&redirectBasketUrl({ ErrorStatus=>'no_member_service' });
	}

	# ログイン情報を取得
	require DB::NsoLoginTempDB;
	my %where = ( LoginTempID=>1 );
	my $LoginTempDB = NsoLoginTempDB->new();
	$LoginTempDB->load_data_no_lock({ where=>\%where });

	# ログイン情報が存在しない場合、カート画面へ
	if ( $LoginTempDB->{RecordCount} == 0 ) {
		&redirectBasketUrl({ ErrorStatus=>'logged_in' });
	}

	my @arrLoginTemp = @{$LoginTempDB->{RecordList}};
	my %recLoginTemp = %{$arrLoginTemp[0]};
	$samePeriodID = $recLoginTemp{SamePeriodID};

	# 会員情報を取得 (SamePeriodID)
	require DB::NsoMemberDB;
	my $MemberDB = NsoMemberDB->new({ ConfigSystem=>\%ConfigSystem, ConfigMaster=>\%ConfigMaster });
	if ( $MemberDB->{resultDbConnect} ne "" ) {
		&redirectBasketUrl({ ErrorStatus=>'db_access_error101' });
	}
	my %resultMemberDB = $MemberDB->Member_Select_ID_Query({ SamePeriodID=>$samePeriodID });
	if ( $resultMemberDB{status_err} ne "" ) {
		&redirectBasketUrl({ ErrorStatus=>'db_access_error103' });
	}
	
	# 会員情報が取得できなかった場合、カート画面へ
	if ( $resultMemberDB{RecordCount} == 0 ) {
		&redirectBasketUrl({ ErrorStatus=>'logged_in_error' });
	}
	my %recMember = %{$resultMemberDB{RecordList}};
	# 会員区分＝承認待ちの場合、カート画面へ
	unless ( $recMember{MemberFlag} == 3 ) {
		&redirectBasketUrl({ ErrorStatus=>'logged_in_no_approval_member' });
	}
	
	# ログイン情報を更新(最終更新日時変更のため)
	$LoginTempDB->update_no_lock(\%recLoginTemp);
	
	# Cookieの有効期限を更新
	$LoginTempDB->update_expiration_cookie();
	
	# 同期IDを保持
	$SamePeriodID = $samePeriodID;
	# 保有ポイント数を保持
	$PossessionPoint = $recMember{Point};
	# ポイント有効期限を保持
	$PointExpireDate = $recMember{PointExpireDate};
	
	&main();
}

;#
;# カート画面へリダイレクト
;#
sub redirectBasketUrl {
	my ($queryHash) = shift if @_;
	
	# カート画面ページURL
	my $basketUrl = $ConfigSystem{base_href}{cgishop}.$ConfigSystem{shop_script_name}{basket};
	# SSL状況に応じてURLを置換する
	$basketUrl = $NsoMisc->getChangedURL({url=>$basketUrl, key=>'AfterCart'});

	my $queryString = $NsoMisc->make_query_string($queryHash, 'get');

	print $NsoMisc->redirect(join("", $basketUrl, $queryString));
	exit();
}

;#
;# エラーメッセージ取得処理
;#
sub error_message {

	my %ErrorMessageHash = (
		login_error			=> qq(メールアドレス、またはパスワードが間違っています。<br>),
		no_approval_member	=> qq(管理者による会員承認が完了していません。<br>),
		logged_in			=> qq(ログインの有効期限が過ぎています。再度ログインしてください。<br>),
		no_member_service	=> qq(現在、会員サービスは使用できません。<br>),
		only_member_service	=> qq(会員しか購入できません。<br>),
		db_access_error		=> qq(システムエラーが発生しました。システム管理者に連絡してください。<br>),
		
		# TemplOrder3 #redirectOrder1Url()から
		err_TemplOrder3_001 => qq(クーポン情報を取得できませんでした。もう一度実行してください。<br>再度、このメッセージが表\示される場合は、お手数ですが、ショップ運営者へお問い合わせください。<br>),
		err_TemplOrder3_002 => qq(クーポンIDの入力に誤りがあります。<br>),
		err_TemplOrder3_003 => qq(クーポン情報を取得できませんでした。もう一度実行してください。<br>再度、このメッセージが表\示される場合は、お手数ですが、ショップ運営者へお問い合わせください。<br>),
		err_TemplOrder3_004 => qq(入力されたクーポンIDは、すでに使用されています。恐れ入りますが、クーポンIDはお一人様につき一度のみのご使用とさせていただいております。<br>),
		err_TemplOrder3_005 => qq(恐れ入りますが、入力されたクーポンIDは、ご使用期限が過ぎているため、ご使用いただけません。<br>),
		err_TemplOrder3_006 => qq(恐れ入りますが、入力されたクーポンIDは、商品合計金額が不足しているため、ご利用いただけません。<br>),
		err_TemplOrder3_007 => qq(ご注文手続きの間に、ポイント数の変更が行われました。<br>お手数ですが、もう一度ご注文を行ってください。<br>),
#		err_TemplOrder3_008 => qq(★会員情報の保有ポイント更新時、ポイント使用後の保有ポイント数が0未満になる<br>),
		err_TemplOrder3_009 => qq(データベースへ接続できませんでした。もう一度実行してください。<br>再度、このメッセージが表\示される場合は、お手数ですが、ショップ運営者へお問い合わせください。<br>),
#		err_TemplOrder3_010 => qq(★会員情報の保有ポイント更新時、会員情報の取得に失敗した<br>),
#		err_TemplOrder3_011 => qq(★会員情報の保有ポイント更新時、会員情報が存在しない<br>),
		err_TemplOrder3_012 => qq(ポイント情報を更新できませんでした。もう一度実行してください。<br>再度、このメッセージが表\示される場合は、お手数ですが、ショップ運営者へお問い合わせください。<br>),
		err_TemplOrder3_013 => qq(クーポン情報を更新できませんでした。もう一度実行してください。<br>再度、このメッセージが表\示される場合は、お手数ですが、ショップ運営者へお問い合わせください。<br>),
		err_TemplOrder3_014 => qq(システムエラーが発生しました。もう一度実行してください。<br>再度、このメッセージが表\示される場合は、お手数ですが、ショップ運営者へお問い合わせください。<br>),
		err_TemplOrder3_015 => qq(データベースエラーが発生しました。もう一度実行してください。<br>再度、このメッセージが表\示される場合は、お手数ですが、ショップ運営者へお問い合わせください。<br>),
		
		# SBPS決済用エラーコード(Order1にリダイレクト系)
		err_SbpsPayInfo_001 => qq(クーポン情報を取得できませんでした。もう一度実行してください。<br>再度、このメッセージが表\示される場合は、お手数ですが、ショップ運営者へお問い合わせください。（sbps_error）<br>),
		err_SbpsPayInfo_002 => qq(クーポンIDの入力に誤りがあります。（sbps_error）<br>),
		err_SbpsPayInfo_003 => qq(クーポン情報を取得できませんでした。もう一度実行してください。<br>再度、このメッセージが表\示される場合は、お手数ですが、ショップ運営者へお問い合わせください。（sbps_error）<br>),
		err_SbpsPayInfo_004 => qq(入力されたクーポンIDは、すでに使用されています。恐れ入りますが、クーポンIDはお一人様につき一度のみのご使用とさせていただいております。（sbps_error）<br>),
		err_SbpsPayInfo_005 => qq(恐れ入りますが、入力されたクーポンIDは、ご使用期限が過ぎているため、ご使用いただけません。（sbps_error）<br>),
		err_SbpsPayInfo_006 => qq(恐れ入りますが、入力されたクーポンIDは、商品合計金額が不足しているため、ご利用いただけません。（sbps_error）<br>),
		err_SbpsPayInfo_007 => qq(ご注文手続きの間に、ポイント数の変更が行われました。<br>お手数ですが、もう一度ご注文を行ってください。（sbps_error）<br>),
		err_SbpsPayInfo_009 => qq(データベースへ接続できませんでした。もう一度実行してください。<br>再度、このメッセージが表\示される場合は、お手数ですが、ショップ運営者へお問い合わせください。（sbps_error）<br>),
		err_SbpsPayInfo_012 => qq(ポイント情報を更新できませんでした。もう一度実行してください。<br>再度、このメッセージが表\示される場合は、お手数ですが、ショップ運営者へお問い合わせください。（sbps_error）<br>),
		err_SbpsPayInfo_013 => qq(クーポン情報を更新できませんでした。もう一度実行してください。<br>再度、このメッセージが表\示される場合は、お手数ですが、ショップ運営者へお問い合わせください。（sbps_error）<br>),
		err_SbpsPayInfo_014 => qq(システムエラーが発生しました。もう一度実行してください。<br>再度、このメッセージが表\示される場合は、お手数ですが、ショップ運営者へお問い合わせください。（sbps_error）<br>),
		err_SbpsPayInfo_015 => qq(データベースエラーが発生しました。もう一度実行してください。<br>再度、このメッセージが表\示される場合は、お手数ですが、ショップ運営者へお問い合わせください。（sbps_error）<br>),
		err_SbpsPayInfo_016 => qq(SBPS決済が正常に完了しませんでした。<br>処理結果：NG ($in{ErrorCode})（sbps_error）),
		err_SbpsPayInfo_017 => qq(SBPS決済が正常に完了しませんでした。<br>処理結果：AR,CR（sbps_error）),
		err_SbpsPayInfo_018 => qq(SBPS決済が正常に完了しませんでした。<br>処理結果：不明（sbps_error）),
		err_SbpsPayInfo_019 => qq(SBPS決済が正常に完了しませんでした。<br>チェックサム値が不正です。（sbps_error）),
		err_SbpsPayInfo_020 => qq(決済方法が設定されていません。<br>店舗管理者は決済方法の設定内容をご確認ください。（sbps_error）),
		err_SbpsPayInfo_021 => qq(SBPS決済が正常に完了しませんでした。<br>金額値が不正です。（sbps_error）),
		err_SbpsPayInfo_022	=> qq(SBPS決済が正常に完了しませんでした。<br>恐れ入りますが、再度注文を行ってください。（sbps_error）),
		
		# 楽天カード用エラーコード(Order1にリダイレクト系)
		NG => qq(楽天カード決済が正常に完了しませんでした。<br>処理結果：NG ($in{ErrorCode})（rakuten_error）),
		CN => qq(申\込がキャンセルされました。<br>処理結果：CN（rakuten_error）),
	);

	my $error_code = shift @_;
	return ( exists $ErrorMessageHash{$error_code} )? $ErrorMessageHash{$error_code}: qq();
}












