#!/usr/bin/perl 
my $bFound = 0;
my $sDir;
foreach $sDir (@INC)
{
if ($sDir eq ".")
{
$bFound = 1;
last;
}
}
if (!$bFound)
{
push (@INC, ".");
}
push (@INC, "cgi-bin");
require al000001;
require as000001;
require ad000001;
require ae000001;
require ao000001;
require sm000001;
require ws000001;
require mp000001;
use Socket;
use strict;
$::prog_name = "ORDERSCR";
$::prog_name = $::prog_name;
$::prog_ver = '$Revision: 53040 $ ';
$::prog_ver = substr($::prog_ver, 11);
$::prog_ver =~ s/ \$//;
$::FORWARD	= 0;
$::BACKWARD	= 1;
$::eDelivery	= 0;
$::eInvoice		= 1;
$::ORDER_BLOB_VERSION = 27;
$::ORDER_DETAIL_BLOB_VERSION = 13;
$::g_nCurrentSequenceNumber = -1;
$::g_nNextSequenceNumber = -1;
$::g_bSpitSSLChange = $::FALSE;
my $nDebugLogLevel = 0;
if ($nDebugLogLevel)
{
$::DEBUG_CLASS_FILTER |= $::DC_ORDERSCRIPT;
$::DEBUG_CLASS_FILTER |= $::DC_SMTP;
$::DC_LOG_SHORT = 1;
}
my $bDivertPSPAuthorise = $::FALSE;
my $nSimulatePSPAuthoriseError = 0;
$::g_pFieldSizes =
{
'NAME'			=> 40,
'FIRSTNAME'		=> 40,
'LASTNAME' 		=> 40,
'SALUTATION'	=> 15,
'JOBTITLE'		=> 50,
'COMPANY'		=> 100,
'PHONE'			=> 25,
'MOBILE'		=> 25,
'FAX'			=> 25,
'EMAIL'			=> 255,
'ADDRESS1'		=> 200,
'ADDRESS2'		=> 200,
'ADDRESS3'		=> 200,
'ADDRESS4'		=> 200,
'POSTALCODE'	=> 50,
'COUNTRY'		=> 75,
'USERDEFINED'	=> 255,
'HOWFOUND'		=> 255,
'WHYBUY'		=> 255,
'PONO'			=> 50,
'DPDUSERDEF'	=> 512,
};
$::g_sSavedMailSeparator = "------SDMultipart-----\r\n";
$::V12STATUS_REFERRED = 	"R";
$::V12STATUS_DECLINED = 	"D";
$::V12STATUS_APPROVED = 	"A";
$::V12STATUS_AMENDED = 		"M";
$::V12STATUS_SIGNED = 		"S";
$::V12STATUS_FUNDED = 		"F";
$::V12STATUS_CANCELLED =	"C";
$::V12FLAG_REFERRED =	8;
$::V12FLAG_DECLINED =	10;
$::V12FLAG_APPROVED =	15;
$::V12FLAG_AMENDED =	21;
$::V12FLAG_SIGNED =	30;
$::V12FLAG_FUNDED =	60;
$::V12FLAG_CANCELLED =	100;
$::g_pStatesToFlags =
{
$::V12STATUS_REFERRED => $::V12FLAG_REFERRED,
$::V12STATUS_DECLINED => $::V12FLAG_DECLINED,
$::V12STATUS_APPROVED => $::V12FLAG_APPROVED,
$::V12STATUS_AMENDED => $::V12FLAG_AMENDED,
$::V12STATUS_SIGNED => $::V12FLAG_SIGNED,
$::V12STATUS_FUNDED => $::V12FLAG_FUNDED, 
$::V12STATUS_CANCELLED => $::V12FLAG_CANCELLED
};
$::V12FINANCE_ERROR			= 0;
$::V12FINANCE_ACKNOWLEDGED	= 1;
$::V12FINANCE_REFERRED		= 2;
$::V12FINANCE_DECLINED		= 3;
$::V12FINANCE_ACCEPTED		= 4;
$::V12FINANCE_AWAITING_FUL	= 5;
$::V12FINANCE_PAY_REQUESTD	= 6;
$::V12FINANCE_PAY_PROCESSED	= 7;
$::V12FINANCE_CANCELLED		= 100;
$::bLogV12Events = $::FALSE;
$::DPD_STANDARD_DELIVERY	= 1;
$::DPD_SPECIFIED_DAY		= 2;
$::DPD_COLLECTION_POINT_PICKUP = 3;
$::DPD_COLLECTION_POINT_PICKUP_CAPTION = "Collection Point Pickup:";
$::DPD_SPECIFIED_DAY_CAPTION = "Specified Day Delivery:";
Init();
ProcessInput();
exit;
sub Init
{
$::g_bFirstError = $::TRUE;
my (@Response, $Status, $Message, $sAction, $sSendMailButton);
@Response = ReadAndParseInput();
($Status, $Message) = @Response;
if ($Status != $::SUCCESS)
{
ACTINIC::TerminalError($Message);
}
if ((not defined $::g_InputHash{'ACTION'}) &&
($::g_InputHash{'m_6'} eq 'VCSCALL'))
{
my $sAuthCallURL = ACTINIC::DecodeText($::g_InputHash{'m_3'}, $ACTINIC::FORM_URL_ENCODED);
$sAuthCallURL =~ /.*?SEQUENCE=(.*?)\&/;
$::g_InputHash{'SEQUENCE'} = $1;
$sAuthCallURL =~ /.*?ACTION=(.*?)\&/;
$::g_InputHash{'ACTION'} = $1;
$sAuthCallURL =~ /.*?CARTID=(.*?)\&/;
$::g_InputHash{'CARTID'} = $1;
$::g_InputHash{'ACT_POSTPROCESS'} = 1;
$::g_InputHash{ON} = $::g_InputHash{m_1};
$::g_InputHash{AM} = $::g_InputHash{p6} * $::g_InputHash{m_8};
}
if ($::g_InputHash{'ACTION'} =~ m/SSP_TRACK/i)
{
my $sPath = ACTINIC::GetPath();
@Response = ACTINIC::ReadPromptFile($sPath);
($Status, $Message) = @Response;
if ($Status != $::SUCCESS)
{
ACTINIC::ReportError($Message, ACTINIC::GetPath());
}
@Response = ACTINIC::ReadSSPSetupFile($sPath);
($Status, $Message) = @Response;
if ($Status != $::SUCCESS)
{
ACTINIC::ReportError($Message, ACTINIC::GetPath());
}
@Response = FormatTrackingPage();
($Status, $Message) = @Response;
if ($Status != $::SUCCESS)
{
ACTINIC::ReportError($Message, ACTINIC::GetPath());
}
my $sHTML = $Response[2];
ACTINIC::PrintPage($sHTML, undef);
exit;
}
if ($::g_InputHash{'ACTION'} =~ m/^V12_TRACKING/i &&
$::g_InputHash{'Status'} eq $::V12STATUS_SIGNED)
{			
@Response = ReadAndParseBlobs();
my ($Status, $Message) = @Response;
if ($Status != $::SUCCESS)
{
ACTINIC::ReportError($Message, ACTINIC::GetPath());
}
my @Response = CheckV12StatusFlag();
if ($Response[0] != $::SUCCESS)
{				
ACTINIC::RecordErrors($Response[1], ACTINIC::GetPath());
ACTINIC::PrintPSPResponse('text/plain', '0');
exit;
}
my $sON = $::g_InputHash{'SR'};
$sON =~ s/(.*?)-(\d+$)/$1/;
my $bCallbackFlag = $::TRUE;
if (IsAuthoriseSessionPresent($sON))
{
$::Session = new Session($sON, "", ACTINIC::GetPath(), $::FALSE, $bCallbackFlag, $::TRUE, $::AUTHORISE_SESSION_DAYS_V12F);
}		
if (!defined $::Session)
{
LogData("V12 order tracking call - authorize session not found for order $sON");
ACTINIC::PrintPSPResponse('text/plain', '1');
exit;
}
LogData("Generating emails for V12 order");
EmailReceipt($sON);
ACTINIC::PrintPSPResponse('text/plain', '1');
exit;
}
if (!defined $::g_InputHash{'ACTION'} &&
(defined $::g_InputHash{'ApplicationId'}) &&
(defined $::g_InputHash{'SalesReference'}) &&
(defined $::g_InputHash{'Status'}))
{		
$::g_PaymentInfo{'METHOD'} = $::PAYMENT_V12FINANCE;
my	$sPath = ACTINIC::GetPath();
@Response = ACTINIC::ReadPaymentFile($sPath);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}		
@Response = ACTINIC::ReadSetupFile($sPath);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}		
@Response = GetOCCScript($sPath);		
if ($Response[0] != $::SUCCESS)
{
return ($Response[0], $Response[1]);
}
my ($sScript) = $Response[2];
if (eval($sScript) != $::SUCCESS)
{
ACTINIC::ReportError($@, ACTINIC::GetPath());
}		
@Response = UpdateApplicationStatus($::g_InputHash{'ApplicationId'});
if ($Response[0] != $::SUCCESS)
{
return ($Response[0], $Response[1]);
}		
my $nStatus = $Response[2];
my $nAmount = $Response[3];
my $sAuthCode = $Response[4];		
$::g_InputHash{'ACTION'} = sprintf("AUTHORIZE_%d", $::g_PaymentInfo{'METHOD'});
$::g_InputHash{'ON'} = $::g_InputHash{'SalesReference'};
$::g_InputHash{'ON'} =~ s/(.*?)-(\d+$)/$1/;
$::g_InputHash{'CARTID'} = $Response[5];
my $sMsg = sprintf("Processing V12 callback. Line %d. Order:%s Status:%d Amount:%d Cart:%s", __LINE__, $::g_InputHash{'SalesReference'}, $nStatus, $nAmount, $::g_InputHash{'CARTID'});
LogV12Event($sMsg);
my $bCallbackFlag = $::TRUE;	
if (IsAuthoriseSessionPresent($::g_InputHash{ON}))
{
$::Session = new Session($::g_InputHash{ON}, "", ACTINIC::GetPath(), $::FALSE, $bCallbackFlag, $::TRUE, $::AUTHORISE_SESSION_DAYS_V12F);
}		
if (!defined $::Session)
{
LogData("V12 Status update call - authorize session not found for order " . $::g_InputHash{ON});
ACTINIC::PrintPSPResponse('text/plain', '1');
exit;
}
RecordV12FinanceBlob($::g_InputHash{'ON'}, $nStatus, $nAmount, $sAuthCode);
ACTINIC::PrintPSPResponse('text/plain', '1');
exit;
}	
if ($::g_InputHash{'SEQUENCE'} <= 3)
{
CreateAddressBook();
}
@Response = ReadAndParseBlobs();
($Status, $Message) = @Response;
if ($Status != $::SUCCESS)
{
ACTINIC::ReportError($Message, ACTINIC::GetPath());
}
if (defined $::g_InputHash{'SEQUENCE'} && $::g_InputHash{'SEQUENCE'} < 3)
{
ACTINIC::LogData('Call from Order to Mailchimp', $::DC_ORDERSCRIPT);
my $oMailchimp;
my $bPrivacy = ($::g_InputHash{'INVOICEPRIVACY'} eq 'YES');
if (!$::g_BillContact{'SEPARATE'})
{
if (defined $::g_InputHash{'LocationInvoiceCountry'})
{
$::g_LocationInfo{DELIVERY_COUNTRY_CODE} = $::g_InputHash{'LocationInvoiceCountry'};
}
if (defined $::g_InputHash{'LocationInvoiceRegion'})
{
$::g_LocationInfo{DELIVERY_REGION_CODE} = $::g_InputHash{'LocationInvoiceRegion'};
}
if ((defined $::g_InputHash{'LocationInvoiceCountry'}) &&
(defined $::g_InputHash{'INVOICEADDRESS4'}) &&
(defined $::g_InputHash{'INVOICEPOSTALCODE'}))
{
$::g_LocationInfo{DELIVERY_REGION_CODE_FROM_POSTCODE} = 
ActinicOrder::GetSellerDeckRegion($::g_InputHash{'LocationInvoiceCountry'},
$::g_InputHash{'INVOICEADDRESS4'},
$::g_InputHash{'INVOICEPOSTALCODE'},
(defined $::g_InputHash{'LocationInvoiceRegion'}) ? 
$::g_InputHash{'LocationInvoiceRegion'} : 
$ActinicOrder::UNDEFINED_REGION);				
}
}
else 
{
if (defined $::g_InputHash{'LocationDeliveryCountry'})
{			
$::g_LocationInfo{DELIVERY_COUNTRY_CODE} = $::g_InputHash{'LocationDeliveryCountry'};
}
if (defined $::g_InputHash{'LocationDeliveryRegion'})
{				
$::g_LocationInfo{DELIVERY_REGION_CODE} = $::g_InputHash{'LocationDeliveryRegion'};
}
if ((defined $::g_InputHash{'LocationDeliveryCountry'}) &&
(defined $::g_InputHash{'DELIVERADDRESS4'}) &&
(defined $::g_InputHash{'DELIVERPOSTALCODE'}))
{
ActinicOrder::GetSellerDeckRegion($::g_InputHash{'LocationDeliveryCountry'},
$::g_InputHash{'DELIVERADDRESS4'},
$::g_InputHash{'DELIVERPOSTALCODE'},
(defined $::g_InputHash{'LocationDeliveryRegion'}) ? 
$::g_InputHash{'LocationDeliveryRegion'} : 
$ActinicOrder::UNDEFINED_REGION);
}
}
if($::g_InputHash{'INVOICEEMAIL'})
{
my  $hInput = {
'FIRSTNAME' => $::g_InputHash{'INVOICEFIRSTNAME'},
'LASTNAME'  => $::g_InputHash{'INVOICELASTNAME'},
'EMAIL'     => $::g_InputHash{'INVOICEEMAIL'},
'ADDRESS1'  => $::g_InputHash{'INVOICEADDRESS1'},
'ADDRESS2'  => $::g_InputHash{'INVOICEADDRESS2'},
'ADDRESS3'  => $::g_InputHash{'INVOICEADDRESS3'},
'ADDRESS4'  => $::g_InputHash{'INVOICEADDRESS4'},
'COUNTRY'   => $::g_InputHash{'INVOICECOUNTRY'} ? 
$::g_InputHash{'INVOICECOUNTRY'} : 
$::g_InputHash{'LocationInvoiceCountry'},
'POSTALCODE'  => $::g_InputHash{'INVOICEPOSTALCODE'},
'PHONE'  => $::g_InputHash{'INVOICEPHONE'},
};
$oMailchimp = MailchimpPkg->new($hInput, $bPrivacy);
}
else
{
$oMailchimp = MailchimpPkg->new();
}
@Response = $oMailchimp->AddToMailchimp();
if ($Response[0] != $::SUCCESS)
{
ACTINIC::RecordErrors("Error when adding the cart to MailChimp. Error message: $Response[1] ", ACTINIC::GetPath());
}
}
if (defined $::Session)
{
$::g_sWebSiteUrl = $::Session->GetBaseUrl();
$::g_sContentUrl = $::g_sWebSiteUrl;
}
if ((!defined $::g_InputHash{'ACTION'}) &&
(defined $::g_InputHash{'REF'}) &&
(defined $::g_InputHash{'SR'}))
{
my $sFinishButton = ACTINIC::GetPhrase(-1, 504);
$::g_InputHash{'ACTION'} = $sFinishButton;
$::g_InputHash{'SEQUENCE'} = 3;
$::g_InputHash{'ORDERNUMBER'} = $::g_InputHash{'SR'};
$::g_InputHash{'ORDERNUMBER'} =~ s/(.*?)-(\d+$)/$1/;
my $sMsg = sprintf("Bouncing back to the merchant site. Line %d. Order:%s Status:%s", __LINE__, $::g_InputHash{'SR'}, $::g_InputHash{'Status'});
LogV12Event($sMsg);
my @Response = CheckV12StatusFlag();
if ($Response[0] != $::SUCCESS)
{				
ACTINIC::RecordErrors($Response[1], ACTINIC::GetPath());
my $sRefPage = $::Session->GetLastShopPage();
if (defined $$::g_pSetupBlob{'UNFRAMED_CHECKOUT_URL'} &&
$$::g_pSetupBlob{'UNFRAMED_CHECKOUT_URL'} ne "")
{
$sRefPage = $$::g_pSetupBlob{'UNFRAMED_CHECKOUT_URL'};
}
@Response = ACTINIC::BounceToPageEnhanced($$::g_pSetupBlob{'BOUNCE_PAGE_DELAY'}, $Response[1],
$$::g_pSetupBlob{CHECKOUT_DESCRIPTION},
$::g_sWebSiteUrl,
$::g_sContentUrl, $::g_pSetupBlob, $sRefPage, \%::g_InputHash,
$::FALSE);
my $sHTML = $Response[2];
UpdateCheckoutRecord();
my $sDetailCookie = $::Session->ContactDetailsToCookieString();				
$::Session->SaveSession();
ACTINIC::UpdateDisplay($sHTML, $::g_OriginalInputData, undef, undef, $sDetailCookie, ActinicOrder::GenerateCartCookie());
exit;
}
if ($::g_InputHash{'Status'} ne $::V12STATUS_CANCELLED &&
$::g_InputHash{'Status'} ne $::V12STATUS_REFERRED  &&
$::g_InputHash{'Status'} ne $::V12STATUS_DECLINED)
{
$::g_PaymentInfo{'METHOD'} = $::PAYMENT_V12FINANCE;			
my @Response = GetOCCScript(ACTINIC::GetPath());		
if ($Response[0] != $::SUCCESS)
{
return ($Response[0], $Response[1]);
}
my ($sScript) = $Response[2];
if (eval($sScript) != $::SUCCESS)
{
ACTINIC::ReportError($@, ACTINIC::GetPath());
}
RecordV12FinanceBlob();
}
elsif (($::g_InputHash{'Status'} eq $::V12STATUS_DECLINED) || # declined? customer has to choose a different payment method then
($::g_InputHash{'Status'} eq $::V12STATUS_CANCELLED))
{
LogData("v12 Finance Application Declined or Cancelled");
my $sBackButton = ACTINIC::GetPhrase(-1, 503);
$::g_InputHash{'ACTION'} = $sBackButton;
if ($::g_InputHash{'Status'} eq $::V12STATUS_DECLINED)
{
$::g_InputHash{'V12DECLINED'} = 1;
}
else
{
$::g_InputHash{'V12CANCELLED'} = 1;
}
$::g_InputHash{'JS'} = 1;
}
elsif ($::g_InputHash{'Status'} eq $::V12STATUS_REFERRED) # referred?
{
LogData("v12 Finance Application referred");			
my $sBackButton = ACTINIC::GetPhrase(-1, 503);
$::g_InputHash{'ACTION'} = $sBackButton;
$::g_InputHash{'JS'} = 1;
$::g_InputHash{'V12REFERRED'} = 1;			
}
}	
if ($::g_InputHash{"ACTION"} =~ /^OFFLINE_AUTHORIZE/i)
{
DoOfflineAuthorization();
exit;
}
if(($::g_InputHash{"ACTION"} eq "INCONTEXTPSP") ||
($::g_InputHash{ACTION} =~ /^AUTHORIZE/i))
{
$::Session->SetCallBack($::TRUE);
}
else
{
$ACTINIC::B2B->Set('UserDigest',ACTINIC::CAccFindUser());
}
if( $::g_InputHash{'BASE'} )
{
$::g_sContentUrl = $::g_InputHash{'BASE'};
}
}
sub ReadAndParseInput
{
my ($status, $message, $temp);
($status, $message, $::g_OriginalInputData, $temp, %::g_InputHash) = ACTINIC::ReadAndParseInput();
if ($status != $::SUCCESS)
{
return ($status, $message, 0, 0);
}
if( $::g_InputHash{INVOICEADDRESSSELECT} )
{
undef $::g_InputHash{'INVOICESALUTATION'};
undef $::g_InputHash{'INVOICENAME'};
undef $::g_InputHash{'INVOICEFIRSTNAME'};
undef $::g_InputHash{'INVOICELASTNAME'};
undef $::g_InputHash{'INVOICEJOBTITLE'};
undef $::g_InputHash{'INVOICECOMPANY'};
undef $::g_InputHash{'INVOICEADDRESS1'};
undef $::g_InputHash{'INVOICEADDRESS2'};
undef $::g_InputHash{'INVOICEADDRESS3'};
undef $::g_InputHash{'INVOICEADDRESS4'};
undef $::g_InputHash{'INVOICEPOSTALCODE'};
undef $::g_InputHash{'INVOICECOUNTRY'};
undef $::g_InputHash{'INVOICEPHONE'};
undef $::g_InputHash{'INVOICEMOBILE'};
undef $::g_InputHash{'INVOICEFAX'};
undef $::g_InputHash{'INVOICEEMAIL'};
};
if( $::g_InputHash{DELIVERADDRESSSELECT} )
{
undef $::g_InputHash{'DELIVERSALUTATION'};
undef $::g_InputHash{'DELIVERNAME'};
undef $::g_InputHash{'DELIVERFIRSTNAME'};
undef $::g_InputHash{'DELIVERLASTNAME'};
undef $::g_InputHash{'DELIVERJOBTITLE'};
undef $::g_InputHash{'DELIVERCOMPANY'};
undef $::g_InputHash{'DELIVERADDRESS1'};
undef $::g_InputHash{'DELIVERADDRESS2'};
undef $::g_InputHash{'DELIVERADDRESS3'};
undef $::g_InputHash{'DELIVERADDRESS4'};
undef $::g_InputHash{'DELIVERPOSTALCODE'};
undef $::g_InputHash{'DELIVERCOUNTRY'};
undef $::g_InputHash{'DELIVERPHONE'};
undef $::g_InputHash{'DELIVERMOBILE'};
undef $::g_InputHash{'DELIVERFAX'};
undef $::g_InputHash{'DELIVEREMAIL'};
undef $::g_InputHash{'DELIVERUSERDEFINED'};
}
return ($::SUCCESS, "", 0, 0);
}
sub ReadAndParseBlobs
{
my ($Status, $Message, @Response, $sPath);
$sPath = ACTINIC::GetPath();
my @arrFuncns =
(
\&ACTINIC::ReadCatalogFile,
\&ACTINIC::ReadSetupFile,
\&ACTINIC::ReadLocationsFile,
\&ACTINIC::ReadPaymentFile,
\&ACTINIC::ReadPhaseFile,
\&ACTINIC::ReadPromptFile,
\&ACTINIC::ReadTaxSetupFile,
\&ACTINIC::ReadSSPSetupFile,
\&ACTINIC::ReadDiscountBlob,
\&ACTINIC::ReadPostCodeRegionsFile,
);
my $pfunRead;
foreach $pfunRead (@arrFuncns)
{
@Response = &$pfunRead($sPath);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
}
ACTINIC::InitMonthMap();
$::Session = undef;
$::Authorise = undef;
if ($::g_InputHash{"ACTION"} =~ /^PSP_IPN_/i)
{
return ($::SUCCESS, "", 0, 0);
}
my ($sContactDetails);
($::g_sCartId, $sContactDetails) = ACTINIC::GetCookies();
if ($::g_InputHash{CARTID} &&
$::g_InputHash{CARTID} =~ /^[a-zA-Z0-9]+$/)
{
$::g_sCartId = $::g_InputHash{CARTID};
}
if ($::g_InputHash{CART} &&
$::g_InputHash{CART} =~ /^[a-zA-Z0-9]+$/)
{
$::g_sCartId = $::g_InputHash{CART};
}
my $bCallbackFlag;
if	(($::g_InputHash{"ACTION"} eq "INCONTEXTPSP") ||
($::g_InputHash{"ACTION"} =~ /^AUTHORIZE/i) ||
($::g_InputHash{"ACTION"} =~ /^OFFLINE_AUTHORIZE/i))
{
$bCallbackFlag = $::TRUE;
}
else
{
$bCallbackFlag = $::FALSE;
}
if (($::g_InputHash{'ACTION'} =~ m/^AUTHORIZE/i) ||
($::g_InputHash{'ACTION'} =~ m/^OFFLINE_AUTHORIZE/i) ||
($::g_InputHash{'ACTION'} eq 'INCONTEXTPSP') ||
($::g_InputHash{'ACTION'} eq 'OFFLINEPSP_' . $::PAYMENT_SELLERDECKBYOPAYO))
{
if (defined $::g_InputHash{ON})
{
if (IsAuthoriseSessionPresent($::g_InputHash{ON}) ||
("OFFLINEPSP_$::PAYMENT_SELLERDECKBYOPAYO" eq $::g_InputHash{'ACTION'}))
{
my $nAuthorise = $::TRUE;
if ("OFFLINEPSP_$::PAYMENT_SELLERDECKBYOPAYO" eq $::g_InputHash{'ACTION'})
{
my ($nStatus, $sError) = ACTINIC::AuthenticateUser($::g_InputHash{'USER'}, $::g_InputHash{'PASS'});
if ($nStatus != $::SUCCESS)
{
LogData("Authentication failed for action [$::g_InputHash{'ACTION'}]");
my $sResponse = "45300";
binmode STDOUT;
ACTINIC::PrintHeader('application/octet-stream', (length $sResponse), undef, $::FALSE);
print $sResponse;
exit;
}	
$bCallbackFlag = $::TRUE;
$sContactDetails = "";
$nAuthorise = 2;
}
$::Session = new Session($::g_InputHash{ON}, $sContactDetails, ACTINIC::GetPath(), $::FALSE, $bCallbackFlag, $nAuthorise);
}
}
}
if (!defined $::Session)
{
$::Session = new Session($::g_sCartId, $sContactDetails, ACTINIC::GetPath(), $::FALSE, $bCallbackFlag, $::FALSE);
if (!$::Session->IsCallBack() &&
$::Session->IsNewSession())
{
if ($::g_InputHash{'ACTION'} ne ACTINIC::GetPhrase(-1, 113))
{
my $sRefPage = $$::g_pSetupBlob{CATALOG_URL} . $$::g_pSetupBlob{CATALOG_PAGE};
$::bCookieCheckRequired = $::FALSE;
my @Response = ACTINIC::BounceToPageEnhanced(undef, ACTINIC::GetPhrase(-1, 1962) . ACTINIC::GetPhrase(-1, 2249, $::g_sCart, $::g_sCart) . ACTINIC::GetPhrase(-1, 1970) . ACTINIC::GetPhrase(-1, 2049),
$$::g_pSetupBlob{CHECKOUT_DESCRIPTION},
$::g_sWebSiteUrl,
$::g_sContentUrl, $::g_pSetupBlob, $sRefPage, \%::g_InputHash,
$::FALSE);
if ($Response[0] != $::SUCCESS)
{
ACTINIC::ReportError(ACTINIC::GetPhrase(-1, 2249), $::Session->GetSessionFileFolder());
}
ACTINIC::SaveSessionAndPrintPage($Response[2]);
exit;
}
}
}
if ($::g_bSpitSSLChange &&
$sContactDetails ne "")
{
$::Session->CookieStringToContactDetails();
}
@Response = GetCheckoutStatus();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
return ($::SUCCESS, "", 0, 0);
}
sub GetCheckoutStatus
{
my ($Status, $Message,
$pBillContact, $pShipContact, $pShipInfo, $pTaxInfo, $pGeneralInfo, $pPaymentInfo, $pLocationInfo) = $::Session->RestoreCheckoutInfo();
if ($Status != $::SUCCESS)
{
return ($Status, $Message);
}
no strict 'refs';
%::g_BillContact = %$pBillContact;
%::g_ShipContact = %$pShipContact;
%::g_ShipInfo		= %$pShipInfo;
%::g_TaxInfo		= %$pTaxInfo;
%::g_GeneralInfo = %$pGeneralInfo;
%::g_PaymentInfo = %$pPaymentInfo;
%::g_LocationInfo = %$pLocationInfo;
$::g_sTaxDump = (join "|", keys %::g_TaxInfo) . (join "|", values %::g_TaxInfo);	
$::g_sShippingDump = ActinicOrder::GetShippingDump();
return ($::SUCCESS, "");
}
sub ProcessInput
{
my (@Response, $sDetailCookie, $sError);
$::g_nCurrentSequenceNumber = $::g_InputHash{'SEQUENCE'};
if (!defined $::g_nCurrentSequenceNumber)
{
$::g_nCurrentSequenceNumber = $::STARTSEQUENCE;
}
my ($sConfirmButton, $sStartButton, $sDoneButton, $sNextButton, $sFinishButton, $sBackButton, $sCancelButton, $sChangeLocationButton, $sApplyButton);
$sConfirmButton = ACTINIC::GetPhrase(-1, 153);
$sStartButton = ACTINIC::GetPhrase(-1, 113);
$sDoneButton = ACTINIC::GetPhrase(-1, 114);
$sNextButton = ACTINIC::GetPhrase(-1, 502);
$sBackButton = ACTINIC::GetPhrase(-1, 503);
$sFinishButton = ACTINIC::GetPhrase(-1, 504);
$sCancelButton = ACTINIC::GetPhrase(-1, 505);
$sChangeLocationButton = ACTINIC::GetPhrase(0, 18);
$sApplyButton = ACTINIC::GetPhrase(-1, 3082);
my $sConfirmOrderButton = ACTINIC::GetPhrase(-1, 2602);
my ($sHTML, $sAction, $eDirection);
if (defined $::g_InputHash{'ACTION_CONFIRM'})
{
$::g_InputHash{'ACTION'} = $sConfirmOrderButton;
undef $::g_InputHash{'ACTION_CONFIRM'};
}
$sAction = $::g_InputHash{'ACTION'};
if (($sAction eq $sBackButton) &&
(defined $::g_InputHash{'ERROR'}))
{
$sError = ACTINIC::HTMLEncode($::g_InputHash{'ERROR'});
}
elsif (($sAction eq $sBackButton) &&
(defined $::g_InputHash{'V12REFERRED'}))
{
my $sMsg = "<span style=\"font-size: 13px;\"><strong>Your credit application has been referred for further checks.</strong>" .
"<br><br>V12 Retail Finance cannot make an instant decision on the application from the data they have received and they may " .
"contact you to get any further information required. A decision is usually made within 10 minutes, where in a small number of " .
"cases it may take two to three hours. As soon as a decision has been made, V12 Retail Finance will email you with the details of what to do next.<br><br></span>";
my $sRefPage = $::Session->GetLastShopPage();
if (defined $$::g_pSetupBlob{'UNFRAMED_CHECKOUT_URL'} &&
$$::g_pSetupBlob{'UNFRAMED_CHECKOUT_URL'} ne "")
{
$sRefPage = $$::g_pSetupBlob{'UNFRAMED_CHECKOUT_URL'};
}
@Response = ACTINIC::BounceToPageEnhanced(7, $sMsg,
$$::g_pSetupBlob{CHECKOUT_DESCRIPTION},
$::g_sWebSiteUrl,
$::g_sContentUrl, $::g_pSetupBlob, $sRefPage, \%::g_InputHash,
$::FALSE);
$sHTML = $Response[2];
UpdateCheckoutRecord();
$sDetailCookie = $::Session->ContactDetailsToCookieString();
$::Session->MarkAsClosed();
$::Session->SaveSession();
goto THEEND;
}
elsif ($::g_InputHash{'ACTION'} =~ m/^BEGINPSP_(\d+)$/i)
{
my $sMode;
$sMode = (defined $::g_InputHash{'MODE'}) ? $::g_InputHash{'MODE'} : 'HTML';
my $nPSP = $1;
my $sMethod = 'GetPspPage1';
@Response = ActinicOrder::ValidateStart($::TRUE);
if ($Response[0] == $::BADDATA)
{
$sHTML = $Response[1];
goto THEEND;
}
if ($Response[0] == $::SUCCESS)
{
if (ActinicDiscounts::IsMultipleFixedPriceCouponAccepted())
{
my $sCoupons = $::Session->GetCSVCouponCodes();
$::Session->SetCSVCouponCodesOrig($sCoupons);
}
$::Session->SetCheckoutStarted();
$::Session->SetInCheckout();
@Response = CallPspCheckoutMethod($nPSP, $sMethod);
}
if ($sMode eq 'JSON')
{
if ($Response[0] != $::SUCCESS)
{
my $hOutput = {'error' => {'message' => $Response[1]}};
my $sOutput = ACTINIC::EncodeJson($hOutput);
LogData($$::g_pPaymentList{$nPSP}{'PROMPT'} . ': JSON error response: ' . $sOutput);
ACTINIC::PrintJSON($sOutput);
}
exit;
}
if ($Response[0] != $::SUCCESS)
{
ACTINIC::RecordErrors(sprintf("Request %s for PSP %s returned '%s'", $sMethod, $$::g_pPaymentList{$nPSP}{'PROMPT'}, $Response[1]));
my $sMessage = ACTINIC::GetPhrase(-1, 3105, $$::g_pPaymentList{$nPSP}{'PROMPT'}, $Response[1]);
@Response = ACTINIC::BounceToPageEnhanced($$::g_pSetupBlob{'BOUNCE_PAGE_DELAY'}, $sMessage,
$$::g_pSetupBlob{CHECKOUT_DESCRIPTION},
$::g_sWebSiteUrl,
$::g_sContentUrl, $::g_pSetupBlob, $::Session->GetLastShopPage(), \%::g_InputHash,
$::FALSE);
}
$sHTML = $Response[2];
goto THEEND;
}
elsif ($::g_InputHash{'ACTION'} =~ m/^OFFLINEPSP_(\d+)$/i)
{
my $nPSP = $1;
my $sMethod = 'OfflinePSP';
@Response = CallPspCheckoutMethod($nPSP, $sMethod);
my $sResponse;
if ($Response[0] != $::SUCCESS)
{
ACTINIC::RecordErrors(sprintf("Request %s for PSP %s returned '%s'", $sMethod, $$::g_pPaymentList{$nPSP}{'PROMPT'}, $Response[1]));
my $sMessage = ACTINIC::GetPhrase(-1, 3105, $$::g_pPaymentList{$nPSP}{'PROMPT'}, $Response[1]);
$sResponse = "99900";
}
else
{
$sResponse = "20000";
}
binmode STDOUT;
ACTINIC::PrintHeader('application/octet-stream', (length $sResponse), undef, $::FALSE);
print $sResponse;
exit;
}
elsif ($::g_InputHash{'SUBACTION'} =~ m/^CHECKOUTPSP_(\d+)$/i)
{
my $nPSP = $1;
my $sMode;
$sMode = (defined $::g_InputHash{'MODE'}) ? $::g_InputHash{'MODE'} : 'HTML';
my $sMethod = ($::g_InputHash{'ACTION'} eq $sCancelButton) ? 'GetPspCancelPage' : 'GetPspPage2';
@Response = CallPspCheckoutMethod($nPSP, $sMethod);
if ($sMode eq 'JSON')
{
if ($Response[0] != $::SUCCESS)
{
my $hOutput = {'error' => {'message' => $Response[1]}};
my $sOutput = ACTINIC::EncodeJson($hOutput);
LogData($$::g_pPaymentList{$nPSP}{'PROMPT'} . ': JSON error response: ' . $sOutput);
ACTINIC::PrintJSON($sOutput);
exit;
}
}
if ($Response[0] != $::SUCCESS)
{
ACTINIC::RecordErrors("$sMethod for PSP $nPSP returned: $Response[1]");
my $sMessage = ACTINIC::GetPhrase(-1, 3105, $$::g_pPaymentList{$nPSP}{PROMPT}, $Response[1]);
@Response = ACTINIC::BounceToPageEnhanced(undef, $sMessage,
$$::g_pSetupBlob{CHECKOUT_DESCRIPTION},
$::g_sWebSiteUrl,
$::g_sContentUrl, $::g_pSetupBlob, $::Session->GetLastShopPage(), \%::g_InputHash,
$::FALSE);
$sHTML = $Response[2];
goto THEEND;
}
else
{
if (length $Response[2])
{
$sHTML = $Response[2];
goto THEEND;
}
$::g_nCurrentSequenceNumber = 3;
$sAction = $sNextButton;
}
}
elsif ($::g_InputHash{'ACTION'} =~ m/^PSP_IPN_(\d+)$/i)
{
LogData('IPN received by OrderScript');
my $nPSP = $1;
my $sMethod = 'ProcessIPN';
@Response = CallPspCheckoutMethod($nPSP, $sMethod);
if ($Response[0] != $::SUCCESS)
{
ACTINIC::ReportError("Logic error: $sMethod for PSP $nPSP $Response[1]");
}
ACTINIC::ReportError("Logic error: $sMethod for PSP $nPSP should have exited");
}
if ($sAction =~ m/$sStartButton/i)
{
$::Session->SetCheckoutStarted();
$::Session->SetInCheckout();
}
elsif (!$::Session->IsCheckoutStarted())
{
@Response = ACTINIC::BounceToPageEnhanced(undef, ACTINIC::GetPhrase(-1, 2300),
$$::g_pSetupBlob{CHECKOUT_DESCRIPTION},
$::g_sWebSiteUrl,
$::g_sContentUrl, $::g_pSetupBlob, $::Session->GetLastShopPage(), \%::g_InputHash,
$::FALSE);
$sHTML = $Response[2];
goto THEEND;
}
elsif (($::g_InputHash{'ACTION'} ne $sDoneButton) &&
(!exists $::g_InputHash{$sDoneButton . ".x"}) &&
!$::Session->IsCallBack() &&
$::Session->IsClosed())
{
@Response = ACTINIC::BounceToPageEnhanced(-1, ACTINIC::GetPhrase(-1, 1282),
$$::g_pSetupBlob{CHECKOUT_DESCRIPTION},
$::g_sWebSiteUrl,
$::g_sContentUrl, $::g_pSetupBlob,
$::Session->GetLastShopPage(),
\%::g_InputHash,
$::FALSE);
$sHTML = $Response[2];
goto THEEND;
}
elsif ($sAction eq $sApplyButton)
{		
my ($bActuallyValidate) = ($eDirection == $::FORWARD);
$::g_nNextSequenceNumber = $::g_nCurrentSequenceNumber;
$sError .= ValidateCoupon($bActuallyValidate);
if ($sError eq '')
{
$::Session->SetOverUseCoupon('');
if ($$::g_pSetupBlob{MAKE_SHIPPING_CHARGE})
{
@Response = ActinicOrder::GetShippingPluginResponse();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
}			
if ($::Session->GetOverUseCoupon())
{
$sError = ACTINIC::GetPhrase(-1, 3081, ACTINIC::HTMLEncode($::g_InputHash{'COUPONCODE'}));
}
}
if (!defined $::g_InputHash{'SEQUENCE'})
{
my $sError = ValidateOrderConfirmation();
$sHTML = DisplayShippingConfirmation($sError);
}
else
{
@Response = DisplayPage($sError, $::g_nNextSequenceNumber, $eDirection);		
$sHTML = $Response[2];
}
goto THEEND;
}
elsif ($sAction eq 'REMOVECOUPON')
{
$::g_nNextSequenceNumber = $::g_nCurrentSequenceNumber;
my $nIndex = $::g_InputHash{"COUPONINDEX"};
ActinicDiscounts::RemoveCouponCode($nIndex);
if (!defined $::g_InputHash{'SEQUENCE'})
{
my $sError = ValidateOrderConfirmation();
$sHTML = DisplayShippingConfirmation($sError);
}
else
{
@Response = DisplayPage($sError, $::g_nNextSequenceNumber, $eDirection);		
$sHTML = $Response[2];
}
goto THEEND;
}	
if ($::Session->IsPSPRequested())
{
if (($sAction =~ m/$sBackButton/i) &&
($::g_InputHash{'SEQUENCE'} = 3))
{
LogData("PSP backed out (back link):\n$::g_OriginalInputData");
$::Session->SetPSPRequested($::FALSE);
}
else
{
if ($::g_InputHash{"ACTION"} ne "INCONTEXTPSP")
{
if ($::Session->IsPageRefreshed())
{
LogData('Page refreshed');
}
else
{
$::Session->SetPSPSignature("");
LogData('PSP backed out (browser back button)');
}
}
}
}
if ($sAction eq $sConfirmButton)
{
my $nPSP = $::g_PaymentInfo{METHOD};
my $sMethod = 'GetPspPage3';
@Response = CallPspCheckoutMethod($nPSP, $sMethod);
if ($Response[0] != $::SUCCESS)
{
if ($Response[1] ne '')
{
ACTINIC::RecordErrors("Method $sMethod for PSP $nPSP returned $Response[1]");
}
my $sMessage = ACTINIC::GetPhrase(-1, 3105, $$::g_pPaymentList{$nPSP}{PROMPT}, $Response[1]);
@Response = ACTINIC::BounceToPageEnhanced(undef, $sMessage,
$$::g_pSetupBlob{CHECKOUT_DESCRIPTION},
$::g_sWebSiteUrl,
$::g_sContentUrl, $::g_pSetupBlob, ActinicOrder::GetCheckoutUrl(), \%::g_InputHash,
$::FALSE);
$sHTML = $Response[2];
goto THEEND;
}
if ($Response[2] ne '')
{
$sHTML = $Response[2];
goto THEEND;
}
$::g_nCurrentSequenceNumber = 3;
$sAction = $sNextButton;
}
elsif ($sAction eq 'GETPSPFORM')
{
my $nStatus;
$sError = ValidatePayment($::TRUE, 'text');
if ($sError eq '')
{
my $sFileName = 'PSPForm.html';
$::g_InputHash{JS} = "1";
if (ActinicOrder::PaymentStringToEnum($::g_PaymentInfo{'METHOD'}) != $::PAYMENT_V12FINANCE)
{				
$::g_pPaymentList->{ActinicOrder::PaymentStringToEnum($::g_PaymentInfo{'METHOD'})}{BOUNCE_HTML} = $sFileName;				
}
($nStatus, $sError, $sHTML) = CallOCCPlugIn();
if ($sError ne '')
{
ACTINIC::RecordErrors("GETPSPFORM CallOCCPlugIn Error:\r\n$sError", ACTINIC::GetPath());
}
else
{
@Response = CompleteOrder();
if ($Response[0] != $::SUCCESS)
{
ACTINIC::RecordErrors("GETPSPFORM CompleteOrder Error:\r\n$sError", ACTINIC::GetPath());
$sError = $Response[1];
}
else
{
LogData("PSP form prepared");
if (PSPUsesInContext())
{
$::Session->SaveSession();
ACTINIC::PrintText($sHTML);
return;
}
if (PSPUsesAuthoriseFile())
{
CloneSession();
}
}
}
}
$::Session->SaveSession();
if ($sError)
{
$sHTML = "Error: $sError";
$sError = "";
}
ACTINIC::PrintText($sHTML);
return;
}
elsif ($sAction eq 'GETSHIPPINGSELECT')
{
my $sHTML;
if ((defined $::g_InputHash{'LocationDeliveryRegion'}) &&
($::g_InputHash{'LocationDeliveryRegion'} ne ''))
{
$::g_InputHash{'LocationDeliveryRegion'} =~ s/^.*\.//;
$::g_LocationInfo{DELIVERY_REGION_CODE} = sprintf("%s.%s", $::g_LocationInfo{DELIVERY_COUNTRY_CODE}, $::g_InputHash{'LocationDeliveryRegion'});
}
if ($$::g_pSetupBlob{MAKE_SHIPPING_CHARGE})
{
my @Response = ActinicOrder::GetShippingPluginResponse();
$sHTML = $::s_Ship_ShippingVariables{$::VARPREFIX . 'SHIPPINGSELECT'};
if ($Response[0] != $::SUCCESS)
{
$sHTML = "Error: " . ACTINIC::GetPhrase(-1, 1974) . ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor) .
ACTINIC::GetPhrase(-1, 102) . ACTINIC::GetPhrase(-1, 1975) . ACTINIC::GetPhrase(-1, 1970) . " - ". $Response[1] . "<BR>\n";
}
elsif (${$Response[2]}{ValidateFinalInput} != $::SUCCESS)
{
$sHTML = "Error: " . ACTINIC::GetPhrase(-1, 1974) . ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor) .
ACTINIC::GetPhrase(-1, 102) . ACTINIC::GetPhrase(-1, 1975) . ACTINIC::GetPhrase(-1, 1970) . " - ". ${$Response[3]}{ValidateFinalInput} . "<BR>\n";
}
}
UpdateCheckoutRecord();
$::Session->SaveSession();
ACTINIC::PrintText($sHTML);
return;
}
elsif ($sAction eq "INCONTEXTPSP")
{
my ($nStatus);
$::g_nCurrentSequenceNumber = 3;
$sAction = $sNextButton;
$::s_sOrderNumber = $::g_InputHash{ON};
($nStatus, $sError, $sHTML) = CallOCCPlugIn();
if ($nStatus != $::SUCCESS)
{
ACTINIC::RecordErrors($sError, ACTINIC::GetPath());
$sError = $sHTML;
$sAction = $sBackButton;
}
elsif ($sHTML ne '')
{
goto THEEND;
}
}
elsif ($sAction eq "GETALLFINANCEPRODUCTS")
{
my ($nStatus);
$::g_nCurrentSequenceNumber = 3;		
$::g_PaymentInfo{'METHOD'} = $::PAYMENT_V12FINANCE;
($nStatus, $sError, $sHTML) = CallOCCPlugIn();		
if ($nStatus != $::SUCCESS)
{
ACTINIC::RecordErrors($sError, ACTINIC::GetPath());
$sError = $sHTML;			
}
elsif ($sHTML ne '')
{
ACTINIC::PrintText($sHTML);
return;
}
}
my $sChangeRequest = GetChangeRequest();
if ($sAction eq "" &&
$::g_InputHash{ACTIONOVERRIDE})
{
$sAction = $::g_InputHash{ACTIONOVERRIDE};
}
elsif ($sAction =~ m/$sStartButton/i ||
$sAction =~ m/$sNextButton/i ||
$sAction =~ m/$sFinishButton/i ||
$sAction =~ m/$sConfirmOrderButton/i ||
$sAction =~ m/^AUTHORIZE/i ||
$sAction =~ m/RECORDORDER/i ||
exists $::g_InputHash{$sNextButton . ".x"} ||
exists $::g_InputHash{$sConfirmOrderButton . ".x"} ||
exists $::g_InputHash{$sFinishButton . ".x"})
{
$eDirection = $::FORWARD;
}
elsif ($sChangeRequest ne '' ||
$sAction =~ m/$sBackButton/i ||
$sAction =~ m/$sChangeLocationButton/i ||
exists $::g_InputHash{$sBackButton . ".x"} ||
$sAction eq 'RESUME_CHECKOUT')
{
$eDirection = $::BACKWARD;
}
elsif ($sAction =~ m/$sDoneButton/i ||
exists $::g_InputHash{$sDoneButton . ".x"})
{
my $sRefPage = $::Session->GetLastShopPage();
if (defined $$::g_pSetupBlob{'UNFRAMED_CHECKOUT_URL'} &&
$$::g_pSetupBlob{'UNFRAMED_CHECKOUT_URL'} ne "")
{
$sRefPage = $$::g_pSetupBlob{'UNFRAMED_CHECKOUT_URL'};
}
if( !$ACTINIC::B2B->Get('UserDigest') )
{
if (defined $::g_InputHash{'ALTERNATEMALLHOME'})
{
$sRefPage = $::g_InputHash{'ALTERNATEMALLHOME'};
}
}
@Response = ACTINIC::BounceToPagePlain(0, undef, undef, $::g_sWebSiteUrl,
$::g_sContentUrl, $::g_pSetupBlob, $sRefPage, \%::g_InputHash);
if ($Response[0] != $::SUCCESS)
{
ACTINIC::ReportError($Response[1], ACTINIC::GetPath());
return;
}
$sHTML = $Response[2];
if ($ACTINIC::B2B->Get('UserDigest'))
{
$sHTML =~ s/([\?|\&]ACTINIC_REFERRER[^\&|"|']*)//gi;
$sHTML =~ s/($::g_sAccountScriptName)(\&)/$1\?/gi;
}
goto THEEND;
}
else
{
ValidateInput($::BACKWARD);
$sHTML = GetCancelPage();
$::Session->ClearInCheckout();
goto THEEND;
}
@Response = ValidateInput($eDirection);
if ($Response[0] == $::BADDATA)
{
$sHTML = $Response[1];
$sDetailCookie = $Response[2];
goto THEEND;
}
elsif ($Response[0] != $::SUCCESS)
{
ACTINIC::ReportError($Response[1], ACTINIC::GetPath());
return;
}
if($sAction =~ m/$sChangeLocationButton/i)
{
$::g_nCurrentSequenceNumber = $::STARTSEQUENCE;
$eDirection = $::FORWARD;
}
if ($sChangeRequest ne '')
{
if ($sChangeRequest eq 'CHANGE_CART')
{
my $sCartURL = GetCGIScriptURL('ca') .
"?ACTION=SHOWCART&FROM=CHECKOUT_$::g_nCurrentSequenceNumber";
binmode STDOUT;
print "Location: $sCartURL\r\n\r\n";
exit;
}
my %hashNextSequence = (
'CHANGE_ADDRESS' => 0,
'CHANGE_SHIPPING' => 1,
'CHANGE_TAX_EXEMPTION' => 1,
'CHANGE_COUPON' => 1,
);
$::g_nNextSequenceNumber = $hashNextSequence{$sChangeRequest};
}
elsif ($sAction eq 'RESUME_CHECKOUT')
{
$::g_nNextSequenceNumber = $::g_nCurrentSequenceNumber;
}
elsif ($eDirection == $::FORWARD)
{
$::g_nNextSequenceNumber = $::g_nCurrentSequenceNumber + 1;
}
else
{
$::g_nNextSequenceNumber = $::g_nCurrentSequenceNumber - 1;
}
ActinicOrder::ParseAdvancedTax();
@Response = DisplayPage($sError, $::g_nNextSequenceNumber, $eDirection);
if ($Response[0] != $::SUCCESS)
{
ACTINIC::ReportError($Response[1], ACTINIC::GetPath());
return;
}
$sHTML = $Response[2];
$sDetailCookie = $Response[3];
THEEND:
ACTINIC::UpdateDisplay($sHTML, $::g_OriginalInputData, undef, undef, $sDetailCookie, ActinicOrder::GenerateCartCookie());
}
sub GetChangeRequest
{
my @arrChangeRequests = qw(CART ADDRESS SHIPPING TAX_EXEMPTION COUPON);
my $sRequest;
foreach $sRequest (@arrChangeRequests)
{
my $sRequestKey = 'CHANGE_' . $sRequest;
if (exists $::g_InputHash{$sRequestKey} ||
exists $::g_InputHash{$sRequestKey . ".x"})
{
return $sRequestKey;
}
}
return '';
}
sub GetCGIScriptURL
{
my ($sScriptPrefix) = @_;
return sprintf('%s%s%6.6d%s', 
$$::g_pSetupBlob{'CGI_URL'}, $sScriptPrefix, 
$$::g_pSetupBlob{'CGI_ID'}, $$::g_pSetupBlob{'CGI_EXT'});
}
sub ValidateInput
{
my ($eDirection);
if ($#_ != 0)
{
$eDirection = $::FORWARD;
}
($eDirection) = @_;
my ($bActuallyValidate) = ($eDirection == $::FORWARD);
my (@Response);
if ($::g_nCurrentSequenceNumber == $::STARTSEQUENCE)
{
@Response = ValidateStart($bActuallyValidate); # validate the input/cart settings
return (@Response);
}
else
{
my $parrInputPhases = GetPhaseListFromInput();
my ($nPhase, $sError);
foreach $nPhase (@$parrInputPhases)
{
if ($nPhase == $::BILLCONTACTPHASE)
{
$sError .= ValidateBill($bActuallyValidate);
}
elsif ($nPhase == $::SHIPCONTACTPHASE)
{
$sError .= ValidateShipContact($bActuallyValidate);
}
elsif ($nPhase == $::SHIPCHARGEPHASE)
{
$sError .= ValidateShipCharge($bActuallyValidate);
}
elsif ($nPhase == $::TAXCHARGEPHASE)
{
$sError .= ActinicOrder::ValidateTax($bActuallyValidate);
}
elsif ($nPhase == $::GENERALPHASE)
{
$sError .= ValidateGeneral($bActuallyValidate);
}
elsif ($nPhase == $::PAYMENTPHASE || $nPhase == $::PAYSELECTPHASE)
{
$sError .= ValidatePayment($bActuallyValidate);
}
elsif ($nPhase == $::TANDCPHASE)
{
$sError .= ValidateTermsAndConditions($bActuallyValidate);
}
elsif ($nPhase == $::COUPONPHASE)
{
$sError .= ValidateCoupon($bActuallyValidate);
}
elsif ($nPhase == $::COMPLETEPHASE)
{
if($::g_InputHash{'ACTION'} =~ m/^AUTHORIZE_(\d+)$/i)
{
$::g_PaymentInfo{'METHOD'} = $1;
}
if (!defined $::g_PaymentInfo{'METHOD'})
{
$sError .= ACTINIC::GetPhrase(-1, 1282);	
next;
}
if (length $::g_PaymentInfo{'METHOD'} == 0)
{
EnsurePaymentSelection();
}
my ($ePaymentMethod) = ActinicOrder::PaymentStringToEnum($::g_PaymentInfo{'METHOD'}); # the payment method is stored as "ENUMERATEDID:DESCRIPTION"
if ($ACTINIC::B2B->Get('UserDigest') &&
($ePaymentMethod == $::PAYMENT_ON_ACCOUNT ||
$ePaymentMethod == $::PAYMENT_INVOICE))
{
$sError .= ValidateSignature($bActuallyValidate);
}
}
elsif ($nPhase == $::RECEIPTPHASE)
{
}
elsif ($nPhase == $::PRELIMINARYINFOPHASE)
{
if ($sError eq '')
{
$sError .= ActinicOrder::ValidatePreliminaryInfo($bActuallyValidate, $::FALSE);
}
}
}
if ($sError ne '')
{
@Response = DisplayPage($sError, $::g_nCurrentSequenceNumber, $eDirection);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
$Response[0] = $::BADDATA;
$Response[1] = $Response[2];
$Response[2] = $Response[3];
return (@Response);
}
}
return (UpdateCheckoutRecord());
}
sub ValidateStart
{
if ($#_ != 0)
{
return ($::FAILURE, ACTINIC::GetPhrase(-1, 12, 'ValidateStart'), 0, 0);
}
my ($bActuallyValidate) = @_;
if (!$bActuallyValidate)
{
return ($::SUCCESS, "", 0, 0);
}
my ($nLineCount, @Response, $Status, $Message);
my $pCartObject;
@Response = $::Session->GetCartObject();
if ($Response[0] != $::SUCCESS)
{
$nLineCount = 0;
}
else
{
$pCartObject = $Response[2];
$nLineCount = $pCartObject->CountItems();
}
my ($sLocalPage, $sBaseUrl, $sHTML);
if ($nLineCount <= 0)
{
$sLocalPage = $::Session->GetLastShopPage();
if (ACTINIC::IsCatalogFramed() ||
($$::g_pSetupBlob{CLEAR_ALL_FRAMES} &&
$$::g_pSetupBlob{UNFRAMED_CHECKOUT}))
{
$sLocalPage = ACTINIC::RestoreFrameURL($sLocalPage);
}
@Response = ACTINIC::BounceToPageEnhanced(5, ACTINIC::GetPhrase(-1, 1962) . ACTINIC::GetPhrase(-1, 44, $::g_sCart, $::g_sCart) . ACTINIC::GetPhrase(-1, 1970) . ACTINIC::GetPhrase(-1, 2049),
$$::g_pSetupBlob{CHECKOUT_DESCRIPTION},
$::g_sWebSiteUrl,
$::g_sContentUrl, $::g_pSetupBlob, $sLocalPage, \%::g_InputHash,
$::FALSE);
($Status, $Message, $sHTML) = @Response;
if ($Status != $::SUCCESS)
{
return (@Response);
}
return ($::BADDATA, $sHTML, 0, 0);
}
my $pCartList = $pCartObject->GetCartList();
my $nIndex;
foreach ($nIndex = $#$pCartList; $nIndex >= 0; $nIndex--)
{
my $pFailure;
($Status, $Message, $pFailure) = ActinicOrder::ValidateOrderDetails($pCartList->[$nIndex], $nIndex);
if ($Status != $::SUCCESS)
{
my $sURL = $::g_sCartScript . "?ACTION=SHOWCART";
$sURL .= $::g_InputHash{SHOP} ? '&SHOP=' . ACTINIC::EncodeText2($::g_InputHash{SHOP}, $::FALSE) : '';
@Response = ACTINIC::BounceToPageEnhanced(5, ACTINIC::GetPhrase(-1, 1962) . ACTINIC::GetPhrase(-1, 2167) . ACTINIC::GetPhrase(-1, 1970) . ACTINIC::GetPhrase(-1, 2049),
$$::g_pSetupBlob{CHECKOUT_DESCRIPTION},
$::g_sWebSiteUrl,
$::g_sContentUrl, $::g_pSetupBlob, $sURL , \%::g_InputHash,
$::FALSE);
($Status, $Message, $sHTML) = @Response;
if ($Status != $::SUCCESS)
{
return (@Response);
}
return ($::BADDATA, $sHTML, 0, 0);
}
}
($Status, $sHTML) = ActinicOrder::CheckBuyerLimit($::g_sCartId,'',$::TRUE);
if ($Status != $::SUCCESS)
{
return ($::BADDATA,$sHTML);
}
return ($::SUCCESS, "", 0, 0);
}
sub ValidateBill
{
if ($#_ != 0)
{
ACTINIC::ReportError(ACTINIC::GetPhrase(-1, 12, 'ValidateBill'), ACTINIC::GetPath());
}
my ($bActuallyValidate) = @_;
if( $::g_InputHash{ADBACTION} )
{
return('');
}
undef $::g_BillContact{'ADDRESSSELECT'};
if ($::g_InputHash{INVOICEADDRESSSELECT} )
{
$::g_BillContact{'ADDRESSSELECT'} = $::g_InputHash{INVOICEADDRESSSELECT};
my $sUserDigest = $ACTINIC::B2B->Get('UserDigest');
my ($status, $sMessage, $pBuyer) = ACTINIC::GetBuyer($sUserDigest, ACTINIC::GetPath());
if ($status != $::SUCCESS)
{
return ($sMessage);
}
my $pAccount;
($status, $sMessage, $pAccount) = ACTINIC::GetCustomerAccount($$pBuyer{AccountID}, ACTINIC::GetPath());
if ($status != $::SUCCESS)
{
return ($sMessage);
}
my $pAddress;
($status, $sMessage, $pAddress) = ACTINIC::GetCustomerAddress($$pBuyer{AccountID}, $::g_InputHash{INVOICEADDRESSSELECT}, ACTINIC::GetPath());
ACTINIC::CloseCustomerAddressIndex();
if ($status != $::SUCCESS)
{
return ($sMessage);
}
if ($pAccount->{InvoiceAddressRule} != 1 &&
$pBuyer->{InvoiceAddressRule} != 0 )
{
$::g_BillContact{'NAME'}		= $pBuyer->{'Name'};
$::g_BillContact{'FIRSTNAME'}	= $pBuyer->{'FirstName'};
$::g_BillContact{'LASTNAME'}	= $pBuyer->{'LastName'};
$::g_BillContact{'SALUTATION'}	= $pBuyer->{'Salutation'};
$::g_BillContact{'JOBTITLE'}	= $pBuyer->{'Title'};
}
else
{
$::g_BillContact{'NAME'}		= $pAccount->{'Name'};
$::g_BillContact{'FIRSTNAME'}	= $pAccount->{'FirstName'};
$::g_BillContact{'LASTNAME'}	= $pAccount->{'LastName'};
$::g_BillContact{'SALUTATION'}	= $pAccount->{'Salutation'};
$::g_BillContact{'JOBTITLE'}	= $pAccount->{'Title'};
}
$::g_BillContact{'PHONE'} 		= $pAccount->{'TelephoneNumber'};
$::g_BillContact{'MOBILE'} 		= $pAccount->{'MobileNumber'};
$::g_BillContact{'FAX'} 		= $pAccount->{'FaxNumber'};
if (length $::g_BillContact{'PHONE'} > $::g_pFieldSizes->{'PHONE'})
{
$::g_BillContact{'PHONE'}	=~ s/(.*?)(\/.*|$)/$1/;
}
$::g_BillContact{'PHONE'}		=~ s/(.{0,$::g_pFieldSizes->{'PHONE'}}).*/$1/;
$::g_BillContact{'MOBILE'}		=~ s/(.{0,$::g_pFieldSizes->{'MOBILE'}}).*/$1/;
$::g_BillContact{'FAX'}			=~ s/(.{0,$::g_pFieldSizes->{'FAX'}}).*/$1/;
$::g_BillContact{'EMAIL'} 		= $pAccount->{'EmailAddress'};
$::g_BillContact{'EMAIL_CONFIRM'} 		= $pAccount->{'EmailAddress'};
$::g_BillContact{'ADDRESS1'} 		= $pAddress->{'Line1'};
$::g_BillContact{'ADDRESS2'} 		= $pAddress->{'Line2'};
$::g_BillContact{'ADDRESS3'} 		= $pAddress->{'Line3'};
$::g_BillContact{'ADDRESS4'} 		= $pAddress->{'Line4'};
$::g_BillContact{'POSTALCODE'} 	= $pAddress->{'PostCode'};
$::g_BillContact{'COUNTRY'} 		= ACTINIC::GetCountryName($pAddress->{'CountryCode'});
$::g_BillContact{'SEPARATE'}		= $::TRUE;
$::g_LocationInfo{INVOICE_COUNTRY_CODE} = $pAddress->{'CountryCode'};
my $sPostcodeRegion = ActinicOrder::GetSellerDeckRegion($pAddress->{CountryCode},
$pAddress->{Line4},
$pAddress->{PostCode},
$ActinicOrder::UNDEFINED_REGION);
my $sRegion = $sPostcodeRegion ? $sPostcodeRegion : ($pAddress->{'StateCode'} ? $pAddress->{'StateCode'} : $ActinicOrder::UNDEFINED_REGION);
$::g_LocationInfo{INVOICE_REGION_CODE} = $sRegion;
ActinicOrder::ParseAdvancedTax();
if($$::g_pTaxSetupBlob{TAX_BY} == $::eTaxByInvoice)
{
if(defined $$::g_pTaxSetupBlob{TAX_1} &&
$$::g_pTaxSetupBlob{TAX_1}{ID} == $pAddress->{'Tax1ID'})
{
$::g_TaxInfo{'EXEMPT1'} = $pAddress->{'ExemptTax1'} ? 1 : 0;
$::g_TaxInfo{'EXEMPT1DATA'} = $pAddress->{'Tax1ExemptData'};
}
if(defined $$::g_pTaxSetupBlob{TAX_2} &&
$$::g_pTaxSetupBlob{TAX_2}{ID} == $pAddress->{'Tax2ID'})
{
$::g_TaxInfo{'EXEMPT2'} = $pAddress->{'ExemptTax2'} ? 1 : 0;
$::g_TaxInfo{'EXEMPT2DATA'} = $pAddress->{'Tax2ExemptData'};
}
}
$::g_BillContact{'MOVING'} 		= $::FALSE;
$::g_BillContact{'PRIVACY'} 		= $::TRUE;
$::g_BillContact{'REMEMBERME'}	= $::FALSE; 
$::g_BillContact{'CREATEANACCOUNT'}	= $::FALSE;
$::g_BillContact{'NEWCUSTOMERPASSWORD'}	= $::FALSE;
ACTINIC::CopyHash(\%::g_BillContact, \%::g_InputHash, '', 'INVOICE');
}
else
{
GetContactFromInput('INVOICE', \%::g_BillContact);
$::g_BillContact{'SEPARATE'}	= ($::g_InputHash{'SEPARATESHIP'} ne "") ? $::TRUE : $::FALSE;
$::g_BillContact{'REMEMBERME'}	= (defined $::g_InputHash{'REMEMBERME'} && $::g_InputHash{'REMEMBERME'} ne "") ?
$::TRUE : $::FALSE;
$::g_BillContact{'CREATEANACCOUNT'}	= (defined $::g_InputHash{'CREATEANACCOUNT'} && $::g_InputHash{'CREATEANACCOUNT'} ne "") ?
$::TRUE : $::FALSE;
$::g_BillContact{'NEWCUSTOMERPASSWORD'}	= (defined $::g_InputHash{'NEWCUSTOMERPASSWORD'} &&defined $::g_InputHash{'NEWCUSTOMERPASSWORD2'}) ?
$::g_InputHash{'NEWCUSTOMERPASSWORD'} : '';
$::g_LocationInfo{INVOICE_COUNTRY_CODE} = $::g_InputHash{'LocationInvoiceCountry'};
$::g_LocationInfo{INVOICE_REGION_CODE} = $::g_InputHash{'LocationInvoiceRegion'};
if (!$::g_BillContact{'SEPARATE'})
{
$::g_LocationInfo{DELIVERY_COUNTRY_CODE} = $::g_InputHash{'LocationInvoiceCountry'};
$::g_LocationInfo{DELIVERY_REGION_CODE} = $::g_InputHash{'LocationInvoiceRegion'};
}
ActinicOrder::NormaliseAddressLocation('Invoice', $bActuallyValidate);
}
if ($$::g_pSetupBlob{SHOPPER_NAME_HANDLING_MODE} eq 1)
{
$::g_BillContact{'NAME'}	=  $::g_BillContact{'FIRSTNAME'}.' '.$::g_BillContact{'LASTNAME'};
$::g_BillContact{'NAME'}	=~ s/(.{0,$::g_pFieldSizes->{'NAME'}}).*/$1/;
}
ActinicOrder::SetAddressFieldsFromLocationCodes('Invoice');
if (!$::g_BillContact{'SEPARATE'})
{
ACTINIC::CopyHash(\%::g_BillContact, \%::g_ShipContact, '',  '');
}
ACTINIC::TrimHashEntries(\%::g_BillContact);
my ($sError);
if (!$bActuallyValidate)
{
return ($sError);
}
$sError .= CheckInputField(0, GetAddressMapping(), \%::g_BillContact);
if (ACTINIC::IsPromptRequired(0, 14) &&
$::g_BillContact{'USERDEFINED'} eq "" &&
!$ACTINIC::B2B->Get('UserDigest'))
{
$sError .= ACTINIC::GetRequiredMessage(0, 14);
}
if (length $::g_BillContact{'USERDEFINED'} > $::g_pFieldSizes->{'USERDEFINED'})
{
$sError .= ACTINIC::GetLengthFailureMessage(0, 14, $::g_pFieldSizes->{'USERDEFINED'});
}
if ($::g_BillContact{'CREATEANACCOUNT'} == $::TRUE)
{
my ($status, $sMessage, $sPH) = ACTINIC::GetUser($::g_BillContact{EMAIL});
if ($status == $::SUCCESS)
{
$sError .= ACTINIC::GetRequiredMessage(0, 12, ACTINIC::GetPhrase(-1, 2770, $::g_BillContact{EMAIL}));
}
if ($::g_BillContact{'NEWCUSTOMERPASSWORD'} eq "")
{	
$sError .= ACTINIC::GetRequiredMessage(-1, 2749);
}
if ($::g_InputHash{'NEWCUSTOMERPASSWORD2'} eq "")
{	
$sError .= ACTINIC::GetRequiredMessage(-1, 2750);
}
}
if($sError eq '')
{
}
return ActinicOrder::FormatCheckoutInputError(ACTINIC::GetPhrase(-1, 147), $sError);
}
sub GetContactFromInput
{
my ($sKeyPrefix, $rhashContact) = @_;
$rhashContact->{'MOVING'}	= $::FALSE;
$rhashContact->{'PRIVACY'}	= $::FALSE;
ClearAddress($rhashContact);
ACTINIC::CopyHash(\%::g_InputHash, $rhashContact, $sKeyPrefix, '', $::FALSE);
$rhashContact->{'MOVING'}	= ($rhashContact->{'MOVING'}) ? $::TRUE : $::FALSE;
$rhashContact->{'PRIVACY'}	= ($rhashContact->{'PRIVACY'}) ? $::TRUE : $::FALSE;
}
sub ClearAddress
{
my ($rhashContact) = @_;
my $sKey;
foreach $sKey (@ActinicOrder::arrAddressKeys)
{
$rhashContact->{$sKey} = '';
}
}
sub GetAddressMapping
{
my $rhashFields =
{
'SALUTATION' 		=> 0,
'NAME'				=> 1,
'JOBTITLE'			=> 2,
'COMPANY'			=> 3,
'ADDRESS1'			=> 4,
'ADDRESS2'			=> 5,
'ADDRESS3'			=> 6,
'ADDRESS4'			=> 7,
'POSTALCODE'		=> 8,
'COUNTRY'			=> 9,
'PHONE'				=> 10,
'FAX'					=> 11,
'EMAIL'				=> 12,
'MOBILE'				=> 20,
'FIRSTNAME'			=> 21,
'LASTNAME'			=> 22,
'EMAIL_CONFIRM'	=> 23,
};
if ($$::g_pSetupBlob{SHOPPER_NAME_HANDLING_MODE} eq 1) # first name/ last name handling
{
delete $rhashFields->{'NAME'};
}
else
{
delete  $rhashFields->{'FIRSTNAME'};
delete  $rhashFields->{'LASTNAME'};
}
return $rhashFields;
}
sub ValidateCoupon
{
my ($bActuallyValidate) = @_;
if (ActinicDiscounts::IsMultipleFixedPriceCouponAccepted())
{
if (exists $::g_InputHash{'COUPONCODE'})
{						
if ($::g_InputHash{'COUPONCODE'} ne "" &&
$$::g_pDiscountBlob{'COUPON_ON_CHECKOUT'})
{
my $sNewCoupon = $::g_InputHash{'COUPONCODE'};
my (@aCoupons) = split(/,/, $::Session->GetCSVCouponCodes());
my ($sCoupon);
foreach $sCoupon (@aCoupons) 
{
if ($sCoupon eq $sNewCoupon)
{
return ActinicOrder::FormatCheckoutInputError(ACTINIC::GetPhrase(-1, 2353), ACTINIC::GetPhrase(-1, 3080, $sNewCoupon)); # Voucher code %s was already applied to this order
}
}				
if ($bActuallyValidate)
{
$::Session->GetCartObject();
my @Response = ActinicDiscounts::ValidateCoupon($::g_InputHash{'COUPONCODE'});
if ($Response[0] == $::FAILURE)
{
return ActinicOrder::FormatCheckoutInputError(ACTINIC::GetPhrase(-1, 2353), $Response[1]);
}			
}
my $sCoupons = $::Session->GetCSVCouponCodes() ? ($::Session->GetCSVCouponCodes() . "," . $::g_InputHash{'COUPONCODE'}) : $::g_InputHash{'COUPONCODE'};
$::Session->SetCSVCouponCodes($sCoupons);
}
}		
}
else
{
if (exists $::g_InputHash{'COUPONCODE'})
{
$::g_PaymentInfo{'COUPONCODE'} = $::g_InputHash{'COUPONCODE'};
}
if ($::g_InputHash{'COUPONCODE'} ne "" &&
$$::g_pDiscountBlob{'COUPON_ON_CHECKOUT'})
{
if ($bActuallyValidate)
{
$::Session->GetCartObject();
my @Response = ActinicDiscounts::ValidateCoupon($::g_PaymentInfo{'COUPONCODE'});
if ($Response[0] == $::FAILURE)
{
$::g_PaymentInfo{'COUPONCODE'} = '';
return ActinicOrder::FormatCheckoutInputError(ACTINIC::GetPhrase(-1, 2353), $Response[1]);
}
}
}
}	
return '';
}
sub ValidateTermsAndConditions
{
my ($bActuallyValidate) = @_;
$::g_BillContact{'AGREEDTANDC'}	= (defined $::g_InputHash{'AGREETERMSCONDITIONS'} && $::g_InputHash{'AGREETERMSCONDITIONS'} ne "") ? $::TRUE : $::FALSE;
my $sError = '';
if ($bActuallyValidate)
{
if (defined $$::g_pSetupBlob{'CHECKOUT_NEEDS_TERMS_AGREED'} &&
!$::g_BillContact{'AGREEDTANDC'})
{
$sError = ACTINIC::GetPhrase(-1, 2385);
}
}
return ActinicOrder::FormatCheckoutInputError(ACTINIC::GetPhrase(-1, 2386), $sError);
}
sub ValidateShipContact
{
if ($#_ != 0)
{
ACTINIC::ReportError(ACTINIC::GetPhrase(-1, 12, 'ValidateShipContact'), ACTINIC::GetPath());
}
my ($bActuallyValidate) = @_;
if ($::ACT_ADB)
{
ConfigureAddressBook();
$::ACT_ADB->ToForm();
$::s_VariableTable{$::VARPREFIX.'ADDRESSBOOK'}	= $::ACT_ADB->Show();
}
else
{
$::s_VariableTable{$::VARPREFIX.'ADDRESSBOOK'}	= "";
}
my $bCheckReversed = (defined $$::g_pSetupBlob{'REVERSE_ADDRESS_CHECK'} &&
$$::g_pSetupBlob{'REVERSE_ADDRESS_CHECK'});
undef $::g_ShipContact{ADDRESSSELECT};
if( $::g_InputHash{DELIVERADDRESSSELECT} )
{
$::g_ShipContact{ADDRESSSELECT} = $::g_InputHash{DELIVERADDRESSSELECT};
my $sUserDigest = $ACTINIC::B2B->Get('UserDigest');
my ($status, $sMessage, $pBuyer) = ACTINIC::GetBuyer($sUserDigest, ACTINIC::GetPath());
if ($status != $::SUCCESS)
{
return ($sMessage);
}
my $pAccount;
($status, $sMessage, $pAccount) = ACTINIC::GetCustomerAccount($$pBuyer{AccountID}, ACTINIC::GetPath());
if ($status != $::SUCCESS)
{
return ($sMessage);
}
my $pAddress;
($status, $sMessage, $pAddress) = ACTINIC::GetCustomerAddress($$pBuyer{AccountID}, $::g_InputHash{DELIVERADDRESSSELECT}, ACTINIC::GetPath());
ACTINIC::CloseCustomerAddressIndex();
if ($status != $::SUCCESS)
{
return ($sMessage);
}
$::g_ShipContact{'COMPANY'}	= $pAccount->{CompanyName};
$::g_ShipContact{'NAME'}		= $pBuyer->{Name};
$::g_ShipContact{'FIRSTNAME'}	= $pBuyer->{'FirstName'};
$::g_ShipContact{'LASTNAME'}	= $pBuyer->{'LastName'};
$::g_ShipContact{'SALUTATION'}	= $pBuyer->{Salutation};
$::g_ShipContact{'JOBTITLE'}	= $pBuyer->{Title};
$::g_ShipContact{'PHONE'} 		= $pBuyer->{'TelephoneNumber'};
$::g_ShipContact{'MOBILE'} 		= $pBuyer->{'MobileNumber'};
$::g_ShipContact{'FAX'} 		= $pBuyer->{'FaxNumber'};
if (length $::g_ShipContact{'PHONE'} > $::g_pFieldSizes->{'PHONE'})
{
$::g_ShipContact{'PHONE'}	=~ s/(.*?)(\/.*|$)/$1/;
}
$::g_ShipContact{'PHONE'}		=~ s/(.{0,$::g_pFieldSizes->{'PHONE'}}).*/$1/;
$::g_ShipContact{'MOBILE'}		=~ s/(.{0,$::g_pFieldSizes->{'MOBILE'}}).*/$1/;
$::g_ShipContact{'FAX'}			=~ s/(.{0,$::g_pFieldSizes->{'FAX'}}).*/$1/;
$::g_ShipContact{'EMAIL'} 		= $pBuyer->{'EmailAddress'};
$::g_ShipContact{'EMAIL_CONFIRM'} 		= $pBuyer->{'EmailAddress'};
$::g_ShipContact{'ADDRESS1'}	= $pAddress->{'Line1'};
$::g_ShipContact{'ADDRESS2'}	= $pAddress->{'Line2'};
$::g_ShipContact{'ADDRESS3'}	= $pAddress->{'Line3'};
$::g_ShipContact{'ADDRESS4'}	= $pAddress->{'Line4'};
$::g_ShipContact{'POSTALCODE'} 	= $pAddress->{'PostCode'};
$::g_LocationInfo{DELIVERPOSTALCODE} 	= $pAddress->{'PostCode'};
$::g_ShipContact{'COUNTRY'} 	= ACTINIC::GetCountryName($pAddress->{'CountryCode'});
$::g_LocationInfo{DELIVERY_COUNTRY_CODE} = $pAddress->{'CountryCode'};
my $sPostcodeRegion = ActinicOrder::GetSellerDeckRegion($pAddress->{CountryCode},
$pAddress->{Line4},
$pAddress->{PostCode},
$ActinicOrder::UNDEFINED_REGION);
my $sRegion = $sPostcodeRegion ? $sPostcodeRegion : ($pAddress->{'StateCode'} ? $pAddress->{'StateCode'} : $ActinicOrder::UNDEFINED_REGION);		
$::g_LocationInfo{DELIVERY_REGION_CODE} = $sRegion;
$::g_ShipContact{PRIVACY} 		  = $::TRUE;
}
else
{
if (((!$bCheckReversed && !$::g_BillContact{'SEPARATE'}) ||
($bCheckReversed && $::g_BillContact{'SEPARATE'})) )
{
$::g_ShipContact{'SALUTATION'} 	= $::g_BillContact{'SALUTATION'};
$::g_ShipContact{'NAME'}		= $::g_BillContact{'NAME'};
$::g_ShipContact{'FIRSTNAME'}	= $::g_BillContact{'FIRSTNAME'};
$::g_ShipContact{'LASTNAME'} 	= $::g_BillContact{'LASTNAME'};
$::g_ShipContact{'JOBTITLE'}	= $::g_BillContact{'JOBTITLE'};
$::g_ShipContact{'COMPANY'} 	= $::g_BillContact{'COMPANY'};
$::g_ShipContact{'ADDRESS1'}	= $::g_BillContact{'ADDRESS1'};
$::g_ShipContact{'ADDRESS2'}	= $::g_BillContact{'ADDRESS2'};
$::g_ShipContact{'ADDRESS3'}	= $::g_BillContact{'ADDRESS3'};
$::g_ShipContact{'ADDRESS4'}	= $::g_BillContact{'ADDRESS4'};
$::g_ShipContact{'POSTALCODE'} 	= $::g_BillContact{'POSTALCODE'};
$::g_ShipContact{'COUNTRY'} 	= $::g_BillContact{'COUNTRY'};
my $sUserDigest = $ACTINIC::B2B->Get('UserDigest');
if ($sUserDigest)
{
my ($status, $sMessage, $pBuyer) = ACTINIC::GetBuyer($sUserDigest, ACTINIC::GetPath());
if ($status != $::SUCCESS)
{
return ($sMessage);
}
$::g_ShipContact{'PHONE'} 		= $pBuyer->{'TelephoneNumber'};
$::g_ShipContact{'MOBILE'}	 	= $pBuyer->{'MobileNumber'};
$::g_ShipContact{'FAX'} 		= $pBuyer->{'FaxNumber'};
if (length $::g_ShipContact{'PHONE'} > $::g_pFieldSizes->{'PHONE'})
{
$::g_ShipContact{'PHONE'}	=~ s/(.*?)(\/.*|$)/$1/;
}
$::g_ShipContact{'PHONE'}		=~ s/(.{0,$::g_pFieldSizes->{'PHONE'}}).*/$1/;
$::g_ShipContact{'MOBILE'}		=~ s/(.{0,$::g_pFieldSizes->{'MOBILE'}}).*/$1/;
$::g_ShipContact{'EMAIL'} 		= $pBuyer->{'EmailAddress'};
}
else
{
$::g_ShipContact{'PHONE'} 		= $::g_BillContact{'PHONE'};
$::g_ShipContact{'MOBILE'} 		= $::g_BillContact{'MOBILE'};
$::g_ShipContact{'FAX'} 		= $::g_BillContact{'FAX'};
$::g_ShipContact{'EMAIL'} 		= $::g_BillContact{'EMAIL'};
$::g_ShipContact{'EMAIL_CONFIRM'} 		= $::g_BillContact{'EMAIL_CONFIRM'};
}
$::g_ShipContact{'USERDEFINED'} 	= "";
}
else
{
GetContactFromInput('DELIVER', \%::g_ShipContact);
if ($::g_BillContact{'SEPARATE'})
{
$::g_LocationInfo{DELIVERY_COUNTRY_CODE} = $::g_InputHash{'LocationDeliveryCountry'};
$::g_LocationInfo{DELIVERY_REGION_CODE} = $::g_InputHash{'LocationDeliveryRegion'};
}
}
$::g_ShipContact{'PRIVACY'} = $::g_BillContact{'PRIVACY'};
ActinicOrder::NormaliseAddressLocation('Delivery');
}
if ($$::g_pSetupBlob{SHOPPER_NAME_HANDLING_MODE} eq 1)
{
$::g_ShipContact{'NAME'} =  $::g_ShipContact{'FIRSTNAME'} .' '.	$::g_ShipContact{'LASTNAME'};
$::g_ShipContact{'NAME'} =~ s/(.{0,$::g_pFieldSizes->{'NAME'}}).*/$1/;
}
ActinicOrder::SetAddressFieldsFromLocationCodes('Delivery');
ACTINIC::TrimHashEntries(\%::g_ShipContact);
my ($sError);
if (!$bActuallyValidate ||
(!$bCheckReversed && !$::g_BillContact{'SEPARATE'}) ||
($bCheckReversed && $::g_BillContact{'SEPARATE'}))
{
return ($sError);
}
$sError .= CheckInputField(1, GetAddressMapping(), \%::g_ShipContact);
if (ACTINIC::IsPromptRequired(1, 13) &&
$::g_ShipContact{'USERDEFINED'} eq "" &&
!$ACTINIC::B2B->Get('UserDigest'))
{
$sError .= ACTINIC::GetRequiredMessage(1, 13);
}
if (length $::g_ShipContact{'USERDEFINED'} > $::g_pFieldSizes->{'USERDEFINED'})
{
$sError .= ACTINIC::GetLengthFailureMessage(1, 13, $::g_pFieldSizes->{'USERDEFINED'});
}
if($sError eq '')
{
}
return ActinicOrder::FormatCheckoutInputError(ACTINIC::GetPhrase(-1, 148), $sError);
}
sub CheckInputField
{
my ($nPhase, $pMapping, $pHash, $sFormat) = @_;
my ($sKey, $sError);
my ($parrInputKeys) = GetInputHashKeysInSourceOrder($nPhase);
my $sAddressPrefix = $nPhase == 0 ? 'INVOICE' : 'DELIVER';
my %hashInputKey;
my $bInternationalZone = $::FALSE;
if ($$::g_pSetupBlob{MAKE_SHIPPING_CHARGE} &&
(($nPhase == 1) ||
(!$::g_BillContact{'SEPARATE'} &&
$nPhase == 0)))
{
my @Response = ActinicOrder::GetShippingPluginResponse();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
$bInternationalZone = defined $Response[14] ? $Response[14] : $::FALSE;
}	
my $bPhoneRequired = (($$::g_pSetupBlob{'IS_GFS_ENABLED'} == $::TRUE) &&		
($bInternationalZone));
if (!$::g_InputHash{$sAddressPrefix . 'ADDRESSSELECT'})
{
foreach $sKey (@$parrInputKeys)
{
$hashInputKey{$sKey} = 1;
}
foreach $sKey (keys %{$pMapping})
{
if ((ACTINIC::IsPromptRequired($nPhase, $pMapping->{$sKey}) ||
(($sKey eq 'PHONE') &&
$bPhoneRequired)) &&
!exists $hashInputKey{$sKey})
{
$sError .= ACTINIC::GetRequiredMessage($nPhase, $pMapping->{$sKey}, "This is a required field but there is no way to input it");
}
}
}
foreach $sKey (@$parrInputKeys)
{
if ((ACTINIC::IsPromptRequired($nPhase, $pMapping->{$sKey}) ||
(($sKey eq 'PHONE') &&
$bPhoneRequired)) &&
$$pHash{$sKey} eq "")
{
if ($sFormat ne 'text')
{
$sError .= ACTINIC::GetRequiredMessage($nPhase, $pMapping->{$sKey});
}
else
{
$sError .= ACTINIC::GetRequiredMessageAsText($nPhase, $pMapping->{$sKey});
}
}
if ($sKey eq 'EMAIL_CONFIRM')
{
if ($$pHash{$sKey} ne $$pHash{'EMAIL'})
{
$sError .= ACTINIC::GetRequiredMessage($nPhase, $pMapping->{'EMAIL'}, "Email doesn't match");
}
}
elsif ($sKey eq 'EMAIL' &&
$$pHash{$sKey} ne ''	&&
$$pHash{$sKey} !~ /\@/)
{
$sError .= ACTINIC::GetRequiredMessage($nPhase, $pMapping->{$sKey}, ACTINIC::GetPhrase(-1, 2378));
}
if (exists $::g_pFieldSizes->{$sKey} &&
(length $$pHash{$sKey} > $::g_pFieldSizes->{$sKey}))
{
if ($sFormat ne 'text')
{
$sError .= ACTINIC::GetLengthFailureMessage($nPhase, $pMapping->{$sKey}, $::g_pFieldSizes->{$sKey});
}
else
{
$sError .= ACTINIC::GetLengthFailureMessageAsText($nPhase, $pMapping->{$sKey}, $::g_pFieldSizes->{$sKey});
}
}		
}
return $sError;
}
sub CheckBothAddressesFieldLengths
{
my ($sError, $sTruncation);
$sTruncation .= CheckAddressFieldLengths($::BILLCONTACTPHASE, GetAddressMapping(), \%::g_BillContact);
$sTruncation .= CheckAddressFieldLengths($::SHIPCONTACTPHASE, GetAddressMapping(), \%::g_ShipContact);
if ($sTruncation ne '')
{
$sError .= $sTruncation . "Your address data has been truncated.<br>\n"
}
return ($sError);
}
sub CheckAddressFieldLengths
{
my ($nPhase, $pMapping, $pHash, $sFormat) = @_;
my ($sKey, $sError);
foreach $sKey (@ActinicOrder::arrAddressKeys)
{
if (exists $::g_pFieldSizes->{$sKey} &&
(length $$pHash{$sKey} > $::g_pFieldSizes->{$sKey}))
{
if ($sFormat ne 'text')
{
$sError .= ACTINIC::GetLengthFailureMessage($nPhase, $pMapping->{$sKey}, $::g_pFieldSizes->{$sKey});
}
else
{
$sError .= ACTINIC::GetLengthFailureMessageAsText($nPhase, $pMapping->{$sKey}, $::g_pFieldSizes->{$sKey});
}
$$pHash{$sKey} =~ s/(.{0,$::g_pFieldSizes->{$sKey}}).*/$1/;
}		
}
return $sError;
}
sub GetInputHashKeysInSourceOrder
{
my ($nPhase) = @_;
my %hashPrefixes =
(
0 => 'INVOICE',
1 => 'DELIVER',
4 => 'GENERAL',
5 => 'PAYMENT',
);
my ($sPrefix);
if (defined $hashPrefixes{$nPhase})
{
$sPrefix = $hashPrefixes{$nPhase};
}
my $sLocationPrefix = 
$nPhase == 0 ? 'LocationInvoice' :
$nPhase == 1 ? 'LocationDelivery' : 
'';
my @arrKeyValues = split /[&=]/, $::g_OriginalInputData;
my @arrKeys;
my %hashKeysAdded = ();
my $i;
for ($i = 0; $i < scalar(@arrKeyValues); $i += 2)
{
my $sKey = $arrKeyValues[$i];
if ($sKey =~ /^$sPrefix(.*)$/)
{
AddValueToArrayIfUnique(\@arrKeys, \%hashKeysAdded, $1);
}
elsif ($sLocationPrefix ne '' &&
$sKey =~ /^$sLocationPrefix(.*)$/)
{
if ($1 eq 'Country')
{
AddValueToArrayIfUnique(\@arrKeys, \%hashKeysAdded, 'COUNTRY');
}
elsif ($1 eq 'Region')
{
AddValueToArrayIfUnique(\@arrKeys, \%hashKeysAdded, 'ADDRESS4');
}
}
}
return (\@arrKeys);
}
sub AddValueToArrayIfUnique
{
my ($parrTarget, $phashValues, $sValue) = @_;
if (!exists $phashValues->{$sValue})
{
push @$parrTarget, $sValue;
$phashValues->{$sValue} = 1;
}
}
sub GetPhaseListFromInput
{
my $rhashPhases = {
'INVOICE'			=> $::BILLCONTACTPHASE,
'DELIVER'			=> $::SHIPCONTACTPHASE,
'SHIPPING'			=> $::SHIPCHARGEPHASE,
'TAX'					=> $::TAXCHARGEPHASE,
'GENERAL'			=> $::GENERALPHASE,
'PAYMENT'			=> $::PAYMENTPHASE,
'COMPLETE'			=> $::COMPLETEPHASE,
'RECEIPT'			=> $::RECEIPTPHASE,
'PRELIM'				=> $::PRELIMINARYINFOPHASE,
'PAYMENTSELECT'	=> $::PAYSELECTPHASE,
'COUPON'				=> $::COUPONPHASE,
'TANDC'				=> $::TANDCPHASE,
};
my @arrKeyValues = split /[&=]/, $::g_OriginalInputData;
my @arrKeys;
my $i;
for ($i = 0; $i < scalar(@arrKeyValues); $i += 2)
{
my $sKey = $arrKeyValues[$i];
if ($arrKeyValues[$i] eq 'ActCheckoutPhase')
{
my $sPhaseLabel = $arrKeyValues[$i + 1];
push @arrKeys, $rhashPhases->{$sPhaseLabel};
}
}
if ($::g_nCurrentSequenceNumber == 3)
{
push @arrKeys, $::COMPLETEPHASE;
}
return (\@arrKeys);
}
sub ValidateShipCharge
{
if ($#_ != 0)
{
ACTINIC::ReportError(ACTINIC::GetPhrase(-1, 12, 'ValidateShipCharge'), ACTINIC::GetPath());
}
my ($bActuallyValidate) = @_;
my ($sError);
if ($$::g_pSetupBlob{MAKE_SHIPPING_CHARGE} &&
!ActinicOrder::IsPhaseHidden($::SHIPCHARGEPHASE))
{
my @Response = ActinicOrder::GetShippingPluginResponse();
if ($bActuallyValidate)
{
my $sMessage = "";
if ($Response[0] != $::SUCCESS)
{
$sMessage = $Response[1];
}
elsif (${$Response[2]}{ValidatePreliminaryInput} != $::SUCCESS)
{
$sMessage = ${$Response[3]}{ValidatePreliminaryInput};
}
elsif (${$Response[2]}{ValidateFinalInput} != $::SUCCESS)
{
$sMessage = ${$Response[3]}{ValidateFinalInput};
}
if ($sMessage ne "")
{
$sError .= ACTINIC::GetPhrase(-1, 1974) . ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor) .
ACTINIC::GetPhrase(-1, 102) . ACTINIC::GetPhrase(-1, 1975) . ACTINIC::GetPhrase(-1, 1970) . " - ". $sMessage . "<BR>\n";
}
}
}
$::g_ShipInfo{'USERDEFINED'}	= $::g_InputHash{'SHIPUSERDEFINED'};	
my ($bDPDVarDefined, $bDPDEnabled) = ACTINIC::IsCustomVarDefined("IsDPDEnabled");	
if ($bDPDEnabled)
{		
$::g_ShipInfo{'DPDSHIPPINGTYPE'} = $::g_InputHash{'DPDShippingType'};
$::g_ShipInfo{'DPDPICKUPLOCATION'} = $::g_InputHash{'DPDPickupLocation'};
$::g_ShipInfo{'DPDDELIVERYDATE'} = $::g_InputHash{'DPDDeliveryDate'};
my $nShippingType = $::g_ShipInfo{'DPDSHIPPINGTYPE'};
my $sExtraInfo = $::g_ShipInfo{'USERDEFINED'} ne "" ? ", " : "";
if ($nShippingType == $::DPD_SPECIFIED_DAY)
{
$sExtraInfo .= "$::DPD_SPECIFIED_DAY_CAPTION$::g_InputHash{'DPDDeliveryDate'}";
}
elsif($nShippingType == $::DPD_COLLECTION_POINT_PICKUP)
{
$sExtraInfo .= "$::DPD_COLLECTION_POINT_PICKUP_CAPTION$::g_InputHash{'DPDPickupLocation'}";
}
else
{
$sExtraInfo = "";
}
$::g_ShipInfo{'DPDEXTRAINFO'} = $sExtraInfo;
}
else
{
$::g_ShipInfo{'DPDSHIPPINGTYPE'} = "";
$::g_ShipInfo{'DPDPICKUPLOCATION'} = "";
$::g_ShipInfo{'DPDDELIVERYDATE'} = "";
}
ACTINIC::TrimHashEntries(\%::g_ShipInfo);
if (defined $::g_InputHash{'SHIPUSERDEFINED'})
{
if ($bActuallyValidate &&
ACTINIC::IsPromptRequired(2, 1) &&
$::g_ShipInfo{'USERDEFINED'} eq "")
{
$sError .= ACTINIC::GetRequiredMessage(2, 1);
}
if (length $::g_ShipInfo{'USERDEFINED'} > $::g_pFieldSizes->{'USERDEFINED'})
{
$sError .= ACTINIC::GetLengthFailureMessage(2, 1, $::g_pFieldSizes->{'USERDEFINED'});
}
if ($sError ne "")
{
$sError = ACTINIC::GetPhrase(-1, 1974) . ACTINIC::GetPhrase(-1, 149) . ACTINIC::GetPhrase(-1, 1975) . ACTINIC::GetPhrase(-1, 1961, $sError);
}
}
return ($sError);
}
sub ValidateGeneral
{
if ($#_ != 0)
{
ACTINIC::ReportError(ACTINIC::GetPhrase(-1, 12, 'ValidateGeneral'), ACTINIC::GetPath());
}
my ($bActuallyValidate) = @_;
$::g_GeneralInfo{'HOWFOUND'} 	= $::g_InputHash{'GENERALHOWFOUND'};
$::g_GeneralInfo{'WHYBUY'} 		= $::g_InputHash{'GENERALWHYBUY'};
$::g_GeneralInfo{'USERDEFINED'} = $::g_InputHash{'GENERALUSERDEFINED'};
ACTINIC::TrimHashEntries(\%::g_GeneralInfo);
my ($sError);
if (!$bActuallyValidate)
{
return ($sError);
}
my $pMapping =
{
'HOWFOUND' 		=> 0,
'WHYBUY'			=> 1,
'USERDEFINED'	=> 2,
};
$sError .= CheckInputField(4, $pMapping, \%::g_GeneralInfo);
return ActinicOrder::FormatCheckoutInputError(ACTINIC::GetPhrase(-1, 151), $sError);
}
sub ValidatePayment
{
if ($#_ != 0 && $#_ != 1)
{
ACTINIC::ReportError(ACTINIC::GetPhrase(-1, 12, 'ValidatePayment'), ACTINIC::GetPath());
}
my ($bActuallyValidate, $sFormat) = @_;
$::g_PaymentInfo{'METHOD'}			= $::g_InputHash{'PAYMENTMETHOD'};
$::g_PaymentInfo{'USERDEFINED'}	= $::g_InputHash{'PAYMENTUSERDEFINED'};
$::g_PaymentInfo{'PONO'}			= $::g_InputHash{'PAYMENTPONO'};
$::g_PaymentInfo{'CARDTYPE'}		= $::g_InputHash{'PAYMENTCARDTYPE'};
$::g_PaymentInfo{'CARDNUMBER'}	= $::g_InputHash{'PAYMENTCARDNUMBER'};
$::g_PaymentInfo{'CARDISSUE'}		= $::g_InputHash{'PAYMENTCARDISSUE'};
$::g_PaymentInfo{'CARDVV2'}		= $::g_InputHash{'PAYMENTCARDVV2'};
$::g_PaymentInfo{'EXPMONTH'}		= $::g_InputHash{'PAYMENTEXPMONTH'};
$::g_PaymentInfo{'EXPYEAR'}		= $::g_InputHash{'PAYMENTEXPYEAR'};
$::g_PaymentInfo{'STARTMONTH'}	= $::g_InputHash{'PAYMENTSTARTMONTH'};
$::g_PaymentInfo{'STARTYEAR'}		= $::g_InputHash{'PAYMENTSTARTYEAR'};
ACTINIC::TrimHashEntries(\%::g_PaymentInfo);
my ($sError);
if (!$bActuallyValidate)
{
return ($sError);
}
my @Response = $::Session->GetCartObject();
if ($Response[0] != $::SUCCESS)
{
return ($Response[1]);
}
my $pCartObject = $Response[2];
my $pCartList = $pCartObject->GetCartList();
my (@SummaryResponse) = $pCartObject->SummarizeOrder($::FALSE);
if (($SummaryResponse[6] == 0) ||
(!$$::g_pSetupBlob{'PRICES_DISPLAYED'}))
{
EnsurePaymentSelection();
}
else
{
if (0 == length $::g_PaymentInfo{'METHOD'})
{
return(ACTINIC::GetPhrase(-1, 55, ACTINIC::GetPhrase(-1, 152)));
}
my (@arrMethods, $nMethodID);
ActinicOrder::GenerateValidPayments(\@arrMethods);
my ($bFound) = $::FALSE;
foreach $nMethodID (@arrMethods)
{
if ($nMethodID == $::g_PaymentInfo{'METHOD'})
{
$bFound = $::TRUE;
last;
}
}
if (!$bFound)
{
return (ACTINIC::GetPhrase(-1, 2448, $::g_PaymentInfo{'METHOD'}));
}
}
my $pMapping =
{
'PONO' 			=> 6,
'USERDEFINED'	=> 7,
};
$sError .= CheckInputField(5, $pMapping, \%::g_PaymentInfo, $sFormat);
my ($ePaymentMethod) = ActinicOrder::PaymentStringToEnum($::g_PaymentInfo{'METHOD'}); # the payment method is stored as "ENUMERATEDID:DESCRIPTION"
if (defined $::g_InputHash{'PAYMENTCARDTYPE'} &&
$ePaymentMethod == $::PAYMENT_CREDIT_CARD)
{
if ($::g_PaymentInfo{'CARDTYPE'} eq "")
{
$sError .= ACTINIC::GetRequiredMessage(5, 1);
}
my ($nIndex, $sCCID, $bFound);
$bFound = $::FALSE;
for ($nIndex = 0; $nIndex < 12; $nIndex++)
{
$sCCID = sprintf('CC%d', $nIndex);
if ($$::g_pSetupBlob{$sCCID} eq
$::g_PaymentInfo{'CARDTYPE'})
{
$bFound = $::TRUE;
last;
}
}
if (!$bFound)
{
$sError .= ACTINIC::GetPhrase(-1, 1974) . ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor) . ACTINIC::GetPhrase(5, 1) .
ACTINIC::GetPhrase(-1, 1975) . ACTINIC::GetPhrase(-1, 1970) .
ACTINIC::GetPhrase(-1, 107, $::g_PaymentInfo{'CARDTYPE'}) . "<BR>\n"
}
my ($nNumber) = $::g_PaymentInfo{'CARDNUMBER'};
$nNumber =~ s/\s//g;
$nNumber =~ s/-//g;
if ($nNumber eq "")
{
$sError .= ACTINIC::GetRequiredMessage(5, 2);
}
if ($nNumber =~ /[^0-9]/)
{
$sError .= ACTINIC::GetPhrase(-1, 1974) . ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor) . ACTINIC::GetPhrase(5, 2) .
ACTINIC::GetPhrase(-1, 1975) . ACTINIC::GetPhrase(-1, 1970) .
ACTINIC::GetPhrase(-1, 108) . "<BR>\n"
}
my ($nCheckSum, $nDigitCount) = (0, 0);
my ($nDigit, $nCheck);
for($nIndex = (length $nNumber) - 1; $nIndex >= 0; $nIndex--)
{
$nDigit = substr($nNumber, $nIndex, 1);
$nCheck = (1 + $nDigitCount++ % 2) *
$nDigit;
if ( $nCheck >= 10)
{
$nCheck++;
}
$nCheckSum += $nCheck;
}
if (($nCheckSum % 10) != 0)
{
$sError .= ACTINIC::GetPhrase(-1, 1974) . ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor) . ACTINIC::GetPhrase(5, 2) .
ACTINIC::GetPhrase(-1, 1975) . ACTINIC::GetPhrase(-1, 1970) .
ACTINIC::GetPhrase(-1, 109) . "<BR>\n"
}
if ($$::g_pSetupBlob{$sCCID . '_ISSUENUMBERFLAG'})
{
if ($::g_PaymentInfo{'CARDISSUE'} eq "" ||
$::g_PaymentInfo{'CARDISSUE'} < 0 ||
$::g_PaymentInfo{'CARDISSUE'} > 255)
{
$sError .= ACTINIC::GetPhrase(-1, 110, ACTINIC::GetPhrase(-1, 1974) . ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor) .
ACTINIC::GetPhrase(5, 5) . ACTINIC::GetPhrase(-1, 1975) . ACTINIC::GetPhrase(-1, 1970), $::g_PaymentInfo{'CARDTYPE'}) . "<BR>\n"
}
}
else
{
$::g_PaymentInfo{'CARDISSUE'} = "";
}
if ($$::g_pSetupBlob{$sCCID . '_CVV2FLAG'})
{
my $nLength = $$::g_pSetupBlob{$sCCID . '_CVV2DIGITS'};
if ($::g_PaymentInfo{'CARDVV2'} !~ /^[0-9]{$nLength,$nLength}$/)
{
$sError .= ACTINIC::GetPhrase(-1, 560) . "<BR>\n"
}
}
else
{
$::g_PaymentInfo{'CARDVV2'} = "";
}
my @listCurrentTime = localtime(time);
my $nMonth = $listCurrentTime[$::TIME_MONTH];
my $nYear = $listCurrentTime[$::TIME_YEAR];
$nMonth++;
$nYear += 1900;
if ($$::g_pSetupBlob{$sCCID . '_STARTDATEFLAG'})
{
if (($::g_PaymentInfo{'STARTMONTH'} !~ /^\d{2}$/) ||
($::g_PaymentInfo{'STARTYEAR'} !~ /^\d{4}$/))
{
$sError .= ACTINIC::GetRequiredMessage(5, 3);
$::g_PaymentInfo{'STARTMONTH'} = "";
$::g_PaymentInfo{'STARTYEAR'} = "";
}
if ($::g_PaymentInfo{'STARTYEAR'} == $nYear &&
$::g_PaymentInfo{'STARTMONTH'} > $nMonth)
{
$sError .= ACTINIC::GetPhrase(-1, 1974) . ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor) . ACTINIC::GetPhrase(5, 3) .
ACTINIC::GetPhrase(-1, 1975) . ACTINIC::GetPhrase(-1, 1970) .
ACTINIC::GetPhrase(-1, 111) . "<BR>\n"
}
}
else
{
$::g_PaymentInfo{'STARTMONTH'} = "";
$::g_PaymentInfo{'STARTYEAR'} = "";
}
if (($::g_PaymentInfo{'EXPMONTH'} !~ /^\d{2}$/) ||
($::g_PaymentInfo{'EXPYEAR'} !~ /^\d{4}$/))
{
$sError .= ACTINIC::GetRequiredMessage(5, 4);
$::g_PaymentInfo{'EXPMONTH'} = "";
$::g_PaymentInfo{'EXPYEAR'} = "";
}
if ($::g_PaymentInfo{'EXPYEAR'} == $nYear &&
$::g_PaymentInfo{'EXPMONTH'} < $nMonth)
{
$sError .= ACTINIC::GetPhrase(-1, 1974) . ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor) . ACTINIC::GetPhrase(5, 4) .
ACTINIC::GetPhrase(-1, 1975) . ACTINIC::GetPhrase(-1, 1970) .
ACTINIC::GetPhrase(-1, 112) . "<BR>\n"
}
if ($$::g_pSetupBlob{$sCCID . '_STARTDATEFLAG'})
{
if ($::g_PaymentInfo{'EXPYEAR'} < $::g_PaymentInfo{'STARTYEAR'} ||
($::g_PaymentInfo{'EXPYEAR'} == $::g_PaymentInfo{'STARTYEAR'} &&
$::g_PaymentInfo{'EXPMONTH'} <= $::g_PaymentInfo{'STARTMONTH'}))
{
$sError .= ACTINIC::GetPhrase(-1, 1974) . ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor) . ACTINIC::GetPhrase(5, 4) .
ACTINIC::GetPhrase(-1, 1975) . ACTINIC::GetPhrase(-1, 1970) .
ACTINIC::GetPhrase(-1, 561) . "<BR>\n"
}
}
}
else
{
$::g_PaymentInfo{'CARDTYPE'}		= "";
$::g_PaymentInfo{'CARDNUMBER'}	= "";
$::g_PaymentInfo{'CARDISSUE'}		= "";
$::g_PaymentInfo{'CARDVV2'}		= "";
$::g_PaymentInfo{'EXPMONTH'}		= "";
$::g_PaymentInfo{'EXPYEAR'}		= "";
$::g_PaymentInfo{'STARTMONTH'}	= "";
$::g_PaymentInfo{'STARTYEAR'}		= "";
}
if ($sFormat ne 'text')
{
return ActinicOrder::FormatCheckoutInputError(ACTINIC::GetPhrase(-1, 152), $sError);
}
elsif ($sError ne '')
{
return sprintf("\n%s\n%s", ACTINIC::GetPhrase(-1, 152), $sError);
}
return '';
}
sub ValidateSignature
{
$::g_sSignature = $::g_InputHash{SIGNATURE};
if ($::g_sSignature ne '')
{
$::g_sSignature =~ /^([a-fA-F0-9]{32})$/;
$::g_sSignature = $1;
}
return (undef);
}
sub DisplayPage
{
if ($#_ != 2)
{
return ($::FAILURE, ACTINIC::GetPhrase(-1, 12, 'DisplayPage'), 0, 0);
}
my (%VariableTable, $sDetailCookie);
my ($sError, $nPageNumber, $eDirection) = @_;
my (@Response, $sPath);
$sPath = ACTINIC::GetPath();
my ($pCartList);
my $sMessage;
if($::g_InputHash{'ACTION'} !~ m/^AUTHORIZE_(\d+)$/i)
{
@Response = $::Session->GetCartObject();
if ($::Session->IsClosed())
{			
@Response = ACTINIC::BounceToPageEnhanced(7, ACTINIC::GetPhrase(-1, 1282),
$$::g_pSetupBlob{CHECKOUT_DESCRIPTION},
$::g_sWebSiteUrl,
$::g_sContentUrl, $::g_pSetupBlob,
$::Session->GetLastShopPage(),
\%::g_InputHash,
$::FALSE);
return (@Response);
}
my $pCartObject = $Response[2];
$pCartList = $pCartObject->GetCartList();
my $nLineCount = CountValidCartItems($pCartList);
if ($nLineCount != scalar @$pCartList &&
$::g_bFirstError)
{
$::g_bFirstError = $::FALSE;
$sMessage = "<P>" . ACTINIC::GetPhrase(-1, 1974) . ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor) . ACTINIC::GetPhrase(-1, 175) . ACTINIC::GetPhrase(-1, 1975) . ACTINIC::GetPhrase(-1, 1970);
return(DisplayPage($sMessage, $::g_nCurrentSequenceNumber, $eDirection));
}
}
my (@DeleteDelimiters, @KeepDelimiters, $nInc, $status);
my ($pVarTable, $pDeleteDelimiters, $pKeepDelimiters, $nKeyCount, $pSelectTable);
$nInc = ($eDirection == $::FORWARD) ? 1 : -1;
$nKeyCount = 0;
while ($nKeyCount == 0 &&
$nPageNumber >= 0)
{
my $sTempCookie;
($status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters, $pSelectTable, $sTempCookie) =
ProcessPage($nPageNumber, $eDirection);
$sDetailCookie .= $sTempCookie;
if ($status != $::SUCCESS)
{
if ($::g_bFirstError)
{
$::g_bFirstError = $::FALSE;
$sMessage = "<P>" . ACTINIC::GetPhrase(-1, 1974) . ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor) . $sMessage . ACTINIC::GetPhrase(-1, 1975) . ACTINIC::GetPhrase(-1, 1970);
return(DisplayPage($sMessage, $::g_nCurrentSequenceNumber, $eDirection));
}
else
{
return($status, $sMessage, 0, undef);
}
}
if ($nPageNumber != 2)
{
$nKeyCount = (keys %$pVarTable) + (keys %$pSelectTable);
}
else
{
$nKeyCount = 1;
$pVarTable = {};
}
$nPageNumber += $nInc;
}
$nPageNumber -= $nInc;
if ($nKeyCount == 0)
{
if (length $sError > 0)
{
my ($sRefPage) = $::Session->GetLastShopPage();
if ($$::g_pSetupBlob{UNFRAMED_CHECKOUT} &&
$$::g_pSetupBlob{UNFRAMED_CHECKOUT_URL})
{
$sRefPage = $$::g_pSetupBlob{UNFRAMED_CHECKOUT_URL};
}
my @Response = ACTINIC::BounceToPageEnhanced(-1, $sError, ACTINIC::GetPhrase(-1, 25),
$::g_sWebSiteUrl, $::g_sContentUrl, $::g_pSetupBlob, $sRefPage, \%::g_InputHash);
if ($Response[0] != $::SUCCESS)
{
ACTINIC::ReportError($sError, ACTINIC::GetPath());
}
return ($::SUCCESS, '', $Response[2], undef);
}
else
{
return ($::SUCCESS, "", GetCancelPage(), undef);
}
}
my $bTangibleProducts = ACTINIC::CartHasTangibleGoods() ? $::TRUE : $::FALSE;
$pVarTable->{$::VARPREFIX.'TANGIBLEPRODUCTSINCART'} = $bTangibleProducts;
my (@a1, @a2);
@a1 = %VariableTable;
@a2 = %$pVarTable;
push (@a1, @a2);
%VariableTable = @a1;
@DeleteDelimiters = @$pDeleteDelimiters;
@KeepDelimiters = @$pKeepDelimiters;
if (length $VariableTable{$::VARPREFIX.'ERROR'})
{
$sError .= ' ' . $VariableTable{$::VARPREFIX.'ERROR'};
}
$sError = ACTINIC::GroomError($sError);
$VariableTable{$::VARPREFIX.'ERROR'} = $sError;
$VariableTable{$::VARPREFIX.'SEQUENCE'} = $nPageNumber;
my ($sFileName);
$sFileName = sprintf('order%2.2d.html', $nPageNumber);
if ($::g_sOverrideCheckoutFileName)
{
$sFileName = $::g_sOverrideCheckoutFileName;
}
@Response = ActinicOrder::GenerateShoppingCartLines($pCartList, $::FALSE, [], $sFileName);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
if (2 == $nPageNumber)
{
my ($bV12VarDefined, $bV12Enabled) = ACTINIC::IsCustomVarDefined("IsV12FinanceEnabled");
if ($bV12VarDefined &&
$bV12Enabled)
{
my $bProductsAvail = $::FALSE;
my $nPaymentMethod = $::g_PaymentInfo{'METHOD'};
$::g_PaymentInfo{'METHOD'} = $::PAYMENT_V12FINANCE;
@Response = GetOCCScript($sPath);		
if ($Response[0] != $::SUCCESS)
{
return ($Response[0], $Response[1]);
}
my ($sScript) = $Response[2];
if (eval($sScript) != $::SUCCESS)
{
ACTINIC::ReportError($@, ACTINIC::GetPath());
}			
@Response = GetFinanceProductsArray();
if ($Response[0] == $::SUCCESS)
{	
my $FinanceProducts = $Response[2];
my $nLoan = ActinicOrder::GetOrderTotal();
foreach my $FinanceProduct (@{$Response[2]})
{
if ($FinanceProduct->{'MinLoan'} <= $nLoan &&
$FinanceProduct->{'MaxLoan'} >= $nLoan)
{
$bProductsAvail = $::TRUE;
last;
}				
}			
}
$::g_PaymentInfo{'METHOD'} = $nPaymentMethod;
if ($bProductsAvail == $::FALSE)
{
$::g_InputHash{"NOV12F"} = 1;
}
}		
}
@Response = ACTINIC::TemplateFile($sPath.$sFileName, \%VariableTable);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my ($sDigest,$sBaseFile) = ACTINIC::CaccGetCookies();
$sPath = ($sBaseFile) ? $sBaseFile : $::g_sContentUrl;
my $sWebSiteURL = $::g_sWebSiteUrl;
if ($sDigest)
{
my $sCgiUrl = $::g_sAccountScript;
$sCgiUrl   .= ($::g_InputHash{SHOP} ? 
'?SHOP=' . ACTINIC::EncodeText2($::g_InputHash{SHOP}, $::FALSE) . '&' : 
'?');
$sCgiUrl   .= "ACTINIC_REFERRER=" . ACTINIC::EncodeText2($::g_sAccountScript) . '&';
$sCgiUrl .= "PRODUCTPAGE=";
$sWebSiteURL = $sCgiUrl;
}
@Response = ACTINIC::MakeLinksAbsolute($Response[2], $sWebSiteURL, $sPath);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my ($sHTML) = $Response[2];
my ($sDelimiter);
foreach $sDelimiter (@DeleteDelimiters)
{
$sHTML =~ s/$::DELPREFIX$sDelimiter(.*?)$::DELPREFIX$sDelimiter//gs;
}
foreach $sDelimiter (@KeepDelimiters)
{
$sHTML =~ s/$::DELPREFIX$sDelimiter//gs;
}
my ($sSelectName, $sDefaultOption);
while ( ($sSelectName, $sDefaultOption) = each %$pSelectTable)
{
$sHTML =~ s/(<\s*SELECT[^>]+?NAME\s*=\s*("|')?$sSelectName.+?)<OPTION\s+VALUE\s*=\s*("|')?$sDefaultOption("|')?\s*>/$1<OPTION SELECTED VALUE="$sDefaultOption">/is;
if ($1 eq "")
{
$sDefaultOption = "---";
$sHTML =~ s/(<\s*SELECT[^>]+?NAME\s*=\s*("|')?$sSelectName.+?)<OPTION\s+VALUE\s*=\s*("|')?$sDefaultOption("|')?\s*>/$1<OPTION SELECTED VALUE="$sDefaultOption">/is;
}
}
return ($::SUCCESS, "", $sHTML, $sDetailCookie);
}
sub ProcessPage
{
if ($#_ != 1)
{
return($::SUCCESS, ACTINIC::GetPhrase(-1, 12, 'ProcessPage'), undef, undef, undef, undef, undef);
}
my ($nPageNumber, $eDirection) = @_;
my @scratch = keys %$::g_pPhaseList;
my $nPhaseCount = $#scratch - 1;
my $sDetailCookie;
if ($nPageNumber > $nPhaseCount)
{
return($::SUCCESS, ACTINIC::GetPhrase(-1, 146, $nPageNumber, $nPhaseCount), undef, undef, undef, undef, $sDetailCookie);
}
if (($nPageNumber == 2) &&
(defined $::g_InputHash{'ON'}) &&
($::g_InputHash{'ON'} ne '') &&
($eDirection == $::BACKWARD))
{
my $sOrderNumber = $::g_InputHash{'ON'};
if (IsAuthoriseSessionPresent($sOrderNumber))
{
ACTINIC::DeleteFile(GetAuthoriseSessionFileName($sOrderNumber));
}
if (IsCustomerEmailPresent($sOrderNumber))
{
ACTINIC::DeleteFile(GetCustomerEmailFileName($sOrderNumber));
}
if (IsAdminEmailPresent($sOrderNumber))
{
ACTINIC::DeleteFile(GetadminEmailFileName($sOrderNumber));
}
}
undef %::s_LargeVariableTable;
@::s_LargeDeleteDelimiters = ();
@::s_LargeKeepDelimiters = ();
undef %::s_LargeSelectTable;
my ($sPhaseList) = $$::g_pPhaseList{$nPageNumber};
my ($pVarTable, $pDeleteDelimiters, $pKeepDelimiters, $pSelectTable);
$pVarTable = {};
my (@Phases) = split (//, $sPhaseList);
my ($nPhase, $status, $sMessage);
foreach $nPhase (@Phases)
{
if ($nPhase == $::BILLCONTACTPHASE)
{
($pVarTable, $pDeleteDelimiters, $pKeepDelimiters) = DisplayBillContactPhase();
if (!defined $pSelectTable)
{
$pSelectTable = {};
}
ActinicOrder::MapLocationSelections($pSelectTable);
}
elsif ($nPhase == $::SHIPCONTACTPHASE)
{
($pVarTable, $pDeleteDelimiters, $pKeepDelimiters) = DisplayShipContactPhase();
}
elsif ($nPhase == $::SHIPCHARGEPHASE)
{
($status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters) =
ActinicOrder::DisplayShipChargePhase();
if ($status != $::SUCCESS)
{
my $sDeliveryCountry = ACTINIC::GetCountryName($::g_LocationInfo{DELIVERY_COUNTRY_CODE});
if ($::g_BillContact{COUNTRY} eq $sDeliveryCountry &&
!$$::g_pLocationList{EXPECT_INVOICE})
{
undef $::g_BillContact{COUNTRY};
}
if ($::g_ShipContact{COUNTRY} eq $sDeliveryCountry)
{
undef $::g_ShipContact{COUNTRY};
}
return ($status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters, $pSelectTable, $sDetailCookie);
}
UpdateCheckoutRecord();
}
elsif ($nPhase == $::TAXCHARGEPHASE)
{
($status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters) = ActinicOrder::DisplayTaxPhase();
if ($status != $::SUCCESS)
{
my $sInvoiceCountry = ACTINIC::GetCountryName($::g_LocationInfo{INVOICE_COUNTRY_CODE});
if ($::g_BillContact{COUNTRY} eq $sInvoiceCountry)
{
undef $::g_BillContact{COUNTRY};
}
if ($::g_ShipContact{COUNTRY} eq $sInvoiceCountry &&
!$$::g_pLocationList{EXPECT_DELIVERY})
{
undef $::g_ShipContact{COUNTRY};
}
my $sDeliveryCountry = ACTINIC::GetCountryName($::g_LocationInfo{DELIVERY_COUNTRY_CODE});
if ($::g_BillContact{COUNTRY} eq $sDeliveryCountry &&
!$$::g_pLocationList{EXPECT_INVOICE})
{
undef $::g_BillContact{COUNTRY};
}
if ($::g_ShipContact{COUNTRY} eq $sDeliveryCountry)
{
undef $::g_ShipContact{COUNTRY};
}
return ($status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters, $pSelectTable, $sDetailCookie);
}
UpdateCheckoutRecord();
}
elsif ($nPhase == $::COMPLETEPHASE)
{
if (length $::g_PaymentInfo{'METHOD'} == 0)
{
EnsurePaymentSelection();
}
my @Response = $::Session->GetCartObject();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my $pCartObject = $Response[2];
my $pCartList = $pCartObject->GetCartList();
my (@SummaryResponse) = $pCartObject->SummarizeOrder($::FALSE);
my ($ePaymentMethod);
if ($SummaryResponse[6] == 0)
{
$ePaymentMethod = -1;
}
else
{
$ePaymentMethod= ActinicOrder::PaymentStringToEnum($::g_PaymentInfo{'METHOD'}); # the payment method is stored as "ENUMERATEDID:DESCRIPTION"
}
if ($$::g_pPaymentList{$ePaymentMethod}{PAYMENT_TYPE})
{
my (@Response) = CallOCCPlugIn();
if ($Response[0] == $::ACCEPTED)
{
@Response = CompleteOrder();
if ($Response[0] != $::SUCCESS)
{
return(@Response);
}
undef %::s_VariableTable;
undef @::s_DeleteDelimiters;
undef @::s_KeepDelimiters;
($pVarTable, $pDeleteDelimiters, $pKeepDelimiters) =
(\%::s_VariableTable, \@::s_DeleteDelimiters, \@::s_KeepDelimiters);
}
elsif ($Response[0] == $::PENDING)
{
my ($sHTML) = $Response[2];
@Response = CompleteOrder();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
ACTINIC::SaveSessionAndPrintPage($sHTML, undef, $::FALSE);
exit;
}
elsif ($Response[0] == $::REJECTED)
{
ACTINIC::SaveSessionAndPrintPage($Response[2], undef, $::FALSE);
exit;
}
else
{
return (@Response);
}
}				
elsif ($ACTINIC::B2B->Get('UserDigest') &&
($ePaymentMethod == $::PAYMENT_ON_ACCOUNT ||
$ePaymentMethod == $::PAYMENT_INVOICE))
{
my ($Status, $Message, @Response);
@Response = $::Session->GetCartObject();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my $pCartObject = $Response[2];
my $pCartList = $pCartObject->GetCartList();
my (@SummaryResponse, $nTotal);
@SummaryResponse = $pCartObject->SummarizeOrder($::FALSE);
if ($SummaryResponse[0] != $::SUCCESS)
{
return (@SummaryResponse);
}
$nTotal = $SummaryResponse[6];
my $sVitalOrderDetails =
$::g_BillContact{NAME} .
$::g_BillContact{FIRSTNAME} .
$::g_BillContact{LASTNAME} .
$::g_BillContact{COMPANY} .
$::g_BillContact{ADDRESS1} .
$::g_BillContact{ADDRESS2} .
$::g_BillContact{ADDRESS3} .
$::g_BillContact{ADDRESS4} .
$::g_BillContact{POSTALCODE} .
$::g_BillContact{COUNTRY} .
$::g_BillContact{PHONE} .
$::g_BillContact{MOBILE} .
$::g_BillContact{EMAIL} .
$::g_ShipContact{NAME} .
$::g_ShipContact{FIRSTNAME} .
$::g_ShipContact{LASTNAME} .
$::g_ShipContact{COMPANY} .
$::g_ShipContact{ADDRESS1} .
$::g_ShipContact{ADDRESS2} .
$::g_ShipContact{ADDRESS3} .
$::g_ShipContact{ADDRESS4} .
$::g_ShipContact{POSTALCODE} .
$::g_ShipContact{COUNTRY} .
$::g_ShipContact{PHONE} .
$::g_ShipContact{MOBILE} .
$::g_ShipContact{EMAIL} .
$nTotal;
my $pCartItem;
foreach $pCartItem (@$pCartList)
{
$sVitalOrderDetails .= $pCartItem->{PRODUCT_REFERENCE} . $pCartItem->{QUANTITY};
my ($sSectionBlobName);
($Status, $Message, $sSectionBlobName) = ACTINIC::GetSectionBlobName($pCartItem->{SID});
if ($Status == $::FAILURE)
{
return ($Status, $Message);
}
@Response = ACTINIC::GetProduct($pCartItem->{PRODUCT_REFERENCE},  $sSectionBlobName,
ACTINIC::GetPath());
my $pProduct;
($Status, $Message, $pProduct) = @Response;
if ($Status == $::NOTFOUND)
{
next;
}
if ($Status != $::SUCCESS)
{
return (@Response);
}
my $VariantList;
if( $pProduct->{COMPONENTS} )
{
my $sKey;
foreach $sKey (keys %$pCartItem)
{
if( $sKey =~ /^COMPONENT\_/ )
{
$VariantList->[$'] = $pCartItem->{$sKey};
}
}
}
my %Component;
my $pComponent;
foreach $pComponent (@{$pProduct->{COMPONENTS}})
{
@Response = ActinicOrder::FindComponent($pComponent,$VariantList);
($Status, %Component) = @Response;
if ($Status == $::SUCCESS and $Component{quantity} > 0 )
{
my $sProdName;
if( !$pComponent->[0] &&
$Component{text} )
{
$Component{quantity} = 0; # Quantity=0 for attributes
}
$sVitalOrderDetails .= $Component{code} . ($pCartItem->{QUANTITY} * $Component{quantity});
}
}
}
eval
{
require Digest::MD5;
import Digest::MD5 'md5_hex';
};
if ($@)
{
require di000001;
import Digest::Perl::MD5 'md5_hex';
}
my $sMD5Vitals = md5_hex($sVitalOrderDetails);
my $sUser = $ACTINIC::B2B->Get('UserName');
my $sMD5User = md5_hex($ACTINIC::B2B->Get('UserName') . $ACTINIC::B2B->Get('UserDigest'));
undef %::s_VariableTable;
undef @::s_DeleteDelimiters;
undef @::s_KeepDelimiters;
$::s_VariableTable{$::VARPREFIX.'USER'} = $sUser;
$::s_VariableTable{$::VARPREFIX.'VITAL'} = $sMD5Vitals;
$::s_VariableTable{$::VARPREFIX.'ID'} = $sMD5User;
($pVarTable, $pDeleteDelimiters, $pKeepDelimiters) =
(\%::s_VariableTable, \@::s_DeleteDelimiters, \@::s_KeepDelimiters);
$::g_sOverrideCheckoutFileName = 'signature.html';
}
else
{
my (@Response) = CompleteOrder();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
undef %::s_VariableTable;
undef @::s_DeleteDelimiters;
undef @::s_KeepDelimiters;
($pVarTable, $pDeleteDelimiters, $pKeepDelimiters) =
(\%::s_VariableTable, \@::s_DeleteDelimiters, \@::s_KeepDelimiters);
$::Session->PaymentMade();
}
}
elsif ($nPhase == $::RECEIPTPHASE)
{
my ($ePaymentMethod);
if($::g_InputHash{'ACTION'} =~ m/^AUTHORIZE_(\d+)$/i)
{
$ePaymentMethod = $1; # the : is to help parsing
}
elsif (length $::g_PaymentInfo{METHOD} == 0)
{
$ePaymentMethod = $::PAYMENT_CREDIT_CARD; # the : is to help parsing
}
else
{
($ePaymentMethod) = ActinicOrder::PaymentStringToEnum($::g_PaymentInfo{METHOD}); # the payment method is stored as "ENUMERATEDID:DESCRIPTION"
}
if ($ACTINIC::B2B->Get('UserDigest') &&
($ePaymentMethod == $::PAYMENT_ON_ACCOUNT ||
$ePaymentMethod == $::PAYMENT_INVOICE))
{
my (@Response) = CompleteOrder();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
}
if ($$::g_pPaymentList{$ePaymentMethod}{PAYMENT_TYPE} &&
$::g_InputHash{'ACTION'} =~ m/^AUTHORIZE/i)
{
my $bSaveAuth = (defined $::g_InputHash{'DOIT'}) ? $::FALSE : $::TRUE;
if ($bDivertPSPAuthorise &&
$bSaveAuth)
{
ACTINIC::RecordErrors("Calling SaveAuthCallback", ACTINIC::GetPath());
SaveAuthCallback();
ACTINIC::RecordErrors("Returned from SaveAuthCallback", ACTINIC::GetPath());
ACTINIC::PrintPSPResponse('text/plain', '1');
exit;
}
$::Session->RecordPSPTracking();
LogData("AUTHORIZE:\n$::g_OriginalInputData");
if (!defined $::g_InputHash{ON})
{
ACTINIC::RecordErrors("Auth callback without order number {ON}", ACTINIC::GetPath());
}
my $sText;
if (defined $::g_InputHash{'ACT_POSTPROCESS'})
{
my ($sFilename, $pPaymentMethodHash);
$pPaymentMethodHash = $$::g_pPaymentList{$ePaymentMethod};
$sFilename = $$pPaymentMethodHash{POST_PROCESS};
my (@Response) = CallPlugInScript($sFilename);
if ($Response[0] != $::SUCCESS)
{
ACTINIC::RecordErrors($Response[1], ACTINIC::GetPath());
}
LogData("AUTHORIZERESULT:" . $::g_PaymentInfo{'AUTHORIZERESULT'});
}
else
{
my $sText;
LogData ("RecordAuthorization:");
my $sError = RecordAuthorization();
if (length $sError != 0)
{
$sText = sprintf("%s:%s", $::g_PaymentInfo{'AUTHORIZERESULT'}, $sError);
}
else
{
$sText = $::g_PaymentInfo{'AUTHORIZERESULT'};
}
LogData("AUTHORIZERESULT:" . $sText);
ACTINIC::PrintPSPResponse('text/plain', $sText);
}
SendDelayedEmails($::g_InputHash{ON});
UpdateCheckoutRecord();
$::Session->SaveSession();
exit;
}
elsif (($ePaymentMethod == $::PAYMENT_CREDIT_CARD) &&
$::g_InputHash{'ACTION'} =~ m/RECORDORDER/i &&
defined $::g_InputHash{BLOB})
{
my $sText;
my $nOrderLength = length $::g_InputHash{BLOB};
if ($nOrderLength > 1024 * 250)
{
$sText = "0" . ACTINIC::GetPhrase(-1, 300);
}
else
{
my $sError = RecordOrder($::g_InputHash{ORDERNUMBER}, \$::g_InputHash{BLOB}, $::TRUE);
if (length $sError != 0)
{
my $bOmitMailDump = $::FALSE;
my $sErrorMessage = $sError;
if($sError =~ /^000/)
{
$bOmitMailDump = $::TRUE;
$sErrorMessage =~ s/^0+//;
}
NotifyOfError($sErrorMessage, $bOmitMailDump);
ACTINIC::RecordErrors($sErrorMessage, ACTINIC::GetPath()); # record the error to error.err
$sText = "0" . $sError;
}
else
{
$sText = "1";
$::Session->PaymentMade();
}
}
ACTINIC::PrintText($sText);
$::Session->SaveSession();
exit;
}
else
{
($status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters) = DisplayReceiptPhase($::g_InputHash{ORDERNUMBER}, $ePaymentMethod);
if ($status != $::SUCCESS)
{
return ($status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters, $pSelectTable, $sDetailCookie);
}
UpdateCheckoutRecord();
$sDetailCookie = $::Session->ContactDetailsToCookieString();
$::Session->MarkAsClosed();
$::Session->SaveSession();
}
}
elsif ($nPhase == $::PRELIMINARYINFOPHASE)
{
($status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters, $pSelectTable) = ActinicOrder::DisplayPreliminaryInfoPhase();
if ($status != $::SUCCESS)
{
return ($status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters, $pSelectTable, $sDetailCookie);
}
UpdateCheckoutRecord();
}
my (@Array1, @Array2);
@Array1 = %$pVarTable;
@Array2 = %::s_LargeVariableTable;
push (@Array1, @Array2);
%::s_LargeVariableTable = @Array1;
if (defined $pDeleteDelimiters)
{
push (@::s_LargeDeleteDelimiters, @$pDeleteDelimiters);
}
if (defined $pKeepDelimiters)
{
push (@::s_LargeKeepDelimiters, @$pKeepDelimiters);
}
if (defined $pSelectTable)
{
@Array1 = %$pSelectTable;
@Array2 = %::s_LargeSelectTable;
push (@Array1, @Array2);
%::s_LargeSelectTable = @Array1;
undef $pSelectTable;
}
($pDeleteDelimiters, $pKeepDelimiters) = ActinicOrder::ParseDelimiterStatus($nPhase);
push (@::s_LargeDeleteDelimiters, @$pDeleteDelimiters);
push (@::s_LargeKeepDelimiters, @$pKeepDelimiters);
}
return ($::SUCCESS, '', \%::s_LargeVariableTable, \@::s_LargeDeleteDelimiters, \@::s_LargeKeepDelimiters,
\%::s_LargeSelectTable, $sDetailCookie);
}
sub SendDelayedEmails
{
my $sOrderNumber = shift;
if ($::Session->IsPaymentMade())
{
if (IsCustomerEmailPresent($sOrderNumber))
{
LogData("Sending saved customer email for $sOrderNumber");
SendSavedEmail(GetCustomerEmailFileName($sOrderNumber))
}
if (IsAdminEmailPresent($sOrderNumber))
{
LogData("Sending saved admin email for $sOrderNumber");
SendSavedEmail(GetAdminEmailFileName($sOrderNumber))
}
}
}
sub DisplayBillContactPhase
{
undef %::s_VariableTable;
undef @::s_DeleteDelimiters;
undef @::s_KeepDelimiters;
if (ActinicOrder::IsPhaseComplete($::BILLCONTACTPHASE) ||
ActinicOrder::IsPhaseHidden($::BILLCONTACTPHASE))
{
push (@::s_DeleteDelimiters, 'INVOICEPHASE');
return (\%::s_VariableTable, \@::s_DeleteDelimiters, \@::s_KeepDelimiters);
}
else
{
push (@::s_KeepDelimiters, 'INVOICEPHASE');
}
if (0 == length $::g_BillContact{'COUNTRY'})
{
if ($$::g_pLocationList{EXPECT_INVOICE} &&
$::g_LocationInfo{INVOICE_COUNTRY_CODE} ne $ActinicOrder::REGION_NOT_SUPPLIED)
{
$::g_BillContact{'COUNTRY'} = ACTINIC::GetCountryName($::g_LocationInfo{INVOICE_COUNTRY_CODE});
}
elsif ($$::g_pLocationList{EXPECT_DELIVERY} &&
$::g_LocationInfo{DELIVERY_COUNTRY_CODE} ne $ActinicOrder::REGION_NOT_SUPPLIED)
{
$::g_BillContact{'COUNTRY'} = ACTINIC::GetCountryName($::g_LocationInfo{DELIVERY_COUNTRY_CODE});
}
}
$::s_VariableTable{$::VARPREFIX.'COUPONCODE'}		= ACTINIC::EncodeText2($::g_PaymentInfo{'COUPONCODE'});
if (!$::g_BillContact{'SEPARATE'})
{
ACTINIC::CopyHash(\%::s_VariableTable, \%::s_VariableTable, $::VARPREFIX.'INVOICE',  $::VARPREFIX.'DELIVER', 0);
}
$::s_VariableTable{$::VARPREFIX.'INVOICETITLE'}		= ACTINIC::GetPhrase(-1, 147);
$::s_VariableTable{$::VARPREFIX.'DELIVERTITLE'}		= ACTINIC::GetPhrase(-1, 148);
ACTINIC::SetCheckStatusNQV(\%::g_BillContact, \%::s_VariableTable, 'MOVING',			'INVOICEMOVINGCHECKSTATUS');
ACTINIC::SetCheckStatusNQV(\%::g_BillContact, \%::s_VariableTable, 'PRIVACY',			'INVOICEPRIVACYCHECKSTATUS');
ACTINIC::SetCheckStatusNQV(\%::g_BillContact, \%::s_VariableTable, 'SEPARATE',		'INVOICESEPARATECHECKSTATUS');
ACTINIC::SetCheckStatusNQV(\%::g_BillContact, \%::s_VariableTable, 'REMEMBERME',		'INVOICEREMEMBERME',	'CHECKED');
return (\%::s_VariableTable, \@::s_DeleteDelimiters, \@::s_KeepDelimiters);
}
sub DisplayShipContactPhase
{
undef %::s_VariableTable;
undef @::s_DeleteDelimiters;
undef @::s_KeepDelimiters;
if (ActinicOrder::IsPhaseComplete($::SHIPCONTACTPHASE) ||
ActinicOrder::IsPhaseHidden($::SHIPCONTACTPHASE) )
{
push (@::s_DeleteDelimiters, 'DELIVERPHASE');
return (\%::s_VariableTable, \@::s_DeleteDelimiters, \@::s_KeepDelimiters);
}
elsif (defined $$::g_pSetupBlob{'REVERSE_ADDRESS_CHECK'} && $$::g_pSetupBlob{'REVERSE_ADDRESS_CHECK'})
{
if ($::g_BillContact{'SEPARATE'})
{
push (@::s_DeleteDelimiters, 'DELIVERPHASE');
return (\%::s_VariableTable, \@::s_DeleteDelimiters, \@::s_KeepDelimiters);
}
else
{
push (@::s_KeepDelimiters, 'DELIVERPHASE');
}
}
else
{
if (!$::g_BillContact{'SEPARATE'})
{
push (@::s_DeleteDelimiters, 'DELIVERPHASE');
return (\%::s_VariableTable, \@::s_DeleteDelimiters, \@::s_KeepDelimiters);
}
else
{
push (@::s_KeepDelimiters, 'DELIVERPHASE');
}
}
if ($::ACT_ADB)
{
ConfigureAddressBook();
$::ACT_ADB->ToForm();
$::s_VariableTable{$::VARPREFIX.'ADDRESSBOOK'}	= $::ACT_ADB->Show();
}
else
{
$::s_VariableTable{$::VARPREFIX.'ADDRESSBOOK'}	= "";
}
if (0 == length $::g_ShipContact{'COUNTRY'})
{
if ($$::g_pLocationList{EXPECT_DELIVERY} &&
$::g_LocationInfo{DELIVERY_COUNTRY_CODE} ne $ActinicOrder::REGION_NOT_SUPPLIED)
{
$::g_ShipContact{'COUNTRY'} = ACTINIC::GetCountryName($::g_LocationInfo{DELIVERY_COUNTRY_CODE});
}
elsif ($$::g_pLocationList{EXPECT_INVOICE} &&
$::g_LocationInfo{INVOICE_COUNTRY_CODE} ne $ActinicOrder::REGION_NOT_SUPPLIED)
{
$::g_ShipContact{'COUNTRY'} = ACTINIC::GetCountryName($::g_LocationInfo{INVOICE_COUNTRY_CODE});
}
}
my $sFormat = "<INPUT TYPE=HIDDEN NAME=%s VALUE='%s'>\n";
my $sParam;
foreach (keys %::g_LocationInfo)
{
$sParam .= sprintf($sFormat, $_, $::g_LocationInfo{$_});
}
$::s_VariableTable{$::VARPREFIX.'LOCATIONINFO'} = $sParam;
$::s_VariableTable{$::VARPREFIX.'DELIVERTITLE'} 		= ACTINIC::GetPhrase(-1, 148);
return (\%::s_VariableTable, \@::s_DeleteDelimiters, \@::s_KeepDelimiters);
}
sub DisplayReceiptPhase
{
undef %::s_VariableTable;
undef @::s_DeleteDelimiters;
undef @::s_KeepDelimiters;
if ($#_ < 1)
{
return($::FAILURE, ACTINIC::GetPhrase(-1, 12, 'DisplayReceiptPhase'), undef, undef, undef);
}
my ($Message, $Status);
my ($sOrderNumber, $ePaymentMethod) = @_;
if ($sOrderNumber ne $::g_PaymentInfo{'ORDERNUMBER'})
{		
my $sMsg = sprintf("Receipt requested for different order: '%s' instead of '%s'. Payment method:%s.", $sOrderNumber, $::g_PaymentInfo{'ORDERNUMBER'}, $::g_PaymentInfo{'METHOD'});
LogV12Event($sMsg);
ACTINIC::TerminalError("Receipt requested for different order");
return;
}
MergeAuthoriseToSession($sOrderNumber);
my $bMailDelayed = $::Session->IsMailSaved();
if ($::Session->IsIPCheckFailed())
{
$::s_VariableTable{$::VARPREFIX.'ERROR'} = ACTINIC::GetPhrase(-1, 2308);
}
$::ReceiptPhase = $::TRUE;
my $bInvoiceUsesRegion = $::FALSE;
my $bShipSeparately = ($::g_LocationInfo{SEPARATESHIP} ne '');
if(defined $$::g_pLocationList{INVOICEADDRESS4} &&
$$::g_pLocationList{INVOICEADDRESS4})
{
$bInvoiceUsesRegion = $::TRUE;
$::g_BillContact{ADDRESS4} = ActinicLocations::GetInvoiceAddressRegionName($::g_BillContact{ADDRESS4});
}
if(defined $$::g_pLocationList{DELIVERADDRESS4} &&
$$::g_pLocationList{DELIVERADDRESS4})
{
$::g_ShipContact{ADDRESS4} = ActinicLocations::GetDeliveryAddressRegionName($::g_ShipContact{ADDRESS4});
if (!$bInvoiceUsesRegion &&
!$bShipSeparately)
{
$::g_BillContact{ADDRESS4} = ActinicLocations::GetInvoiceAddressRegionName($::g_BillContact{ADDRESS4});
}
}
else
{
if ($bInvoiceUsesRegion &&
!$bShipSeparately)
{
$::g_ShipContact{ADDRESS4} = ActinicLocations::GetDeliveryAddressRegionName($::g_ShipContact{ADDRESS4});
}
}
if (!$bMailDelayed)
{
LogData("DisplayReceiptPhase: Generating emails");
EmailReceipt($sOrderNumber);
}
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst, $sDate);
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
$mon++;
$year += 1900;
$sDate = sprintf('%d %s %d', $mday, $::g_InverseMonthMap{$mon}, $year); # format the date "day Month Year" eg. "1 April 1998"
$::s_VariableTable{$::VARPREFIX.'CURRENTDATE'} = $sDate;
$::s_VariableTable{$::VARPREFIX.'THEORDERNUMBER'} = $sOrderNumber;
my ($sDirections, $sTemp, @Response);
if ($ePaymentMethod == $::PAYMENT_CREDIT_CARD_SEPARATE)
{
$sDirections = ACTINIC::GetPhrase(-1, 73);
}
$::s_VariableTable{$::VARPREFIX.'SENDSEPARATELY'} = $sDirections;
{
my %HashID = (
'CONTACT_JOB_TITLE' => 'COMPANYCONTACTTITLE',
'COMPANY_NAME' => 'COMPANYNAME',
'ADDRESS_1' => 'COMPANYSTREETADDRESS1',
'ADDRESS_2' => 'COMPANYSTREETADDRESS2',
'ADDRESS_3' => 'COMPANYSTREETADDRESS3',
'ADDRESS_4' => 'COMPANYSTREETADDRESS4',
'POSTAL_CODE' => 'COMPANYPOSTCODE',
'COUNTRY' => 'COMPANYCOUNTRY',
'PHONE' => 'COMPANYPHONE|-1|74',
'FAX' => 'COMPANYFAX|-1|75'
);
ACTINIC::HashToVarTable(\%HashID, \%$::g_pSetupBlob, \%::s_VariableTable, '<br/>');
}
undef $sTemp;
if ((length $$::g_pSetupBlob{'CONTACT_NAME'}) > 0)
{
if ((length $$::g_pSetupBlob{'CONTACT_SALUTATION'}) > 0)
{
$sTemp = $$::g_pSetupBlob{'CONTACT_SALUTATION'} . " " . $$::g_pSetupBlob{'CONTACT_NAME'};
}
else
{
$sTemp = $$::g_pSetupBlob{'CONTACT_NAME'};
}
@Response = ACTINIC::EncodeText($sTemp,$::TRUE,$::TRUE);
$sTemp = $Response[1] . "<BR>";
}
$::s_VariableTable{$::VARPREFIX.'COMPANYCONTACTNAME'} = $sTemp;
undef $sTemp;
if ((length $$::g_pSetupBlob{'EMAIL'}) > 0)
{
$sTemp .= ACTINIC::GetPhrase(-1, 76) . ": <A HREF=\"MAILTO:" . $$::g_pSetupBlob{'EMAIL'} . "\">" .
$$::g_pSetupBlob{'EMAIL'} . "</A><BR>";
}
$::s_VariableTable{$::VARPREFIX.'COMPANYEMAIL'} = $sTemp;
undef $sTemp;
if ((length $$::g_pSetupBlob{'WEB_SITE_URL'}) > 0)
{
my $sService = ($$::g_pSetupBlob{WEB_SITE_URL} =~ /^http(s)?:\/\//) ? '' : 'http://';
$sTemp = ACTINIC::GetPhrase(-1, 77) . ": <A HREF=\"" . $sService . $$::g_pSetupBlob{'WEB_SITE_URL'} . "\">" .
$$::g_pSetupBlob{'WEB_SITE_URL'} . "</A><BR>";
}
$::s_VariableTable{$::VARPREFIX.'COMPANYURL'} = $sTemp;
$::s_VariableTable{$::VARPREFIX.'YOURRECEIPT'} 		= ACTINIC::GetPhrase(-1, 336);
$::s_VariableTable{$::VARPREFIX.'PRINTTHISPAGE'} 	= ACTINIC::GetPhrase(-1, 337);
$::s_VariableTable{$::VARPREFIX.'NEEDTOCONTACT'} 	= ACTINIC::GetPhrase(-1, 338);
$::s_VariableTable{$::VARPREFIX.'INVOICETO'} 		= ACTINIC::GetPhrase(-1, 339);
$::s_VariableTable{$::VARPREFIX.'DELIVERTO'} 		= ACTINIC::GetPhrase(-1, 340);
$::s_VariableTable{$::VARPREFIX.'DATETEXT'} 			= ACTINIC::GetPhrase(-1, 342);
$::s_VariableTable{$::VARPREFIX.'ORDERNUMBERTEXT'}	= ACTINIC::GetPhrase(-1, 343);
$::s_VariableTable{$::VARPREFIX.'MOVING'} = $::g_BillContact{'MOVING'} ? ACTINIC::GetPhrase(-1, 1914) : ACTINIC::GetPhrase(-1, 1915);
my ($sInvoiceName);
undef $sTemp;
if ((length $::g_BillContact{'NAME'}) > 0)
{
$sTemp = $::g_BillContact{'SALUTATION'} . " " . $::g_BillContact{'NAME'};
@Response = ACTINIC::EncodeText($sTemp);
$sInvoiceName .= $Response[1] . "<BR>\n";
}
$::s_VariableTable{$::VARPREFIX.'INVOICENAME'} = $sInvoiceName;
{
my %HashID = (
'JOBTITLE' => 'INVOICEJOBTITLE',
'COMPANY'  => 'INVOICECOMPANY',
'ADDRESS1' => 'INVOICEADDRESS1',
'ADDRESS2' => 'INVOICEADDRESS2',
'ADDRESS3' => 'INVOICEADDRESS3',
'ADDRESS4' => 'INVOICEADDRESS4',
'POSTALCODE' => 'INVOICEPOSTALCODE',
'COUNTRY'  => 'INVOICECOUNTRY',
'PHONE'    => 'INVOICEPHONE|-1|348',
'MOBILE'    => 'INVOICEMOBILE|0|20',
'FAX'      => 'INVOICEFAX|-1|349',
'EMAIL'    => 'INVOICEEMAIL|-1|350',
'USERDEFINED' => 'INVOICEUSERDEFINED|0|14'
);
ACTINIC::HashToVarTable(\%HashID, \%::g_BillContact, \%::s_VariableTable, '<br/>');
}
my ($sDeliveryName);
if ((length $::g_ShipContact{'NAME'}) > 0)
{
$sTemp = $::g_ShipContact{'SALUTATION'} . " " . $::g_ShipContact{'NAME'};
@Response = ACTINIC::EncodeText($sTemp);
$sDeliveryName .= $Response[1] . "<BR>\n";
}
$::s_VariableTable{$::VARPREFIX.'DELIVERNAME'} = $sDeliveryName;
{
my %HashID = (
'JOBTITLE' 	=> 'DELIVERJOBTITLE',
'COMPANY'  	=> 'DELIVERCOMPANY',
'ADDRESS1' => 'DELIVERADDRESS1',
'ADDRESS2' => 'DELIVERADDRESS2',
'ADDRESS3' => 'DELIVERADDRESS3',
'ADDRESS4' => 'DELIVERADDRESS4',
'POSTALCODE' => 'DELIVERPOSTALCODE',
'COUNTRY'  	=> 'DELIVERCOUNTRY',
'PHONE'    	=> 'DELIVERPHONE|-1|348',
'MOBILE'    	=> 'DELIVERMOBILE|1|20',
'FAX'      	=> 'DELIVERFAX|-1|349',
'EMAIL'    	=> 'DELIVEREMAIL|-1|350',
'USERDEFINED' => 'DELIVERUSERDEFINED|1|13'
);
ACTINIC::HashToVarTable(\%HashID, \%::g_ShipContact, \%::s_VariableTable, '<br/>');
}
@Response = $::Session->GetCartObject();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my $pCartObject = $Response[2];
my $pCartList = $pCartObject->GetCartList();
@Response = $pCartObject->SummarizeOrder($::FALSE);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my ($Ignore0, $Ignore1, $nSubTotal, $nShipping, $nTax1, $nTax2, $nTotal, $nShippingTax1, $nShippingTax2,
$nHandling, $nHandlingTax1, $nHandlingTax2) = @Response;
@Response = ActinicOrder::FormatPrice($nTotal, $::TRUE, $::g_pCatalogBlob);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my $sTotal = $Response[4];
$::s_VariableTable{$::VARPREFIX.'ACTINICORDERTOTAL'} = $nTotal;
my $fTotal = $nTotal / (10 ** $$::g_pCatalogBlob{"ICURRDIGITS"});
$::s_VariableTable{$::VARPREFIX.'ORDERTOTALBASEUNIT'} = $fTotal;
$::s_VariableTable{$::VARPREFIX.'TEXTORDERTOTAL'} = $sTotal;
$::s_VariableTable{$::VARPREFIX.'FORMATTEDORDERTOTALCGI'} = ACTINIC::EncodeText2($sTotal, $::FALSE);
$::s_VariableTable{$::VARPREFIX.'FORMATTEDORDERTOTALHTML'} = ACTINIC::EncodeText2($sTotal);
@Response = ActinicOrder::FormatPrice($nTotal, $::FALSE, $::g_pCatalogBlob);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
$sTotal = $Response[4];
$::s_VariableTable{$::VARPREFIX.'NUMERICORDERTOTALCGI'} = ACTINIC::EncodeText2($sTotal, $::FALSE);
$::s_VariableTable{$::VARPREFIX.'NUMERICORDERTOTAL'} = $sTotal;
@Response = ACTINIC::GetDigitalContent($pCartList);
if ($Response[0] == $::FAILURE)
{
return (@Response);
}
my %hDDLinks = %{$Response[2]};
my $sDownloadMessage;
if (keys %hDDLinks > 0)
{
$sDownloadMessage = ACTINIC::GetPhrase(-1, 2250, $$::g_pSetupBlob{'DD_EXPIRY_TIME'});
}
elsif ($bMailDelayed == $::TRUE)
{
$sDownloadMessage = ACTINIC::GetPhrase(-1, 2309);
}
$::s_VariableTable{$::VARPREFIX.'DOWNLOADINSTRUCTION'} = $sDownloadMessage;
my ($sPaymentPanel);
if ($nTotal > 0 && $$::g_pSetupBlob{'PRICES_DISPLAYED'}) # if their is money involed, display the payment panel
{
$::s_VariableTable{$::VARPREFIX.'PAYMENTMETHODTITLE'} = ACTINIC::GetPhrase(-1, 79); # "Payment Method"
undef $sPaymentPanel;
if (length $::g_PaymentInfo{'PONO'} > 0)
{
$sPaymentPanel = "<TR>\n";
@Response = ACTINIC::EncodeText($::g_PaymentInfo{'PONO'});
$sPaymentPanel .= "<TD BGCOLOR=\"$$::g_pSetupBlob{FORM_EMPHASIS_COLOR}\"><FONT FACE=\"ARIAL\" SIZE=\"2\"><B>" .
ACTINIC::GetPhrase(-1, 81) . ":</B></FONT></TD><TD COLSPAN=2><FONT FACE=\"ARIAL\" SIZE=\"2\">";
$sPaymentPanel .= $Response[1] . "</FONT></TD>";
$sPaymentPanel .= "</TR>\n";
}
$::s_VariableTable{$::VARPREFIX.'PURCHASEORDERNUMBER'} = $sPaymentPanel;
my $sPspPendingNotice;
if (($$::g_pPaymentList{$ePaymentMethod}{PAYMENT_TYPE}) &&
($::Session->GetAuthorizeResult() != 1))
{
$sPspPendingNotice = GetPspPendingNotice($ePaymentMethod);
}
$::s_VariableTable{$::VARPREFIX.'PSPPENDINGNOTICE'} = $sPspPendingNotice;
if ($ePaymentMethod == $::PAYMENT_CREDIT_CARD_SEPARATE)
{
push (@::s_KeepDelimiters, 'PAYMENTSENTSEPARATE');
push (@::s_DeleteDelimiters, 'PAYMENTOTHER');
$::s_VariableTable{$::VARPREFIX.'PAYMENTMETHODNAME'} = ACTINIC::GetPhrase(-1, 80);
$::s_VariableTable{$::VARPREFIX.'CREDITCARDTYPETITLE'} = ACTINIC::GetPhrase(-1, 82); # "Acceptable CC's"
my ($nCount, $sCCID, $sCCList);
for ($nCount = 0; $nCount < 12; $nCount++)
{
$sCCID = sprintf('CC%d', $nCount);
if (length $$::g_pSetupBlob{$sCCID} > 0)
{
$sCCList .= $$::g_pSetupBlob{$sCCID} . ", ";
}
}
$sCCList = substr($sCCList, 0, (length $sCCList) - 2);
@Response = ACTINIC::EncodeText($sCCList);
$::s_VariableTable{$::VARPREFIX.'CREDITCARDOPTIONS'} = $Response[1]; # list of acceptable CC's
$::s_VariableTable{$::VARPREFIX.'SELECTONE'} = ACTINIC::GetPhrase(-1, 83); # "Select One"
$::s_VariableTable{$::VARPREFIX.'CREDITCARDNUMBERTITLE'} = ACTINIC::GetPhrase(-1, 84); # "card number"
$::s_VariableTable{$::VARPREFIX.'CREDITCARDISSUENUMBERTITLE'} = ACTINIC::GetPhrase(-1, 85); # "card issue number"
$::s_VariableTable{$::VARPREFIX.'CREDITCARDCCV2TITLE'} = ACTINIC::GetPhrase(5, 8); # "card CCV2 number"
$::s_VariableTable{$::VARPREFIX.'CREDITCARDSTARTDATETITLE'} = ACTINIC::GetPhrase(-1, 86); # "card start date"
$::s_VariableTable{$::VARPREFIX.'CREDITCARDEXPDATETITLE'} = ACTINIC::GetPhrase(-1, 87); # "card exp date"
$::s_VariableTable{$::VARPREFIX.'SIGNATURETITLE'} = ACTINIC::GetPhrase(-1, 88); # "card signature"
}
else
{
push (@::s_DeleteDelimiters, 'PAYMENTSENTSEPARATE');
push (@::s_KeepDelimiters, 'PAYMENTOTHER');
undef $sPaymentPanel;
$sPaymentPanel .= ACTINIC::HTMLEncode(ActinicOrder::EnumToPaymentString($ePaymentMethod));
if (defined $::g_PaymentInfo{'AUTHORIZERESULT'} &&
$::g_PaymentInfo{'AUTHORIZERESULT'} =~ /^0(.+)/)
{
$sPaymentPanel .= "<BR>" . ACTINIC::GetPhrase(-1, 1974) . ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor) . ACTINIC::GetPhrase(-1, 1969) .
ACTINIC::GetPhrase(-1, 1964) .
ACTINIC::GetPhrase(-1, 1970) . ACTINIC::GetPhrase(-1, 1975);
}
$::s_VariableTable{$::VARPREFIX.'PAYMENTMETHODNAME'} = $sPaymentPanel;
if ($ePaymentMethod == $::PAYMENT_CREDIT_CARD)
{
push (@::s_KeepDelimiters, 'PAYMENTCREDITCARD');
$::s_VariableTable{$::VARPREFIX.'CREDITCARDTITLE'} = ACTINIC::GetPhrase(-1, 94); # "Credit Card"
if (length $::g_PaymentInfo{'CARDTYPE'} > 0) # if a credit card type exists, display it
{
$sPaymentPanel = $::g_PaymentInfo{'CARDTYPE'};
}
else
{
$sPaymentPanel = "(" . ACTINIC::GetPhrase(-1, 95) . ")";
}
$::s_VariableTable{$::VARPREFIX.'CREDITCARDTYPE'} = $sPaymentPanel;
}
else
{
push (@::s_DeleteDelimiters, 'PAYMENTCREDITCARD');
}
}
push (@::s_KeepDelimiters, 'PAYMENTPANEL');
}
else
{
push (@::s_DeleteDelimiters, 'PAYMENTPANEL');
}
if (ACTINIC::IsPromptHidden(0, 13))
{
push (@::s_DeleteDelimiters, 'MOVINGSTATUS');
}
else
{
push (@::s_KeepDelimiters, 'MOVINGSTATUS');
}
my ($bDPDVarDefined, $bDPDEnabled) = ACTINIC::IsCustomVarDefined("IsDPDEnabled");
if ($bDPDEnabled)
{		
if (!$::g_ShipInfo{'USERDEFINED'} &&
!$::g_ShipInfo{'DPDEXTRAINFO'})		
{
push (@::s_DeleteDelimiters, 'DELIVERYINSTRUCTION');
}
else
{		
$::s_VariableTable{$::VARPREFIX.'DELIVERINSTRUCTION_LABEL'} = ACTINIC::GetPhrase(-1, 2044);
$::s_VariableTable{$::VARPREFIX.'DELIVERINSTRUCTION_TEXT'} = $::g_ShipInfo{'USERDEFINED'} . $::g_ShipInfo{'DPDEXTRAINFO'};
push (@::s_KeepDelimiters, 'DELIVERYINSTRUCTION');
}
}
else
{
if (!$::g_ShipInfo{'USERDEFINED'})
{
push (@::s_DeleteDelimiters, 'DELIVERYINSTRUCTION');
}
else
{		
$::s_VariableTable{$::VARPREFIX.'DELIVERINSTRUCTION_LABEL'} = ACTINIC::GetPhrase(-1, 2044);
$::s_VariableTable{$::VARPREFIX.'DELIVERINSTRUCTION_TEXT'} = $::g_ShipInfo{'USERDEFINED'};
push (@::s_KeepDelimiters, 'DELIVERYINSTRUCTION');
}
}
return ($::SUCCESS, '', \%::s_VariableTable, \@::s_DeleteDelimiters, \@::s_KeepDelimiters);
}
sub MergeAuthoriseToSession
{
my $sOrderNumber = shift;
if (IsAuthoriseSessionPresent($sOrderNumber))
{
$::Authorise = new Session($sOrderNumber, "", ACTINIC::GetPath(), $::FALSE, $::FALSE, $::TRUE);
$::g_PaymentInfo{'AUTHORIZERESULT'} = $::Authorise->GetAuthorizeResult();
if ($::Authorise->IsIPCheckFailed())
{
$::Session->IPCheckFailed();
}
my $nMailState = $::Authorise->GetMailState();		
if ($nMailState > $::Session->GetMailState())
{
$::Session->SetMailState($nMailState);
}
if ($::Authorise->IsPaymentMade())
{
$::Session->PaymentMade();
}
if ($::Session->IsPaymentMade())
{
LogData("MergeAuthoriseToSession:: Removing authorise file for order $sOrderNumber as payment recorded");
ACTINIC::DeleteFile(GetAuthoriseSessionFileName($sOrderNumber));
}
undef $::Authorise;
}
}
sub GetSaferBlob
{
my ($sOrderNumber, $sPath) = @_;	
my ($Status, $Message);
$::g_InputHash{'ORDERNUMBER'} = $sOrderNumber;
my (@FieldList, @FieldType);
my $objOrderBlob = new OrderBlob(\@FieldType, \@FieldList);
$objOrderBlob->AddWord($ACTINIC::ORDER_BLOB_MAGIC);
$objOrderBlob->AddByte($::ORDER_BLOB_VERSION);
$objOrderBlob->AddString($sOrderNumber);
$::g_BillContact{'REGION'} = ActinicLocations::GetInvoiceAddressRegionName($::g_BillContact{'ADDRESS4'});
$objOrderBlob->AddContact(\%::g_BillContact);
$::g_ShipContact{'REGION'} = ActinicLocations::GetDeliveryAddressRegionName($::g_ShipContact{'ADDRESS4'});
$objOrderBlob->AddContact(\%::g_ShipContact);
my ($ePaymentMethod) = ActinicOrder::PaymentStringToEnum($::g_PaymentInfo{'METHOD'}); # the payment method is stored as "ENUMERATEDID:DESCRIPTION"
$objOrderBlob->AddString($$::g_pCatalogBlob{'SINTLSYMBOLS'});
$objOrderBlob->AddWord($ePaymentMethod);
$objOrderBlob->AddString($::g_PaymentInfo{'USERDEFINED'});
if (! defined $::g_BillContact{MOVING} ||
$::g_BillContact{MOVING} eq '')
{
$::g_BillContact{MOVING} = $::FALSE;
}
$objOrderBlob->AddByte($::g_BillContact{'MOVING'});
$objOrderBlob->AddString($::g_GeneralInfo{'WHYBUY'});
$objOrderBlob->AddString($::g_GeneralInfo{'HOWFOUND'});
$objOrderBlob->AddString(GetGeneralUD3());
my @Response = $::Session->GetCartObject();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my $pCartObject = $Response[2];
my $pCartList = $pCartObject->GetCartList();
my @aCartData;
($Status, $Message, @aCartData) = ActinicOrder::PreprocessCartToDisplay($pCartList, $::TRUE);
my ($pOrderDetail);
my $nShipped = 0;
if ($$::g_pSetupBlob{"DD_AUTO_SHIP"})
{
foreach $pOrderDetail (@aCartData)
{
if ($$pOrderDetail{"SHIPPED"})
{
$nShipped++;
}
my $pComponent;
foreach $pComponent (@{$$pOrderDetail{'COMPONENTS'}})
{
if ($$pComponent{"SHIPPED"})
{
$nShipped++;
}
}
}
}
@Response = $pCartObject->SummarizeOrder($::FALSE);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my ($Ignore, $Ignore2, $nSubTotal, $nShipping, $nTax1, $nTax2, $nTotal, $nShippingTax1, $nShippingTax2,
$nHandling, $nHandlingTax1, $nHandlingTax2) = @Response;
$objOrderBlob->AddQWord($nSubTotal);
$objOrderBlob->AddDWord(0);
$objOrderBlob->AddQWord(0);
$objOrderBlob->AddQWord($nSubTotal);
$objOrderBlob->AddQWord($nShipping);
$objOrderBlob->AddQWord($nShippingTax1);
$objOrderBlob->AddQWord($nShippingTax2);	
my ($bDPDVarDefined, $bDPDEnabled) = ACTINIC::IsCustomVarDefined("IsDPDEnabled");	
if ($bDPDEnabled)
{		
my $sDPDExtraInfo = $::g_ShipInfo{'DPDEXTRAINFO'};
my ($bDPDDelimiterDefined, $sDPDDelimiter) = ACTINIC::IsCustomVarDefined("DPDDelimiter");
if (!$bDPDDelimiterDefined)
{			
$sDPDDelimiter = '|';
}
$sDPDExtraInfo =~ s/($::DPD_COLLECTION_POINT_PICKUP_CAPTION[^\|].*)/$sDPDDelimiter$1$sDPDDelimiter/i;
my $sUserDefined = $::g_ShipInfo{'USERDEFINED'} . $sDPDExtraInfo;
if (length $sUserDefined > $::g_pFieldSizes->{'DPDUSERDEF'})
{
$sUserDefined = substr($sUserDefined, 0, $::g_pFieldSizes->{'DPDUSERDEF'});
}
$objOrderBlob->AddString($sUserDefined);
}
else
{
$objOrderBlob->AddString($::g_ShipInfo{'USERDEFINED'});
}
$objOrderBlob->AddByte($$::g_pTaxSetupBlob{'TAX_INCLUSIVE_PRICING'});
$objOrderBlob->AddByte($ActinicOrder::g_pCurrentTaxZone->{'TAX_1'} != -1);
$objOrderBlob->AddByte($ActinicOrder::g_pCurrentTaxZone->{'TAX_2'} != -1);
@Response = ActinicOrder::GetTaxModelOpaqueData();
if($Response[0] != $::SUCCESS)
{
return(@Response);
}
$objOrderBlob->AddString($Response[2]);
my $sTaxKey;
foreach $sTaxKey (('TAX_1', 'TAX_2'))
{
$objOrderBlob->AddString(ActinicOrder::GetTaxOpaqueData($sTaxKey));
}
$objOrderBlob->AddByte($::g_TaxInfo{'EXEMPT1'});
$objOrderBlob->AddString($::g_TaxInfo{'EXEMPT1DATA'});
$objOrderBlob->AddByte($::g_TaxInfo{'EXEMPT2'});
$objOrderBlob->AddString($::g_TaxInfo{'EXEMPT2DATA'});
$objOrderBlob->AddQWord($nTax1);
$objOrderBlob->AddQWord($nTax2);
$objOrderBlob->AddString($::g_TaxInfo{'USERDEFINED'});
$objOrderBlob->AddQWord($nTotal);
my ($nLineCount) = CountValidCartItems($pCartList);
$nLineCount += $pCartObject->GetAdjustmentCount();
push (@FieldList, $nLineCount);
my $nLineCountIndex = $#FieldList;
push (@FieldType, $::RBDWORD);
$objOrderBlob->AddDWord($nShipped);
$objOrderBlob->AddDWord(0);
my ($sDate) = ACTINIC::GetActinicDate();
$objOrderBlob->AddString($sDate);
$objOrderBlob->AddString($::g_PaymentInfo{'PONO'});
$objOrderBlob->AddString("");
if ($::g_ShipInfo{'ADVANCED'} eq "" &&
$nShipping == 0)
{
$objOrderBlob->AddString("ShippingClass;-1;ShippingZone;-1;BasisTotal;1.000000;Simple;0;");
}
else
{
$objOrderBlob->AddString($::g_ShipInfo{'ADVANCED'});
}
$objOrderBlob->AddString($$::g_pSetupBlob{'AUTH_KEY'});
$objOrderBlob->AddString($::g_LocationInfo{DELIVERY_COUNTRY_CODE});
$objOrderBlob->AddString($::g_LocationInfo{DELIVERY_REGION_CODE});
$objOrderBlob->AddString($::g_LocationInfo{INVOICE_COUNTRY_CODE});
$objOrderBlob->AddString($::g_LocationInfo{INVOICE_REGION_CODE});
if ($$::g_pSetupBlob{MAKE_SHIPPING_CHARGE})
{
@Response = ActinicOrder::GetShippingPluginResponse();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
elsif (${$Response[2]}{GetShippingDescription} != $::SUCCESS)
{
return(${$Response[2]}{GetShippingDescription}, ${$Response[3]}{GetShippingDescription});
}
$objOrderBlob->AddString($Response[5]);
$objOrderBlob->AddString($Response[13]);
}
else
{
$objOrderBlob->AddString('');
$objOrderBlob->AddString('');
}	
$objOrderBlob->AddByte($Response[14]);
$objOrderBlob->AddByte($::g_BillContact{'CREATEANACCOUNT'});
my $sNewPassword = $::g_BillContact{'NEWCUSTOMERPASSWORD'};
if ($::g_BillContact{'CREATEANACCOUNT'} == $::TRUE)
{
$sNewPassword = ACTINIC::GetSHA256Hash($sNewPassword . $ACTINIC::SALT1);
}	
else
{
$sNewPassword = "";
}
$objOrderBlob->AddString($sNewPassword);
$objOrderBlob->AddByte($::FALSE);
$objOrderBlob->AddQWord($nHandling);
$objOrderBlob->AddQWord($nHandlingTax1);
$objOrderBlob->AddQWord($nHandlingTax2);
$objOrderBlob->AddString($::g_ShipInfo{HANDLING});
if ($$::g_pSetupBlob{MAKE_HANDLING_CHARGE})
{
@Response = ActinicOrder::GetShippingPluginResponse();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
elsif (${$Response[2]}{GetHandlingDescription} != $::SUCCESS)
{
return(${$Response[2]}{GetHandlingDescription}, ${$Response[3]}{GetHandlingDescription});
}
$objOrderBlob->AddString($Response[9]);
}
else
{
$objOrderBlob->AddString('');
}
my $sUserDigest = $ACTINIC::B2B->Get('UserDigest');
if ($::g_InputHash{BUYERID} && $::g_InputHash{CUSTOMERID})
{
$objOrderBlob->AddDWord($::g_InputHash{BUYERID});
$objOrderBlob->AddDWord($::g_InputHash{CUSTOMERID});
}
elsif( $sUserDigest )
{
my ($status, $sMessage, $pBuyer) = ACTINIC::GetBuyer($sUserDigest, ACTINIC::GetPath());
if ($status != $::SUCCESS)
{
return ($status, $sMessage);
}
my $nBuyerID = $$pBuyer{ID};
my $nCustomerID = $$pBuyer{AccountID};
$objOrderBlob->AddDWord($nBuyerID);
$objOrderBlob->AddDWord($nCustomerID);
}
else
{
$objOrderBlob->AddDWord(-1);
$objOrderBlob->AddDWord(-1);
}
$objOrderBlob->AddString($::g_sSignature);
my (@aPrefixes) = ('', 'SHIP_', 'HAND_');
my ($sPrefix);
foreach $sPrefix (@aPrefixes)
{
@Response = PrepareOrderTaxOpaqueData($sPrefix);
if($Response[0] != $::SUCCESS)
{
return(@Response);
}
$objOrderBlob->AddString($Response[2]);
}
if($::g_ShipInfo{SSP} =~ /^SSPID=(\d+);/)
{
$objOrderBlob->AddDWord($1);
$objOrderBlob->AddString($::g_ShipInfo{SSP});
}
else
{
$objOrderBlob->AddDWord(-1);
$objOrderBlob->AddString('');
}
$objOrderBlob->AddString($::s_Ship_sSeparatePackageDetails);
$objOrderBlob->AddString($::s_Ship_sMixedPackageDetails);
$objOrderBlob->AddByte($::g_BillContact{'AGREEDTANDC'});
$objOrderBlob->AddString(GetWishListJournal());
$objOrderBlob->AddString(1);
no strict 'refs';
my (%CurrentItem, $pProduct);
my $nSequenceNumber = 0;
my $nCartIndex = 0;
my $sTaxBandPrefix = '';
if (ActinicOrder::PricesIncludeTaxes() &&
!ActinicOrder::UsesMultipleTaxes())
{
$sTaxBandPrefix = 'DEF';
}
foreach $pOrderDetail (@aCartData)
{
%CurrentItem = %$pOrderDetail;
my $pProduct = $CurrentItem{'PRODUCT'};
my $sPrice = $CurrentItem{'ACTINICPRICE'};
my $nTotal = $CurrentItem{'ACTINICCOST'};
$objOrderBlob->AddWord($ACTINIC::ORDER_DETAIL_BLOB_MAGIC);
$objOrderBlob->AddByte($::ORDER_DETAIL_BLOB_VERSION);
$objOrderBlob->AddString($CurrentItem{"REFERENCE"});
$objOrderBlob->AddString($$pProduct{"NAME"});
$objOrderBlob->AddDWord($CurrentItem{"QUANTITY"});
$objOrderBlob->AddQWord($sPrice);
$objOrderBlob->AddQWord($nTotal);
$objOrderBlob->AddQWord($$pProduct{"COST_PRICE"});
if (defined $CurrentItem{"DATE"})
{
$objOrderBlob->AddString($CurrentItem{"DATE"});
}
else
{
$objOrderBlob->AddString("");
}
if (defined $$pProduct{"DATE_PROMPT"})
{
$objOrderBlob->AddString($$pProduct{"DATE_PROMPT"});
}
else
{
$objOrderBlob->AddString("");
}
if (defined $CurrentItem{"INFO"})
{
$objOrderBlob->AddString($CurrentItem{"INFO"});
}
else
{
$objOrderBlob->AddString("");
}
if (defined $$pProduct{"OTHER_INFO_PROMPT"})
{
$objOrderBlob->AddString($$pProduct{"OTHER_INFO_PROMPT"});
}
else
{
$objOrderBlob->AddString("");
}
if (defined $CurrentItem{"SHIPPED"})
{
$objOrderBlob->AddDWord($CurrentItem{"SHIPPED"});
}
else
{
$objOrderBlob->AddDWord(0);
}
$objOrderBlob->AddDWord(0);
$objOrderBlob->AddString($CurrentItem{$sTaxBandPrefix . "TAXBAND1"});
$objOrderBlob->AddString($CurrentItem{$sTaxBandPrefix . "TAXBAND2"});
$objOrderBlob->AddQWord(GetTaxValueForOrderBlob("1", $CurrentItem{"TAX1"}));
$objOrderBlob->AddQWord(GetTaxValueForOrderBlob("2", $CurrentItem{"TAX2"}));
$objOrderBlob->AddString(FormatShippingOpaqueData($pProduct, 0));
my $bParentExcludedFromShipping = $$pProduct{"EXCLUDE_FROM_SHIP"};
$objOrderBlob->AddQWord(0);
$objOrderBlob->AddDWord(0);
$objOrderBlob->AddDWord(0);
my $sTemp = $$pProduct{'REPORT_DESC'};
$sTemp =~  s/\\\n/\r\n/gi;
$objOrderBlob->AddString($sTemp);
@Response = ActinicOrder::PrepareProductTaxOpaqueData($pProduct, $sPrice, $$pProduct{'PRICE'}, $::FALSE);
if($Response[0] != $::SUCCESS)
{
return(@Response);
}
$objOrderBlob->AddString($Response[2]);
$objOrderBlob->AddByte(0);
$objOrderBlob->AddByte($$pProduct{NO_ORDERLINE});
$objOrderBlob->AddByte($::eOrderLineProduct);
$objOrderBlob->AddDWord($nSequenceNumber);
my $parrProductAdjustments = $pCartObject->GetProductAdjustments($nCartIndex);
my $parrAdjustDetails;
$nCartIndex++;
$nSequenceNumber++;
$objOrderBlob->AddByte(0);
$objOrderBlob->AddString("");
$objOrderBlob->AddByte($$pProduct{ASSEMBLY_PRODUCT});
$objOrderBlob->AddString($$pProduct{STOCK_AISLE});
$objOrderBlob->AddString($$pProduct{STOCK_RACK});
$objOrderBlob->AddString($$pProduct{STOCK_SUB_RACK});
$objOrderBlob->AddString($$pProduct{STOCK_BIN});
$objOrderBlob->AddString($$pProduct{BARCODE});
{
my $pComponent;
my $nIndex = 1;
foreach $pComponent (@{$CurrentItem{'COMPONENTS'}})
{
my $sProdName = $$pComponent{'NAME'};
$FieldList[$nLineCountIndex]++;
$objOrderBlob->AddWord($ACTINIC::ORDER_DETAIL_BLOB_MAGIC);
$objOrderBlob->AddByte($::ORDER_DETAIL_BLOB_VERSION);
$objOrderBlob->AddString($$pComponent{REFERENCE});
$objOrderBlob->AddString($sProdName);
$objOrderBlob->AddDWord($$pComponent{QUANTITY});
if ($$pComponent{'SEPARATELINE'})
{
$objOrderBlob->AddQWord($$pComponent{ACTINICPRICE});
$objOrderBlob->AddQWord($$pComponent{ACTINICCOST});
}
else
{
$objOrderBlob->AddQWord(0);
$objOrderBlob->AddQWord(0);
}
$objOrderBlob->AddQWord($$pComponent{COST_PRICE});
$objOrderBlob->AddString("");
$objOrderBlob->AddString("");
$objOrderBlob->AddString("");
$objOrderBlob->AddString("");
if (defined $CurrentItem{"SHIPPED"})
{
$objOrderBlob->AddDWord($$pComponent{QUANTITY});
}
else
{
$objOrderBlob->AddDWord(0);
}
$objOrderBlob->AddDWord(0);
$objOrderBlob->AddString($$pComponent{$sTaxBandPrefix . "TAXBAND1"});
$objOrderBlob->AddString($$pComponent{$sTaxBandPrefix . "TAXBAND2"});
$objOrderBlob->AddQWord(GetTaxValueForOrderBlob("1", $$pComponent{'TAX1'}));
$objOrderBlob->AddQWord(GetTaxValueForOrderBlob("2", $$pComponent{'TAX2'}));
if ($$pComponent{REFERENCE} ne '')
{
$objOrderBlob->AddString(FormatShippingOpaqueData($pComponent,
$bParentExcludedFromShipping));
}
else
{
$objOrderBlob->AddString('');
}
$objOrderBlob->AddQWord(0);
$objOrderBlob->AddDWord(0);
$objOrderBlob->AddDWord(1);
$objOrderBlob->AddString("");
$objOrderBlob->AddString($$pComponent{'TAX_OPAQUE_DATA'});
$objOrderBlob->AddByte($$pComponent{'SEPARATELINE'});
$objOrderBlob->AddByte($$pProduct{NO_ORDERLINE});
$objOrderBlob->AddByte($::eOrderLineComponent);
$objOrderBlob->AddDWord($nSequenceNumber);
$objOrderBlob->AddByte(0);
$objOrderBlob->AddString("");
$objOrderBlob->AddByte($$pComponent{'ASSEMBLY_PRODUCT'});
$objOrderBlob->AddString($$pComponent{'STOCK_AISLE'});
$objOrderBlob->AddString($$pComponent{'STOCK_RACK'});
$objOrderBlob->AddString($$pComponent{'STOCK_SUB_RACK'});
$objOrderBlob->AddString($$pComponent{'STOCK_BIN'});
$objOrderBlob->AddString($$pComponent{'BARCODE'});
$nSequenceNumber++;
$nIndex++;
}
}
foreach $parrAdjustDetails (@$parrProductAdjustments)
{
my $pApplicableProduct = $pProduct;
my $sProdRef = $parrAdjustDetails->[$::eAdjIdxTaxProductRef];
if($sProdRef ne '' &&
$pProduct->{'REFERENCE'} ne $sProdRef)
{
my($nStatus, $sMessage);
($nStatus, $sMessage, $pApplicableProduct) =
ActinicOrder::GetComponentAssociatedProduct($pProduct, $sProdRef);
if($nStatus != $::SUCCESS)
{
return($nStatus, $sMessage);
}
}
$objOrderBlob->AddAdjustment($nSequenceNumber, $parrAdjustDetails, $pApplicableProduct);
$nSequenceNumber++;
}
}
my $parrAdjustments = $pCartObject->GetOrderAdjustments();
my $parrAdjustDetails;
foreach $parrAdjustDetails (@$parrAdjustments)
{
$objOrderBlob->AddAdjustment($nSequenceNumber, $parrAdjustDetails);
$nSequenceNumber++;
}
$parrAdjustments = $pCartObject->GetFinalAdjustments();
foreach $parrAdjustDetails (@$parrAdjustments)
{
$objOrderBlob->AddAdjustment($nSequenceNumber, $parrAdjustDetails);
$nSequenceNumber++;
}
@Response = ACTINIC::OpenWriteBlob("memory");
($Status, $Message) = @Response;
if ($Status != $::SUCCESS)
{
return (@Response);
}
@Response = ACTINIC::WriteBlob(\@FieldList, \@FieldType);
($Status, $Message) = @Response;
if ($Status != $::SUCCESS)
{
return (@Response);
}
@Response = ACTINIC::CloseWriteBlob();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
return($::SUCCESS, '', $Response[2]);
}
sub GetTaxValueForOrderBlob
{
my ($sTaxIdentifier, $nTax) = @_;
if ($::g_TaxInfo{'EXEMPT' . $sTaxIdentifier} ||
!ActinicOrder::IsTaxApplicableForLocation('TAX_' . $sTaxIdentifier))
{
if (ActinicOrder::PricesIncludeTaxes())
{
$nTax = -$nTax;
}
}
return $nTax;
}
sub CompleteOrder
{
ActinicOrder::ParseAdvancedTax();
$::g_PaymentInfo{'ORDERTOTAL'} = ActinicOrder::GetOrderTotal($::TRUE);
my ($Status, $Message, $sOrderNumber);
($Status, $Message, $sOrderNumber) = GetOrderNumber();
if ($Status != $::SUCCESS)
{
return ($Status, $Message);
}
if ($sOrderNumber eq $::g_PaymentInfo{'ORDERNUMBER'})
{
LogData("Avoiding duplication of order $sOrderNumber");
return ($::SUCCESS, undef);
}
my $sPath = ACTINIC::GetPath();
my @Response = GetSaferBlob($sOrderNumber, $sPath);
if($Response[0] != $::SUCCESS)
{
return(@Response);
}
my ($SaferBlob) = $Response[2];
my $DHBlob;
if (length $::g_PaymentInfo{'CARDNUMBER'} > 0 ||
length $::g_PaymentInfo{'CARDTYPE'} > 0 ||
length $::g_PaymentInfo{'EXPYEAR'} > 0 ||
length $::g_PaymentInfo{'EXPMONTH'} > 0)
{
my (@FieldList, @FieldType);
push (@FieldList, $::g_PaymentInfo{'CARDNUMBER'});
push (@FieldType, $::RBSTRING);
push (@FieldList, $::g_PaymentInfo{'CARDTYPE'});
push (@FieldType, $::RBSTRING);
push (@FieldList, $::g_PaymentInfo{'EXPYEAR'} . '/' . $::g_PaymentInfo{'EXPMONTH'});
push (@FieldType, $::RBSTRING);
push (@FieldList, $::g_PaymentInfo{'CARDVV2'});
push (@FieldType, $::RBSTRING);
if (ActinicOrder::PaymentStringToEnum($::g_PaymentInfo{'METHOD'}) == $::PAYMENT_CREDIT_CARD)
{
push (@FieldList, $::g_PaymentInfo{'CARDISSUE'});
push (@FieldType, $::RBSTRING);
push (@FieldList, $::g_PaymentInfo{'STARTYEAR'} .
($::g_PaymentInfo{'STARTYEAR'} eq "" ? '' : '/') .
$::g_PaymentInfo{'STARTMONTH'});
push (@FieldType, $::RBSTRING);
}
else
{
push (@FieldList, 0);
push (@FieldType, $::RBSTRING);
push (@FieldList, "");
push (@FieldType, $::RBSTRING);
}
@Response = ACTINIC::OpenWriteBlob("memory");
($Status, $Message) = @Response;
if ($Status != $::SUCCESS)
{
return (@Response);
}
@Response = ACTINIC::WriteBlob(\@FieldList, \@FieldType);
($Status, $Message) = @Response;
if ($Status != $::SUCCESS)
{
return (@Response);
}
@Response = ACTINIC::CloseWriteBlob();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
$DHBlob = $Response[2];
}
my $EncryptedBlob;
($Status, $Message, $EncryptedBlob) = ACTINIC::EncryptBlob($SaferBlob, $DHBlob);
if ($Status != $::SUCCESS)
{
return ($Status, $Message);
}	
my $sError = RecordOrder($sOrderNumber, \$EncryptedBlob);
if ($sError)
{
return($::FAILURE, NotifyOfError($sError));
}
my $nPaymentMethod = $::g_PaymentInfo{'METHOD'};
if (!$$::g_pPaymentList{$nPaymentMethod}{PAYMENT_TYPE})
{
my $oMailchimpPkg = MailchimpPkg->new();
@Response = $oMailchimpPkg->AddOrder($sOrderNumber);
if ($Response[0] != $::SUCCESS)
{
ACTINIC::RecordErrors("Error when sending the order to MailChimp. Error message: $Response[1] ", ACTINIC::GetPath());
}
}
$::Session->SetPSPSignature(GetOrderSignature());
UpdateCheckoutRecord();
return ($::SUCCESS, "");
}
sub UpdateCheckoutRecord
{
my (%EmptyPaymentInfo);
$EmptyPaymentInfo{'METHOD'} 		= $::g_PaymentInfo{'METHOD'};
$EmptyPaymentInfo{'USERDEFINED'} = $::g_PaymentInfo{'USERDEFINED'};
$EmptyPaymentInfo{'PONO'}			= $::g_PaymentInfo{'PONO'};
$EmptyPaymentInfo{'COUPONCODE'}	= $::g_PaymentInfo{'COUPONCODE'};
$EmptyPaymentInfo{'ORDERNUMBER'}	= $::g_PaymentInfo{'ORDERNUMBER'};
$EmptyPaymentInfo{'ORDERTOTAL'}	= $::g_PaymentInfo{'ORDERTOTAL'};
$EmptyPaymentInfo{'ORDERDATE'}	= $::g_PaymentInfo{'ORDERDATE'};
$EmptyPaymentInfo{'AUTHORIZERESULT'}	= $::g_PaymentInfo{'AUTHORIZERESULT'};
$::g_GeneralInfo{'USERDEFINED'} = GetGeneralUD3();
return ($::Session->UpdateCheckoutInfo(\%::g_BillContact, \%::g_ShipContact, \%::g_ShipInfo, \%::g_TaxInfo,
\%::g_GeneralInfo, \%EmptyPaymentInfo, \%::g_LocationInfo));
}
sub GetOrderSignature
{
my @aMD5hashes;
my (@Response) = $::Session->GetCartObject();
if ($Response[0] != $::SUCCESS)
{
return (ACTINIC::GetActinicDate($::TRUE));
}
my $pCartObject = $Response[2];
my $pCartList = $pCartObject->GetCartList();
my $pOrderDetail;
foreach $pOrderDetail (@$pCartList)
{
my %CurrentItem = %$pOrderDetail;
push (@aMD5hashes, \%CurrentItem);
}
$::g_ShipContact{'COUNTRYCODE'} = $::g_LocationInfo{'DELIVERY_COUNTRY_CODE'};
$::g_BillContact{'COUNTRYCODE'} = $::g_LocationInfo{'INVOICE_COUNTRY_CODE'};
push (@aMD5hashes, \%::g_BillContact);
push (@aMD5hashes, \%::g_ShipContact);
push (@aMD5hashes, \%::g_ShipInfo);
push (@aMD5hashes, \%::g_TaxInfo);
push (@aMD5hashes, \%::g_GeneralInfo);
push (@aMD5hashes, \%::g_PaymentInfo);
push (@aMD5hashes, \%::g_LocationInfo);
use Encode qw(decode encode);
return (ACTINIC::GetMD5Hash(encode('UTF-8', Serialise(\@aMD5hashes))));
}
sub Serialise
{
my $element = shift;
my $sText = SerialiseArray(@{$element});
LogData("Serialised=$sText");
return ($sText);
}
sub SerialiseArray
{
my (@aArray) = @_;
my $sText = "";
foreach (@aArray)
{
my $element = $_;
if( ref($element) eq 'ARRAY' )
{
$sText .= SerialiseArray(@$element);
}
elsif( ref($element) eq 'HASH' )
{
$sText .= SerialiseHash($element);
}
else
{
if ($element ne "")
{
$sText .= $element . '|';
}
}
}
return ($sText);
}
sub SerialiseHash
{
my ($pHash) = shift;
my $sText = "";
my $sKey;
foreach $sKey (sort keys %{$pHash})
{
my $element = $pHash->{$sKey};
if( ref($element) eq 'ARRAY' )
{
$sText .= SerialiseArray(@$element);
}
elsif( ref($element) eq 'HASH' )
{
$sText .= SerialiseHash($element);
}
else
{
if (($sKey ne 'METHOD') &&
($element ne ""))
{
$sText .=  $element . '|';
}
}
}
return ($sText);
}
sub GetCancelPage
{
my ($sRefPage) = $::Session->GetLastShopPage();
if ($$::g_pSetupBlob{UNFRAMED_CHECKOUT} &&
$$::g_pSetupBlob{UNFRAMED_CHECKOUT_URL})
{
$sRefPage = $$::g_pSetupBlob{UNFRAMED_CHECKOUT_URL};
}
my @Response = ACTINIC::BounceToPagePlain(0, undef, undef,
$::g_sWebSiteUrl, $::g_sContentUrl, $::g_pSetupBlob, $sRefPage, \%::g_InputHash);
if ($Response[0] != $::SUCCESS)
{
ACTINIC::ReportError($Response[1], ACTINIC::GetPath());
return;
}
return ($Response[2]);
}
sub DoOfflineAuthorization
{
my	$sPath = ACTINIC::GetPath();
my @Response = ACTINIC::ReadPaymentFile($sPath);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my ($sFilename, $pPaymentMethodHash, $ePaymentMethod);
if($::g_InputHash{'ACTION'} =~ m/^OFFLINE_AUTHORIZE_(\d+)$/i)
{
$ePaymentMethod = $1;
$::g_PaymentInfo{'METHOD'} = $1;
}
else
{
return;
}
$pPaymentMethodHash = $$::g_pPaymentList{$ePaymentMethod};
if ((defined $$pPaymentMethodHash{'POST_PROCESS'}) &&
("" ne $$pPaymentMethodHash{'POST_PROCESS'}))
{
$sFilename = $$pPaymentMethodHash{'POST_PROCESS'};
}
elsif ($::PAYMENT_SELLERDECKBYOPAYO = $ePaymentMethod)
{
$sFilename = $$pPaymentMethodHash{'BOUNCE_SCRIPT'};
}
if (defined $sFilename)
{
my (@Response) = CallPlugInScript($sFilename);
}
else
{
my $sError = RecordAuthorization();
if (length $sError != 0)
{
$sError = sprintf("%s:%s", $::g_PaymentInfo{'AUTHORIZERESULT'}, $sError);
}
else
{
$sError = $::g_PaymentInfo{'AUTHORIZERESULT'};
}
LogData("AUTHORIZERESULT:" . $sError);
ACTINIC::PrintPSPResponse('text/plain', $sError);
}
$::Session->DeleteSessionFile();
}
sub RecordAuthorization
{
my ($psCgiInput) = @_;
$::g_PaymentInfo{'AUTHORIZERESULT'} = '0';
unless (defined $psCgiInput)
{
$psCgiInput = \$::g_OriginalInputData;
}
my $bStatusUpdate = ($$psCgiInput =~ /SU=1/) ? $::TRUE : $::FALSE;
if (length $::g_InputHash{ON} < 5)
{
my $sError = ACTINIC::GetPhrase(-1, 185, (length $::g_InputHash{ON}), $::g_InputHash{ON});
return(NotifyOfError($sError));
}
if ($::g_InputHash{'ACTION'} !~ m/^OFFLINE_AUTHORIZE_(\d+)$/i)
{
if ($::Session->GetPSPCallbackCount() < $nSimulatePSPAuthoriseError)
{
return (NotifyOfError("Simulated error: see variable \$nSimulatePSPAuthoriseError"));		
}
}
my ($ePaymentMethod, $sRemoteIP);
if($::g_InputHash{'ACTION'} =~ m/^AUTHORIZE_(\d+)$/i)
{
$ePaymentMethod = $1;
}
elsif ($::g_InputHash{'ACTION'} =~ m/^OFFLINE_AUTHORIZE_(\d+)$/i)
{
$ePaymentMethod = $1;
}
$sRemoteIP = $ENV{REMOTE_ADDR};
my ($bIPRangeDefined, $sIPRange) = ACTINIC::IsCustomVarDefined("ACT_IPCHECK_" . $ePaymentMethod);
if ($bIPRangeDefined)
{
if (!ACTINIC::IsValidIP($sRemoteIP, $sIPRange))
{
$::Session->IPCheckFailed();
my $sMessage = ACTINIC::GetPhrase(-1, 2307, $sIPRange, $sRemoteIP, $::g_OriginalInputData);
ACTINIC::RecordErrors($sMessage, ACTINIC::GetPath());
ACTINIC::SendMail($::g_sSmtpServer,
$::g_pSetupBlob->{'EMAIL'},
$$::g_pPaymentList{$ePaymentMethod}{PROMPT}." - IP Address Check Exception for order number ".$::g_InputHash{ON},
$sMessage);
}
}
my (@FieldList, @FieldType);
push (@FieldList, hex("22"));
push (@FieldType, $::RBWORD);
push (@FieldList, 2);
push (@FieldType, $::RBBYTE);
push (@FieldList, $ePaymentMethod);
push (@FieldType, $::RBDWORD);
push (@FieldList, $::g_InputHash{TM} ? 1 : 0);
push (@FieldType, $::RBBYTE);
push (@FieldList, $$psCgiInput);
push (@FieldType, $::RBSTRING);
my $sPath = ACTINIC::GetPath();
my @Response = ACTINIC::OpenWriteBlob('memory');
my ($Status, $Message) = @Response;
if ($Status != $::SUCCESS)
{
my $sError = (0 == length $Response[1]) ? "Error opening the write blob" : $Response[1];
return(NotifyOfError($sError));
}
@Response = ACTINIC::WriteBlob(\@FieldList, \@FieldType);
($Status, $Message) = @Response;
if ($Status != $::SUCCESS)
{
my $sError = (0 == length $Response[1]) ? "Error writing blob" : $Response[1];
return(NotifyOfError($sError));
}
@Response = ACTINIC::CloseWriteBlob();
if ($Response[0] != $::SUCCESS)
{
my $sError = (0 == length $Response[1]) ? "Error closing the write blob" : $Response[1];
return(NotifyOfError($sError));
}
my ($ClearBlob) = $Response[2];
my ($EncryptedBlob);
ActinicEncrypt::InitEncrypt(@{$$::g_pSetupBlob{PUBLIC_KEY_128BIT}});
$EncryptedBlob = ActinicEncrypt::Encrypt(undef, $ClearBlob);
my ($sTempFilename) = ACTINIC::GetSessionFileFolder() . $::g_InputHash{ON} . '.occ';
ACTINIC::SecurePath($sTempFilename);
my $sOCCFileName = $::g_InputHash{ON} . '_00.occ';
my ($sOCCFilePath) = ACTINIC::GetSessionFileFolder() . $sOCCFileName;
ACTINIC::SecurePath($sOCCFilePath);
while (-e $sOCCFilePath)
{
my $nIncremental;
($sOCCFileName, $nIncremental) = split /_/, $sOCCFileName;
$sOCCFileName = sprintf("%s_%02d.occ", $::g_InputHash{ON}, ++$nIncremental);
$sOCCFilePath = ACTINIC::GetSessionFileFolder() . $sOCCFileName;
ACTINIC::SecurePath($sOCCFilePath);
}
$sTempFilename = $sOCCFilePath;
unless ( open (COMPLETEFILE, ">" . $sTempFilename))
{
my $sError = ACTINIC::GetPhrase(-1, 21, $sTempFilename, $!);
return(NotifyOfError($sError));
}
binmode COMPLETEFILE;
unless (print COMPLETEFILE $EncryptedBlob)
{
my ($sError) = $!;
close COMPLETEFILE;
unlink $sTempFilename;
$sError = ACTINIC::GetPhrase(-1, 28, $sTempFilename, $sError);
return(NotifyOfError($sError));
}
close COMPLETEFILE;
if ($::FALSE == $bStatusUpdate)
{	
$::g_PaymentInfo{'AUTHORIZERESULT'} = '1';		
my $sError = "";
if (!$$::g_pSetupBlob{PSP_PENDING_STOCK_ALLOCATION} &&
$$::g_pPaymentList{$ePaymentMethod}{PAYMENT_TYPE})
{
my ($sStockFilename) = ACTINIC::GetSessionFileFolder() . ACTINIC::CleanFileName($::g_InputHash{ON} . '.stk');
if (-e $sStockFilename)
{
my @Response = ACTINIC::ReadConfigurationFile($sStockFilename);
if ($Response[0] != $::SUCCESS)
{
$sError = $Response[1];
}
unlink $sStockFilename;
@Response = ActinicOrder::AllocateStock($::pStockLevels);
if ($Response[0] != $::SUCCESS)
{
$sError = $Response[1];
}
}
}
if ($sError ne "")
{
ACTINIC::RecordErrors("Record Authorisation stock update failed " . $sError, ACTINIC::GetPath());
}
my $sOrderAmount = $::g_PaymentInfo{'ORDERTOTAL'};
if ($::g_InputHash{'ACTION'} =~ m/^OFFLINE_AUTHORIZE_(\d+)$/i)
{
$sOrderAmount = $::g_InputHash{'AM'};
}
if (($sOrderAmount eq $::g_InputHash{'AM'}) ||
($sOrderAmount < $::g_InputHash{'AM'}))
{
if (defined $::Session)
{
$::Session->PaymentMade();
}
if ($sOrderAmount ne $::g_InputHash{'AM'})
{
ACTINIC::RecordErrors("Over paid order " . $::g_InputHash{ON} . " expected " . $sOrderAmount . " received " . $::g_InputHash{'AM'}, ACTINIC::GetPath());
}
}
else
{
ACTINIC::RecordErrors("Under paid order " . $::g_InputHash{ON} . " expected " . $sOrderAmount . " received " . $::g_InputHash{'AM'}, ACTINIC::GetPath());
}
my $oMailchimpPkg = MailchimpPkg->new();
@Response = $oMailchimpPkg->AddOrder($::g_InputHash{ON});
if ($Response[0] != $::SUCCESS)
{
ACTINIC::RecordErrors("Error when sending the order to MailChimp. Error message: $Response[1] ", ACTINIC::GetPath());
}
}
return (undef);
}
sub LogData
{
if ($nDebugLogLevel)
{
my $sLogData = shift;
ACTINIC::RecordErrors($sLogData, ACTINIC::GetPath());
}
}
sub LogV12Event
{
if ($::bLogV12Events)
{
my $sLogData = shift;
ACTINIC::RecordErrors($sLogData, ACTINIC::GetPath());
}
}
sub CallOCCPlugIn
{
local ($::sOrderNumber, $::nOrderTotal, %::PriceFormatBlob, %::InvoiceContact, $::sCallBackURLUser, %::OCCShipData);
local ($::sCallBackURLAuth, $::sCallBackURLBack, $::pCartList);
my ($Status, $Message, @Response);
if ($::Session->IsCallBack())
{
if ($::Session->IsAuthorisationFile())
{
$::nOrderTotal = $::g_PaymentInfo{'ORDERTOTAL'}
}
else
{
ACTINIC::ReportError('No authorisation file for callback action [' . $::g_InputHash{'ACTION'} . ']');
}
}
else
{
@Response = $::Session->GetCartObject();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my $pCartObject = $Response[2];
@Response = $pCartObject->SummarizeOrder($::TRUE);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
$::nOrderTotal = $Response[6];
}
%::PriceFormatBlob = %{$::g_pCatalogBlob};
%::InvoiceContact = %::g_BillContact;
%::OCCShipData = %::g_ShipContact;
if ($::g_InputHash{'ACTION'} ne "GETALLFINANCEPRODUCTS")
{
($Status, $Message, $::sOrderNumber) = GetOrderNumber();		
if ($Status != $::SUCCESS)
{
return ($Status, $Message, undef);
}
}
my		$sCgiUrl;
if ($$::g_pSetupBlob{'SSL_USEAGE'} eq 1)
{
$sCgiUrl = $$::g_pSetupBlob{SSL_CGI_URL};
}
else
{
$sCgiUrl = $$::g_pSetupBlob{CGI_URL};
}
my ($sBaseUrl) = sprintf("%sos%6.6d%s?%s", $sCgiUrl, $$::g_pSetupBlob{CGI_ID}, $$::g_pSetupBlob{CGI_EXT},
($::g_InputHash{SHOP} ? 'SHOP=' . ACTINIC::EncodeText2($::g_InputHash{SHOP}, $::FALSE) . '&' : ''));
my	$ePaymentMethod = ActinicOrder::PaymentStringToEnum($::g_PaymentInfo{'METHOD'}); # the payment method is stored as "ENUMERATEDID:DESCRIPTION"
$::sCallBackURLAuth = $sBaseUrl . "SEQUENCE=3&ACTION=AUTHORIZE_$ePaymentMethod&CARTID=$::g_sCartId&ON=$::sOrderNumber&";
@Response = ACTINIC::EncodeText(ACTINIC::GetPhrase(-1, 504), $::FALSE);
my ($sFinish) = $Response[1];
@Response = ACTINIC::EncodeText($::Session->GetLastShopPage(), $::FALSE);
my $sRefPage = $Response[1];
$::sCallBackURLUser = $sBaseUrl . "SEQUENCE=3&ACTION=$sFinish" .
"&ORDERNUMBER=$::sOrderNumber&REFPAGE=" . $sRefPage . "&";
@Response = ACTINIC::EncodeText(ACTINIC::GetPhrase(-1, 503), $::FALSE);
my $sBack = $Response[1];
my $sReferrer = ACTINIC::GetReferrer();
if ($sReferrer =~ /\?.+/)
{
($sReferrer) = split /\?/, $sReferrer;
}
elsif (length $sReferrer < 3)
{
$sReferrer = sprintf("%sos%6.6d%s", $sCgiUrl, $$::g_pSetupBlob{CGI_ID}, $$::g_pSetupBlob{CGI_EXT});
}
$::sCallBackURLBack = $sReferrer . "?SEQUENCE=3" .
"&ACTION=" . $sBack .
"&ON=" . $::sOrderNumber .
"&JS=" . (($::g_InputHash{JS} eq '1') ? '1' : '0') .
"&REFPAGE=" . $sRefPage .
($::g_InputHash{SHOP} ? '&SHOP=' . ACTINIC::EncodeText2($::g_InputHash{SHOP}, $::FALSE) : '') .
"&";
@Response = GetOCCScript(ACTINIC::GetPath());
if ($Response[0] != $::SUCCESS)
{
return ($Response[0], $Response[1]);
}
my ($sScript) = $Response[2];
local $::sPath = ACTINIC::GetPath();
local $::sWebSiteUrl = $::g_sWebSiteUrl;
local $::sContentUrl = $::g_sContentUrl;
local $::sCartID = $::g_sCartId;
if($ACTINIC::B2B->Get('UserDigest'))
{
$::sContentUrl = $ACTINIC::B2B->Get('BaseFile');
$::sContentUrl =~ s#/[^/]*$#/#;
$::sWebSiteUrl = $::g_sAccountScript;
$::sWebSiteUrl .= ($::g_InputHash{SHOP} ? '?SHOP=' . ACTINIC::EncodeText2($::g_InputHash{SHOP}, $::FALSE) . '&': '?');
$::sWebSiteUrl .= 'PRODUCTPAGE=';
}
eval
{
require Digest::MD5;
import Digest::MD5 'md5_hex';
};
if ($@)
{
require di000001;
import Digest::Perl::MD5 'md5_hex';
}
$::eStatus = $::PENDING;
$::sErrorMessage = "";
$::sHTML = "";
if (eval($sScript) != $::SUCCESS)
{
return ($::FAILURE, ACTINIC::GetPhrase(-1, 170, substr($@, 0, 128)),
"An internal error has occurred.<br />" .
"Your order $::sOrderNumber has been recorded but you payment may not have been recorded.<br />" .
"If you have submitted card details then contact the merchant as the payment may or may not have been processed.<br />" .
"Do <b>NOT</b> submit your card details again or you may be charged twice");
}
if ($::sRedirectURL)
{
LogData(sprintf("CallOCCPlugIn:\r\nAction:%s Status:%s Error:%s\r\nRedirectURL:-\r\n%s",
$::g_InputHash{'ACTION'}, $::eStatus, $::sErrorMessage, $::sRedirectURL));
}
else
{
LogData(sprintf("CallOCCPlugIn:\r\nAction:%s Status:%s Error:%s\r\nHTMLResponse:-\r\n%s",
$::g_InputHash{'ACTION'}, $::eStatus, $::sErrorMessage, $::sHTML));
}
return ($::eStatus, $::sErrorMessage, $::sHTML);
}
sub GetOCCScript
{
if (defined $::s_sOCCScript)# if it is already in memory,
{
return ($::SUCCESS, "", $::s_sOCCScript);
}
if ($#_ < 0)
{
return ($::FAILURE, ACTINIC::GetPhrase(-1, 12, 'GetOCCScript'), 0, 0);
}
my ($sPath) = $_[0];
my	$ePaymentMethod = ActinicOrder::PaymentStringToEnum($::g_PaymentInfo{'METHOD'}); # the payment method is stored as "ENUMERATEDID:DESCRIPTION"
my ($sFilename, $pPaymentMethodHash);
$pPaymentMethodHash = $$::g_pPaymentList{$ePaymentMethod};
$sFilename = $sPath . $$pPaymentMethodHash{BOUNCE_SCRIPT};
my @Response = ACTINIC::ReadAndVerifyFile($sFilename);
if ($Response[0] == $::SUCCESS)
{
$::s_sOCCScript = $Response[2];
}
return (@Response);
}
sub GetOrderNumber
{
if (length $::s_sOrderNumber > 0)
{
return ($::SUCCESS, undef, $::s_sOrderNumber, undef);
}
my $ePaymentMethod = ActinicOrder::PaymentStringToEnum($::g_PaymentInfo{'METHOD'});
if (1 == $$::g_pPaymentList{$ePaymentMethod}{PAYMENT_TYPE})
{
if (defined $::g_PaymentInfo{'ORDERNUMBER'} &&
($::g_PaymentInfo{'ORDERNUMBER'} ne ""))
{
LogData("Already have an order number from session file " . $::g_PaymentInfo{'ORDERNUMBER'});
if ($::Session->GetPSPSignature() eq GetOrderSignature())
{
LogData("Same details so use same order number");
$::s_sOrderNumber = $::g_PaymentInfo{'ORDERNUMBER'};
return ($::SUCCESS, undef, $::s_sOrderNumber, undef);
}
else
{
LogData(sprintf("Different details so create new Order Current:%s Expected:%s", GetOrderSignature(), $::Session->GetPSPSignature()));
}
}
else
{
LogData("Order not found in session file so create new Order");
}
}
else
{
LogData("Not a PSP so create new Order");
}
my (@CharacterSet) = split(//, "3456789ABCDEFGHJKLMNPQRSTUVWXY");
my $sInitials;
my $sName = $::g_BillContact{'NAME'};
$sName =~ s/[^a-zA-Z0-9 ]//g;
$sName =~ s/^\s*//;
$sName =~ s/\s*$//;
if (!$sName)
{
$sInitials = substr("00" . ACTINIC::Modulus($$, 100), -2);
}
elsif (2 >= length $sName)
{
$sInitials = substr($sName . ACTINIC::Modulus($$, 10), 0, 2);
}
elsif ($sName =~ /([^ \t\r\n]+)\s*([^ \t\r\n]+)\s*([^ \t\r\n]*)/) # two or three names - get the true initials
{
my $s = $3 ? $3 : $2;
$sInitials = substr($1, 0, 1) . substr($s, 0, 1);
}
else
{
$sInitials = substr($sName, 0, 2);
}
$sInitials = uc($sInitials);
my $sPostCode = uc($::g_BillContact{POSTALCODE});
$sPostCode =~ s/[^A-Z0-9]//g;
srand(time() ^($$ + ($$ << 15)));
while ( (length $sPostCode) < 4)
{
$sPostCode = int(rand(10000)) . $sPostCode; # tack on some pseudo-random numbers
}
$sPostCode = substr($sPostCode, -4, 4);
$sPostCode =~ s/\s/_/g;
my $nNumberBreakRetries = 1;
my $sUnLockFile = ACTINIC::GetPath() . 'Order.num';
my $sBackupFile = ACTINIC::GetPath() . 'Backup.num';
my $sLockFile = ACTINIC::GetPath() . 'OrderLock.num';
ACTINIC::SecurePath($sUnLockFile);
ACTINIC::SecurePath($sBackupFile);
ACTINIC::SecurePath($sLockFile);
START_AGAIN:
if (!-e $sUnLockFile &&
!-e $sLockFile &&
!-e $sBackupFile)
{
unless (open (LOCK, ">$sUnLockFile"))
{
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 182, $sUnLockFile, $!)), undef, undef);
}
binmode LOCK;
my $nCounter = pack("N", 0);
unless (print LOCK $nCounter)
{
my $sError = $!;
close (LOCK);
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 28, $sUnLockFile, $sError)), undef, undef);
}
close (LOCK);
sleep 2;
}
my $nByteLength = 4;
if (!-e $sUnLockFile &&
!-e $sLockFile &&
-e $sBackupFile)
{
unless (open (BACK, "<$sBackupFile"))
{
my $sError = $!;
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 21, $sBackupFile, $sError)), undef, undef);
}
binmode BACK;
my $nCounter;
unless ($nByteLength == read (BACK, $nCounter, $nByteLength))
{
my $sError = $!;
close (BACK);
if (!unlink($sBackupFile))
{
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 201, $!)), undef, undef);
}
sleep 2;
NotifyOfError(ACTINIC::GetPhrase(-1, 2304));
goto START_AGAIN;
}
close (BACK);
unless (open (LOCK, ">$sUnLockFile"))
{
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 182, $sUnLockFile, $!)), undef, undef);
}
binmode LOCK;
unless (print LOCK $nCounter)
{
my $sError = $!;
close (LOCK);
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 28, $sUnLockFile, $sError)), undef, undef);
}
close (LOCK);
sleep 2;
}
my $nDate;
my $bFileIsLocked = $::FALSE;
my $sRenameError;
RETRY:
$bFileIsLocked = $::FALSE;
if ($nNumberBreakRetries < 0)
{
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 201, $sRenameError)), undef, undef);
}
my $nRetries = 20;
while ($nRetries > 0)
{
if (rename($sUnLockFile, $sLockFile))
{
$bFileIsLocked = $::TRUE;
last;
}
$sRenameError = $!;
if (!defined $nDate)
{
my @tmp = stat $sLockFile;
$nDate = $tmp[9];
}
$nRetries--;
sleep 2;
}
if (!$bFileIsLocked)
{
if (-e $sLockFile)
{
my @tmp = stat $sLockFile;
if (!defined $nDate)
{
return ($::FAILURE, (ACTINIC::GetPhrase(-1, 201, $sRenameError)), undef, undef);
}
if (!defined $tmp[9])
{
$nNumberBreakRetries--;
sleep 2;
goto RETRY;
}
if ($nDate == $tmp[9])
{
if ($tmp[7] == 0)
{
if (!unlink($sLockFile))
{
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 201, $!)), undef, undef);
}
sleep 2;
goto START_AGAIN;
}
if (!rename($sLockFile, $sUnLockFile))
{
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 201, $!)), undef, undef);
}
}
$nNumberBreakRetries--;
sleep 2;
goto RETRY;
}
else
{
$nNumberBreakRetries--;
sleep 2;
goto RETRY;
}
}
unless (open (LOCK, "<$sLockFile"))
{
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 182, $sLockFile, $!)), undef, undef);
}
binmode LOCK;
my $nCounterBin;
unless ($nByteLength == read (LOCK, $nCounterBin, $nByteLength))
{
my $sError = $!;
close (LOCK);
unless (open (LOCK, "<$sBackupFile"))
{
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 182, $sBackupFile, $!)), undef, undef);
}
binmode LOCK;
unless ($nByteLength == read (LOCK, $nCounterBin, $nByteLength))
{
close (LOCK);
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 105, $sLockFile, $sError)), undef, undef);
}
}
close (LOCK);
my $nCounter = unpack("N", $nCounterBin);
$nCounter++;
if ($nCounter > 9999999)
{
$nCounter = 0;
}
$nCounterBin = pack ("N", $nCounter);
unless (open (LOCK, ">$sLockFile"))
{
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 182, $sLockFile, $!)), undef, undef);
}
binmode LOCK;
unless (print LOCK $nCounterBin)
{
my $sError = $!;
close (LOCK);
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 28, $sLockFile, $sError)), undef, undef);
}
close (LOCK);
unless (open (LOCK, ">$sBackupFile"))
{
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 182, $sBackupFile, $!)), undef, undef);
}
binmode LOCK;
unless (print LOCK $nCounterBin)
{
my $sError = $!;
close (LOCK);
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 28, $sBackupFile, $sError)), undef, undef);
}
close (LOCK);
if (!rename ($sLockFile, $sUnLockFile))
{
return ($::FAILURE, NotifyOfError(ACTINIC::GetPhrase(-1, 202, $!)), undef, undef);
}
$::s_sOrderNumber = "CS" . substr($$::g_pSetupBlob{CGI_ID}, -1) .
substr("0000" . $nCounter, -4); 
return ($::SUCCESS, undef, $::s_sOrderNumber, undef);
}
sub GetGeneralUD3
{
if (ACTINIC::IsPromptHidden(4, 2))
{
return ($::Session->GetReferrer());
}
return ($::g_GeneralInfo{'USERDEFINED'});
}
sub GetWishListJournal
{	
my $sWishListJournal = '';
my ($bWishListVarDefined, $bWishListEnabled) = ACTINIC::IsCustomVarDefined("IsWishListEnabled");	
if ($bWishListEnabled)
{		
$sWishListJournal = $::Session->GetWishListInCartUser(); 
if ($sWishListJournal ne '')
{
my $sUserName = WishListPkg::GetWishListNameFromEmail($sWishListJournal);
$sWishListJournal = sprintf(ACTINIC::GetPhrase(-1, 3045), $sUserName, $sWishListJournal);
}
}
return ($sWishListJournal);
}	
sub CountValidCartItems
{
if ($#_ != 0)
{
return ($::FAILURE, ACTINIC::GetPhrase(-1, 12, 'CountValidCartItems'), 0, 0);
}
my $pCartList = $_[0];
my ($pOrderDetail, @Response);
my (%CurrentItem, $pProduct);
my $nLineCount = 0;
foreach $pOrderDetail (@$pCartList)
{
%CurrentItem = %$pOrderDetail;
my ($Status, $Message, $sSectionBlobName) = ACTINIC::GetSectionBlobName($CurrentItem{SID});
if ($Status == $::FAILURE)
{
ACTINIC::RecordErrors($Message, ACTINIC::GetPath());
next;
}
@Response = ACTINIC::GetProduct($CurrentItem{"PRODUCT_REFERENCE"},  $sSectionBlobName,
ACTINIC::GetPath());
if ($Response[0] != $::NOTFOUND)
{
$nLineCount++;
}
}
return ($nLineCount);
}
sub EnsurePaymentSelection
{
if (0 < length $::g_PaymentInfo{'METHOD'})
{
return;
}
my @arrPayments;
ActinicOrder::GenerateValidPayments(\@arrPayments);
my $nPaymentOptions = @arrPayments;
if (length $::g_PaymentInfo{'METHOD'} == 0)
{
$::g_PaymentInfo{'METHOD'} = ActinicOrder::GetDefaultPayment($::TRUE, $::TRUE);
if ($::g_PaymentInfo{'METHOD'} == $::PAYMENT_UNDEFINED)
{
$::g_PaymentInfo{'METHOD'} = $::PAYMENT_INVOICE_PRE_PAY	;
}
}
}
sub RecordOrder
{
if ($#_ != 1 && $#_ != 2)
{
return ($::FAILURE, ACTINIC::GetPhrase(-1, 12, 'RecordOrder'), 0, 0);
}
my ($sOrderNumber, $pBlob, $bCheckLightData) = @_;
$::g_PaymentInfo{'ORDERNUMBER'} = $sOrderNumber;
UpdateCheckoutRecord();
my ($Status, $Message, @FileList) = ACTINIC::ReadTheDir($::Session->GetSessionFileFolder());
if ($Status != $::SUCCESS)
{
@FileList = ();
}
my $sFileList = join(' ', @FileList);
my $bOrderExists = ($sFileList =~ /\.ord( |$)/);
if($bCheckLightData)
{
my($nReturnCode, $sError) = CheckSaferEncryptedData($sOrderNumber, $pBlob);
if($nReturnCode != $::TRUE)
{
return($sError);
}
}
my ($sTempFilename) = $::Session->GetSessionFileFolder() . ACTINIC::CleanFileName($sOrderNumber . '.ord');
if (-e $sTempFilename)
{
$::Session->Unlock($sTempFilename);
}
ACTINIC::SecurePath($sTempFilename);
unless ( open (COMPLETEFILE, ">" . $sTempFilename))
{
return(ACTINIC::GetPhrase(-1, 21, $sTempFilename, $!));
}
binmode COMPLETEFILE;
unless (print COMPLETEFILE $$pBlob)
{
my ($sError) = $!;
close COMPLETEFILE;
unlink $sTempFilename;
return(ACTINIC::GetPhrase(-1, 28, $sTempFilename, $sError));
}
close COMPLETEFILE;
$::Session->Lock($sTempFilename);
if (!$bOrderExists &&
$$::g_pSetupBlob{EMAIL_REQUESTED} &&
$$::g_pSetupBlob{EMAIL} ne "" &&
$::g_sSmtpServer ne "")
{
($Status, $Message) = ACTINIC::SendMail($::g_sSmtpServer, $$::g_pSetupBlob{EMAIL},
ACTINIC::GetPhrase(-1, 309), ACTINIC::GetPhrase(-1, 310));
if ($Status != $::SUCCESS)
{
ACTINIC::RecordErrors($Message, ACTINIC::GetPath());
}
}
my ($ePaymentMethod) = ActinicOrder::PaymentStringToEnum($::g_PaymentInfo{'METHOD'}); 
if (!$$::g_pSetupBlob{PSP_PENDING_STOCK_ALLOCATION} &&
$$::g_pPaymentList{$ePaymentMethod}{PAYMENT_TYPE})
{
my @Response = ActinicOrder::CalculateCartQuantities($::TRUE);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my $pStockLevels = $Response[2];
my ($sVarDump, $key, $value);
while (($key, $value) = each(%{$pStockLevels}))
{
$sVarDump .= sprintf("\t'%s' => '%s',\r\n", $key, $value);
}
my $sOut = sprintf("\$::pStockLevels = \r\n\t{\r\n%s\t};\r\nreturn(\$::SUCCESS);", $sVarDump);
my $uTotal;
{
use integer;
$uTotal = unpack('%32C*', $sOut);
}
my $sContent = sprintf("%d;\n%s", $uTotal, $sOut);
my ($sTempFilename) = $::Session->GetSessionFileFolder() . ACTINIC::CleanFileName($sOrderNumber . '.stk');
if (-e $sTempFilename)
{
$::Session->Unlock($sTempFilename);
}
ACTINIC::SecurePath($sTempFilename);
unless ( open (COMPLETEFILE, ">" . $sTempFilename))
{
return(ACTINIC::GetPhrase(-1, 21, $sTempFilename, $!));
}
unless (print COMPLETEFILE $sContent)
{
my ($sError) = $!;
close COMPLETEFILE;
unlink $sTempFilename;
return(ACTINIC::GetPhrase(-1, 28, $sTempFilename, $sError));
}
close COMPLETEFILE;
}
else	
{
($Status, $Message) = ActinicOrder::AllocateStock();
}
if ($$::g_pDiscountBlob{SINGLE_USE_COUPON_USED} == $::TRUE)
{
if (ActinicDiscounts::IsMultipleFixedPriceCouponAccepted() && # multiple coupons accepted?
$::Session->GetCSVCouponCodes())
{
my $CouponManager = new CouponManager(ACTINIC::GetPath());			
my (@aCoupons) = split(/,/, $::Session->GetCSVCouponCodes());
my $sCoupon;
foreach $sCoupon (@aCoupons)
{
$CouponManager->SetCouponUsed($sCoupon);
}			
}
elsif (exists $::g_PaymentInfo{'COUPONCODE'} &&
$::g_PaymentInfo{'COUPONCODE'} ne '')
{
my $CouponManager = new CouponManager(ACTINIC::GetPath());
($Status, $Message) = $CouponManager->SetCouponUsed($::g_PaymentInfo{'COUPONCODE'});
}
}
if ($Status != $::SUCCESS)
{
ACTINIC::RecordErrors($Message, ACTINIC::GetPath());
}
return (undef);
}
sub CheckSaferEncryptedData
{
my ($sOrderNumber, $pBlob) = @_;
my (@BlobDetails) = unpack("C4NNC*", $$pBlob);
my $sError;
my $nLightDataOffset = 4 + 8 + $BlobDetails[3] + $BlobDetails[4];
my $sBlobLightData = substr($$pBlob, $nLightDataOffset);
my @bFixedKey = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
my @Response = GetSaferBlob($sOrderNumber, ACTINIC::GetPath());
if($Response[0] != $::SUCCESS)
{
return($::FALSE, $Response[1]);
}
my ($SaferBlob) = $Response[2];
ActinicSafer::InitTables();
my $sActualLight = ActinicEncrypt::EncryptSafer($SaferBlob, @bFixedKey);
if($sActualLight ne $sBlobLightData)
{
return($::FALSE, '000' . ACTINIC::GetPhrase(-1, 360));
}
return($::TRUE, '');
}
sub EmailReceipt
{
my ($sOrderNumber) = shift;
my ($bSendEmailsNow) = shift;
my ($sSubjectSuffix) = shift;
if (!defined $bSendEmailsNow)
{
$bSendEmailsNow = $::TRUE;
}
if (($bSendEmailsNow &&
$::Session->IsMailSent()) ||
(!$bSendEmailsNow &&
$::Session->IsMailSaved()))
{
my $sMsg = "Email already %s, skipping";
LogData(sprintf($sMsg, $bSendEmailsNow ? "sent" : "saved"));					
return;
}		
my $sUserDigest = $ACTINIC::B2B->Get('UserDigest');
my ($Status, $BuyerStatus, $sMessage, $pBuyer, $pAccount);
if ($sUserDigest)
{
($BuyerStatus, $sMessage, $pBuyer) = ACTINIC::GetBuyer($sUserDigest, ACTINIC::GetPath());
if ($BuyerStatus != $::SUCCESS &&
$BuyerStatus != $::NOTFOUND)
{
return ($BuyerStatus, $sMessage);
}
if ($BuyerStatus != $::NOTFOUND)
{
($Status, $sMessage, $pAccount) = ACTINIC::GetCustomerAccount($$pBuyer{AccountID}, ACTINIC::GetPath());
if ($Status != $::SUCCESS)
{
return ($Status, $sMessage);
}
}
}
my @aRecipients;
my $sName = '';
my $sTemplateFile = '';
my $sEmailCopyAddresses = $::g_pSetupBlob->{'EMAIL_COPY_ADDRESSES'};
@aRecipients = split(/ /, $sEmailCopyAddresses);
if ($sUserDigest &&
$BuyerStatus != $::NOTFOUND)
{
$sName = $$pBuyer{Salutation} ? $$pBuyer{Salutation} . ' ' : '';
$sName .= $$pBuyer{Name};
if ($$pBuyer{EmailOnOrder})
{
if (!$$pBuyer{EmailAddress})
{
ACTINIC::RecordErrors(ACTINIC::GetPhrase(-1, 280), ACTINIC::GetPath());
}
push(@aRecipients, $$pBuyer{EmailAddress});
}
$sTemplateFile = 'Act_BuyerEmail.txt';
}
else
{
$sName = $::g_BillContact{'SALUTATION'} ? $::g_BillContact{'SALUTATION'} . ' ' : '';
$sName .= $::g_BillContact{'NAME'};
if ($$::g_pSetupBlob{EMAIL_CUSTOMER_RECEIPT}) # an e-mail should be sent to the customer, thus add his address to the recipients
{
if (!$::g_BillContact{EMAIL})
{
ACTINIC::RecordErrors(ACTINIC::GetPhrase(-1, 280), ACTINIC::GetPath());
}
push(@aRecipients, $::g_BillContact{EMAIL});
}
$sTemplateFile = 'Act_CustomerEmail.txt';
}
my $sMailFile = '';
if (scalar(@aRecipients) > 0)
{
if (!$bSendEmailsNow)
{
$sMailFile = $::Session->GetSessionFileFolder() . $sOrderNumber . "_customer.mail";
}
LogData("Sending email for order $sOrderNumber");
($Status, $sMessage) = GenerateCustomerMail($sOrderNumber, $sTemplateFile, \@aRecipients, $sName, $sMailFile, $sSubjectSuffix);
if ($Status != $::SUCCESS)
{			
LogData("Sending email for order $sOrderNumber failed, '$sMessage'");
ACTINIC::RecordErrors($sMessage, ACTINIC::GetPath());
}
LogData("Sending email for order $sOrderNumber succeeded");
if ($bSendEmailsNow)
{
$::Session->SetMailSent();
}
else
{
$::Session->SetMailSaved();
}
$::Session->SaveSession();
my $nMailState = $bSendEmailsNow ? $::MAIL_STATE_SENT : $::MAIL_STATE_SAVED;
$::Session->FlashUpdate($sOrderNumber, $nMailState);
}
if ($sUserDigest &&
$BuyerStatus != $::NOTFOUND &&
$$pAccount{EmailOnOrder} &&
$$pAccount{EmailAddress})
{
my $sName = $$pAccount{Salutation} ? $$pAccount{Salutation} . ' ' : '';
$sName .= $$pAccount{Name};
@aRecipients = ($$pAccount{EmailAddress});
$sMailFile = '';
if (!$bSendEmailsNow)
{
$sMailFile = $::Session->GetSessionFileFolder() . $sOrderNumber . "_admin.mail";
}
($Status, $sMessage) = GenerateCustomerMail($sOrderNumber,
'Act_AdminEmail.txt',
\@aRecipients,
$sName,
$sMailFile,
$sSubjectSuffix);
if ($Status != $::SUCCESS)
{
ACTINIC::RecordErrors($sMessage, ACTINIC::GetPath());
}
}
if (defined $$::g_pSetupBlob{'EMAIL_ORDER'} && $$::g_pSetupBlob{'EMAIL_ORDER'})
{
($Status, $sMessage) = GeneratePresnetMail();
if ($Status != $::SUCCESS)
{
ACTINIC::RecordErrors($sMessage, ACTINIC::GetPath());
}
}
}
sub GenerateCustomerMail
{
my ($sOrderNumber, $sTemplateFile, $paRecipients, $sName, $sMailFile, $sSubjectSuffix) = @_;
my (@Response, $Status, $Message);
$ACTINIC::B2B->ClearXML();
if (scalar(@{$paRecipients}) == 0)
{
return ($::SUCCESS, "");
}
if (!$$::g_pSetupBlob{EMAIL})
{
return ($::FAILURE, ACTINIC::GetPhrase(-1, 279));
}
if (!$::g_sSmtpServer)
{
return ($::FAILURE, ACTINIC::GetPhrase(-1, 281));
}
@Response = $::Session->GetCartObject();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my $pCartObject = $Response[2];
if (!$$::g_pSetupBlob{'EMAIL_CURRENCY_SYMBOL'})
{
$::USEINTLCURRENCYSYMBOL = $::TRUE;
}
@Response = $pCartObject->SummarizeOrder($::TRUE);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my ($Ignore0, $Ignore1, $nSubTotal, $nShipping, $nTax1, $nTax2, $nTotal, $nShippingTax1, $nShippingTax2, $nHandling, $nHandlingTax1, $nHandlingTax2) = @Response;
@Response = ActinicOrder::SummarizeOrderPrintable(@Response);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my ($Ignore2, $Ignore3, $sSubTotal, $sShipping, $sHandling, $sTax1, $sTax2, $sTotal) = @Response;
my $pCartList = $pCartObject->GetCartList();
$ACTINIC::B2B->SetXML('CUSTOMER_NAME',$sName);
my ($bDPDVarDefined, $bDPDEnabled) = ACTINIC::IsCustomVarDefined("IsDPDEnabled");
if ($bDPDEnabled)
{
$ACTINIC::B2B->SetXML('DELIVERINSTRUCTION_TEXT', $::g_ShipInfo{'USERDEFINED'} . $::g_ShipInfo{'DPDEXTRAINFO'});
}
else
{
$ACTINIC::B2B->SetXML('DELIVERINSTRUCTION_TEXT', $::g_ShipInfo{'USERDEFINED'});
}
$ACTINIC::B2B->SetXML('ORDER_NUMBER', $sOrderNumber);
my $nPaymentMethod = $::g_PaymentInfo{METHOD};
my $sPaymentDescription = $::g_pPaymentList->{$nPaymentMethod}-> {PROMPT};
$ACTINIC::B2B->SetXML('PAYMENT_METHOD', $sPaymentDescription);
my $sPspPendingNotice;
if (($$::g_pPaymentList{$nPaymentMethod}{PAYMENT_TYPE}) &&
($::Session->GetAuthorizeResult() != 1))
{
$sPspPendingNotice = GetPspPendingNotice($nPaymentMethod);
}
$ACTINIC::B2B->SetXML('PAYMENT_PENDING_NOTICE', $sPspPendingNotice);
my ($nSec, $nMin, $nHour, $nMday, $nMon, $nYear, $nWday, $nYday, $nIsdst, $sDate);
if ($::TIME_USELOCALTIME)
{
($nSec, $nMin, $nHour, $nMday, $nMon, $nYear, $nWday, $nYday, $nIsdst) = localtime(time);
}
else
{
($nSec, $nMin, $nHour, $nMday, $nMon, $nYear, $nWday, $nYday, $nIsdst) = gmtime(time);
}
$nMon++;
$nYear += 1900;
my ($sMon) = $::g_InverseMonthMap{$nMon};
my ($sDatePrompt) = ACTINIC::FormatDate($nMday, $sMon, $nYear);
$sDate = $sDatePrompt . sprintf(" %2.2d:%2.2d %s", $nHour, $nMin, ACTINIC::GetUTC());
if ($::Session->IsIPCheckFailed())
{
$sDate .= "\r\n" . ACTINIC::GetPhrase(-1, 2308);
}
$ACTINIC::B2B->SetXML('ORDER_DATE',$sDate);
my %hashShipMap = (
'SALUTATION'	=> 'SHIP_SALUTATION',
'NAME'			=> 'SHIP_NAME',
'JOBTITLE'		=> 'SHIP_TITLE',
'COMPANY'		=> 'SHIP_COMPANY',
'ADDRESS1'		=> 'SHIP_ADDRESS1',
'ADDRESS2'		=> 'SHIP_ADDRESS2',
'ADDRESS3'		=> 'SHIP_ADDRESS3',
'ADDRESS4'		=> 'SHIP_ADDRESS4',
'POSTALCODE'	=> 'SHIP_POSTCODE',
'COUNTRY'		=> 'SHIP_COUNTRY',
'PHONE'			=> 'SHIP_PHONE',
'FAX'				=> 'SHIP_FAX',
'EMAIL'			=> 'SHIP_EMAIL',
'USERDEFINED'	=> 'SHIP_USERDEFINED',
);
my ($sTempUserDefined) = $::g_ShipContact{'USERDEFINED'};
if (!$::g_BillContact{'SEPARATE'} &&
$::g_BillContact{'USERDEFINED'})
{
$::g_ShipContact{'USERDEFINED'} = $::g_BillContact{'USERDEFINED'};
}
$::g_ShipContact{'USERDEFINED'} = $::g_ShipInfo{'USERDEFINED'};
my ($bDPDVarDefined, $bDPDEnabled) = ACTINIC::IsCustomVarDefined("IsDPDEnabled");
if ($bDPDEnabled)
{
$::g_ShipContact{'USERDEFINED'} .= $::g_ShipInfo{'DPDEXTRAINFO'}; # add collection point pickup / specified day delivery if set		
}
SetXMLFromHash(\%hashShipMap, \%::g_ShipContact);
$::g_ShipContact{'USERDEFINED'} = $sTempUserDefined;
my %hashBillMap = (
'SALUTATION'	=> 'BILL_SALUTATION',
'NAME'			=> 'BILL_NAME',
'JOBTITLE'		=> 'BILL_TITLE',
'COMPANY'		=> 'BILL_COMPANY',
'ADDRESS1'		=> 'BILL_ADDRESS1',
'ADDRESS2'		=> 'BILL_ADDRESS2',
'ADDRESS3'		=> 'BILL_ADDRESS3',
'ADDRESS4'		=> 'BILL_ADDRESS4',
'POSTALCODE'	=> 'BILL_POSTCODE',
'COUNTRY'		=> 'BILL_COUNTRY',
'PHONE'			=> 'BILL_PHONE',
'FAX'				=> 'BILL_FAX',
'EMAIL'			=> 'BILL_EMAIL',
'USERDEFINED'	=> 'BILL_USERDEFINED',
);
if ($::g_BillContact{'SEPARATE'})
{
$ACTINIC::B2B->SetXML('BILL_LABEL', ACTINIC::GetPhrase(-1, 339));
SetXMLFromHash(\%hashBillMap, \%::g_BillContact);
}
else
{
$ACTINIC::B2B->SetXML('BILL_LABEL', "");
my ($sKey, $sValue);
while (($sKey, $sValue) = each(%hashBillMap))
{
$ACTINIC::B2B->SetXML($sValue, "");
$ACTINIC::B2B->SetXML($sValue . "_SEP", "");
}
}
my %hashCompanyMap = (
'COMPANY_NAME'			=> 'COMPANY_NAME',
'CONTACT_SALUTATION'	=> 'COMPANY_SALUTATION',
'CONTACT_NAME'			=> 'COMPANY_CONTACT_NAME',
'CONTACT_JOB_TITLE'	=> 'COMPANY_CONTACT_TITLE',
'ADDRESS_1'				=> 'COMPANY_CONTACT_ADDRESS1',
'ADDRESS_2'				=> 'COMPANY_CONTACT_ADDRESS2',
'ADDRESS_3'				=> 'COMPANY_CONTACT_ADDRESS3',
'ADDRESS_4'				=> 'COMPANY_CONTACT_ADDRESS4',
'POSTAL_CODE'			=> 'COMPANY_CONTACT_POSTCODE',
'COUNTRY'				=> 'COMPANY_CONTACT_COUNTRY',
'PHONE'					=> 'COMPANY_CONTACT_PHONE',
'FAX'						=> 'COMPANY_CONTACT_FAX',
'EMAIL'					=> 'COMPANY_CONTACT_EMAIL',
'WEB_SITE_URL'			=> 'COMPANY_CONTACT_WEBSITE',
);
SetXMLFromHash(\%hashCompanyMap, \%$::g_pSetupBlob);
my ($nColumns, $nColumnsToPrice);
$nColumns = 0;
$ACTINIC::B2B->SetXML('CART', ACTINIC::GetPhrase(-1, 165));
if ($$::g_pSetupBlob{PRICES_DISPLAYED})
{
$ACTINIC::B2B->AppendXML('CART', " (" . ACTINIC::GetPhrase(-1, 96, $$::g_pCatalogBlob{'CURRENCY'}) . ")");
}
$ACTINIC::B2B->AppendXML('CART', "\r\n");
my $nProdRefColumnWidth = 0;
if ($$::g_pSetupBlob{PROD_REF_COUNT} > 0)
{
$nProdRefColumnWidth = $$::g_pSetupBlob{PROD_REF_COUNT} > (length ACTINIC::GetPhrase(-1, 97)) ?
$$::g_pSetupBlob{PROD_REF_COUNT} : (length ACTINIC::GetPhrase(-1, 97));
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%-%d.%ds ", $nProdRefColumnWidth, $nProdRefColumnWidth),
ACTINIC::GetPhrase(-1, 97)));
$nColumns++;
}
my $nDescriptionColumnWidth = 30 > (length ACTINIC::GetPhrase(-1, 98)) ? 30 : (length ACTINIC::GetPhrase(-1, 98));
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%-%d.%ds ", $nDescriptionColumnWidth, $nDescriptionColumnWidth),
ACTINIC::GetPhrase(-1, 98)));
$nColumns++;
my $nQuantityColumnWidth = 6 > (length ACTINIC::GetPhrase(-1, 159)) ? 6 : (length ACTINIC::GetPhrase(-1, 159));
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%ds ", $nQuantityColumnWidth),
ACTINIC::GetPhrase(-1, 159)));
$nColumns++;
my $nPriceColumnWidth = 0;
if ($$::g_pSetupBlob{PRICES_DISPLAYED})
{
$nPriceColumnWidth = 11;
$nPriceColumnWidth = $nPriceColumnWidth > (length ACTINIC::GetPhrase(-1, 99)) ? $nPriceColumnWidth :
length ACTINIC::GetPhrase(-1, 99);
$nPriceColumnWidth = $nPriceColumnWidth > (length ACTINIC::GetPhrase(-1, 100)) ? $nPriceColumnWidth :
length ACTINIC::GetPhrase(-1, 100);
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%ds ", $nPriceColumnWidth),
ACTINIC::GetPhrase(-1, 99)));
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%ds ", $nPriceColumnWidth),
ACTINIC::GetPhrase(-1, 100)));
$nColumns += 2;
}
$ACTINIC::B2B->AppendXML('CART', "\r\n");
$ACTINIC::B2B->AppendXML('CART', "-" x ($nProdRefColumnWidth + 2 + $nDescriptionColumnWidth + 2 + $nQuantityColumnWidth + 2 + 2 * ($nPriceColumnWidth + 2)));
my @TableFormat;
my $nCol = 0;
if ($$::g_pSetupBlob{PROD_REF_COUNT} > 0)
{
$TableFormat[$nCol++] = sprintf(" %%-%ds ",$nProdRefColumnWidth);
}
$TableFormat[$nCol++] = sprintf(" %%-%ds ",$nDescriptionColumnWidth);
$TableFormat[$nCol++] = sprintf(" %%%ds ", $nQuantityColumnWidth);
$TableFormat[$nCol++] = sprintf(" %%%ds ", $nPriceColumnWidth);
$TableFormat[$nCol++] = sprintf(" %%%ds ", $nPriceColumnWidth);
my @aCartData;
($Status, $Message, @aCartData) = ActinicOrder::PreprocessCartToDisplay($pCartList, $::TRUE);
my $nCartIndex = 0;
my ($pOrderDetail, $pProduct);
my @aDownloadLinks;
foreach $pOrderDetail (@aCartData)
{
my %CurrentItem = %$pOrderDetail;
my @aComponentsIncluded;
my @aComponentsSeparated;
my $pComponent;
foreach $pComponent (@{$CurrentItem{'COMPONENTS'}})
{
if ($pComponent->{'SEPARATELINE'})
{
push @aComponentsSeparated, $pComponent;
}
else
{
push @aComponentsIncluded, $pComponent;
}
}
$pProduct = $CurrentItem{'PRODUCT'};
my $bProductSupressed = $$pProduct{NO_ORDERLINE};
my $pPrintTable;
my $nColumn = 0;
my $nEffectiveQuantity = ActinicOrder::EffectiveCartQuantity($pOrderDetail,$pCartList,\&ActinicOrder::IdenticalCartLines,undef);
my $nCurrentRow = 0;
$ACTINIC::B2B->AppendXML('CART', "\r\n");
if (!$bProductSupressed)
{
MailOrderLine( $$pProduct{REFERENCE},
$$pProduct{NAME},
$$pOrderDetail{QUANTITY},
$CurrentItem{'PRICE'},
$CurrentItem{'COST'},
$nDescriptionColumnWidth,
@TableFormat
);
if ($CurrentItem{'DDLINK'} ne "")
{
push @aDownloadLinks, MailDownloadLink($$pProduct{REFERENCE}, $$pProduct{NAME}, $CurrentItem{'DDLINK'});
}
}
foreach $pComponent (@aComponentsIncluded)
{
my $sPrice;
my $sCost;
if ($bProductSupressed)
{
$bProductSupressed = $::FALSE;
if ($$::g_pSetupBlob{'PRICES_DISPLAYED'})
{
$sPrice = $CurrentItem{'PRICE'} ? $CurrentItem{'PRICE'} : "--";
$sCost  = $CurrentItem{'COST'}  ? $CurrentItem{'COST'}  : "--";
}
}
MailOrderLine( $pComponent->{'REFERENCE'},
$pComponent->{'NAME'},
$pComponent->{'QUANTITY'},
$sPrice,
$sCost,
$nDescriptionColumnWidth,
@TableFormat
);
if ($pComponent->{'DDLINK'} ne "")
{
push @aDownloadLinks, MailDownloadLink($pComponent->{'REFERENCE'}, $pComponent->{'NAME'}, $pComponent->{'DDLINK'});
}
}
if (length $$pProduct{'OTHER_INFO_PROMPT'} > 0)
{
MailOrderLine( "",
$$pProduct{'OTHER_INFO_PROMPT'} . "\r\n  " . $CurrentItem{'INFO'},
"",
"",
"",
$nDescriptionColumnWidth,
@TableFormat
);
}
if (length $$pProduct{'DATE_PROMPT'} > 0)
{
my ($nDay, $nMonth, $sMonth, $nYear, $sDate);
if ($CurrentItem{"DATE"} =~ /(\d{4})\/0?(\d{1,2})\/0?(\d{1,2})/)
{
$nYear = $1;
$nMonth = $2;
$nDay = $3;
$sMonth = $::g_InverseMonthMap{$nMonth};
$sDate = ACTINIC::FormatDate($nDay, $sMonth, $nYear);
}
else
{
$sDate = $CurrentItem{"DATE"};
ACTINIC::RecordErrors(sprintf(ACTINIC::GetPhrase(-1, 2158, $$pProduct{'DATE_PROMPT'}) . " [%s]",
$CurrentItem{"DATE"}), ACTINIC::GetPath());
}
MailOrderLine( "",
$$pProduct{'DATE_PROMPT'} . "\r\n  " . $sDate,
"",
"",
"",
$nDescriptionColumnWidth,
@TableFormat
);
}
foreach $pComponent (@aComponentsSeparated)
{
MailOrderLine( $pComponent->{'REFERENCE'},
$pComponent->{'NAME'},
$pComponent->{'QUANTITY'},
$pComponent->{'PRICE'},
$pComponent->{'COST'},
$nDescriptionColumnWidth,
@TableFormat
);
if ($pComponent->{'DDLINK'} ne "")
{
push @aDownloadLinks, MailDownloadLink($pComponent->{'REFERENCE'}, $pComponent->{'NAME'}, $pComponent->{'DDLINK'});
}
}
my $parrProductAdjustments = $pCartObject->GetConsolidatedProductAdjustments($nCartIndex);
my $parrAdjustDetails;
$nCurrentRow = 0;
$pPrintTable = [];
foreach $parrAdjustDetails (@$parrProductAdjustments)
{
@Response = ActinicOrder::FormatPrice($parrAdjustDetails->[$::eAdjIdxAmount], $::TRUE, $::g_pCatalogBlob);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
MailOrderLine( '',
$parrAdjustDetails->[$::eAdjIdxProductDescription],
"",
"",
$Response[2],
$nDescriptionColumnWidth,
@TableFormat
);
}
$nCartIndex++;
}
if ($$::g_pSetupBlob{PRICES_DISPLAYED} &&
$nTotal > 0)
{
$ACTINIC::B2B->AppendXML('CART', "=" x ($nProdRefColumnWidth + 2 + $nDescriptionColumnWidth + 2 + $nQuantityColumnWidth + 2 + 2 * ($nPriceColumnWidth + 2)));
$ACTINIC::B2B->AppendXML('CART', "\r\n");
my $nTextColumnWidth;
if ($nProdRefColumnWidth)
{
$nTextColumnWidth += $nProdRefColumnWidth + 2;
}
$nTextColumnWidth += $nDescriptionColumnWidth + 2;
$nTextColumnWidth += $nQuantityColumnWidth + 2;
if ($nPriceColumnWidth)
{
$nTextColumnWidth += $nPriceColumnWidth + 2;
}
$nTextColumnWidth -= 2;
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%d.%ds ", $nTextColumnWidth, $nTextColumnWidth), ACTINIC::GetPhrase(-1, 101) . ":"));
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%ds\r\n", $nPriceColumnWidth), $sSubTotal));
my $parrFinalAdjustments = $pCartObject->GetFinalAdjustments();
my @arrAdjustments = @{$pCartObject->GetOrderAdjustments()};
push @arrAdjustments, @{$pCartObject->GetFinalAdjustments()};
my $parrAdjustDetails;
foreach $parrAdjustDetails (@arrAdjustments)
{
my $FullDescr = $parrAdjustDetails->[$::eAdjIdxProductDescription];
my ($parrProductDescription, $nLineCount) =
ActinicOrder::WrapText($FullDescr, $nTextColumnWidth - 2);
my $bWrapped = (@$parrProductDescription > 1);
my $sDescriptionLine = $parrProductDescription->[0];
if(!$bWrapped)
{
$sDescriptionLine .= ':';
}
$ACTINIC::B2B->AppendXML('CART',
sprintf(sprintf(" %%%d.%ds ", $nTextColumnWidth, $nTextColumnWidth),
$sDescriptionLine));
@Response = ActinicOrder::FormatPrice($parrAdjustDetails->[$::eAdjIdxAmount], $::TRUE, $::g_pCatalogBlob);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%ds\r\n", $nPriceColumnWidth), $Response[2]));
my $i;
for($i = 1; $i < @$parrProductDescription; $i++)
{
$sDescriptionLine = $parrProductDescription->[$i];
if($i == @$parrProductDescription - 1)
{
$sDescriptionLine .= ':';
}
$ACTINIC::B2B->AppendXML('CART',
sprintf(sprintf(" %%%d.%ds\r\n", $nTextColumnWidth, $nTextColumnWidth), ' ' . $parrProductDescription->[$i]));
}
}
if ($$::g_pSetupBlob{MAKE_SHIPPING_CHARGE} && $nShipping > 0)
{
@Response = ActinicOrder::GetShippingPluginResponse();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
elsif (${$Response[2]}{GetShippingDescription} != $::SUCCESS)
{
return ( ${$Response[2]}{GetShippingDescription}, ${$Response[3]}{GetShippingDescription});
}
my $sShipDescription = $Response[5];
my $sShippingText = ACTINIC::GetPhrase(-1, 102);
if ($sShipDescription ne "")
{
$sShippingText .= " ($sShipDescription)";
}
$sShippingText .= ":";
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%d.%ds ", $nTextColumnWidth, $nTextColumnWidth), $sShippingText));
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%ds\r\n", $nPriceColumnWidth), $sShipping));
}
if ($$::g_pSetupBlob{MAKE_HANDLING_CHARGE} && $nHandling != 0)
{
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%d.%ds ", $nTextColumnWidth, $nTextColumnWidth), ACTINIC::GetPhrase(-1, 199) . ":"));
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%ds\r\n", $nPriceColumnWidth), $sHandling));
}
if ($nTax1 != 0)
{
if (!ActinicOrder::PricesIncludeTaxes() || $nTax1 < 0)
{
my $sTaxName = ActinicOrder::GetTaxName('TAX_1');
if ($nTax1 < 0)
{
$sTaxName = 'Exempted ' . $sTaxName;
}
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%d.%ds ", $nTextColumnWidth, $nTextColumnWidth), $sTaxName . ":"));
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%ds\r\n", $nPriceColumnWidth), $sTax1));
}
}
if ($nTax2 != 0)
{
if (!ActinicOrder::PricesIncludeTaxes() || $nTax2 < 0)
{
my $sTaxName = ActinicOrder::GetTaxName('TAX_2');
if ($nTax2 < 0)
{
$sTaxName = 'Exempted ' . $sTaxName;
}
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%d.%ds ", $nTextColumnWidth, $nTextColumnWidth), $sTaxName . ":"));
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%ds\r\n", $nPriceColumnWidth), $sTax2));
}
}
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%d.%ds ", $nTextColumnWidth, $nTextColumnWidth), ACTINIC::GetPhrase(-1, 103) . ":"));
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%ds\r\n", $nPriceColumnWidth), $sTotal));
if (ActinicOrder::PricesIncludeTaxes())
{
if ($nTax1 > 0 ||
ActinicOrder::UsesMultipleTaxes())
{
my $sTaxName = ActinicOrder::GetTaxName('TAX_1');
$sTaxName = 'Including ' . $sTaxName;
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%d.%ds ", $nTextColumnWidth, $nTextColumnWidth), $sTaxName . ":"));
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%ds\r\n", $nPriceColumnWidth), $sTax1));
}
if ($nTax2 > 0)
{
my $sTaxName = ActinicOrder::GetTaxName('TAX_2');
$sTaxName = 'Including ' . $sTaxName;
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%d.%ds ", $nTextColumnWidth, $nTextColumnWidth), $sTaxName . ":"));
$ACTINIC::B2B->AppendXML('CART', sprintf(sprintf(" %%%ds\r\n", $nPriceColumnWidth), $sTax2));
}
}		
if($::s_Ship_nSSPProviderID != -1 &&
$$::g_pSSPSetupBlob{$::s_Ship_nSSPProviderID} &&
$$::g_pSSPSetupBlob{$::s_Ship_nSSPProviderID}{'RATE_DISCLAIMER'})
{
$ACTINIC::B2B->AppendXML('CART',
sprintf("\r\n%s\r\n",
ACTINIC::SplitString($$::g_pSSPSetupBlob{$::s_Ship_nSSPProviderID}{'RATE_DISCLAIMER'},
70,
"\r\n")));
}
}
if (@aDownloadLinks > 0)
{
$ACTINIC::B2B->AppendXML('CART', "\r\n" . ACTINIC::GetPhrase(-1, 2250, $$::g_pSetupBlob{'DD_EXPIRY_TIME'}));
my $sLine;
foreach $sLine (@aDownloadLinks)
{
$ACTINIC::B2B->AppendXML('CART', "\r\n\r\n" . $sLine);
}
}
if($::s_Ship_bDisplayExtraCartInformation == $::TRUE)
{
if($::s_Ship_nSSPProviderID != -1 &&
$$::g_pSSPSetupBlob{$::s_Ship_nSSPProviderID} &&
$$::g_pSSPSetupBlob{$::s_Ship_nSSPProviderID}{'TRADEMARKS'})
{
$ACTINIC::B2B->AppendXML('EXTRAFOOTER',
sprintf("\r\n%s\r\n",
ACTINIC::SplitString($$::g_pSSPSetupBlob{$::s_Ship_nSSPProviderID}{'TRADEMARKS'},
70,
"\r\n")));
}
}
else
{
$ACTINIC::B2B->AppendXML('EXTRAFOOTER', '');
}
my $sFilename = ACTINIC::GetPath() . $sTemplateFile;
unless (open (TEMPLATE, "<$sFilename"))
{
return ($::FAILURE, ACTINIC::GetPhrase(-1, 21, $sFilename, $!));
}
my ($sTemplate, $sTextBody, $sHTMLBody);
{
local $/;
$sTemplate = <TEMPLATE>;
}
close (TEMPLATE);
$::USEINTLCURRENCYSYMBOL = $::FALSE;
$sTemplate =~ s/([^\r])\n/$1\r\n/g;
eval
{
require ax000001;
};
if ($@)
{
return $@;
}
my $oXMLParser = new ACTINIC_PXML();
if ($sTemplate =~ /^\s*<!doctype html/i)
{
require ht000001;
my $oHTMLParser = new HTMLToText;					
$sTextBody = $oHTMLParser->Parse($sTemplate);
@Response = ActinicOrder::GenerateShoppingCartLines($pCartList, $::FALSE, [], "ECTemplate.html");
if ($Response[0] != $::SUCCESS)
{
return @Response;
}
my $sHTMLCart = $Response[2];
if (@aDownloadLinks > 0)
{
$sHTMLCart .= '<br>' . ACTINIC::GetPhrase(-1, 2250, $$::g_pSetupBlob{'DD_EXPIRY_TIME'});
}
$ACTINIC::B2B->SetXML('CART', $sHTMLCart);
for my $sTag (keys %{$ACTINIC::B2B->{XML}})
{
if ($sTag =~ /_SEP$/ &&
$ACTINIC::B2B->{XML}->{$sTag} ne '')
{
$ACTINIC::B2B->{XML}->{$sTag} = '<br>';
}
}
($sHTMLBody, undef) = $oXMLParser->Parse($sTemplate);
}
else
{
($sTextBody, undef) = $oXMLParser->Parse($sTemplate);
}
my $sRecipient;
if (defined $sMailFile &&
length $sMailFile > 0)
{
unless (open (MFILE, ">$sMailFile"))
{
return ($::FAILURE, ACTINIC::GetPhrase(-1, 21, $sFilename, $!));
}
foreach $sRecipient (@{$paRecipients})
{
print MFILE $sRecipient . ",";
}
print MFILE "\n";
print MFILE ACTINIC::GetPhrase(-1, 234) . " $sOrderNumber" . "\n";
if ($sHTMLBody ne '')
{
print MFILE $::g_sSavedMailSeparator;
}
print MFILE $sTextBody;
if ($sHTMLBody ne '')
{
print MFILE $::g_sSavedMailSeparator;
print MFILE $sHTMLBody;
}
close MFILE;
}
else
{
foreach $sRecipient (@{$paRecipients})
{
if ($sRecipient ne "")
{
($Status, $Message) = ACTINIC::SendMail($::g_sSmtpServer,
$sRecipient,
ACTINIC::GetPhrase(-1, 234) . " $sOrderNumber" . $sSubjectSuffix,
$sTextBody,
$sHTMLBody,
$$::g_pSetupBlob{EMAIL});
if($Status != $::SUCCESS)
{
return ($::FAILURE, $Message);
}
}
}
}
return ($::SUCCESS, "");
}
sub MailOrderLine
{
my ($sProdRef, $sName, $sQuantity, $sPrice, $sCost, $nDescriptionColumnWidth, @TableFormat) = @_;
my $pPrintTable;
my $nColumn = 0;
my $nCurrentRow = 0;
if ($$::g_pSetupBlob{PROD_REF_COUNT} > 0)
{
if (!($sProdRef =~ /^v\:[0-9]+$/))
{
$pPrintTable->[$nColumn++]->[0] = $sProdRef;
}
else
{
$pPrintTable->[$nColumn++]->[0] = "";
}
}
$sName =~ s/(!!\<|\>!!)//g;
my ($pProductDescription, $nLineCount) = ActinicOrder::WrapText($sName, $nDescriptionColumnWidth);
foreach (@$pProductDescription)
{
$pPrintTable->[$nColumn]->[$nCurrentRow++] = $_;
}
$nColumn++;
$pPrintTable->[$nColumn++]->[0] = $sQuantity;
if (!$$::g_pSetupBlob{'PRICES_DISPLAYED'})
{
$sPrice = "";
$sCost  = "";
}
$pPrintTable->[$nColumn++]->[0] = $sPrice;
$pPrintTable->[$nColumn++]->[0] = $sCost;
my $nLine;
for( $nLine=0; $nLine < $nCurrentRow; $nLine++ )
{
my $nCol;
for( $nCol=0; $nCol < $nColumn; $nCol++ )
{
$ACTINIC::B2B->AppendXML('CART', sprintf($TableFormat[$nCol], $pPrintTable->[$nCol]->[$nLine]));
}
$ACTINIC::B2B->AppendXML('CART', "\r\n");
}
}
sub MailDownloadLink
{
my ($sProdRef, $sName, $sLink) = @_;
my $sLine;
if ($$::g_pSetupBlob{PROD_REF_COUNT} > 0)
{
$sLine = $sProdRef . " ";
}
$sLine .= $sName . "\r\n" . $sLink;
return $sLine;
}
sub GeneratePresnetMail
{
my ($sTextMailBody, @Response, $Status, $Message);
@Response = $::Session->GetCartObject();
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my $pCartObject = $Response[2];
my $pCartList = $pCartObject->GetCartList();
$sTextMailBody = "Order#: $::g_InputHash{ORDERNUMBER}\r\n";
$sTextMailBody .= "Shop Name: $$::g_pSetupBlob{COMPANY_NAME}\r\n";
$sTextMailBody .= "Shop's Email: $$::g_pSetupBlob{EMAIL}\r\n";
$sTextMailBody .= "Sender's Email: $::g_BillContact{EMAIL}\r\n";
$sTextMailBody .= "Sender's Town/City: $::g_BillContact{ADDRESS4}\r\n";
$sTextMailBody .= "Sender's Country: $::g_BillContact{COUNTRY}\r\n";
$sTextMailBody .= "Recipient's Town/City: $::g_ShipContact{ADDRESS4}\r\n";
$sTextMailBody .= "Recipient's Country: $::g_ShipContact{COUNTRY}\r\n";
$sTextMailBody .= "Referrer: " . GetGeneralUD3() . "\r\n";
@Response = ACTINIC::EncodeText($$::g_pCatalogBlob{'SINTLSYMBOLS'});
$sTextMailBody .= "Currency: $Response[1]\r\n";
@Response = $pCartObject->SummarizeOrder($::FALSE);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my ($Ignore0, $Ignore1, $nSubTotal, $nShipping, $nTax1, $nTax2, $nTotal, $nShippingTax1, $nShippingTax2,
$nHandling, $nHandlingTax1, $nHandlingTax2) = @Response;
my ($nIntegral, $nFractional, $nFactor);
$nFactor = 10 ** $$::g_pCatalogBlob{'ICURRDIGITS'};
if ($nFactor == 1)
{
$sTextMailBody .= "Order Value: $nTotal\r\n";
}
else
{
my ($sFormat, $sFormattedTotal);
$sFormat = sprintf("%%d.%%0%dd", $$::g_pCatalogBlob{'ICURRDIGITS'});
$sFormattedTotal = sprintf($sFormat,
$nTotal / $nFactor, ACTINIC::Modulus($nTotal, $nFactor) );
$sTextMailBody .= "Order Value: $sFormattedTotal\r\n";
}
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst, $sDate);
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = gmtime(time);
$mon++;
$year += 1900;
$sDate = sprintf("%02d/%02d/%4d %2.2d:%2.2d GMT", $mday, $mon, $year, $hour, $min);
$sTextMailBody .= "Order Date & time: $sDate\r\n";
$sTextMailBody .= "Latest delivery date: $::g_ShipContact{USERDEFINED}\r\n";
my ($pOrderDetail, %CurrentItem, $pProduct, $sLine);
foreach $pOrderDetail (@$pCartList)
{
%CurrentItem = %$pOrderDetail;
my $sSectionBlobName;
($Status, $Message, $sSectionBlobName) = ACTINIC::GetSectionBlobName($CurrentItem{SID});
if ($Status == $::FAILURE)
{
return ($Status, $Message);
}
@Response = ACTINIC::GetProduct($CurrentItem{"PRODUCT_REFERENCE"}, $sSectionBlobName,
ACTINIC::GetPath());
($Status, $Message, $pProduct) = @Response;
if ($Status == $::NOTFOUND)
{
}
if ($Status == $::FAILURE)
{
return (@Response);
}
$sLine = sprintf("Item: %-21s", $$pProduct{'REFERENCE'});
$sLine .= $$pProduct{'NAME'};
$sTextMailBody .= "$sLine\r\n";
}
my ($sSubject, $sEmailRecpt);
$sSubject = $$::g_pSetupBlob{COMPANY_NAME};
$sEmailRecpt .= 'orderorder@pres.net';
($Status, $Message) = ACTINIC::SendMail($::g_sSmtpServer,
$sEmailRecpt,
$sSubject,
$sTextMailBody);
if($Status != $::SUCCESS)
{
return ($::FAILURE, $Message);
}
return ($::SUCCESS, "");
}
sub IsAuthoriseSessionPresent
{
my ($sOrderNumber) = shift;
my $sFileName = GetAuthoriseSessionFileName($sOrderNumber);
return (-e $sFileName ? $::TRUE : $::FALSE);
}
sub GetAuthoriseSessionFileName
{
my ($sOrderNumber) = shift;
return ACTINIC::GetSessionFileFolder() . $sOrderNumber . ".authorise";
}
sub IsCustomerEmailPresent
{
my ($sOrderNumber) = shift;
my $sFileName = GetCustomerEmailFileName($sOrderNumber);
return (-e $sFileName ? $::TRUE : $::FALSE);
}
sub GetCustomerEmailFileName
{
my ($sOrderNumber) = shift;
return ACTINIC::GetSessionFileFolder() . $sOrderNumber . "_customer.mail";
}
sub IsAdminEmailPresent
{
my ($sOrderNumber) = shift;
my $sFileName = GetAdminEmailFileName($sOrderNumber);
return (-e $sFileName ? $::TRUE : $::FALSE);
}
sub GetAdminEmailFileName
{
my ($sOrderNumber) = shift;
return ACTINIC::GetSessionFileFolder() . $sOrderNumber . "_admin.mail";
}
sub SendSavedEmail
{
my ($sMailFile) = shift;
if (-e $sMailFile)
{
if (open (MFILE, "<$sMailFile"))
{
my $sRecipients = <MFILE>;
chomp($sRecipients);
my $sSubject = <MFILE>;
my $sMailBody;
chomp($sSubject);
{
local $/;
$sMailBody = <MFILE>;
}
close MFILE;
my @lRecipientlist = split(/,/, $sRecipients);
my $sRecipient;
foreach $sRecipient (@lRecipientlist)
{
$sRecipient =~ s/\s*//;
if (length $sRecipient == 0)
{
next;
}
my ($sTextBody, $sHTMLBody);
my @arrParts = split($::g_sSavedMailSeparator, $sMailBody);
if (scalar(@arrParts) == 1)
{
$sTextBody = $sMailBody;
}
else
{
$sTextBody = $arrParts[1];
$sHTMLBody = $arrParts[2];
}
my ($Status, $Message) = ACTINIC::SendMail($::g_sSmtpServer,
$sRecipient,
$sSubject,
$sTextBody,
$sHTMLBody,
$$::g_pSetupBlob{EMAIL});
if($Status != $::SUCCESS)
{
ACTINIC::RecordErrors("SendMail asynchronous error:\n$Message", ACTINIC::GetPath());
}
}
ACTINIC::DeleteFile($sMailFile);
}
else
{
ACTINIC::RecordErrors("Send asynchronous mail error:\n" . ACTINIC::GetPhrase(-1, 21, $sMailFile, $!), ACTINIC::GetPath());
}
}
}
sub CallPlugInScript
{
if ($#_ != 0)
{
ACTINIC::RecordErrors("CallPlugInScript, validate params:\n",
ACTINIC::GetPath());
return ($::FAILURE, ACTINIC::GetPhrase(-1, 12, 'CallPlugInScript'), 0, 0);
}
my ($sScriptName) = @_;
my @Response = GetPlugInScript(ACTINIC::GetPath(), $sScriptName);
if ($Response[0] != $::SUCCESS)
{
ACTINIC::RecordErrors("CallPlugInScript, could not load script:\n",
ACTINIC::GetPath());
return (@Response);
}
my ($sScript) = $Response[2];
local $::sPath = ACTINIC::GetPath();
$::sPlugInScriptError = '';
eval
{
require Digest::MD5;
import Digest::MD5 'md5_hex';
};
if ($@)
{
require di000001;
import Digest::Perl::MD5 'md5_hex';
}
eval($sScript);
if ($@)
{
ACTINIC::RecordErrors("CallPlugInScript, execute: $@\n",
ACTINIC::GetPath());
return ($::FAILURE, ACTINIC::GetPhrase(-1, 170, $@));
}
if ($::sPlugInScriptError)
{
ACTINIC::RecordErrors("CallPlugInScript, report: $::sPlugInScriptError\n",
ACTINIC::GetPath());
return ($::FAILURE, ACTINIC::GetPhrase(-1, 170, $::sPlugInScriptError));
}
return ($::SUCCESS, '');
}
sub GetPlugInScript
{
if ($#_ < 1)
{
return ($::FAILURE, ACTINIC::GetPhrase(-1, 12, 'GetPlugInScript'), 0, 0);
}
my ($sPath) = $_[0];
my ($sFilename) = $sPath . $_[1];
my @Response = ACTINIC::ReadAndVerifyFile($sFilename);
return (@Response);
}
sub AdjustTaxTreatment
{
my ($eTreatment) = @_;
if ($::g_TaxInfo{EXEMPT1})
{
if ($ActinicOrder::TAX1 == $eTreatment)
{
$eTreatment = $ActinicOrder::EXEMPT;
}
elsif ($ActinicOrder::BOTH == $eTreatment)
{
$eTreatment = $ActinicOrder::TAX2;
}
}
if ($::g_TaxInfo{EXEMPT2})
{
if ($ActinicOrder::TAX2 == $eTreatment)
{
$eTreatment = $ActinicOrder::EXEMPT;
}
elsif ($ActinicOrder::BOTH == $eTreatment)
{
$eTreatment = $ActinicOrder::TAX1;
}
}
return ($eTreatment);
}
sub NotifyOfError
{
my ($sError, $bOmitMailDump) = @_;
if ($$::g_pSetupBlob{EMAIL} ne "" && $::g_sSmtpServer ne "")
{
my ($sPrompt1, $sPrompt2, $sPrompt3, $sPrompt4, $sPrompt5);
if (defined $$::g_pPromptList{"-1,1957"}{PROMPT})
{
$sPrompt1 = ACTINIC::GetPhrase(-1, 1957);
$sPrompt2 = ACTINIC::GetPhrase(-1, 1958);
$sPrompt3 = ACTINIC::GetPhrase(-1, 1959);
$sPrompt4 = ACTINIC::GetPhrase(-1, 2097);
$sPrompt5 = ACTINIC::GetPhrase(-1, 2098);
}
else
{
$sPrompt1 = "Following error has been displayed to a customer:\n\n";
$sPrompt2 = "\nDebugging information:\nInput Hash:\n";
$sPrompt3 = "Error in Catalog order";
$sPrompt4 = "Calling Address:";
$sPrompt5 = "Calling Host:";
}
my $sText;
$sText .= $sPrompt1;
$sText .= $sError . "\n\n";
$sText .= GetContactDetailsString();
$sText .= $::ENV{REMOTE_HOST} ? "\n" . $sPrompt5 . " " . $::ENV{REMOTE_HOST} . "\n" : '';
$sText .= $::ENV{REMOTE_ADDR} ? "\n" . $sPrompt4 . " " . $::ENV{REMOTE_ADDR} . "\n" : '';
if(!$bOmitMailDump)
{
$sText .= $sPrompt2;
my $sKey;
foreach $sKey (sort keys %::g_InputHash)
{
my $sValue = $::g_InputHash{$sKey};
if ($sKey =~ /^PAYMENTCARD/i)
{
$sValue =~ s/[a-z0-9]/\*/gi;
}
$sText .= $sKey . ' : "' . $sValue . "\"\n";
}
}
my ($Status, $Message) = ACTINIC::SendMail($::g_sSmtpServer, $$::g_pSetupBlob{EMAIL},
$sPrompt3, $sText);
if ($Status != $::SUCCESS)
{
ACTINIC::RecordErrors($Message, ACTINIC::GetPath());
}
}
return $sError;
}
sub CreateAddressBook
{
if( $ACTINIC::B2B->Get('UserDigest') )
{
return;
}
eval 'require ab000001;';
if ( $@ )
{
ACTINIC::ReportError($@, ACTINIC::GetPath());
}
$::ACT_ADB = ADDRESS_BOOK->new(
FormPrefix			=>	'DELIVER',
FormNames 			=> [	'NAME', 'FIRSTNAME',
'LASTNAME', 'ADDRESS1',
'JOBTITLE',		'COMPANY',
'ADDRESS2',		'ADDRESS3',
'ADDRESS4',		'POSTALCODE',
'COUNTRY',		'PHONE',
'FAX',			'EMAIL',
'USERDEFINED',	'SALUTATION'	],
LocationInfoNames=> [	'DELIVERY_REGION_CODE',
'DELIVERY_COUNTRY_CODE',
'DELIVERPOSTALCODE'	],
DeliveryFormHash => 	\%::g_ShipContact,
LocationHash		=> 	\%::g_LocationInfo,
InputFormHash	 	=> 	\%::g_InputHash,
Nnam_1				=> 	'NAME',
Nnam_2				=> 	'ADDRESS1',
);
if (!defined($::g_InputHash{ADBADD}))
{
$::ACT_ADB->Init();
}	
}
sub ConfigureAddressBook
{
if ($$::g_pSetupBlob{SHOPPER_NAME_HANDLING_MODE} eq 1)
{
$::g_ShipContact{'NAME'}	=  $::g_ShipContact{'FIRSTNAME'}.' '.$::g_ShipContact{'LASTNAME'};
$::g_ShipContact{'NAME'}	=~ s/(.{0,$::g_pFieldSizes->{'NAME'}}).*/$1/;
$::g_InputHash{'DELIVERNAME'}	=  $::g_InputHash{'DELIVERFIRSTNAME'}.' '.$::g_InputHash{'DELIVERLASTNAME'};
$::g_InputHash{'DELIVERNAME'}	=~ s/(.{0,$::g_pFieldSizes->{'NAME'}}).*/$1/;
}
$::ACT_ADB->Set(
OneAddressMessage 	 => 	ACTINIC::GetPhrase(-1, 271),
MoreAddressesMessage => 	ACTINIC::GetPhrase(-1, 272),
StatusMessage 		 => 	ACTINIC::GetPhrase(-1, 273),
MaxAddressesWarning  => 	ACTINIC::GetPhrase(-1, 274, ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor),ACTINIC::GetPhrase(-1, 1970)),
NoAddressesMessage 	 => 	ACTINIC::GetPhrase(-1, 275),
AddMessage 		    => 	ACTINIC::GetPhrase(-1, 276),
DeleteLabel 		    => 	ACTINIC::GetPhrase(-1, 277),
Action			       =>	$::g_InputHash{'ACTION'},
Sequence		       =>	$::g_InputHash{'SEQUENCE'}
);
$::ACT_ADB->Init();
}
sub NotifyMallAdministratorOfNewOrder
{
eval 'require MallInterfaceLayer;';
if ($@)
{
return($::SUCCESS);
}
return (MallInterfaceLayer::NewOrder(ACTINIC::GetPath(), $::g_InputHash{ORDERNUMBER}, $::g_InputHash{SHOP}));
}
sub PrepareOrderTaxOpaqueData
{
my($sKeyPrefix) = @_;
my $sKey = $sKeyPrefix . 'TAX_OPAQUE_DATA';
my ($nTaxID, $sOpaqueData);
foreach $nTaxID (sort keys %$::g_pTaxesBlob)
{
$sOpaqueData .= "$nTaxID\t$$::g_pTaxesBlob{$nTaxID}{$sKey}\n";
}
return($::SUCCESS, '', $sOpaqueData);
}
sub SetXMLFromHash
{
my ($pHashID, $pHash) = @_;
my ($sKey, $sValue);
while (($sKey, $sValue) = each(%$pHashID))
{
if ($$pHash{$sKey} eq "")
{
$ACTINIC::B2B->SetXML($sValue, "");
$ACTINIC::B2B->SetXML($sValue . "_SEP", "");
}
else
{
$ACTINIC::B2B->SetXML($sValue, $$pHash{$sKey} . " ");
$ACTINIC::B2B->SetXML($sValue . "_SEP", "\r\n");
}
}
return($::SUCCESS, '');
}
sub FormatTrackingPage
{
my $sHTML = '';
my $nSSPID = $::g_InputHash{SSP_ID};
my $phashSSPProvider = $$::g_pSSPSetupBlob{$nSSPID};
if (!defined $phashSSPProvider)
{
return($::SUCCESS, '', ACTINIC::GetPhrase(-1, 2271));
}
my %hashVariables;
$hashVariables{$::VARPREFIX.'LICENSEKEY'} = ACTINIC::DecodeXOREncryption($$phashSSPProvider{'AccessKey'}, $::UPS_ENCRYPT_PASSWORD);
$hashVariables{$::VARPREFIX.'TYPEOFINQUIRYNUMBER'} = $::g_InputHash{TrackingType};
my $nMaxTrackingNumbers = $$phashSSPProvider{MaxTrackingNumbers};
my $i;
for($i = 1; $i <= $nMaxTrackingNumbers; $i++)
{
if(defined $::g_InputHash{'NUMBER' . $i})
{
$hashVariables{$::VARPREFIX.'INQUIRYNR' . $i} = $::g_InputHash{'NUMBER' . $i};
}
else
{
$hashVariables{$::VARPREFIX.'INQUIRYNR' . $i} = '';
}
}
$hashVariables{$::VARPREFIX.'INQUIRYNR'} = $::g_InputHash{'NUMBER'};
$hashVariables{$::VARPREFIX.'SENDERSHIPPERNUMBER'} = $::g_InputHash{'ShipperNumber'};
$hashVariables{$::VARPREFIX.'DESTINATIONPOSTALCODE'} = $::g_InputHash{'DestinationPostalCode'};
$hashVariables{$::VARPREFIX.'DESTINATIONCOUNTRY'} = $::g_InputHash{'DestinationCountry'};
$hashVariables{$::VARPREFIX.'FROMPICKUPMONTH'} = $::g_InputHash{'FromPickupMonth'};
$hashVariables{$::VARPREFIX.'FROMPICKUPDAY'} = $::g_InputHash{'FromPickupDay'};
$hashVariables{$::VARPREFIX.'FROMPICKUPYEAR'} = $::g_InputHash{'FromPickupYear'};
$hashVariables{$::VARPREFIX.'TOPICKUPMONTH'} = $::g_InputHash{'ToPickupMonth'};
$hashVariables{$::VARPREFIX.'TOPICKUPDAY'} = $::g_InputHash{'ToPickupDay'};
$hashVariables{$::VARPREFIX.'TOPICKUPYEAR'} = $::g_InputHash{'ToPickupYear'};
$ACTINIC::B2B->SetXML('FORWARDMESSAGE', ACTINIC::GetPhrase(-1, 2272));
my @Response = ACTINIC::TemplateFile(ACTINIC::GetPath() . $$phashSSPProvider{TrackingTemplate}, \%hashVariables);
if($Response[0] != $::SUCCESS)
{
return(@Response);
}
$sHTML = $Response[2];
return($::SUCCESS, '', $sHTML);
}
sub GetContactDetailsString
{
my $sText;
$sText .= ACTINIC::GetPhrase(-1, 339) . "\n";
unless (ACTINIC::IsPromptHidden(0, 0))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 0)  . " $::g_BillContact{'SALUTATION'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 1))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 1)  . " $::g_BillContact{'NAME'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 21))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 21)  . " $::g_BillContact{'FIRSTNAME'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 22))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 22)  . " $::g_BillContact{'LASTNAME'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 2))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 2)  . " $::g_BillContact{'JOBTITLE'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 3))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 3)  . " $::g_BillContact{'COMPANY'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 4))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 4)  . " $::g_BillContact{'ADDRESS1'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 5))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 5)  . " $::g_BillContact{'ADDRESS2'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 6))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 6)  . " $::g_BillContact{'ADDRESS3'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 7))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 7)  . " $::g_BillContact{'ADDRESS4'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 8))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 8)  . " $::g_BillContact{'POSTALCODE'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 9))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 9)  . " $::g_BillContact{'COUNTRY'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 10))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 10) . " $::g_BillContact{'PHONE'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 20))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 20) . " $::g_BillContact{'MOBILE'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 11))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 11) . " $::g_BillContact{'FAX'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 12))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 12) . " $::g_BillContact{'EMAIL'}\n";
}
unless (ACTINIC::IsPromptHidden(0, 13))
{
$sText .= "\t" . ACTINIC::GetPhrase(0, 13) . " $::g_BillContact{'USERDEFINED'}\n";
}
$sText .= "\n" . ACTINIC::GetPhrase(-1, 340) . "\n";
unless (ACTINIC::IsPromptHidden(1, 0))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 0)  . " $::g_ShipContact{'SALUTATION'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 1))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 1)  . " $::g_ShipContact{'NAME'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 21))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 21)  . " $::g_ShipContact{'FIRSTNAME'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 22))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 22)  . " $::g_ShipContact{'LASTNAME'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 2))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 2)  . " $::g_ShipContact{'JOBTITLE'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 3))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 3)  . " $::g_ShipContact{'COMPANY'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 4))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 4)  . " $::g_ShipContact{'ADDRESS1'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 5))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 5)  . " $::g_ShipContact{'ADDRESS2'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 6))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 6)  . " $::g_ShipContact{'ADDRESS3'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 7))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 7)  . " $::g_ShipContact{'ADDRESS4'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 8))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 8)  . " $::g_ShipContact{'POSTALCODE'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 9))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 9)  . " $::g_ShipContact{'COUNTRY'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 10))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 10) . " $::g_ShipContact{'PHONE'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 20))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 20) . " $::g_ShipContact{'MOBILE'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 11))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 11) . " $::g_ShipContact{'FAX'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 12))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 12) . " $::g_ShipContact{'EMAIL'}\n";
}
unless (ACTINIC::IsPromptHidden(1, 13))
{
$sText .= "\t" . ACTINIC::GetPhrase(1, 13) . " $::g_ShipContact{'USERDEFINED'}\n";
}
return ($sText);
}
sub FormatShippingOpaqueData
{
my ($phashShippingDetails, $bParentExcluded) = @_;
my $sOpaqueData = $phashShippingDetails->{'OPAQUE_SHIPPING_DATA'};
$sOpaqueData .= ";ALT_WEIGHT=$phashShippingDetails->{'ALT_WEIGHT'}";
$sOpaqueData .= ";EXCLUDE_FROM_SHIP=$phashShippingDetails->{'EXCLUDE_FROM_SHIP'}";
$sOpaqueData .= ";SHIP_CATEGORY=$phashShippingDetails->{'SHIP_CATEGORY'}";
$sOpaqueData .= ";SHIP_QUANTITY=$phashShippingDetails->{'SHIP_QUANTITY'}";
$sOpaqueData .= ";SHIP_SUPPLEMENT=$phashShippingDetails->{'SHIP_SUPPLEMENT'}";
$sOpaqueData .= ";SHIP_SUPPLEMENT_ONCE=$phashShippingDetails->{'SHIP_SUPPLEMENT_ONCE'}";
$sOpaqueData .= ";HAND_SUPPLEMENT=$phashShippingDetails->{'HAND_SUPPLEMENT'}";
$sOpaqueData .= ";HAND_SUPPLEMENT_ONCE=$phashShippingDetails->{'HAND_SUPPLEMENT_ONCE'}";
$sOpaqueData .= ";EXCLUDE_PARENT=$bParentExcluded";
$sOpaqueData .= ";SEP_LINE=$phashShippingDetails->{'SEPARATE_LINE'}";
$sOpaqueData .= ";USE_ASSOC_SHIP=$phashShippingDetails->{'USE_ASSOCIATED_SHIP'}";
if($phashShippingDetails->{SHIP_SEPARATELY})
{
$sOpaqueData .= ';SEPARATE;';
}
else
{
$sOpaqueData .= ';';
}
return ($sOpaqueData);
}
sub SaveAuthCallback
{
if ((!defined $::g_InputHash{ON}) ||
($::g_InputHash{ON} eq ""))
{
ACTINIC::RecordErrors("No ON field", ACTINIC::GetPath());
return;
}
my ($sFilename) = ACTINIC::GetPath() . $::g_InputHash{ON} . ".html";
ACTINIC::SecurePath($sFilename);
unless (open (WBFILE, ">$sFilename"))
{
ACTINIC::RecordErrors("Unable to open $sFilename for writing: $!", ACTINIC::GetPath());
return;
}
my	$sCgiUrl;
if ($$::g_pSetupBlob{'SSL_USEAGE'} eq 1)
{
$sCgiUrl = $$::g_pSetupBlob{SSL_CGI_URL};
}
else
{
$sCgiUrl = $$::g_pSetupBlob{CGI_URL};
}
my ($sActionURL) = sprintf("%sos%6.6d%s", $sCgiUrl, $$::g_pSetupBlob{CGI_ID}, $$::g_pSetupBlob{CGI_EXT});
print WBFILE '<html><head></head><body><br/>';
print WBFILE sprintf('<form method=POST action=%s>', $sActionURL);
my ($sKey, $sValue);
print WBFILE '<table>';
while (($sKey, $sValue) = each %::g_InputHash)
{
print WBFILE sprintf('<tr><td>%s:</td><td><input type="text" name="%s" value="%s"/></td></tr>', $sKey, $sKey, $sValue);
}
print WBFILE '</table>';
print WBFILE '<input type="submit" name="DOIT" value="Send" />';
print WBFILE '</form>';
print WBFILE '</body></html>';
close (WBFILE);
chmod 0644, $sFilename;
}
sub GetCheckoutBaseUrl
{
my		$sCgiUrl;
if ($$::g_pSetupBlob{'SSL_USEAGE'} eq 1)
{
$sCgiUrl = $$::g_pSetupBlob{SSL_CGI_URL};
}
else
{
$sCgiUrl = $$::g_pSetupBlob{CGI_URL};
}
return (sprintf("%sos%6.6d%s?%s", $sCgiUrl, $$::g_pSetupBlob{CGI_ID}, $$::g_pSetupBlob{CGI_EXT},
($::g_InputHash{SHOP} ? 'SHOP=' . ACTINIC::EncodeText2($::g_InputHash{SHOP}, $::FALSE) . '&' : '')));
}
sub PSPUsesInContext
{
my ($subref, $bInContext);
if ($subref = ACTINIC::Function_Exists("main::IsInContextPSP"))
{
$bInContext = $subref->();
}
LogData(sprintf("PSPUsesInContext returning %s", ($bInContext) ? "TRUE" : "FALSE"));
return ($bInContext);
}
sub PSPUsesAuthoriseFile
{
my ($subref, $bUsesAuthoriseFile);
$bUsesAuthoriseFile = $::TRUE;
if ($subref = ACTINIC::Function_Exists("main::UseAuthoriseFile"))
{
$bUsesAuthoriseFile = $subref->();
}
LogData(sprintf("PSPUsesAuthoriseFile returning %s", ($bUsesAuthoriseFile) ? "TRUE" : "FALSE"));
return ($bUsesAuthoriseFile);
}
sub CallPspCheckoutMethod
{
$::g_PaymentInfo{'METHOD'} = shift;
my $sMethod = shift;
if (!defined $$::g_pPaymentList{$::g_PaymentInfo{'METHOD'}} ||
!$$::g_pPaymentList{$::g_PaymentInfo{'METHOD'}}{ENABLED})
{
return ($::FAILURE, 'Unsupported action '. $::g_InputHash{'ACTION'});
}
my @Response = GetOCCScript(ACTINIC::GetPath());
if ($Response[0] != $::SUCCESS)
{
return ($::FAILURE, $Response[1]);
}
if (eval($Response[2]) != $::SUCCESS)
{
return ($::FAILURE, ACTINIC::GetPhrase(-1, 170, substr($@, 0, 200)));
}
my $subref;
if (!($subref = ACTINIC::Function_Exists("main::$sMethod")))
{
return ($::FAILURE, "The method $sMethod is not defined in the PSP script for " . $$::g_pPaymentList{$::g_PaymentInfo{'METHOD'}}{PROMPT});
}
return($subref->());
}
sub CloneSession
{
my $bPSPRequested = shift;
if (!defined $bPSPRequested)
{
$bPSPRequested = $::TRUE;
}
$::Session->SetPSPRequested($bPSPRequested);
my ($bPaymentMade) = $::Session->IsPaymentMade();
$::Session->PaymentMade();
if (ActinicOrder::IsDDProductInCart() &&
$bPSPRequested)
{
LogData("Saving email to disk");
EmailReceipt($::g_PaymentInfo{'ORDERNUMBER'}, $::FALSE);
}
if (!$bPaymentMade)
{
$::Session->ClearPaymentMade();
}
$::Session->CloneSession($::g_PaymentInfo{'ORDERNUMBER'});
LogData('Authorise file created for order ' . $::g_PaymentInfo{'ORDERNUMBER'});
}
sub GetPspPendingNotice
{
my $nPsp = shift;
my $subref;
if (!($subref = ACTINIC::Function_Exists("main::GetPspPendingNotice_$nPsp")))
{
return ('');
}
return ($subref->());
}
sub DisplayShippingConfirmation
{
my %hVariableTable;
if ($::g_PaymentInfo{METHOD} == $::PAYMENT_AMAZONPAY)
{
$hVariableTable{$::VARPREFIX.'AMAZONORDERREFERENCE'} = GetSessionParam($::AMAZONPAY_SESSION_ORDER_REF);
}
my @aDeleteDelimiters;
my @aKeepDelimiters;
my ($Message, $Status);
my ($sError) = @_;
my $bInvoiceUsesRegion = $::FALSE;
my $bShipSeparately = ($::g_LocationInfo{SEPARATESHIP} ne '');
if(defined $$::g_pLocationList{INVOICEADDRESS4} &&
$$::g_pLocationList{INVOICEADDRESS4})
{
$bInvoiceUsesRegion = $::TRUE;
$::g_BillContact{ADDRESS4} = ActinicLocations::GetInvoiceAddressRegionName($::g_BillContact{ADDRESS4});
}
if(defined $$::g_pLocationList{DELIVERADDRESS4} &&
$$::g_pLocationList{DELIVERADDRESS4})
{
$::g_ShipContact{ADDRESS4} = ActinicLocations::GetDeliveryAddressRegionName($::g_ShipContact{ADDRESS4});
if (!$bInvoiceUsesRegion &&
!$bShipSeparately)
{
$::g_BillContact{ADDRESS4} = ActinicLocations::GetInvoiceAddressRegionName($::g_BillContact{ADDRESS4});
}
}
else
{
if ($bInvoiceUsesRegion &&
!$bShipSeparately)
{
$::g_ShipContact{ADDRESS4} = ActinicLocations::GetDeliveryAddressRegionName($::g_ShipContact{ADDRESS4});
}
}
my $bKeepDelivery4Change = $::FALSE;
my $bKeepInvoice4Change = $::FALSE;
if ((ActinicOrder::StateRequiredForValidation('Delivery', $::g_LocationInfo{DELIVERY_COUNTRY_CODE})) &&
($::g_LocationInfo{DELIVERY_REGION_CODE} eq $ActinicOrder::UNDEFINED_REGION))
{
$bKeepDelivery4Change = $::TRUE;
}
if ((ActinicOrder::StateRequiredForValidation('Invoice', $::g_LocationInfo{INVOICE_COUNTRY_CODE})) &&
($::g_LocationInfo{INVOICE_REGION_CODE} eq $ActinicOrder::UNDEFINED_REGION))
{
if ($::g_LocationInfo{SEPARATESHIP} ne '')
{
$bKeepInvoice4Change = $::TRUE;
}
else
{
$bKeepDelivery4Change = $::TRUE;
}
}
if ($bKeepDelivery4Change)
{
push (@aKeepDelimiters, 'DELIVERYADDR4CHANGE');
}
else
{
push (@aDeleteDelimiters, 'DELIVERYADDR4CHANGE');
}
if ($bKeepInvoice4Change)
{
push (@aKeepDelimiters, 'INVOICEADDR4CHANGE');
}
else
{
push (@aDeleteDelimiters, 'INVOICEADDR4CHANGE');
}
my ($sTemp, @Response);
$hVariableTable{$::VARPREFIX.'YOURRECEIPT'} 		= ACTINIC::GetPhrase(-1, 336);
$hVariableTable{$::VARPREFIX.'PRINTTHISPAGE'} 	= ACTINIC::GetPhrase(-1, 337);
$hVariableTable{$::VARPREFIX.'NEEDTOCONTACT'} 	= ACTINIC::GetPhrase(-1, 338);
$hVariableTable{$::VARPREFIX.'INVOICETO'} 		= ACTINIC::GetPhrase(-1, 339);
$hVariableTable{$::VARPREFIX.'DELIVERTO'} 		= ACTINIC::GetPhrase(-1, 340);
$hVariableTable{$::VARPREFIX.'DATETEXT'} 			= ACTINIC::GetPhrase(-1, 342);
$hVariableTable{$::VARPREFIX.'MOVING'} = $::g_BillContact{'MOVING'} ? ACTINIC::GetPhrase(-1, 1914) : ACTINIC::GetPhrase(-1, 1915);
my ($sInvoiceName);
undef $sTemp;
if ((length $::g_BillContact{'NAME'}) > 0)
{
$sTemp = $::g_BillContact{'SALUTATION'} . " " . $::g_BillContact{'NAME'};
@Response = ACTINIC::EncodeText($sTemp);
$sInvoiceName .= $Response[1] . "<BR>\n";
}
$hVariableTable{$::VARPREFIX.'INVOICENAME'} = $sInvoiceName;
my ($sDeliveryName);
if ((length $::g_ShipContact{'NAME'}) > 0)
{
$sTemp = $::g_ShipContact{'SALUTATION'} . " " . $::g_ShipContact{'NAME'};
@Response = ACTINIC::EncodeText($sTemp);
$sDeliveryName .= $Response[1] . "<BR>\n";
}
$hVariableTable{$::VARPREFIX.'DELIVERYNAME'} = $sDeliveryName;
if (ACTINIC::IsPromptHidden(0, 13))
{
push (@aDeleteDelimiters, 'MOVINGSTATUS');
}
else
{
push (@aKeepDelimiters, 'MOVINGSTATUS');
}
if (!$::g_ShipInfo{'USERDEFINED'})
{
push (@aDeleteDelimiters, 'DELIVERYINSTRUCTION');
}
else
{
$hVariableTable{$::VARPREFIX.'DELIVERYINSTRUCTION_LABEL'} = ACTINIC::GetPhrase(-1, 2044);
$hVariableTable{$::VARPREFIX.'DELIVERYINSTRUCTION_TEXT'} = $::g_ShipInfo{'USERDEFINED'};
push (@aKeepDelimiters, 'DELIVERYINSTRUCTION');
}
my ($status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters) = ActinicOrder::DisplayShipChargePhase();
if ($status != $::SUCCESS)
{
my $sDeliveryCountry = ACTINIC::GetCountryName($::g_LocationInfo{DELIVERY_COUNTRY_CODE});
if ($::g_BillContact{COUNTRY} eq $sDeliveryCountry &&
!$$::g_pLocationList{EXPECT_INVOICE})
{
undef $::g_BillContact{COUNTRY};
}
if ($::g_ShipContact{COUNTRY} eq $sDeliveryCountry)
{
undef $::g_ShipContact{COUNTRY};
}
}
%hVariableTable = ACTINIC::MergeHashesToArray(\%hVariableTable, $pVarTable);
push (@aDeleteDelimiters, @$pDeleteDelimiters);
push (@aKeepDelimiters, @$pKeepDelimiters);
($pVarTable, $pDeleteDelimiters, $pKeepDelimiters) = ActinicOrder::DisplayGeneralPhase();
%hVariableTable = ACTINIC::MergeHashesToArray(\%hVariableTable, $pVarTable);
push (@aDeleteDelimiters, @$pDeleteDelimiters);
push (@aKeepDelimiters, @$pKeepDelimiters);
($status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters) = ActinicOrder::DisplayTaxPhase();
if ($status != $::SUCCESS)
{
return ($status, $sMessage);
}
%hVariableTable = ACTINIC::MergeHashesToArray(\%hVariableTable, $pVarTable);
push (@aDeleteDelimiters, @$pDeleteDelimiters);
push (@aKeepDelimiters, @$pKeepDelimiters);
($pDeleteDelimiters, $pKeepDelimiters) = ActinicOrder::ParseDelimiterStatus($::TAXCHARGEPHASE);
push (@aDeleteDelimiters, @$pDeleteDelimiters);
push (@aKeepDelimiters, @$pKeepDelimiters);
$hVariableTable{$::VARPREFIX.'COUPONCODE'} = ACTINIC::EncodeText2($::g_PaymentInfo{'COUPONCODE'});
if ($::g_BillContact{'AGREEDTANDC'})
{
$hVariableTable{$::VARPREFIX.'INVOICEAGREETERMSCONDITIONS'} = 'CHECKED';
}
else
{
$hVariableTable{$::VARPREFIX.'INVOICEAGREETERMSCONDITIONS'} = '';
}
my $sWarning;
if ($::g_PaymentInfo{METHOD} == $::PAYMENT_AMAZONPAY)
{
if ($::TESTMODE)
{
push (@aKeepDelimiters, 'AMAZONPAYSIMULATION');
}
else
{
push (@aDeleteDelimiters, 'AMAZONPAYSIMULATION');
}
push (@aDeleteDelimiters, 'SIMPLESUBMIT');
push (@aKeepDelimiters, 'AMAZONPAYSUBMIT');
}
else
{
$sWarning = '<div align="center">' . ACTINIC::GetPhrase(-1, 1962) . ACTINIC::GetPhrase(-1, 1971) . ACTINIC::GetPhrase(-1, 1974);
if ($$::g_pSetupBlob{'CHECKOUT_NEEDS_TERMS_AGREED'}) # T&C flag is used			
{
$sWarning .= ACTINIC::GetPhrase(-1, 3024);
}
else
{
$sWarning .= ACTINIC::GetPhrase(-1, 3025);
}
$sWarning .= ACTINIC::GetPhrase(-1, 1975) . ACTINIC::GetPhrase(-1, 1970) . ACTINIC::GetPhrase(-1, 1970) . '</div><p>';
push (@aDeleteDelimiters, 'AMAZONPAYSIMULATION');
push (@aKeepDelimiters, 'SIMPLESUBMIT');
push (@aDeleteDelimiters, 'AMAZONPAYSUBMIT');
}
if (length $hVariableTable{$::VARPREFIX.'ERROR'})
{
$sError .= ' ' . $hVariableTable{$::VARPREFIX.'ERROR'};
}
$sError = ACTINIC::GroomError($sError);
$hVariableTable{$::VARPREFIX.'ERROR'} = $sWarning . $sError;
my $sFileName = 'PPOrderConfirm.html';
my $sPath = ACTINIC::GetPath();
@Response = $::Session->GetCartObject($::FALSE);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my $pCartObject = $Response[2];
my $pCartList = $pCartObject->GetCartList();
@Response = ActinicOrder::GenerateShoppingCartLines($pCartList, $::FALSE, [], $sFileName);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
@Response = ACTINIC::TemplateFile($sPath.$sFileName, \%hVariableTable);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my ($sDigest,$sBaseFile) = ACTINIC::CaccGetCookies();
$sPath = ($sBaseFile) ? $sBaseFile : $::g_sContentUrl;
@Response = ACTINIC::MakeLinksAbsolute($Response[2], $::g_sWebSiteUrl, $sPath);
if ($Response[0] != $::SUCCESS)
{
return (@Response);
}
my ($sHTML) = $Response[2];
my ($sDelimiter);
foreach $sDelimiter (@aDeleteDelimiters)
{
$sHTML =~ s/$::DELPREFIX$sDelimiter(.*?)$::DELPREFIX$sDelimiter//gs;
}
foreach $sDelimiter (@aKeepDelimiters)
{
$sHTML =~ s/$::DELPREFIX$sDelimiter//gs;
}
{
my $sSelectName = 'LocationInvoiceCountry';
my $sDefaultOption = $::g_LocationInfo{INVOICE_COUNTRY_CODE};
$sHTML =~ s/(<\s*SELECT[^>]+?NAME\s*=\s*("|')?$sSelectName.+?)<OPTION\s+VALUE\s*=\s*("|')?$sDefaultOption("|')?\s*>/$1<option selected value="$sDefaultOption">/is;
$sSelectName = 'LocationDeliveryCountry';
$sDefaultOption = $::g_LocationInfo{DELIVERY_COUNTRY_CODE};
$sHTML =~ s/(<\s*SELECT[^>]+?NAME\s*=\s*("|')?$sSelectName.+?)<OPTION\s+VALUE\s*=\s*("|')?$sDefaultOption("|')?\s*>/$1<option selected value="$sDefaultOption">/is;
}
$::g_PaymentInfo{'ORDERTOTAL'} = ActinicOrder::GetOrderTotal($::TRUE);
UpdateCheckoutRecord();
return ($::SUCCESS, "", $sHTML);
}
sub ValidateOrderConfirmation
{
my $sError = ValidateGeneral($::TRUE);
my @Response;
$::g_BillContact{'AGREEDTANDC'}	= (defined $::g_InputHash{'AGREETERMSCONDITIONS'} && $::g_InputHash{'AGREETERMSCONDITIONS'} ne "") ? $::TRUE : $::FALSE;
if ($$::g_pDiscountBlob{'COUPON_ON_CHECKOUT'})
{
$::Session->GetCartObject();
if (ActinicDiscounts::IsMultipleFixedPriceCouponAccepted())
{			
if ($::g_InputHash{'COUPONCODE'} ne "")
{
@Response = ActinicDiscounts::ValidateCoupon($::g_InputHash{'COUPONCODE'});
if ($Response[0] == $::FAILURE)
{
$sError .= ACTINIC::GetPhrase(-1, 1971,  $::g_sRequiredColor) . $Response[1] . ACTINIC::GetPhrase(-1, 1970);
}
}
elsif ($::Session->GetCSVCouponCodes() ne $::Session->GetCSVCouponCodesOrig())
{				
$sError .= ACTINIC::GetPhrase(-1, 1971,  $::g_sRequiredColor) . "Your order may have changed due to a change with the coupon code(s). Please recheck your order." . ACTINIC::GetPhrase(-1, 1970);
$::Session->SetCSVCouponCodesOrig($::Session->GetCSVCouponCodes());
}
}
elsif ($::g_InputHash{'COUPONCODE'} ne "")
{
@Response = ActinicDiscounts::ValidateCoupon($::g_InputHash{'COUPONCODE'});
if ($Response[0] == $::FAILURE)
{
$sError .= ACTINIC::GetPhrase(-1, 1971,  $::g_sRequiredColor) . $Response[1] . ACTINIC::GetPhrase(-1, 1970);
}
elsif ($::g_PaymentInfo{'COUPONCODE'} ne $::g_InputHash{'COUPONCODE'})
{
$sError .= ACTINIC::GetPhrase(-1, 1971,  $::g_sRequiredColor) . "Your order may have changed due to a change with the coupon code. Please recheck your order." . ACTINIC::GetPhrase(-1, 1970);
}
$::g_PaymentInfo{'COUPONCODE'} = $::g_InputHash{'COUPONCODE'};
}
}
if ($$::g_pSetupBlob{'CHECKOUT_NEEDS_TERMS_AGREED'} &&
!$::g_BillContact{'AGREEDTANDC'})
{
$sError .= ACTINIC::GetPhrase(-1, 2385);
}
if (ACTINIC::IsPromptRequired(0, 14) &&
$::g_BillContact{'USERDEFINED'} eq "" &&
!$ACTINIC::B2B->Get('UserDigest'))
{
$sError .= ACTINIC::GetRequiredMessage(0, 14);
}
if (length $::g_BillContact{'USERDEFINED'} > $::g_pFieldSizes->{'USERDEFINED'})
{
$sError .= ACTINIC::GetLengthFailureMessage(0, 14, $::g_pFieldSizes->{'USERDEFINED'});
}
if ($sError eq '')
{
$sError .= ValidateShipCharge($::TRUE);
}
if ($sError eq '')
{
if ($::g_PaymentInfo{'ORDERTOTAL'} != ActinicOrder::GetOrderTotal($::TRUE))
{
$sError = ACTINIC::GetPhrase(-1, 1971,  $::g_sRequiredColor) . "Your order value has changed due to the changes you made. Please recheck your order." . ACTINIC::GetPhrase(-1, 1970);
}
}
UpdateCheckoutRecord();
return ($sError);
}
sub CheckV12StatusFlag	
{
my $nFlag = $::g_pStatesToFlags->{$::g_InputHash{'Status'}};
if (!$nFlag ||
$::g_InputHash{'Flag'} != $nFlag)
{
my $sMsg = sprintf("Unexpected response from the V12 server<br>Status:%s Flag:%d", 
$::g_InputHash{'Status'}, $::g_InputHash{'Flag'});
return ($::FAILURE, $sMsg);
}
return ($::SUCCESS, "");
}
package OrderBlob;
sub new
{
my ($Proto, $parrType, $parrValue) = @_;
my $sClass = ref($Proto) || $Proto;
my $Self  = {};
bless ($Self, $sClass);
$Self->{_TYPES}	= $parrType;
$Self->{_VALUES}	= $parrValue;
return($Self);
}
sub AddByte
{
my ($Self, $nValue) = @_;
push @{$Self->{_TYPES}}, $::RBBYTE;
push @{$Self->{_VALUES}}, $nValue;
}
sub AddWord
{
my ($Self, $nValue) = @_;
push @{$Self->{_TYPES}}, $::RBWORD;
push @{$Self->{_VALUES}}, $nValue;
}
sub AddDWord
{
my ($Self, $nValue) = @_;
push @{$Self->{_TYPES}}, $::RBDWORD;
push @{$Self->{_VALUES}}, $nValue;
}
sub AddQWord
{
my ($Self, $nValue) = @_;
push @{$Self->{_TYPES}}, $::RBQWORD;
push @{$Self->{_VALUES}}, $nValue;
}
sub AddString
{
my ($Self, $sValue) = @_;
push @{$Self->{_TYPES}}, $::RBSTRING;
push @{$Self->{_VALUES}}, $sValue;
}
sub AddContact
{
my ($Self, $pContact) = @_;
$Self->AddString($$pContact{'NAME'});
$Self->AddString($$pContact{'FIRSTNAME'});
$Self->AddString($$pContact{'LASTNAME'});
$Self->AddString($$pContact{'SALUTATION'});
$Self->AddString($$pContact{'JOBTITLE'});
$Self->AddString($$pContact{'COMPANY'});
$Self->AddString($$pContact{'ADDRESS1'});
$Self->AddString($$pContact{'ADDRESS2'});
$Self->AddString($$pContact{'ADDRESS3'});
$Self->AddString($$pContact{'REGION'});
$Self->AddString($$pContact{'COUNTRY'});
$Self->AddString($$pContact{'POSTALCODE'});
$Self->AddString($$pContact{'PHONE'});
$Self->AddString($$pContact{'MOBILE'});
$Self->AddString($$pContact{'FAX'});
$Self->AddString($$pContact{'EMAIL'});
$Self->AddString($$pContact{'USERDEFINED'});
if (! defined $$pContact{PRIVACY} ||
$$pContact{PRIVACY} eq '')
{
$$pContact{PRIVACY} = $::FALSE;
}
$Self->AddByte($$pContact{'PRIVACY'});
}
sub AddAdjustment
{
my ($Self, $nOrderSequenceNumber, $parrAdjustDetails, $pProduct) = @_;
my $nAmount = $parrAdjustDetails->[$::eAdjIdxAmount];
$Self->AddWord($ACTINIC::ORDER_DETAIL_BLOB_MAGIC);
$Self->AddByte($::ORDER_DETAIL_BLOB_VERSION);
$Self->AddString($parrAdjustDetails->[$::eAdjIdxProductRef]);
$Self->AddString($parrAdjustDetails->[$::eAdjIdxProductDescription]);
$Self->AddDWord(0);
$Self->AddQWord($nAmount);
$Self->AddQWord($nAmount);
$Self->AddQWord(0);
$Self->AddString('');
$Self->AddString('');
$Self->AddString('');
$Self->AddString('');
$Self->AddDWord(0);
$Self->AddDWord(0);
my $rarrTaxOpaqueData = ActinicOrder::PricesIncludeTaxes() ?
$parrAdjustDetails->[$::eAdjIdxDefOpaqueData] :
$parrAdjustDetails->[$::eAdjIdxCurOpaqueData];
$Self->AddString($rarrTaxOpaqueData->[0]);
$Self->AddString($rarrTaxOpaqueData->[1]);
my $nTax = $parrAdjustDetails->[$::eAdjIdxTax1];
if ($::g_TaxInfo{'EXEMPT1'} ||
!ActinicOrder::IsTaxApplicableForLocation('TAX_1'))
{
if (ActinicOrder::PricesIncludeTaxes())
{
$nTax = -$nTax;
}
}
$Self->AddQWord($nTax);
$nTax = $parrAdjustDetails->[$::eAdjIdxTax2];
if ($::g_TaxInfo{'EXEMPT2'} ||
!ActinicOrder::IsTaxApplicableForLocation('TAX_2'))
{
if (ActinicOrder::PricesIncludeTaxes())
{
$nTax = -$nTax;
}
}
$Self->AddQWord($nTax);
$Self->AddString('');
$Self->AddQWord(0);
$Self->AddDWord(0);
$Self->AddDWord(0);
$Self->AddString('');
my @arrResponse;
if($pProduct)
{
@arrResponse = ActinicOrder::PrepareProductTaxOpaqueData($pProduct,
$nAmount, $$pProduct{'PRICE'}, $parrAdjustDetails->[$::eAdjIdxCustomTaxAsExempt]);
}
else
{
@arrResponse = ActinicOrder::PrepareProductTaxOpaqueData(undef,
$nAmount, $nAmount, $::FALSE, $ActinicOrder::PRORATA);
}
$Self->AddString($arrResponse[2]);
$Self->AddByte(0);
$Self->AddByte(0);
$Self->AddByte($parrAdjustDetails->[$::eAdjIdxLineType]);
$Self->AddDWord($nOrderSequenceNumber);
$Self->AddByte($parrAdjustDetails->[$::eAdjIdxTaxTreatment]);
$Self->AddString($parrAdjustDetails->[$::eAdjIdxCouponCode]);
$Self->AddByte(0);
$Self->AddString('');
$Self->AddString('');
$Self->AddString('');
$Self->AddString('');
$Self->AddString('');
}