#!/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 ao000001; require sm000001; require mp000001; use strict; Init(); DispatchCommands(); exit; sub DispatchCommands { my (@Response, $Status, $Message, $sHTML, $sAction, $sCartID); $::g_sCurrentPage = $::g_InputHash{"PAGE"}; $sAction = $::g_InputHash{"ACTION"}; my ($key, $value); if ($sAction eq "REGQUERY") { SendRegInfo(); exit; } elsif ($sAction eq "FEEFOXML") { FeefoXMLWrapper(); exit; } elsif ($sAction eq "GETUSEDCOUPONS") { ($Status, $Message, $sHTML) = GetUsedCoupons(); PrintPageAjax($sHTML, 'text/html'); exit; } elsif ($sAction eq "COOKIEERROR") { $::bCookieCheckRequired = $::FALSE; my $sMessage = ACTINIC::GetPhrase(-1, 52) . "\n"; ($Status, $Message, $sHTML) = ReturnToLastPage(-1, $sMessage, ACTINIC::GetPhrase(-1, 53)); PrintPage($sHTML, $sCartID); exit; } elsif ($$::g_pSetupBlob{CATALOG_SUSPENDED}) { @Response = ReturnToLastPage(7, ACTINIC::GetPhrase(-1, 2077), ""); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } @Response = BounceHelper($sHTML); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } PrintPage($sHTML); } elsif ((($sAction eq $::g_sSendCouponLabel) || ($sAction eq $::g_sApplyCouponLabel)) || (($sAction eq "") && ($::g_InputHash{'COUPONCODE'} ne ""))) { RecordCouponCode(); exit; } elsif ($sAction eq "REMOVECOUPON") { my $nIndex = $::g_InputHash{"COUPONINDEX"}; ActinicDiscounts::RemoveCouponCode($nIndex); if ($::g_InputHash{"SHOWNOCART"}) { if (defined $::Session) { $::Session->SaveSession(); } ($Status, $Message, $sHTML) = GetUsedCoupons(); PrintPageAjax($sHTML, 'text/html'); exit; } ShowCart(); } elsif ($sAction eq "SSLBOUNCE") { PrintSSLBouncePage(); exit; } elsif ($sAction eq "SHOWCART") { ShowCart(); } elsif ($::g_sCurrentPage eq "PRODUCT") { my ($ProductRef, $ProductID); my $bAddToWishList = $::FALSE; my ($bWishListVarDefined, $bWishListEnabled) = ACTINIC::IsCustomVarDefined("IsWishListEnabled"); if ($bWishListEnabled) { foreach (keys %::g_InputHash) { if( $_ =~ /^WL_/) { $ProductRef = $'; $ProductRef =~ s/\.[xy]$//; $ProductRef =~ s/_.*//g; $ProductID = $ProductRef; $ProductRef =~ s/^\d+\!//g; $bAddToWishList = $::TRUE; last; } } } if (!$bAddToWishList) { ProcessAddToCartCall(); } else { my @Response = ValidateWishListItem(); if ($Response[0] != $::SUCCESS) { PrintPage($Response[2], $Response[3]); exit; } my $sCgiURL = $::g_sWishListScript . "?ACTION=ADD&PRODREF=$ProductRef&SID=" . $::g_InputHash{SID} . "&Q_$ProductRef=" . $::g_InputHash{"Q_$ProductID"}; $::g_InputHash{JS}='1'; my $sKey; foreach $sKey (sort keys %::g_InputHash) { if(($sKey =~ /v_$ProductRef\_(\d+)/) || ($sKey =~ /O_$ProductRef$/) || ($sKey =~ /Y_$ProductRef$/) || ($sKey =~ /M_$ProductRef$/) || ($sKey =~ /DAY_$ProductRef$/)) { $sCgiURL .= sprintf("&%s=%s", $sKey, $::g_InputHash{$sKey}); } } if (defined $::g_InputHash{"AJAX"}) { if (($::Session->GetWishListDigest()) || ($ACTINIC::B2B->Get('UserDigest'))) { PrintPageAjax('{"result":"OK"}', 'application/json'); } else { PrintPageAjax('{"result":"ENFORCE_LOGIN","redirectUrl":"' . $sCgiURL . '"}', 'application/json'); } exit; } if ($::g_InputHash{NEXT_ACTION} eq 'GO_BACK') { $sCgiURL .= "&NEXT_ACTION=GO_BACK"; } my ($bClearFrames) = $::FALSE; @Response = ACTINIC::BounceToPagePlain(0, "", $$::g_pSetupBlob{CHECKOUT_DESCRIPTION}, $::g_sWebSiteUrl, $::g_sContentUrl, $::g_pSetupBlob, $sCgiURL , \%::g_InputHash, $bClearFrames); my ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } PrintPage($sHTML); exit; } } elsif ($::g_sCurrentPage eq "ORDERDETAIL") { if ($sAction eq $::g_sCancelButtonLabel) { @Response = ReturnToLastPage(0, "", ""); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } PrintPage($sHTML); } else { my %OrderDetails; ($Status, $Message, %OrderDetails) = ValidateOrderDetails($::FALSE); if ($Status == $::BADDATA) { $sHTML = $Message; PrintPage($sHTML, $sCartID); exit; } elsif ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); } AddItemToCart(\%OrderDetails); @Response = BounceAfterAddToCart(); ($Status, $Message, $sHTML, $sCartID) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } PrintPage($sHTML, $sCartID); } } else { exit; } } sub RecordCouponCode { my $sErrorMessage; my @Response = $::Session->GetCartObject(); if ($::g_InputHash{'COUPONCODE'} ne "" && $$::g_pDiscountBlob{'COUPON_ON_PRODUCT'}) { @Response = ActinicDiscounts::ValidateCoupon($::g_InputHash{'COUPONCODE'}); if ($Response[0] == $::FAILURE) { $sErrorMessage .= ACTINIC::GetPhrase(-1, 1971, $::g_sRequiredColor) . $Response[1] . ACTINIC::GetPhrase(-1, 1970); } else { if (ActinicDiscounts::IsMultipleFixedPriceCouponAccepted()) { my $sCoupons = $::Session->GetCSVCouponCodes(); my $sNewEntry = $::g_InputHash{'COUPONCODE'}; if ($sCoupons =~ /\b$sNewEntry\b/) { $::Session->SetCouponError(ACTINIC::GetPhrase(-1, 3080, $sNewEntry)); } else { ActinicDiscounts::AppendCouponCode($::g_InputHash{'COUPONCODE'}); $::Session->SetCouponError(''); } } else { $::g_PaymentInfo{'COUPONCODE'} = $::g_InputHash{'COUPONCODE'}; $::Session->SetCoupon($::g_PaymentInfo{'COUPONCODE'}); } if ($Response[2]) { $::Session->SetHighlanderCoupon($::g_InputHash{'COUPONCODE'}); } } } if ($sErrorMessage ne "") { my %hErrors; @Response = ReturnToLastPage(5, $sErrorMessage); } else { @Response = ReturnToLastPage(0, ""); } PrintPage($Response[2]); } sub ProcessAddToCartCall { my ($sHTML, $sCartID, @Response); my ($Status, $Message, $sSectionBlobName) = ACTINIC::GetSectionBlobName($::g_InputHash{SID}); if ($Status == $::FAILURE) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); } ($Status, $Message) = ACTINIC::ReadSectionFile(ACTINIC::GetPath().$sSectionBlobName); if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); } my $nCartMode = ${$::g_pSectionList{$sSectionBlobName}}{CART_MODE}; if ($::g_InputHash{NEXT_ACTION} eq 'ADD_ANOTHER') { @Response = AddSingleItem(); } elsif ($nCartMode == $::ATCM_SIMPLE) { @Response = OrderDetails(); } elsif ($nCartMode == $::ATCM_ADVANCED) { @Response = AddSingleItem(); } elsif ($nCartMode == $::ATCM_SINGLE) { @Response = AddMultipleItems(); } elsif ($nCartMode == $::ATCM_PDONCART) { @Response = AddItemWithDefaultParams(); } ($Status, $Message, $sHTML, $sCartID) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } my $oMailchimp = MailchimpPkg->new(); @Response = $oMailchimp->AddToMailchimp(); if ($Response[0] != $::SUCCESS) { ACTINIC::RecordErrors($Response[1], ACTINIC::GetPath()); } PrintPage($sHTML, $sCartID); exit } sub AddItemToCart { my $pValues = shift; $$pValues{'PRODUCT_REFERENCE'} =~ s/^\d+\!//g; my ($Status, $Message, $pCartObject) = $::Session->GetCartObject(); if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } $pCartObject->AddItem($pValues); $pCartObject->CombineCartLines(); } sub AddItemWithDefaultParams { my ($sProdRef, $pProduct) = ActinicOrder::GetProductDetails(); my ($Status, $Message, $sSectionBlobName) = ACTINIC::GetSectionBlobName($::g_InputHash{SID}); if ($Status == $::FAILURE) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); } my @Response; @Response = CheckQuantity($sProdRef, $sSectionBlobName, $pProduct, -1); if ($Response[0] != $::SUCCESS) { return ($::SUCCESS, $Response[1], $Response[2], ""); } my ($bAllowedToBuy, $sMessage) = IsCustomerAllowedToBuy($pProduct); if (!$bAllowedToBuy) { @Response = ReturnToLastPage(-1, $sMessage); return @Response; } my ($pCartObject); my %Values = ActinicOrder::GetProductFromInput($sProdRef, $pProduct); my ($nCartQuantity, $nMinQuantity); $nMinQuantity = $$pProduct{"MIN_QUANTITY_ORDERABLE"}; # get the min quantity count. this is maintained on a per product. my ($pProductQuantities); ($Status, $sMessage, $pProductQuantities) = ActinicOrder::CalculateCartQuantities(); if ($Status != $::SUCCESS) { return ($Status, $sMessage); } $nCartQuantity = $$pProductQuantities{$sProdRef}; if (($Values{QUANTITY} + $nCartQuantity) < $nMinQuantity) { $Values{QUANTITY} = $nMinQuantity - $nCartQuantity; } my ($Status, $Message, $pFailures) = ActinicOrder::ValidateOrderDetails(\%Values, -1, $::TRUE, $::FALSE); # validate components but not other info/date if ($Status != $::SUCCESS) { my (%hErrors, $sItem); $pFailures->{MESSAGE} = $Message; $pFailures->{PRODUCTNAME} = $pProduct->{NAME}; $pFailures->{PREVQUANTITY} = $Values{QUANTITY}; $pFailures->{PREVDATE} = $Values{DATE}; $pFailures->{PREVINFOINPUT} = $Values{INFOINPUT}; foreach $sItem (keys %::g_InputHash) { if ($sItem =~ /(v_$sProdRef\_\d+)$/) { $pFailures->{$1} = $::g_InputHash{$1}; } } $hErrors{$sProdRef} = $pFailures; $Message = ACTINIC::GetPhrase(-1,2181); my @Response = RedisplayProductPageWithErrors($Message, %hErrors); return @Response; } if (!defined $Values{QUANTITY}) { $sMessage = "" . $$pProduct{"NAME"} . ":" . "Invalid order details" . ""; return ($::FAILURE, $sMessage, undef, undef); } $::s_bCartQuantityCalculated = $::FALSE; AddItemToCart(\%Values); my @aFailureList; @Response = ActinicOrder::ShowCart(\@aFailureList); return @Response; } sub AddSingleItem { my ($sProdRef, $pProduct) = ActinicOrder::GetProductDetails(); my %Values = ActinicOrder::GetProductFromInput($sProdRef, $pProduct); my ($bAllowedToBuy, $sMessage) = IsCustomerAllowedToBuy($pProduct); if (!$bAllowedToBuy) { my @Response = ReturnToLastPage(-1, $sMessage); return @Response; } my ($Status, $Message, $pFailures) = ActinicOrder::ValidateOrderDetails(\%Values, -1, $::TRUE); if ($Status == $::SUCCESS) { AddItemToCart(\%Values); return (BounceAfterAddToCart()); } my (%hErrors, $sItem); $pFailures->{MESSAGE} = $Message; $pFailures->{PRODUCTNAME} = $pProduct->{NAME}; $pFailures->{PREVQUANTITY} = $Values{QUANTITY}; $pFailures->{PREVDATE} = $Values{DATE}; $pFailures->{PREVINFOINPUT} = $Values{INFOINPUT}; foreach $sItem (keys %::g_InputHash) { if ($sItem =~ /(v_$sProdRef\_\d+)$/) { $pFailures->{$1} = $::g_InputHash{$1}; } } $hErrors{$sProdRef} = $pFailures; $Message = ACTINIC::GetPhrase(-1,2181); my @Response = RedisplayProductPageWithErrors($Message, %hErrors); return @Response; } sub AddMultipleItems { my $sPath = ACTINIC::GetPath(); my ($Status, $Message, $sSectionBlobName) = ACTINIC::GetSectionBlobName($::g_InputHash{SID}); if ($Status == $::FAILURE) { ACTINIC::ReportError($Message, $sPath); } my $sItem; my %hErrors; my $bErrorOnPage = $::FALSE; my ($pCartObject, @Response, @aToBeAdded); @Response = $::Session->GetCartObject(); ($Status, $Message, $pCartObject) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } my $nAddedProducts = 0; my $nFailedProducts = 0; my ($Status, $Message, $bFailure, $pFailures, $bAllowedToBuy); foreach $sItem (keys %::g_InputHash) { $bFailure = $::FALSE; if ($sItem !~ /^Q_(.*)$/) { next; } my $sProdref = $1; if ($::g_InputHash{$sItem} eq "" || $::g_InputHash{$sItem} eq "0") { next; } my ($pProduct); @Response = ACTINIC::GetProduct($sProdref, $sSectionBlobName, $sPath); ($Status, $Message, $pProduct) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, $sPath); } my %Values = ActinicOrder::GetProductFromInput($sProdref, $pProduct); ($bAllowedToBuy, $Message) = IsCustomerAllowedToBuy($pProduct); if (!$bAllowedToBuy) { $pFailures = {}; $nFailedProducts++; $bFailure = $::TRUE; } if (!$bFailure) { ($Status, $Message, $pFailures) = ActinicOrder::ValidateOrderDetails(\%Values, -1, $::TRUE); if ($Status == $::SUCCESS) { push @aToBeAdded, \%Values; $nAddedProducts++; } else { $nFailedProducts++; $bFailure = $::TRUE; $bErrorOnPage = $::TRUE; } } $pFailures->{REDISPLAYONLY} = !$bFailure; $pFailures->{MESSAGE} = $Message; $pFailures->{PRODUCTNAME} = $pProduct->{NAME}; $pFailures->{PREVQUANTITY} = $Values{QUANTITY}; $pFailures->{PREVDATE} = $Values{DATE}; $pFailures->{PREVINFOINPUT} = $Values{INFOINPUT}; my $sVariantKey; foreach $sVariantKey (keys %::g_InputHash) { if ($sVariantKey =~ /(v_$sProdref\_\d+)$/) { $pFailures->{$1} = $::g_InputHash{$1}; } } $hErrors{$sProdref} = $pFailures; } if ($nAddedProducts == 0 && $nFailedProducts == 0) { $Message = ACTINIC::GetPhrase(-1,2202); $bErrorOnPage = $::TRUE; } elsif ($nFailedProducts == 0) { my $pItem; foreach $pItem (@aToBeAdded) { AddItemToCart($pItem); } } if ($bErrorOnPage) { if ($nAddedProducts > 0) { $Message = ACTINIC::GetPhrase(-1,2181); } @Response = RedisplayProductPageWithErrors($Message, %hErrors); } else { @Response = BounceAfterAddToCart(); } return @Response; } sub RedisplayProductPageWithErrors { my ($sErrorMessage, %hErrors) = @_; my $sPath = ACTINIC::GetPath(); my $sFileName = $::g_InputHash{PAGEFILENAME}; my $sMessage; $sMessage = ACTINIC::GetPhrase(-1,1971, $::g_sErrorColor) . $sErrorMessage . ACTINIC::GetPhrase(-1,1970); my $sGenMessage = ACTINIC::GetPhrase(-1,2178, $$::g_pSetupBlob{FORM_BACKGROUND_COLOR}, $sMessage); my %VariableTable; my @Response = ACTINIC::TemplateFile($sPath.$sFileName, \%VariableTable); if ($Response[0] != $::SUCCESS) { return (@Response); } my $sProdref; foreach $sProdref (keys %hErrors) { $sMessage = $hErrors{$sProdref}->{MESSAGE}; $sMessage = ACTINIC::GetPhrase(-1,1971, $::g_sErrorColor) . $sMessage . ACTINIC::GetPhrase(-1,1970); $ACTINIC::B2B->SetXML('CartError_' . $sProdref, $sMessage); my $sProdRefMeta = quotemeta ($sProdref); my $sStyle = " STYLE=\"background-color: $::g_sErrorColor\""; my ($sTemp, $sTempIndex); if ($hErrors{$sProdref}->{QUANTITY}) { $Response[2] =~ s/(NAME=\s*["']?Q_$sProdRefMeta['"]?)/$1 $sStyle/is; } if ($hErrors{$sProdref}->{INFOINPUT}) { $Response[2] =~ s/(NAME=\s*["']?O_$sProdRefMeta['"]?)/$1 $sStyle/is; } if ($hErrors{$sProdref}->{DATE}) { $Response[2] =~ s/(NAME=\s*["']?Y_$sProdRefMeta['"]?)/$1 $sStyle/is; $Response[2] =~ s/(NAME=\s*["']?M_$sProdRefMeta['"]?)/$1 $sStyle/is; $Response[2] =~ s/(NAME=\s*["']?DAY_$sProdRefMeta['"]?)/$1 $sStyle/is; } $sTemp = ACTINIC::HTMLEncode($hErrors{$sProdref}->{PREVQUANTITY}); $Response[2] =~ s/(NAME=\s*["']?Q_$sProdRefMeta['"]?[^>]*?VALUE=\s*["']?)(\d+)(['"]?)/$1$sTemp$3/is; $sTemp = ACTINIC::HTMLEncode($hErrors{$sProdref}->{PREVINFOINPUT}); if ($sTemp) { if (!($Response[2] =~ /name=\s*["']?O_$sProdRefMeta['"]?[^>]*?value=\s*['"]?/i) ) { $Response[2] =~ s/(name=\s*["']?O_$sProdRefMeta['"]?.*?)(>)/$1 value=\"$sTemp\"$2/is; } else { $Response[2] =~ s/(name=\s*["']?O_$sProdRefMeta['"]?[^>]*?value=\s*["']?)(.*?)(['"]?)/$1$sTemp$3/is; } } my ($nYear, $nMonth, $nDay, $sMonth); $sTemp = ACTINIC::HTMLEncode($hErrors{$sProdref}->{PREVDATE}); if ($sTemp) { ($nYear, $nMonth, $nDay, $sMonth) = ParseDateStamp($sTemp); $Response[2] =~ s/(NAME=\s*["']?Y_$sProdRefMeta['"]?.*?)()(.*?)(<\/SELECT)/$1$2$3$4$5/is; $Response[2] =~ s/(NAME=\s*["']?Y_$sProdRefMeta['"]?.*?)($nYear)/$1$2 SELECTED$3/is; $Response[2] =~ s/(NAME=\s*["']?M_$sProdRefMeta['"]?.*?)($sMonth)/$1$2 SELECTED$3/is; $Response[2] =~ s/(NAME=\s*["']?DAY_$sProdRefMeta['"]?.*?)($nDay)/$1$2 SELECTED$3/is; } my $sKey; my ($sSearch, $sSearch1); foreach $sKey (keys %{$hErrors{$sProdref}}) { if ($sKey =~ /v_$sProdRefMeta\_(\d+)/) { my $nCompIndex = $1; $sTempIndex = 'v_' . $sProdRefMeta . '_' . $nCompIndex; $sTemp = $hErrors{$sProdref}->{$sKey}; my $sDropDownRegExp = ")"; $Response[2] =~ s/$sSearch1/$1$2/is; $Response[2] =~ s/$sSearch/$1 CHECKED/is; } elsif ($Response[2] =~ /$sCheckBoxRegExp/is) { if ($sTemp =~ /on/i) { $sSearch = "({REDISPLAYONLY}) { $sGenMessage .= ACTINIC::GetPhrase(-1,2179, $sProdref, $hErrors{$sProdref}->{PRODUCTNAME}); } } $Response[2] = ACTINIC::MakeExtendedInfoLinksAbsolute($Response[2], $::g_sWebSiteUrl); $sGenMessage .= ACTINIC::GetPhrase(-1,2180); $ACTINIC::B2B->SetXML('CartError_List', $sGenMessage); return (@Response); } sub FeefoXMLWrapper { my (@Response) = ACTINIC::HTTP_SendAndReceive('www.feefo.com', 80, '/feefo/xmlfeed.jsp' . $::g_InputHash{"FEEFOPARAM"}, ""); if($Response[0] != $::SUCCESS) { return($::FAILURE, $Response[1]); } my $sHTTPResponse = $Response[4]; my $nLength = length $sHTTPResponse; binmode STDOUT; ACTINIC::PrintHeader('text/xml', $nLength, "", $::TRUE); print $sHTTPResponse; } sub SendRegInfo { my ($sPath, $sOut, $sType, $key, $value); my @ItemsToSend = qw(VERSIONFULL CATALOGURL LICENSE DETAILS LASTUPLOADDATE); if (defined $::g_InputHash{"HTML"} && $::g_InputHash{"HTML"} == 1) { $sType = 'text/html'; $sOut = ""; foreach (@ItemsToSend) { $sOut .= "$_$$::g_pCatalogBlob{$_}"; } $sOut .= ""; } else { $sType = 'application/octet-stream'; foreach (@ItemsToSend) { $sOut .= "$_|$$::g_pCatalogBlob{$_}|"; } } my $nLength = length $sOut; binmode STDOUT; ACTINIC::PrintHeader($sType, $nLength, "", $::TRUE); print $sOut; } sub BounceAfterAddToCart { my $oMailchimp = MailchimpPkg->new(); my @Response = $oMailchimp->AddToMailchimp(); if ($Response[0] != $::SUCCESS) { ACTINIC::RecordErrors("Error when adding the cart to MailChimp. Error message: $Response[1] ", ACTINIC::GetPath()); } my ($Status, $Message, %OrderDetails, $sCartID, @Response); $::s_bCartQuantityCalculated = $::FALSE; my $pCartObject; @Response = $::Session->GetCartObject(); ($Status, $Message, $pCartObject) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } $pCartObject->CombineCartLines(); my $nLineCount = $pCartObject->CountItems(); my ($sPageTitle, $sCartHTML); $sPageTitle = ACTINIC::GetPhrase(-1, 51); my $pCartList = $pCartObject->GetCartList(); @Response = ActinicOrder::GenerateShoppingCartLines($pCartList, $::FALSE, [], "ODTemplate.html"); if ($Response[0] != $::SUCCESS) { return (@Response); } my $sCartHTML = $Response[2]; $::Session->SetCheckoutUrl(ActinicOrder::GetCheckoutUrl()); my ($sHTML); my $nBounceDelay = $$::g_pSetupBlob{'BOUNCE_PAGE_DELAY'}; if (($nBounceDelay == 0 && ($::g_InputHash{NEXT_ACTION} ne 'ADD_ANOTHER')) || (defined $$::g_pSetupBlob{'DISPLAY_CART_AFTER_CONFIRM'} && $$::g_pSetupBlob{'DISPLAY_CART_AFTER_CONFIRM'})) { $::s_bCartQuantityCalculated = $::FALSE; ShowCart(); } elsif ($::g_InputHash{ACTION} eq ACTINIC::GetPhrase(-1, 184)) { @Response = ACTINIC::EncodeText($::Session->GetBaseUrl(), $::FALSE); my $sDestinationUrl = $::Session->GetCheckoutUrl(); ($Status, $sHTML) = ActinicOrder::CheckBuyerLimit($sCartID,$sDestinationUrl,$::FALSE); if ($Status != $::SUCCESS) { return ($::SUCCESS,"",$sHTML,$sCartID); } @Response = ACTINIC::BounceToPageEnhanced(2, ACTINIC::GetPhrase(-1, 1962) . $sCartHTML . ACTINIC::GetPhrase(-1, 1970) . ACTINIC::GetPhrase(-1, 2051), $sPageTitle, $::g_sWebSiteUrl, $::g_sContentUrl, $::g_pSetupBlob, $sDestinationUrl, \%::g_InputHash, $$::g_pSetupBlob{UNFRAMED_CHECKOUT}); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } } else { @Response = ReturnToLastPage($nBounceDelay, ACTINIC::GetPhrase(-1, 1962) . $sCartHTML . ACTINIC::GetPhrase(-1, 1970) . ACTINIC::GetPhrase(-1, 2051), $sPageTitle); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } } return ($::SUCCESS, "", $sHTML); } sub ValidateOrderDetails { my ($bInfoExists, $bDateExists, $key, $value, $sMessage, %Values); $bInfoExists = $::FALSE; $bDateExists = $::FALSE; $sMessage = ""; my ($sCookie, $Status, $Message, @Response); $sCookie = $::Session->GetSessionID(); my ($ProductRef, $pProduct); $ProductRef = $::g_InputHash{"PRODREF"}; if (length $ProductRef == 0) { return ($::FAILURE, ACTINIC::GetPhrase(-1, 54), 0, 0); } my ($sSectionBlobName); ($Status, $Message, $sSectionBlobName) = ACTINIC::GetSectionBlobName($::g_InputHash{SID}); if ($Status == $::FAILURE) { return ($Status, $Message); } @Response = ACTINIC::GetProduct($ProductRef, $sSectionBlobName, ACTINIC::GetPath()); ($Status, $Message, $pProduct) = @Response; if ($Status != $::SUCCESS) { return (@Response); } %Values = ActinicOrder::GetProductFromInput($ProductRef, $pProduct); my $pFailure; ($Status, $Message, $pFailure) = ActinicOrder::ValidateOrderDetails(\%Values, -1, $::TRUE); if ($Status != $::SUCCESS) { my $sHTML = sprintf($::ERROR_FORMAT, $Message); $ACTINIC::B2B->SetXML('CARTUPDATEERROR', $sHTML); my $sCartID; my ($nYear, $nMonth, $nDay, $sMonth) = ParseDateStamp($Values{"DATE"}); @Response = OrderDetails($nDay, $nMonth, $nYear, $Values{"INFOINPUT"}, $pFailure); ($Status, $Message, $sHTML, $sCartID) = @Response; if ($Status != $::SUCCESS) { return(@Response); } my (%Variables); $Variables{"NAME=QUANTITY VALUE=\"\\d+\""} = "NAME=QUANTITY VALUE=\"" . ACTINIC::HTMLEncode($::g_InputHash{"QUANTITY"}) ."\""; @Response = ACTINIC::TemplateString($sHTML, \%Variables); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } return ($::BADDATA, $sHTML, 0, 0); } else { $ACTINIC::B2B->SetXML('CARTUPDATEERROR', ''); my (%EmptyPaymentInfo); $EmptyPaymentInfo{'METHOD'} = $::g_PaymentInfo{'METHOD'}; $EmptyPaymentInfo{'USERDEFINED'} = $::g_PaymentInfo{'USERDEFINED'}; $EmptyPaymentInfo{'PONO'} = $::g_PaymentInfo{'PONO'}; $EmptyPaymentInfo{'COUPONCODE'} = $::g_PaymentInfo{'COUPONCODE'}; if ($ACTINIC::B2B->Get('UserDigest') || defined $::g_PaymentInfo{'SCHEDULE'}) { $EmptyPaymentInfo{'SCHEDULE'} = $::g_PaymentInfo{'SCHEDULE'}; } $::Session->UpdateCheckoutInfo(\%::g_BillContact, \%::g_ShipContact, \%::g_ShipInfo, \%::g_TaxInfo, \%::g_GeneralInfo, \%EmptyPaymentInfo, \%::g_LocationInfo); return ($::SUCCESS, "", %Values); } return ($::FAILURE, "Should never get here (ValidateData)", 0, 0); } sub CheckQuantity { my ($ProductRef, $sSectionBlobName, $pProduct, $nIndex) = @_; my ($nMaxQuantity, @Response, $Status, $Message); if ($::g_sCurrentPage eq "PRODUCT") { ($Status, $Message, $nMaxQuantity) = ActinicOrder::GetMaxRemains($ProductRef, $sSectionBlobName, $nIndex); if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); } if (($nMaxQuantity == -1) || (($::g_sCurrentPage eq "PRODUCT") && ($nMaxQuantity == 0))) { $Message .= "" . ACTINIC::GetPhrase(-1, 63) . ""; @Response = ReturnToLastPage(5, $Message, ACTINIC::GetPhrase(-1, 64)); return ($::FAILURE, $Response[1], $Response[2], ""); } if (($$::g_pSetupBlob{'STOCK_CONTROL_MODE'} != 0) && ($$pProduct{'OUT_OF_STOCK'})) { $Message .= ACTINIC::GetPhrase(-1, 297, $$pProduct{'NAME'}) . "\n"; @Response = ReturnToLastPage(5, $Message, ACTINIC::GetPhrase(-1, 64)); return ($::FAILURE, $Response[1], $Response[2], ""); } } return ($::SUCCESS, "", "", $nMaxQuantity); } sub OrderDetails { my (@Date, $sDefaultInfo, $pFailure); ($Date[0], $Date[1], $Date[2], $sDefaultInfo, $pFailure) = @_; if (!defined $Date[0]) { my $now = time; my @now = gmtime($now); $Date[0] = $now[3]; $Date[1] = $now[4] + 1; $Date[2] = $now[5] + 1900; } my ($sPath, $bStandAlonePage); $sPath = ACTINIC::GetPath(); my ($sLine, %VariableTable); my ($ProductRef, $pProduct) = ActinicOrder::GetProductDetails(); my ($Status, $Message, $sSectionBlobName) = ACTINIC::GetSectionBlobName($::g_InputHash{SID}); if ($Status == $::FAILURE) { ACTINIC::ReportError($Message, $sPath); } my ($sCartID, $nMaxQuantity, @Response); if ($::g_sCurrentPage eq "PRODUCT") { @Response = CheckQuantity($ProductRef, $sSectionBlobName, $pProduct, -1); } else { @Response = CheckQuantity($ProductRef, $sSectionBlobName, $pProduct, -2); } if ($Response[0] != $::SUCCESS) { return ($::SUCCESS, $Response[1], $Response[2], ""); } $nMaxQuantity = $Response[3]; my (@DeleteDelimiters, @KeepDelimiters); my($sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters, $pSelectTable); ($Status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters, $pSelectTable) = ActinicOrder::DisplayPreliminaryInfoPhase($::FALSE); if ($Status != $::SUCCESS) { return ($Status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters); } my (@Array1, @Array2, %SelectTable); @Array1 = %$pVarTable; @Array2 = %VariableTable; push (@Array1, @Array2); %VariableTable = @Array1; if (defined $pSelectTable) { @Array1 = %$pSelectTable; @Array2 = %SelectTable; push (@Array1, @Array2); %SelectTable = @Array1; } push (@DeleteDelimiters, @$pDeleteDelimiters); push (@KeepDelimiters, @$pKeepDelimiters); ($pDeleteDelimiters, $pKeepDelimiters) = ActinicOrder::ParseDelimiterStatus($::PRELIMINARYINFOPHASE); push (@DeleteDelimiters, @$pDeleteDelimiters); push (@KeepDelimiters, @$pKeepDelimiters); my $nVarCount = (keys %$pVarTable) + (keys %$pSelectTable); $sLine = ''; $sLine .= ""; my $VariantList; if( $pProduct->{COMPONENTS} ) { my $sProdRefHTML; ($VariantList, $sProdRefHTML) = ACTINIC::GetVariantList($ProductRef); $sLine .= $sProdRefHTML; } $VariableTable{$::VARPREFIX."PRODUCTREF"} = $sLine; my $pTree; ($Status, $sMessage, $pTree) = ACTINIC::PreProcessXMLTemplate(ACTINIC::GetPath() . "ODTemplate.html"); if ($Status != $::SUCCESS) { return ($Status, $sMessage); } $::Session->SetCheckoutUrl(ActinicOrder::GetCheckoutUrl()); my $pXML = new Element({"_CONTENT" => $pTree}); my $sProductLineHTML = ACTINIC_PXML::GetTemplateFragment($pXML, "ODLine"); my %hVariables; my $sProductTable; if (!$pProduct->{NO_ORDERLINE} ) { @Response = ACTINIC::ProcessEscapableText($$pProduct{"NAME"}); ($Status, $sLine) = @Response; if ($Status != $::SUCCESS) { return (@Response); } $hVariables{$::VARPREFIX."PRODUCTNAME"} = $sLine; @Response = FormatProductReference($ProductRef); ($Status, $Message, $sLine) = @Response; if ($Status != $::SUCCESS) { return (@Response); } $hVariables{$::VARPREFIX."DISPLAYPRODUCTREF"} = ' ' . $sLine; ($Status, $Message, $sProductTable) = ACTINIC::TemplateString($sProductLineHTML, \%hVariables); if ($Status != $::SUCCESS) { return ($Status, $Message); } } my (%Component, $pAcomponent, $sComponents); foreach $pAcomponent (@{$pProduct->{COMPONENTS}}) { @Response = ActinicOrder::FindComponent($pAcomponent, $VariantList, ',', $::TRUE); ($Status, %Component) = @Response; if ($Status != $::SUCCESS) { my %Values = ActinicOrder::GetProductFromInput($ProductRef, $pProduct); my (%hErrors, $sItem); my $pFailures = {}; $pFailures->{MESSAGE} = $Response[1]; $pFailures->{PRODUCTNAME} = $pProduct->{NAME}; $pFailures->{PREVQUANTITY} = $Values{QUANTITY}; $pFailures->{PREVDATE} = $Values{DATE}; $pFailures->{PREVINFOINPUT} = $Values{INFOINPUT}; foreach $sItem (keys %::g_InputHash) { if ($sItem =~ /(v_$ProductRef\_\d+)$/) { $pFailures->{$1} = $::g_InputHash{$1}; } } $hErrors{$ProductRef} = $pFailures; $Message = ACTINIC::GetPhrase(-1,2181); my @Response = RedisplayProductPageWithErrors($Message, %hErrors); return @Response; } if( $Component{quantity} > 0 ) { $hVariables{$::VARPREFIX."PRODUCTNAME"} = ""; $hVariables{$::VARPREFIX."DISPLAYPRODUCTREF"} = ""; if ( $Component{text} ) { @Response = ACTINIC::ProcessEscapableText($Component{text}); ($Status, $sLine) = @Response; if ($Status != $::SUCCESS) { return (@Response); } $hVariables{$::VARPREFIX."PRODUCTNAME"} = $sLine; } if ( $Component{code} ) { @Response = FormatProductReference($Component{code}); ($Status, $Message, $sLine) = @Response; if ($Status == $::SUCCESS) { $hVariables{$::VARPREFIX."DISPLAYPRODUCTREF"} = ' ' . $sLine; } } ($Status, $Message, $sLine) = ACTINIC::TemplateString($sProductLineHTML, \%hVariables); if ($Status != $::SUCCESS) { return ($Status, $Message); } $sProductTable .= $sLine; } } $ACTINIC::B2B->SetXML("ODLine", $sProductTable ); my ($bAllowedToBuy, $sMessage) = IsCustomerAllowedToBuy($pProduct); if (!$bAllowedToBuy) { my @Response = ReturnToLastPage(-1, $sMessage); return @Response; } @Response = ActinicOrder::GetProductPricesHTML($pProduct, $VariantList, $sSectionBlobName); if ($Response[0] != $::SUCCESS) { return (@Response); } $VariableTable{$::VARPREFIX."PRODUCTPRICE"} = $Response[2]; if (($$pProduct{"MIN_QUANTITY_ORDERABLE"} == $$pProduct{"MAX_QUANTITY_ORDERABLE"}) || # nothing to edit - so hard code the quantity ($::g_sCurrentPage eq "PRODUCT" && $nMaxQuantity == 1)) { if ($nMaxQuantity == 1) { $VariableTable{$::VARPREFIX."QUANTITY"} = '1' . ""; } else { $VariableTable{$::VARPREFIX."QUANTITY"} = $$pProduct{"MIN_QUANTITY_ORDERABLE"} . ""; } } else { my $nDefaultQuantity = $pProduct->{MIN_QUANTITY_ORDERABLE}; if ($::g_sCurrentPage eq "PRODUCT") { my $nMaxOrderable = ($pProduct->{MAX_QUANTITY_ORDERABLE} == 0 ? $::MAX_ORD_QTY : $pProduct->{MAX_QUANTITY_ORDERABLE}); if ($nMaxQuantity != $nMaxOrderable) { $nDefaultQuantity = 1; } } else { $nDefaultQuantity = $::g_InputHash{"Q_$ProductRef"}; } $VariableTable{$::VARPREFIX."QUANTITY"} = ""; } if (length $$pProduct{"DATE_PROMPT"} > 0) { my $nMinYear = $$pProduct{"DATE_MIN"}; my $nMaxYear = $$pProduct{"DATE_MAX"}; my ($nDefaultDay, $nDefaultMonth, $nDefaultYear) = (1, 1, $nMinYear); if ($#Date > 0) { if (defined $Date[0]) { $nDefaultDay = $Date[0]; } if (defined $Date[1]) { $nDefaultMonth = $Date[1]; } if (defined $Date[2]) { $nDefaultYear = $Date[2]; } } my ($sStyle, $sYearLine); if ($pFailure->{"DATE"}) { $sStyle = " style=\"background-color: $::g_sErrorColor\""; } my $sDayLine = ACTINIC::GenerateComboHTML("DAY_$ProductRef", $nDefaultDay, "%2.2d", $sStyle, (1..31)); my $sMonthLine = ACTINIC::GenerateComboHTML("M_$ProductRef", $::g_InverseMonthMap{$nDefaultMonth}, "%s", $sStyle, @::gMonthList); if ($nMinYear == $nMaxYear) { $sYearLine = "$nMinYear" } else { $sYearLine = ACTINIC::GenerateComboHTML("Y_$ProductRef", $nDefaultYear, "%4.4d", $sStyle, ($nMinYear..$nMaxYear)); } my $sDatePrompt = ACTINIC::FormatDate($sDayLine, $sMonthLine, $sYearLine); $ACTINIC::B2B->SetXML("DateInput", 1); $VariableTable{$::VARPREFIX."DATEPROMPTCAPTION"} = $$pProduct{"DATE_PROMPT"}; $VariableTable{$::VARPREFIX."DATEPROMPTVALUE"} = $sDatePrompt; # add the date prompt (if any) to the var table } my $sInfoPrompt = $$pProduct{"OTHER_INFO_PROMPT"}; if (length $sInfoPrompt > 0) { $ACTINIC::B2B->SetXML("InfoInput", 1); $VariableTable{$::VARPREFIX."INFOINPUTCAPTION"} = $sInfoPrompt; $VariableTable{$::VARPREFIX."INFOINPUTVALUE"} = ActinicOrder::InfoHTMLGenerate($ProductRef, $ProductRef, $sDefaultInfo, $::FALSE, $pFailure->{"INFOINPUT"}); } if (defined $$::g_pSetupBlob{'SUPPRESS_CART_WITH_CONFIRM'} && $$::g_pSetupBlob{'SUPPRESS_CART_WITH_CONFIRM'}) { $ACTINIC::B2B->SetXML("ShoppingCart", ""); # don't display the cart contents } else { my $pCartObject; @Response = $::Session->GetCartObject(); ($Status, $Message, $pCartObject) = @Response; if ($Status != $::SUCCESS) { return (@Response); } my $pCartList = $pCartObject->GetCartList(); if ($#{$pCartList} >= 0) { @Response = ActinicOrder::GenerateShoppingCartLines($pCartList, $::FALSE, [], "ODTemplate.html"); if ($Response[0] != $::SUCCESS) { return (@Response); } } else { $ACTINIC::B2B->SetXML("ShoppingCart", ""); } } @Response = ACTINIC::TemplateFile($sPath."ODTemplate.html", \%VariableTable); my ($sHTML); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } $::Session->SetCheckoutUrl(ActinicOrder::GetCheckoutUrl()); @Response = BounceHelper($sHTML); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } my ($sDelimiter); foreach $sDelimiter (@DeleteDelimiters) { $sHTML =~ s/$::DELPREFIX$sDelimiter(.*?)$::DELPREFIX$sDelimiter//gis; } foreach $sDelimiter (@KeepDelimiters) { $sHTML =~ s/$::DELPREFIX$sDelimiter//gis; } my ($sSelectName, $sDefaultOption); while ( ($sSelectName, $sDefaultOption) = each %$pSelectTable) { $sHTML =~ s/(<\s*SELECT[^>]+?NAME\s*=\s*("|')?$sSelectName.+?)/$1/is; } return ($::SUCCESS, "", $sHTML); } sub IsCustomerAllowedToBuy { my ($pProduct) = @_; my $sMessage; my $bAllowedToBuy = $::TRUE; my ($bShowRetailPrices, $bShowCustomerPrices, $nAccountSchedule) = ACTINIC::DeterminePricesToShow(); if ('' ne $ACTINIC::B2B->Get('UserDigest')) { if ( ( ($::FALSE == $bShowCustomerPrices) && ($::TRUE == $bShowRetailPrices) && (0 == scalar(@{$pProduct->{'PRICES'}->{$ActinicOrder::RETAILID}})) ) || ( ( ($::TRUE == $bShowCustomerPrices) && (0 == scalar(@{$pProduct->{'PRICES'}->{$nAccountSchedule}})) ) && ( ($::FALSE == $bShowRetailPrices) || (0 == scalar(@{$pProduct->{'PRICES'}->{$ActinicOrder::RETAILID}})) ) ) ) { $sMessage = ACTINIC::GetPhrase(-1, 351); $bAllowedToBuy = $::FALSE; } } else { if (0 == scalar(@{$pProduct->{'PRICES'}->{$ActinicOrder::RETAILID}})) { $sMessage = ACTINIC::GetPhrase(-1,333);# 'This product is only avalable to registered customers' $bAllowedToBuy = $::FALSE; } } return ($bAllowedToBuy, $sMessage); } sub FormatProductReference { if (!defined $_[0]) { return ($::FAILURE, ACTINIC::GetPhrase(-1, 12, 'FormatProductReference'), 0, 0); } my ($sProdRef, $sFormat, $sLine, @Response, $Status, $Message); $sProdRef = $_[0]; $sLine = ""; if ($$::g_pSetupBlob{"PROD_REF_COUNT"} > 0 and !($sProdRef =~ /^v\:[0-9]+$/)) { $sProdRef =~ s/^\d+\!//g; $sLine = ACTINIC::GetPhrase(-1, 65, $sProdRef); @Response = ACTINIC::EncodeText($sLine); ($Status, $sLine) = @Response; if ($Status != $::SUCCESS) { return (@Response); } } return ($::SUCCESS, "", $sLine, 0); } sub Init { $::prog_name = "SHOPCART"; $::prog_name = $::prog_name; $::prog_ver = '$Revision: 51036 $ '; $::prog_ver = substr($::prog_ver, 11); $::prog_ver =~ s/ \$//; $ActinicOrder::s_nContext = $ActinicOrder::FROM_CART; my (@Response, $Status, $Message); @Response = ReadAndParseInput(); ($Status, $Message) = @Response; if ($Status != $::SUCCESS) { ACTINIC::TerminalError($Message); } @Response = ReadAndParseBlobs(); ($Status, $Message) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); } @Response = ACTINIC::ReadSSPSetupFile(ACTINIC::GetPath()); if ($Response[0] != $::SUCCESS) { ACTINIC::ReportError($Response[1], ACTINIC::GetPath()); } $ACTINIC::B2B->Set('UserDigest',ACTINIC::CAccFindUser()); ACTINIC::InitMonthMap(); if(!defined $::g_InputHash{"ACTION"}) { if(defined $::g_InputHash{"ACTION_CONFIRM.x"}) { $::g_InputHash{"ACTION"} = $::g_sConfirmButtonLabel; } elsif(defined $::g_InputHash{"ACTION_CANCEL.x"}) { $::g_InputHash{"ACTION"} = $::g_sCancelButtonLabel; } elsif(defined $::g_InputHash{"ACTION_BUYNOW.x"}) { $::g_InputHash{"ACTION"} = ACTINIC::GetPhrase(-1, 184); } elsif(defined $::g_InputHash{"ACTION_SEND.x"}) { $::g_InputHash{"ACTION"} = $::g_sSendCouponLabel; } elsif (defined $$::g_pSetupBlob{'EDIT_IMG'} && $$::g_pSetupBlob{'EDIT_IMG'} ne '') { my $sKey; foreach $sKey (keys(%::g_InputHash)) { if ($sKey =~ /^ACTION_EDIT(\d+)\.x/) { $::g_InputHash{$1} = $::g_sEditButtonLabel; } elsif ($sKey =~ /^ACTION_REMOVE(\d+)\.x/) { $::g_InputHash{$1} = $::g_sRemoveButtonLabel; } } } } } sub ReadAndParseInput { my ($status, $message, $temp); ($status, $message, $::g_OriginalInputData, $temp, %::g_InputHash) = ACTINIC::ReadAndParseInput(); if ($status != $::SUCCESS) { return ($status, $message, 0, 0); } return ($::SUCCESS, "", 0, 0); } sub ReadAndParseBlobs { my ($Status, $Message, @Response, $sPath); $sPath = ACTINIC::GetPath(); @Response = ACTINIC::ReadPromptFile($sPath); if ($Response[0] != $::SUCCESS) { return (@Response); } @Response = ACTINIC::ReadCatalogFile($sPath); ($Status, $Message) = @Response; if ($Status != $::SUCCESS) { return (@Response); } @Response = ACTINIC::ReadSetupFile($sPath); ($Status, $Message) = @Response; if ($Status != $::SUCCESS) { return (@Response); } @Response = ACTINIC::ReadLocationsFile($sPath); ($Status, $Message) = @Response; if ($Status != $::SUCCESS) { return (@Response); } @Response = ACTINIC::ReadPaymentFile($sPath); if ($Response[0] != $::SUCCESS) { return (@Response); } my ($Status, $Message) = ACTINIC::ReadDiscountBlob($sPath); if ($Status != $::SUCCESS) { return ($Status, $Message); } $::ERROR_FORMAT = ACTINIC::GetPhrase(-1,2178, $$::g_pSetupBlob{FORM_BACKGROUND_COLOR}) . ACTINIC::GetPhrase(-1, 1961) . ACTINIC::GetPhrase(-1,2180); my ($sCartID, $sContactDetails) = ACTINIC::GetCookies(); $::Session = new Session($sCartID, $sContactDetails, ACTINIC::GetPath(), $::TRUE); $::g_sWebSiteUrl = $::Session->GetBaseUrl(); $::g_sContentUrl = $::g_sWebSiteUrl; my ($pBillContact, $pShipContact, $pShipInfo, $pTaxInfo, $pGeneralInfo, $pPaymentInfo, $pLocationInfo); @Response = $::Session->RestoreCheckoutInfo(); if ($Response[0] != $::SUCCESS) { return (@Response); } no strict 'refs'; ($Status, $Message, $pBillContact, $pShipContact, $pShipInfo, $pTaxInfo, $pGeneralInfo, $pPaymentInfo, $pLocationInfo) = @Response; %::g_BillContact = %$pBillContact; %::g_ShipContact = %$pShipContact; %::g_ShipInfo = %$pShipInfo; %::g_TaxInfo = %$pTaxInfo; %::g_GeneralInfo = %$pGeneralInfo; %::g_PaymentInfo = %$pPaymentInfo; %::g_LocationInfo = %$pLocationInfo; @Response = ACTINIC::ReadTaxSetupFile($sPath); if ($Response[0] != $::SUCCESS) { return (@Response); } ActinicOrder::ParseAdvancedTax(); return ($::SUCCESS, ""); } sub ReturnToLastPage { my ($nDelay, $sMessage, $sTitle); ($nDelay, $sMessage, $sTitle) = @_; if (!defined $sTitle) { $sTitle = ""; } my $sLastPage = $::Session->GetLastPage(); if ($sLastPage =~ /$::g_sWishListScript/i) { $nDelay = 0; if ($::g_InputHash{NEXT_ACTION} eq 'GO_TO_CART') { $sLastPage = $::g_sCartScript . '?ACTION=SHOWCART&SID=0'; } elsif ($sLastPage !~ /\?/) { $sLastPage .= "?ACTION=SHOWFORM"; } return (ACTINIC::BounceToPageEnhanced($nDelay, $sMessage, $sTitle, $::g_sWebSiteUrl, $::g_sContentUrl, $::g_pSetupBlob, $sLastPage, \%::g_InputHash)); } return (ACTINIC::ReturnToLastPage($nDelay, $sMessage, $sTitle, $::g_sWebSiteUrl, $::g_sContentUrl, $::g_pSetupBlob, %::g_InputHash)); } sub GroomHTML { my ($sMessage, $sTitle); ($sMessage, $sTitle) = @_; if (!defined $sTitle) { $sTitle = ""; } return (ACTINIC::GroomHTML($sMessage, $sTitle, $::g_sWebSiteUrl, $::g_sContentUrl, $::g_pSetupBlob, %::g_InputHash)); } sub PrintPage { my $sCartCookie = ActinicOrder::GenerateCartCookie(); return ( ACTINIC::UpdateDisplay($_[0], $::g_OriginalInputData, $_[1], $_[2], '', $sCartCookie) ); } sub AddLink { my ($sURL, $sTarget, $sImage, $sAlt, $sText) = @_; my ($sHTML); $sHTML .= ""; if (defined $sImage && $sImage ne '' && ACTINIC::CheckFileExists($sImage, ACTINIC::GetPath())) { $sHTML .= ""; } $sHTML .= "" . $sText . ""; return($::SUCCESS, "", $sHTML); } sub ShowCart { my ($Status, $Message, $sHTML); my ($pCartObject, @Response); @Response = $::Session->GetCartObject(); ($Status, $Message, $pCartObject) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } my $pCartList = $pCartObject->GetCartList(); my @aFailureList; my ($pOrderDetail, $sErrorMessage); my $nIndex; $nIndex = 0; foreach $pOrderDetail (@{$pCartList}) { my ($nStatus, $sMessage, $pFailure) = ActinicOrder::ValidateOrderDetails($pOrderDetail, -2); if ($nStatus != $::SUCCESS) { $sErrorMessage .= "" . $sMessage; push @aFailureList, $pFailure; $nIndex++; next; } push @aFailureList, {}; $nIndex++; } if (length $sErrorMessage > 0) { my $sHTML = sprintf($::ERROR_FORMAT, $sErrorMessage); $ACTINIC::B2B->SetXML('CARTUPDATEERROR', $sHTML); } else { $ACTINIC::B2B->SetXML('CARTUPDATEERROR', ''); } @Response = ActinicOrder::ShowCart(\@aFailureList); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } if (scalar @$pCartList) { my $oMailchimpPkg = MailchimpPkg->new(); @Response = $oMailchimpPkg->AddToMailchimp(); if ($Response[0] != $::SUCCESS) { ACTINIC::RecordErrors("Error when adding the cart to MailChimp. Error message: $Response[1] ", ACTINIC::GetPath()); } } PrintPage($sHTML, $::Session->GetSessionID()); exit; } sub PrintSSLBouncePage { my $sHTML; 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); } } else { my $sCookie = ACTINIC::EncodeText2($ENV{'HTTP_COOKIE'}, $::TRUE); my $sSessionID = ACTINIC::EncodeText2($::Session->GetSessionID(), $::TRUE); my $sBusinessCookie = ACTINIC::CAccBusinessCookie(); my $sReferrer = ACTINIC::GetReferrer(); if ((defined $::g_InputHash{REFPAGE}) && (!ACTINIC::IsStaticPage($sReferrer))) { my ($sBefore, $sAfter) = split(/\?/, $sReferrer); my ($sNewRefPage) = "REFPAGE=" . ACTINIC::EncodeText2($::g_InputHash{REFPAGE}, $::FALSE); if ($sAfter !~ /=/) { $sAfter = $sNewRefPage . $sAfter } elsif ($sAfter =~ /(^|\&)REFPAGE=.*?(\&|$)/) { $sAfter =~ s/(^|\&)REFPAGE=.*?(\&|$)/$1$sNewRefPage$2/; } else { $sAfter = $sNewRefPage . ($sAfter =~ /=/ ? "&" : "") . $sAfter; } $sReferrer = $sBefore . "?" . $sAfter; } my ($sURL, $sParams) = split /\?/, $::g_InputHash{'URL'}; my %EncodedInput = split(/[&=]/, $sParams); my ($key, $value); my $sHTMLParams; while (($key, $value) = each %EncodedInput) { $value = ACTINIC::DecodeText($value, $ACTINIC::FORM_URL_ENCODED); $value = ACTINIC::EncodeText2($value); $sHTMLParams .= sprintf("", $key, $value); } $sHTML = "\n" . "\n" . "\n" . "\n" . "\n" . "\n" . "\n" . "\n" . "\n" . "\n" . $sHTMLParams . "Click Next to go to a secure server and continue the checkout process. " . "\n" . "\n"; } ACTINIC::PrintPage($sHTML, $::Session->GetSessionID()); } sub BounceHelper { my $sHTML = shift @_; my @Response; if( !$ACTINIC::B2B->Get('UserDigest') ) { @Response = ACTINIC::MakeLinksAbsolute($sHTML, $::g_sWebSiteUrl, $::g_sContentUrl); } else { my $sBaseFile = $ACTINIC::B2B->Get('BaseFile'); my $smPath = ($sBaseFile) ? $sBaseFile : $::g_sContentUrl; my $sCgiUrl = $::g_sAccountScript; $sCgiUrl .= ($::g_InputHash{SHOP} ? '?SHOP=' . ACTINIC::EncodeText2($::g_InputHash{SHOP}, $::FALSE) . '&': '?'); $sCgiUrl .= 'PRODUCTPAGE='; @Response = ACTINIC::MakeLinksAbsolute($sHTML, $sCgiUrl, $smPath); } return(@Response); } sub ParseDateStamp { my $sDate = shift @_; my ($nYear, $nMonth, $sMonth, $nDay); $sDate =~ /(\d+)\/(\d+)\/(\d+)/; $nYear = $1; $nMonth = $2 +1 - 1; $sMonth = $::g_InverseMonthMap{$nMonth}; $nDay = $3 + 1 - 1; return ($nYear, $nMonth, $nDay, $sMonth); } sub ValidateWishListItem { my $bStock = @_; if (!defined $bStock) { $bStock = $::FALSE; } my ($sProdRef, $pProduct) = ActinicOrder::GetProductDetails(); my %Values = ActinicOrder::GetProductFromInput($sProdRef, $pProduct); if (((!defined $Values{QUANTITY})|| ($Values{QUANTITY} eq '')) && ($::g_InputHash{"WL_$sProdRef"})) { my $nMinQty = $$pProduct{"MIN_QUANTITY_ORDERABLE"}; $Values{QUANTITY} = $nMinQty; $::g_InputHash{"Q_$sProdRef"} = $nMinQty; } my ($Status, $Message, $pFailures) = ActinicOrder::ValidateOrderDetails(\%Values, -1, $::TRUE, $::TRUE, $bStock); if ($Status != $::SUCCESS) { my (%hErrors, $sItem); $pFailures->{MESSAGE} = $Message; $pFailures->{PRODUCTNAME} = $pProduct->{NAME}; $pFailures->{PREVQUANTITY} = $Values{QUANTITY}; $pFailures->{PREVDATE} = $Values{DATE}; $pFailures->{PREVINFOINPUT} = $Values{INFOINPUT}; foreach $sItem (keys %::g_InputHash) { if ($sItem =~ /(v_$sProdRef\_\d+)$/) { $pFailures->{$1} = $::g_InputHash{$1}; } } $hErrors{$sProdRef} = $pFailures; $Message = ACTINIC::GetPhrase(-1,2181); my @Response = RedisplayProductPageWithErrors($Message, %hErrors); return ($Status, $Response[1], $Response[2], $Response[3]); } return ($Status, ""); } sub PrintPageAjax { my ($sHTML, $sType) = @_; binmode STDOUT; my $nLength = length $sHTML; if($ENV{'PerlXS'} eq 'PerlIS') { print "HTTP/1.0 200 OK\n"; } print "Content-type: $sType\r\n"; print "Content-length: $nLength\r\n"; print "Cache-Control: no-store, no-cache\r\n"; print "Pragma: no-cache\r\n"; print "\r\n"; print $sHTML; } sub GetUsedCoupons { my ($sHTML); if ($::Session->GetCouponError()) { $sHTML = '' . $::Session->GetCouponError() . ''; } my @Coupons = split(',', $::Session->GetCSVCouponCodes()); my $nCouponIndex = $#Coupons; my $sCoupon; foreach $sCoupon (reverse(@Coupons)) { $sHTML .= ACTINIC::GetPhrase(-1, 3085, ACTINIC::EncodeText2($sCoupon), $::g_sCartScript, $nCouponIndex, ACTINIC::GetPhrase(-1, 3083)); $nCouponIndex--; } return($::SUCCESS, "", $sHTML); }
\n"; @Response = ReturnToLastPage(5, $Message, ACTINIC::GetPhrase(-1, 64)); return ($::FAILURE, $Response[1], $Response[2], ""); } } return ($::SUCCESS, "", "", $nMaxQuantity); } sub OrderDetails { my (@Date, $sDefaultInfo, $pFailure); ($Date[0], $Date[1], $Date[2], $sDefaultInfo, $pFailure) = @_; if (!defined $Date[0]) { my $now = time; my @now = gmtime($now); $Date[0] = $now[3]; $Date[1] = $now[4] + 1; $Date[2] = $now[5] + 1900; } my ($sPath, $bStandAlonePage); $sPath = ACTINIC::GetPath(); my ($sLine, %VariableTable); my ($ProductRef, $pProduct) = ActinicOrder::GetProductDetails(); my ($Status, $Message, $sSectionBlobName) = ACTINIC::GetSectionBlobName($::g_InputHash{SID}); if ($Status == $::FAILURE) { ACTINIC::ReportError($Message, $sPath); } my ($sCartID, $nMaxQuantity, @Response); if ($::g_sCurrentPage eq "PRODUCT") { @Response = CheckQuantity($ProductRef, $sSectionBlobName, $pProduct, -1); } else { @Response = CheckQuantity($ProductRef, $sSectionBlobName, $pProduct, -2); } if ($Response[0] != $::SUCCESS) { return ($::SUCCESS, $Response[1], $Response[2], ""); } $nMaxQuantity = $Response[3]; my (@DeleteDelimiters, @KeepDelimiters); my($sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters, $pSelectTable); ($Status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters, $pSelectTable) = ActinicOrder::DisplayPreliminaryInfoPhase($::FALSE); if ($Status != $::SUCCESS) { return ($Status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters); } my (@Array1, @Array2, %SelectTable); @Array1 = %$pVarTable; @Array2 = %VariableTable; push (@Array1, @Array2); %VariableTable = @Array1; if (defined $pSelectTable) { @Array1 = %$pSelectTable; @Array2 = %SelectTable; push (@Array1, @Array2); %SelectTable = @Array1; } push (@DeleteDelimiters, @$pDeleteDelimiters); push (@KeepDelimiters, @$pKeepDelimiters); ($pDeleteDelimiters, $pKeepDelimiters) = ActinicOrder::ParseDelimiterStatus($::PRELIMINARYINFOPHASE); push (@DeleteDelimiters, @$pDeleteDelimiters); push (@KeepDelimiters, @$pKeepDelimiters); my $nVarCount = (keys %$pVarTable) + (keys %$pSelectTable); $sLine = ''; $sLine .= ""; my $VariantList; if( $pProduct->{COMPONENTS} ) { my $sProdRefHTML; ($VariantList, $sProdRefHTML) = ACTINIC::GetVariantList($ProductRef); $sLine .= $sProdRefHTML; } $VariableTable{$::VARPREFIX."PRODUCTREF"} = $sLine; my $pTree; ($Status, $sMessage, $pTree) = ACTINIC::PreProcessXMLTemplate(ACTINIC::GetPath() . "ODTemplate.html"); if ($Status != $::SUCCESS) { return ($Status, $sMessage); } $::Session->SetCheckoutUrl(ActinicOrder::GetCheckoutUrl()); my $pXML = new Element({"_CONTENT" => $pTree}); my $sProductLineHTML = ACTINIC_PXML::GetTemplateFragment($pXML, "ODLine"); my %hVariables; my $sProductTable; if (!$pProduct->{NO_ORDERLINE} ) { @Response = ACTINIC::ProcessEscapableText($$pProduct{"NAME"}); ($Status, $sLine) = @Response; if ($Status != $::SUCCESS) { return (@Response); } $hVariables{$::VARPREFIX."PRODUCTNAME"} = $sLine; @Response = FormatProductReference($ProductRef); ($Status, $Message, $sLine) = @Response; if ($Status != $::SUCCESS) { return (@Response); } $hVariables{$::VARPREFIX."DISPLAYPRODUCTREF"} = ' ' . $sLine; ($Status, $Message, $sProductTable) = ACTINIC::TemplateString($sProductLineHTML, \%hVariables); if ($Status != $::SUCCESS) { return ($Status, $Message); } } my (%Component, $pAcomponent, $sComponents); foreach $pAcomponent (@{$pProduct->{COMPONENTS}}) { @Response = ActinicOrder::FindComponent($pAcomponent, $VariantList, ',', $::TRUE); ($Status, %Component) = @Response; if ($Status != $::SUCCESS) { my %Values = ActinicOrder::GetProductFromInput($ProductRef, $pProduct); my (%hErrors, $sItem); my $pFailures = {}; $pFailures->{MESSAGE} = $Response[1]; $pFailures->{PRODUCTNAME} = $pProduct->{NAME}; $pFailures->{PREVQUANTITY} = $Values{QUANTITY}; $pFailures->{PREVDATE} = $Values{DATE}; $pFailures->{PREVINFOINPUT} = $Values{INFOINPUT}; foreach $sItem (keys %::g_InputHash) { if ($sItem =~ /(v_$ProductRef\_\d+)$/) { $pFailures->{$1} = $::g_InputHash{$1}; } } $hErrors{$ProductRef} = $pFailures; $Message = ACTINIC::GetPhrase(-1,2181); my @Response = RedisplayProductPageWithErrors($Message, %hErrors); return @Response; } if( $Component{quantity} > 0 ) { $hVariables{$::VARPREFIX."PRODUCTNAME"} = ""; $hVariables{$::VARPREFIX."DISPLAYPRODUCTREF"} = ""; if ( $Component{text} ) { @Response = ACTINIC::ProcessEscapableText($Component{text}); ($Status, $sLine) = @Response; if ($Status != $::SUCCESS) { return (@Response); } $hVariables{$::VARPREFIX."PRODUCTNAME"} = $sLine; } if ( $Component{code} ) { @Response = FormatProductReference($Component{code}); ($Status, $Message, $sLine) = @Response; if ($Status == $::SUCCESS) { $hVariables{$::VARPREFIX."DISPLAYPRODUCTREF"} = ' ' . $sLine; } } ($Status, $Message, $sLine) = ACTINIC::TemplateString($sProductLineHTML, \%hVariables); if ($Status != $::SUCCESS) { return ($Status, $Message); } $sProductTable .= $sLine; } } $ACTINIC::B2B->SetXML("ODLine", $sProductTable ); my ($bAllowedToBuy, $sMessage) = IsCustomerAllowedToBuy($pProduct); if (!$bAllowedToBuy) { my @Response = ReturnToLastPage(-1, $sMessage); return @Response; } @Response = ActinicOrder::GetProductPricesHTML($pProduct, $VariantList, $sSectionBlobName); if ($Response[0] != $::SUCCESS) { return (@Response); } $VariableTable{$::VARPREFIX."PRODUCTPRICE"} = $Response[2]; if (($$pProduct{"MIN_QUANTITY_ORDERABLE"} == $$pProduct{"MAX_QUANTITY_ORDERABLE"}) || # nothing to edit - so hard code the quantity ($::g_sCurrentPage eq "PRODUCT" && $nMaxQuantity == 1)) { if ($nMaxQuantity == 1) { $VariableTable{$::VARPREFIX."QUANTITY"} = '1' . ""; } else { $VariableTable{$::VARPREFIX."QUANTITY"} = $$pProduct{"MIN_QUANTITY_ORDERABLE"} . ""; } } else { my $nDefaultQuantity = $pProduct->{MIN_QUANTITY_ORDERABLE}; if ($::g_sCurrentPage eq "PRODUCT") { my $nMaxOrderable = ($pProduct->{MAX_QUANTITY_ORDERABLE} == 0 ? $::MAX_ORD_QTY : $pProduct->{MAX_QUANTITY_ORDERABLE}); if ($nMaxQuantity != $nMaxOrderable) { $nDefaultQuantity = 1; } } else { $nDefaultQuantity = $::g_InputHash{"Q_$ProductRef"}; } $VariableTable{$::VARPREFIX."QUANTITY"} = ""; } if (length $$pProduct{"DATE_PROMPT"} > 0) { my $nMinYear = $$pProduct{"DATE_MIN"}; my $nMaxYear = $$pProduct{"DATE_MAX"}; my ($nDefaultDay, $nDefaultMonth, $nDefaultYear) = (1, 1, $nMinYear); if ($#Date > 0) { if (defined $Date[0]) { $nDefaultDay = $Date[0]; } if (defined $Date[1]) { $nDefaultMonth = $Date[1]; } if (defined $Date[2]) { $nDefaultYear = $Date[2]; } } my ($sStyle, $sYearLine); if ($pFailure->{"DATE"}) { $sStyle = " style=\"background-color: $::g_sErrorColor\""; } my $sDayLine = ACTINIC::GenerateComboHTML("DAY_$ProductRef", $nDefaultDay, "%2.2d", $sStyle, (1..31)); my $sMonthLine = ACTINIC::GenerateComboHTML("M_$ProductRef", $::g_InverseMonthMap{$nDefaultMonth}, "%s", $sStyle, @::gMonthList); if ($nMinYear == $nMaxYear) { $sYearLine = "$nMinYear" } else { $sYearLine = ACTINIC::GenerateComboHTML("Y_$ProductRef", $nDefaultYear, "%4.4d", $sStyle, ($nMinYear..$nMaxYear)); } my $sDatePrompt = ACTINIC::FormatDate($sDayLine, $sMonthLine, $sYearLine); $ACTINIC::B2B->SetXML("DateInput", 1); $VariableTable{$::VARPREFIX."DATEPROMPTCAPTION"} = $$pProduct{"DATE_PROMPT"}; $VariableTable{$::VARPREFIX."DATEPROMPTVALUE"} = $sDatePrompt; # add the date prompt (if any) to the var table } my $sInfoPrompt = $$pProduct{"OTHER_INFO_PROMPT"}; if (length $sInfoPrompt > 0) { $ACTINIC::B2B->SetXML("InfoInput", 1); $VariableTable{$::VARPREFIX."INFOINPUTCAPTION"} = $sInfoPrompt; $VariableTable{$::VARPREFIX."INFOINPUTVALUE"} = ActinicOrder::InfoHTMLGenerate($ProductRef, $ProductRef, $sDefaultInfo, $::FALSE, $pFailure->{"INFOINPUT"}); } if (defined $$::g_pSetupBlob{'SUPPRESS_CART_WITH_CONFIRM'} && $$::g_pSetupBlob{'SUPPRESS_CART_WITH_CONFIRM'}) { $ACTINIC::B2B->SetXML("ShoppingCart", ""); # don't display the cart contents } else { my $pCartObject; @Response = $::Session->GetCartObject(); ($Status, $Message, $pCartObject) = @Response; if ($Status != $::SUCCESS) { return (@Response); } my $pCartList = $pCartObject->GetCartList(); if ($#{$pCartList} >= 0) { @Response = ActinicOrder::GenerateShoppingCartLines($pCartList, $::FALSE, [], "ODTemplate.html"); if ($Response[0] != $::SUCCESS) { return (@Response); } } else { $ACTINIC::B2B->SetXML("ShoppingCart", ""); } } @Response = ACTINIC::TemplateFile($sPath."ODTemplate.html", \%VariableTable); my ($sHTML); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } $::Session->SetCheckoutUrl(ActinicOrder::GetCheckoutUrl()); @Response = BounceHelper($sHTML); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } my ($sDelimiter); foreach $sDelimiter (@DeleteDelimiters) { $sHTML =~ s/$::DELPREFIX$sDelimiter(.*?)$::DELPREFIX$sDelimiter//gis; } foreach $sDelimiter (@KeepDelimiters) { $sHTML =~ s/$::DELPREFIX$sDelimiter//gis; } my ($sSelectName, $sDefaultOption); while ( ($sSelectName, $sDefaultOption) = each %$pSelectTable) { $sHTML =~ s/(<\s*SELECT[^>]+?NAME\s*=\s*("|')?$sSelectName.+?)/$1/is; } return ($::SUCCESS, "", $sHTML); } sub IsCustomerAllowedToBuy { my ($pProduct) = @_; my $sMessage; my $bAllowedToBuy = $::TRUE; my ($bShowRetailPrices, $bShowCustomerPrices, $nAccountSchedule) = ACTINIC::DeterminePricesToShow(); if ('' ne $ACTINIC::B2B->Get('UserDigest')) { if ( ( ($::FALSE == $bShowCustomerPrices) && ($::TRUE == $bShowRetailPrices) && (0 == scalar(@{$pProduct->{'PRICES'}->{$ActinicOrder::RETAILID}})) ) || ( ( ($::TRUE == $bShowCustomerPrices) && (0 == scalar(@{$pProduct->{'PRICES'}->{$nAccountSchedule}})) ) && ( ($::FALSE == $bShowRetailPrices) || (0 == scalar(@{$pProduct->{'PRICES'}->{$ActinicOrder::RETAILID}})) ) ) ) { $sMessage = ACTINIC::GetPhrase(-1, 351); $bAllowedToBuy = $::FALSE; } } else { if (0 == scalar(@{$pProduct->{'PRICES'}->{$ActinicOrder::RETAILID}})) { $sMessage = ACTINIC::GetPhrase(-1,333);# 'This product is only avalable to registered customers' $bAllowedToBuy = $::FALSE; } } return ($bAllowedToBuy, $sMessage); } sub FormatProductReference { if (!defined $_[0]) { return ($::FAILURE, ACTINIC::GetPhrase(-1, 12, 'FormatProductReference'), 0, 0); } my ($sProdRef, $sFormat, $sLine, @Response, $Status, $Message); $sProdRef = $_[0]; $sLine = ""; if ($$::g_pSetupBlob{"PROD_REF_COUNT"} > 0 and !($sProdRef =~ /^v\:[0-9]+$/)) { $sProdRef =~ s/^\d+\!//g; $sLine = ACTINIC::GetPhrase(-1, 65, $sProdRef); @Response = ACTINIC::EncodeText($sLine); ($Status, $sLine) = @Response; if ($Status != $::SUCCESS) { return (@Response); } } return ($::SUCCESS, "", $sLine, 0); } sub Init { $::prog_name = "SHOPCART"; $::prog_name = $::prog_name; $::prog_ver = '$Revision: 51036 $ '; $::prog_ver = substr($::prog_ver, 11); $::prog_ver =~ s/ \$//; $ActinicOrder::s_nContext = $ActinicOrder::FROM_CART; my (@Response, $Status, $Message); @Response = ReadAndParseInput(); ($Status, $Message) = @Response; if ($Status != $::SUCCESS) { ACTINIC::TerminalError($Message); } @Response = ReadAndParseBlobs(); ($Status, $Message) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); } @Response = ACTINIC::ReadSSPSetupFile(ACTINIC::GetPath()); if ($Response[0] != $::SUCCESS) { ACTINIC::ReportError($Response[1], ACTINIC::GetPath()); } $ACTINIC::B2B->Set('UserDigest',ACTINIC::CAccFindUser()); ACTINIC::InitMonthMap(); if(!defined $::g_InputHash{"ACTION"}) { if(defined $::g_InputHash{"ACTION_CONFIRM.x"}) { $::g_InputHash{"ACTION"} = $::g_sConfirmButtonLabel; } elsif(defined $::g_InputHash{"ACTION_CANCEL.x"}) { $::g_InputHash{"ACTION"} = $::g_sCancelButtonLabel; } elsif(defined $::g_InputHash{"ACTION_BUYNOW.x"}) { $::g_InputHash{"ACTION"} = ACTINIC::GetPhrase(-1, 184); } elsif(defined $::g_InputHash{"ACTION_SEND.x"}) { $::g_InputHash{"ACTION"} = $::g_sSendCouponLabel; } elsif (defined $$::g_pSetupBlob{'EDIT_IMG'} && $$::g_pSetupBlob{'EDIT_IMG'} ne '') { my $sKey; foreach $sKey (keys(%::g_InputHash)) { if ($sKey =~ /^ACTION_EDIT(\d+)\.x/) { $::g_InputHash{$1} = $::g_sEditButtonLabel; } elsif ($sKey =~ /^ACTION_REMOVE(\d+)\.x/) { $::g_InputHash{$1} = $::g_sRemoveButtonLabel; } } } } } sub ReadAndParseInput { my ($status, $message, $temp); ($status, $message, $::g_OriginalInputData, $temp, %::g_InputHash) = ACTINIC::ReadAndParseInput(); if ($status != $::SUCCESS) { return ($status, $message, 0, 0); } return ($::SUCCESS, "", 0, 0); } sub ReadAndParseBlobs { my ($Status, $Message, @Response, $sPath); $sPath = ACTINIC::GetPath(); @Response = ACTINIC::ReadPromptFile($sPath); if ($Response[0] != $::SUCCESS) { return (@Response); } @Response = ACTINIC::ReadCatalogFile($sPath); ($Status, $Message) = @Response; if ($Status != $::SUCCESS) { return (@Response); } @Response = ACTINIC::ReadSetupFile($sPath); ($Status, $Message) = @Response; if ($Status != $::SUCCESS) { return (@Response); } @Response = ACTINIC::ReadLocationsFile($sPath); ($Status, $Message) = @Response; if ($Status != $::SUCCESS) { return (@Response); } @Response = ACTINIC::ReadPaymentFile($sPath); if ($Response[0] != $::SUCCESS) { return (@Response); } my ($Status, $Message) = ACTINIC::ReadDiscountBlob($sPath); if ($Status != $::SUCCESS) { return ($Status, $Message); } $::ERROR_FORMAT = ACTINIC::GetPhrase(-1,2178, $$::g_pSetupBlob{FORM_BACKGROUND_COLOR}) . ACTINIC::GetPhrase(-1, 1961) . ACTINIC::GetPhrase(-1,2180); my ($sCartID, $sContactDetails) = ACTINIC::GetCookies(); $::Session = new Session($sCartID, $sContactDetails, ACTINIC::GetPath(), $::TRUE); $::g_sWebSiteUrl = $::Session->GetBaseUrl(); $::g_sContentUrl = $::g_sWebSiteUrl; my ($pBillContact, $pShipContact, $pShipInfo, $pTaxInfo, $pGeneralInfo, $pPaymentInfo, $pLocationInfo); @Response = $::Session->RestoreCheckoutInfo(); if ($Response[0] != $::SUCCESS) { return (@Response); } no strict 'refs'; ($Status, $Message, $pBillContact, $pShipContact, $pShipInfo, $pTaxInfo, $pGeneralInfo, $pPaymentInfo, $pLocationInfo) = @Response; %::g_BillContact = %$pBillContact; %::g_ShipContact = %$pShipContact; %::g_ShipInfo = %$pShipInfo; %::g_TaxInfo = %$pTaxInfo; %::g_GeneralInfo = %$pGeneralInfo; %::g_PaymentInfo = %$pPaymentInfo; %::g_LocationInfo = %$pLocationInfo; @Response = ACTINIC::ReadTaxSetupFile($sPath); if ($Response[0] != $::SUCCESS) { return (@Response); } ActinicOrder::ParseAdvancedTax(); return ($::SUCCESS, ""); } sub ReturnToLastPage { my ($nDelay, $sMessage, $sTitle); ($nDelay, $sMessage, $sTitle) = @_; if (!defined $sTitle) { $sTitle = ""; } my $sLastPage = $::Session->GetLastPage(); if ($sLastPage =~ /$::g_sWishListScript/i) { $nDelay = 0; if ($::g_InputHash{NEXT_ACTION} eq 'GO_TO_CART') { $sLastPage = $::g_sCartScript . '?ACTION=SHOWCART&SID=0'; } elsif ($sLastPage !~ /\?/) { $sLastPage .= "?ACTION=SHOWFORM"; } return (ACTINIC::BounceToPageEnhanced($nDelay, $sMessage, $sTitle, $::g_sWebSiteUrl, $::g_sContentUrl, $::g_pSetupBlob, $sLastPage, \%::g_InputHash)); } return (ACTINIC::ReturnToLastPage($nDelay, $sMessage, $sTitle, $::g_sWebSiteUrl, $::g_sContentUrl, $::g_pSetupBlob, %::g_InputHash)); } sub GroomHTML { my ($sMessage, $sTitle); ($sMessage, $sTitle) = @_; if (!defined $sTitle) { $sTitle = ""; } return (ACTINIC::GroomHTML($sMessage, $sTitle, $::g_sWebSiteUrl, $::g_sContentUrl, $::g_pSetupBlob, %::g_InputHash)); } sub PrintPage { my $sCartCookie = ActinicOrder::GenerateCartCookie(); return ( ACTINIC::UpdateDisplay($_[0], $::g_OriginalInputData, $_[1], $_[2], '', $sCartCookie) ); } sub AddLink { my ($sURL, $sTarget, $sImage, $sAlt, $sText) = @_; my ($sHTML); $sHTML .= ""; if (defined $sImage && $sImage ne '' && ACTINIC::CheckFileExists($sImage, ACTINIC::GetPath())) { $sHTML .= ""; } $sHTML .= "" . $sText . ""; return($::SUCCESS, "", $sHTML); } sub ShowCart { my ($Status, $Message, $sHTML); my ($pCartObject, @Response); @Response = $::Session->GetCartObject(); ($Status, $Message, $pCartObject) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } my $pCartList = $pCartObject->GetCartList(); my @aFailureList; my ($pOrderDetail, $sErrorMessage); my $nIndex; $nIndex = 0; foreach $pOrderDetail (@{$pCartList}) { my ($nStatus, $sMessage, $pFailure) = ActinicOrder::ValidateOrderDetails($pOrderDetail, -2); if ($nStatus != $::SUCCESS) { $sErrorMessage .= "" . $sMessage; push @aFailureList, $pFailure; $nIndex++; next; } push @aFailureList, {}; $nIndex++; } if (length $sErrorMessage > 0) { my $sHTML = sprintf($::ERROR_FORMAT, $sErrorMessage); $ACTINIC::B2B->SetXML('CARTUPDATEERROR', $sHTML); } else { $ACTINIC::B2B->SetXML('CARTUPDATEERROR', ''); } @Response = ActinicOrder::ShowCart(\@aFailureList); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } if (scalar @$pCartList) { my $oMailchimpPkg = MailchimpPkg->new(); @Response = $oMailchimpPkg->AddToMailchimp(); if ($Response[0] != $::SUCCESS) { ACTINIC::RecordErrors("Error when adding the cart to MailChimp. Error message: $Response[1] ", ACTINIC::GetPath()); } } PrintPage($sHTML, $::Session->GetSessionID()); exit; } sub PrintSSLBouncePage { my $sHTML; 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); } } else { my $sCookie = ACTINIC::EncodeText2($ENV{'HTTP_COOKIE'}, $::TRUE); my $sSessionID = ACTINIC::EncodeText2($::Session->GetSessionID(), $::TRUE); my $sBusinessCookie = ACTINIC::CAccBusinessCookie(); my $sReferrer = ACTINIC::GetReferrer(); if ((defined $::g_InputHash{REFPAGE}) && (!ACTINIC::IsStaticPage($sReferrer))) { my ($sBefore, $sAfter) = split(/\?/, $sReferrer); my ($sNewRefPage) = "REFPAGE=" . ACTINIC::EncodeText2($::g_InputHash{REFPAGE}, $::FALSE); if ($sAfter !~ /=/) { $sAfter = $sNewRefPage . $sAfter } elsif ($sAfter =~ /(^|\&)REFPAGE=.*?(\&|$)/) { $sAfter =~ s/(^|\&)REFPAGE=.*?(\&|$)/$1$sNewRefPage$2/; } else { $sAfter = $sNewRefPage . ($sAfter =~ /=/ ? "&" : "") . $sAfter; } $sReferrer = $sBefore . "?" . $sAfter; } my ($sURL, $sParams) = split /\?/, $::g_InputHash{'URL'}; my %EncodedInput = split(/[&=]/, $sParams); my ($key, $value); my $sHTMLParams; while (($key, $value) = each %EncodedInput) { $value = ACTINIC::DecodeText($value, $ACTINIC::FORM_URL_ENCODED); $value = ACTINIC::EncodeText2($value); $sHTMLParams .= sprintf("", $key, $value); } $sHTML = "\n" . "\n" . "\n" . "\n" . "\n" . "\n" . "\n" . "\n" . "\n" . "\n" . $sHTMLParams . "Click Next to go to a secure server and continue the checkout process. " . "\n" . "\n"; } ACTINIC::PrintPage($sHTML, $::Session->GetSessionID()); } sub BounceHelper { my $sHTML = shift @_; my @Response; if( !$ACTINIC::B2B->Get('UserDigest') ) { @Response = ACTINIC::MakeLinksAbsolute($sHTML, $::g_sWebSiteUrl, $::g_sContentUrl); } else { my $sBaseFile = $ACTINIC::B2B->Get('BaseFile'); my $smPath = ($sBaseFile) ? $sBaseFile : $::g_sContentUrl; my $sCgiUrl = $::g_sAccountScript; $sCgiUrl .= ($::g_InputHash{SHOP} ? '?SHOP=' . ACTINIC::EncodeText2($::g_InputHash{SHOP}, $::FALSE) . '&': '?'); $sCgiUrl .= 'PRODUCTPAGE='; @Response = ACTINIC::MakeLinksAbsolute($sHTML, $sCgiUrl, $smPath); } return(@Response); } sub ParseDateStamp { my $sDate = shift @_; my ($nYear, $nMonth, $sMonth, $nDay); $sDate =~ /(\d+)\/(\d+)\/(\d+)/; $nYear = $1; $nMonth = $2 +1 - 1; $sMonth = $::g_InverseMonthMap{$nMonth}; $nDay = $3 + 1 - 1; return ($nYear, $nMonth, $nDay, $sMonth); } sub ValidateWishListItem { my $bStock = @_; if (!defined $bStock) { $bStock = $::FALSE; } my ($sProdRef, $pProduct) = ActinicOrder::GetProductDetails(); my %Values = ActinicOrder::GetProductFromInput($sProdRef, $pProduct); if (((!defined $Values{QUANTITY})|| ($Values{QUANTITY} eq '')) && ($::g_InputHash{"WL_$sProdRef"})) { my $nMinQty = $$pProduct{"MIN_QUANTITY_ORDERABLE"}; $Values{QUANTITY} = $nMinQty; $::g_InputHash{"Q_$sProdRef"} = $nMinQty; } my ($Status, $Message, $pFailures) = ActinicOrder::ValidateOrderDetails(\%Values, -1, $::TRUE, $::TRUE, $bStock); if ($Status != $::SUCCESS) { my (%hErrors, $sItem); $pFailures->{MESSAGE} = $Message; $pFailures->{PRODUCTNAME} = $pProduct->{NAME}; $pFailures->{PREVQUANTITY} = $Values{QUANTITY}; $pFailures->{PREVDATE} = $Values{DATE}; $pFailures->{PREVINFOINPUT} = $Values{INFOINPUT}; foreach $sItem (keys %::g_InputHash) { if ($sItem =~ /(v_$sProdRef\_\d+)$/) { $pFailures->{$1} = $::g_InputHash{$1}; } } $hErrors{$sProdRef} = $pFailures; $Message = ACTINIC::GetPhrase(-1,2181); my @Response = RedisplayProductPageWithErrors($Message, %hErrors); return ($Status, $Response[1], $Response[2], $Response[3]); } return ($Status, ""); } sub PrintPageAjax { my ($sHTML, $sType) = @_; binmode STDOUT; my $nLength = length $sHTML; if($ENV{'PerlXS'} eq 'PerlIS') { print "HTTP/1.0 200 OK\n"; } print "Content-type: $sType\r\n"; print "Content-length: $nLength\r\n"; print "Cache-Control: no-store, no-cache\r\n"; print "Pragma: no-cache\r\n"; print "\r\n"; print $sHTML; } sub GetUsedCoupons { my ($sHTML); if ($::Session->GetCouponError()) { $sHTML = '' . $::Session->GetCouponError() . ''; } my @Coupons = split(',', $::Session->GetCSVCouponCodes()); my $nCouponIndex = $#Coupons; my $sCoupon; foreach $sCoupon (reverse(@Coupons)) { $sHTML .= ACTINIC::GetPhrase(-1, 3085, ACTINIC::EncodeText2($sCoupon), $::g_sCartScript, $nCouponIndex, ACTINIC::GetPhrase(-1, 3083)); $nCouponIndex--; } return($::SUCCESS, "", $sHTML); }