#!/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; 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 ($$::g_pSetupBlob{CATALOG_SUSPENDED}) { if (!defined $::g_InputHash{'REFPAGE'}) { push @::g_PageList, ACTINIC::GetReferrer(); } @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 "SSLBOUNCE") { PrintSSLBouncePage(); exit; } elsif ($sAction eq "SHOWCART") { @Response = ShowCart(); ($Status, $Message, $sHTML, $sCartID) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } PrintPage($sHTML, $sCartID); } elsif ($::g_sCurrentPage eq "CONFIRMREMOVE") { while (($key, $value) = each %::g_InputHash) { if ($value =~ /$::g_sConfirmButtonLabel/ || $value =~ /$::g_sCancelButtonLabel/) { my ($Temp); $Temp = keys %::g_InputHash; last; } } if ($value eq $::g_sConfirmButtonLabel) { @Response = RemoveItem(); ($Status, $Message, $sHTML, $sCartID) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } PrintPage($sHTML, $sCartID); } else { @Response = ReturnToLastPage(0, "", ""); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } PrintPage($sHTML); } } elsif ($::g_sCurrentPage eq "SHOPPINGCART") { while (($key, $value) = each %::g_InputHash) { if ($value =~ /$::g_sRemoveButtonLabel/ || $value =~ /$::g_sEditButtonLabel/ || $value =~ /$::g_sRemoveAllButtonLabel/) { my ($Temp); $Temp = keys %::g_InputHash; last; } } if ($value eq $::g_sRemoveButtonLabel) { @Response = ConfirmRemove(); } elsif ($value eq $::g_sRemoveAllButtonLabel) { @Response = EmptyCart(); } else { @Response = EditItem(); } ($Status, $Message, $sHTML, $sCartID) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } PrintPage($sHTML, $sCartID); } elsif ($::g_sCurrentPage eq "PRODUCT") { @Response = OrderDetails($::FALSE); ($Status, $Message, $sHTML, $sCartID) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } PrintPage($sHTML, $sCartID); } 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 { if (!defined $::g_InputHash{"ITEMINDEX"} || $#::g_PageList == 1) { @Response = AddToCart(); ($Status, $Message, $sHTML, $sCartID) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } PrintPage($sHTML, $sCartID); } else { @Response = ChangeCartItem(); ($Status, $Message, $sHTML, $sCartID) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } PrintPage($sHTML, $sCartID); } } } else { ACTINIC::ReportError(ACTINIC::GetPhrase(-1, 1284), ACTINIC::GetPath()); exit; } } sub ConfirmRemove { no strict 'refs'; my ($bFound, $key, $value, $nItemIndex); $bFound = $::FALSE; while (($key, $value) = each %::g_InputHash) { if ($value =~ /$::g_sRemoveButtonLabel/) { $bFound = $::TRUE; my ($Temp); $Temp = keys %::g_InputHash; $Temp = $Temp; $nItemIndex = $key; last; } } my (%VariableTable, $sLine); $sLine = "\n"; $VariableTable{$::VARPREFIX."PAGE"} = $sLine; my (@Response, $Status, $Message, $sCartID, $pCartList); @Response = ActinicOrder::GetCartID(ACTINIC::GetPath()); ($Status, $Message, $sCartID) = @Response; if ($Status != $::SUCCESS) { return (@Response); } @Response = ActinicOrder::ReadCart($sCartID, ACTINIC::GetPath()); ($Status, $Message, $pCartList) = @Response; if ($Status != $::SUCCESS) { return (@Response); } my (%CartItem); %CartItem = %{ $$pCartList[$nItemIndex] }; my ($sSectionBlobName); ($Status, $Message, $sSectionBlobName) = ACTINIC::GetSectionBlobName($CartItem{SID}); if ($Status == $::FAILURE) { return ($Status, $Message); } my ($pProduct); my $bDeleted = $::FALSE; @Response = ACTINIC::GetProduct($CartItem{"PRODUCT_REFERENCE"}, $sSectionBlobName, ACTINIC::GetPath()); ($Status, $Message, $pProduct) = @Response; if ($Status == $::NOTFOUND) { $bDeleted = $::TRUE; } if ($Status == $::FAILURE) { return (@Response); } my $nEffectiveQuantity = ActinicOrder::EffectiveCartQuantity(\%CartItem,$pCartList,\&ActinicOrder::IdenticalCartLines,undef); my $spPrice; $spPrice = ActinicOrder::CalculateSchPrice($pProduct,$nEffectiveQuantity,$ACTINIC::B2B->Get('UserDigest')); my $ComponentPrice = 0; if( $pProduct->{COMPONENTS} ) { my ($VariantList, $k); foreach $k (keys %CartItem) { if( $k =~ /^COMPONENT\_/ ) { $VariantList->[$'] = $CartItem{$k}; } } my (%Component, $c); my $nIndex = 1; foreach $c (@{$pProduct->{COMPONENTS}}) { @Response = ActinicOrder::FindComponent($c,$VariantList); ($Status, %Component) = @Response; if ($Status != $::SUCCESS) { return ($Status,$Component{text}); } my $sRef= $Component{code} && $c->[4] == 1 ? $Component{code} : $CartItem{"PRODUCT_REFERENCE"} . "_" . $nIndex; @Response = ActinicOrder::GetComponentPrice($Component{price},$nEffectiveQuantity,$Component{quantity}, undef, $sRef); if ($Response[0] != $::SUCCESS) { return (@Response); } $ComponentPrice += $Response[2]; $nIndex++; } } my $nPriceModel = $$pProduct{PRICING_MODEL}; if( $nPriceModel == $ActinicOrder::PRICING_MODEL_PROD_COMP ) { $spPrice += $ComponentPrice; } elsif( $nPriceModel == $ActinicOrder::PRICING_MODEL_COMP ) { $spPrice = $ComponentPrice; } my ($sDescription, $sProdRef); @Response = ACTINIC::ProcessEscapableText($$pProduct{"NAME"}); ($Status, $sDescription) = @Response; if ($Status != $::SUCCESS) { return (@Response); } @Response = FormatProductReference($CartItem{"PRODUCT_REFERENCE"}); ($Status, $Message, $sProdRef) = @Response; if ($Status != $::SUCCESS) { return (@Response); } my ($sFormat, $sQuantity); $sFormat = ACTINIC::GetPhrase(-1, 166) . ' %d'; $sQuantity = sprintf($sFormat, $CartItem{"QUANTITY"}); my ($sPrice); if(defined $pProduct) { if( $bDeleted ) { $sPrice = ''; } else { my $nRetailPrice = $$pProduct{PRICE}; @Response = ActinicOrder::GetProductTaxBands($pProduct); if ($Response[0] != $::SUCCESS) { return (@Response); } @Response = ActinicOrder::FormatCompletePrice($spPrice, $Response[2], $Response[3], $nRetailPrice); ($Status, $Message, $sPrice) = @Response; if ($Status != $::SUCCESS) { return (@Response); } if (length $sPrice > 0) { $sPrice .= "
"; } } } my ($nTotal, $sTotal); $nTotal = $CartItem{"QUANTITY"} * $spPrice; if(defined $pProduct) { if( $bDeleted ) { $sTotal = ''; } else { my $nRetailPrice = $$pProduct{PRICE}; @Response = ActinicOrder::GetProductTaxBands($pProduct); if ($Response[0] != $::SUCCESS) { return (@Response); } @Response = ActinicOrder::FormatCompletePrice($nTotal, $Response[2], $Response[3], $nRetailPrice, 103); ($Status, $Message, $sTotal) = @Response; if ($Status != $::SUCCESS) { return (@Response); } } } $sTotal .= "
"; my ($sDate); if (length $CartItem{"DATE"} > 0) { $sDate = $$pProduct{"DATE_PROMPT"}; $sDate .= " "; $sDate .= $CartItem{"DATE"}; $sDate .= "
"; } my ($sInfo); if (length $CartItem{"INFOINPUT"} > 0) { $sInfo = $$pProduct{"OTHER_INFO_PROMPT"}; $sInfo .= " "; $sInfo .= $CartItem{"INFOINPUT"}; $sInfo =~ s/%0a/
/g; $sInfo .= "

"; } $sLine = sprintf('

%s%s

%s%s%s%s
%s

', $sDescription, $sProdRef, $sDate, $sInfo, $sPrice, $sQuantity, $sTotal); $sLine .= ACTINIC::GetPhrase(-1, 46) . "

\n"; if (defined $$::g_pSetupBlob{'CONFIRM_IMG'} && $$::g_pSetupBlob{'CONFIRM_IMG'} ne '') { $sLine .= " \n"; } else { $sLine .= " \n"; } if (defined $$::g_pSetupBlob{'CANCEL_IMG'} && $$::g_pSetupBlob{'CANCEL_IMG'} ne '') { $sLine .= "

\n"; } else { $sLine .= "

\n"; } $sLine .= "\n"; $VariableTable{$::VARPREFIX."BODY"} = $sLine; my ($sPath, $sHTML); $sPath = ACTINIC::GetPath(); @Response = ACTINIC::TemplateFile($sPath."CRTemplate.html", \%VariableTable); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } @Response = BounceHelper($sHTML); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } return ($::SUCCESS, "", $sHTML, $sCartID); } sub ChangeCartItem { my ($Status, $Message, %OrderDetails, $nIndex, $sCartID, @Response); @Response = ActinicOrder::GetCartID(ACTINIC::GetPath()); ($Status, $Message, $sCartID) = @Response; if ($Status != $::SUCCESS) { return (@Response); } ($Status, $Message, %OrderDetails) = ValidateOrderDetails($::TRUE); $nIndex = $::g_InputHash{"ITEMINDEX"}; if ($Status == $::BADDATA) { my ($sSearch, $sReplace); $sSearch = "\n" . " 0) { $nDay = substr($CartItem{"DATE"}, 8, 2); $nMonth = substr($CartItem{"DATE"}, 5, 2); # which is in actinic internal format YYYY/MM/DD $nYear = substr($CartItem{"DATE"}, 0, 4); $nMonth = int $nMonth; $nDay = int $nDay; } my ($sHTML); @Response = OrderDetails($::TRUE, $nDay, $nMonth, $nYear); ($Status, $Message, $sHTML, $sCartID) = @Response; if ($Status != $::SUCCESS) { return(@Response); } my ($sSearch, $sReplace); $sSearch = "\n" . " 0) { my ($sInfoValue); $sInfoValue = ACTINIC::EncodeText2($CartItem{"INFOINPUT"}); $Variables{"NAME=INFOINPUT"} = "NAME=INFOINPUT VALUE=\"$sInfoValue\""; } my ($nQuantity); $nQuantity = $CartItem{"QUANTITY"}; $Variables{"NAME=QUANTITY VALUE=\"\\d+\""} = "NAME=QUANTITY VALUE=\"$nQuantity\""; @Response = ACTINIC::TemplateString($sHTML, \%Variables); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } return ($::SUCCESS, "", $sHTML, $sCartID); } sub RemoveItem { my ($sCartID, @Response, $Status, $Message, $nItemIndex); @Response = ActinicOrder::GetCartID(ACTINIC::GetPath()); ($Status, $Message, $sCartID) = @Response; if ($Status != $::SUCCESS) { return (@Response); } @Response = ActinicOrder::RemoveItemFromCart($sCartID, $::g_InputHash{"ITEMINDEX"}, ACTINIC::GetPath()); ($Status, $Message) = @Response; if ($Status != $::SUCCESS) { return (@Response); } @Response = ReturnToLastPage(0, "", ""); my ($sHTML); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } return ($::SUCCESS, "", $sHTML, $sCartID); } sub ShowCart { my ($sCartID, @Response, $Status, $Message); @Response = ActinicOrder::GetCartID(ACTINIC::GetPath()); ($Status, $Message, $sCartID) = @Response; if ($Status != $::SUCCESS) { return (@Response); } my ($pCartList); @Response = ActinicOrder::ReadCart($sCartID, ACTINIC::GetPath()); ($Status, $Message, $pCartList) = @Response; if ($Status != $::SUCCESS && $Status != $::EOF) { return (@Response); } my ($sLine, %VariableTable); $sLine = ""; $VariableTable{$::VARPREFIX."PAGE"} = $sLine; @Response = ActinicOrder::GenerateShoppingCartLines($pCartList, $::TRUE); if ($Response[0] != $::SUCCESS) { return (@Response); } my ($sBody) = $Response[2]; my ($sBack, $sPrevPage, @sTemp); $sPrevPage = ACTINIC::GetLastNonScript(\@::g_PageList); my $sScriptURL = ACTINIC::GetScriptNameRegexp(); if ($sPrevPage =~ /$sScriptURL/ && $sPrevPage !~ /\?$/ ) { $sPrevPage = @::g_PageList[0]; } elsif( $sPrevPage =~ /\?$/ ) { my ($sBodyPage,$sFramePage) = ACTINIC::CAccCatalogBody(); @Response = ACTINIC::ProcessEscapableText($sBodyPage); ($Status, $sBodyPage) = @Response; if ($Status != $::SUCCESS) { return (@Response); } $sPrevPage = $::g_sAccountScript; $sPrevPage .= ($::g_InputHash{SHOP} ? '?SHOP=' . ACTINIC::EncodeText2($::g_InputHash{SHOP}, $::FALSE) . '&': '?'); $sPrevPage .= "PRODUCTPAGE=$sBodyPage"; } if( ACTINIC::IsCatalogFramed() ) { $sBack = ''; } else { $sBack = ACTINIC::GetPhrase(-1, 1973) . "

" . ACTINIC::GetPhrase(-1, 47) . "

" . ACTINIC::GetPhrase(-1, 1970) . "\n"; } $sBody = $sBack . $sBody . $sBack; $VariableTable{$::VARPREFIX."BODY"} = $sBody; my ($sPath, $sHTML); $sPath = ACTINIC::GetPath(); @Response = ACTINIC::TemplateFile($sPath."SCTemplate.html", \%VariableTable); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } @Response = BounceHelper($sHTML); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } return ($::SUCCESS, "", $sHTML, $sCartID); } sub AddToCart { my ($Status, $Message, %OrderDetails, $sCartID, @Response); @Response = ActinicOrder::GetCartID(ACTINIC::GetPath()); ($Status, $Message, $sCartID) = @Response; if ($Status != $::SUCCESS) { return (@Response); } ($Status, $Message, %OrderDetails) = ValidateOrderDetails($::FALSE); if ($Status == $::BADDATA) { return ($::SUCCESS, "", $Message, $sCartID); # but act like life was a ::SUCCESS - display the warning } elsif ($Status != $::SUCCESS) { return($Status, $Message, "", 0); } my ($nInitLineCount); @Response = ActinicOrder::CountCartItems($sCartID, ACTINIC::GetPath()); ($Status, $Message, $nInitLineCount) = @Response; if ($Status == $::FAILURE) { return (@Response); } @Response = ActinicOrder::AddItemToCart($sCartID, ACTINIC::GetPath(), \%OrderDetails); ($Status, $Message) = @Response; if ($Status != $::SUCCESS) { return (@Response); } my ($nLineCount); @Response = ActinicOrder::CountCartItems($sCartID, ACTINIC::GetPath()); ($Status, $Message, $nLineCount) = @Response; if ($Status == $::FAILURE) { return (@Response); } my ($sPageTitle, $sStatusMessage); $sPageTitle = ''; if ($nLineCount > 1) { $sStatusMessage = ACTINIC::GetPhrase(-1, 50, $nLineCount); } else { $sStatusMessage = ACTINIC::GetPhrase(-1, 168); } my ($sHTML); $sPageTitle = ACTINIC::GetPhrase(-1, 51); if (defined $$::g_pSetupBlob{'DISPLAY_CART_AFTER_CONFIRM'} && $$::g_pSetupBlob{'DISPLAY_CART_AFTER_CONFIRM'}) { @Response = DisplayCartWithLinks($sCartID, $sPageTitle); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } } elsif ($::g_InputHash{ACTION} eq ACTINIC::GetPhrase(-1, 184)) { @Response = ACTINIC::EncodeText($::g_PageList[0], $::FALSE); my $sDestinationUrl = $::g_InputHash{CHECKOUTURL} . "&ACTINIC_REFERRER=" . $Response[1]; ($Status, $sHTML) = ActinicOrder::CheckBuyerLimit($sCartID,$sDestinationUrl,$::FALSE); if ($Status != $::SUCCESS) { return ($::SUCCESS,"",$sHTML,$sCartID); } @Response = ACTINIC::BounceToPageEnhanced(2, ACTINIC::GetPhrase(-1, 1962) . $sStatusMessage . ACTINIC::GetPhrase(-1, 1970) . ACTINIC::GetPhrase(-1, 2051), $sPageTitle, \@::g_PageList, $::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(2, ACTINIC::GetPhrase(-1, 1962) . $sStatusMessage . ACTINIC::GetPhrase(-1, 1970) . ACTINIC::GetPhrase(-1, 2051), $sPageTitle); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } } return ($::SUCCESS, "", $sHTML, $sCartID); } sub ValidateOrderDetails { my ($bEditMode) = @_; my ($bInfoExists, $bDateExists, $key, $value, $sMessage, %Values); $bInfoExists = $::FALSE; $bDateExists = $::FALSE; $sMessage = ""; my ($sCookie, $Status, $Message, @Response); $sCookie = ACTINIC::GetCookie(); if (!defined $sCookie || length $sCookie == 0) { my ($sHTML); $sMessage = ACTINIC::GetPhrase(-1, 52) . "\n"; ($Status, $Message, $sHTML) = ReturnToLastPage(-1, $sMessage, ACTINIC::GetPhrase(-1, 53)); return ($::BADDATA, $sHTML, 0, 0); } 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); } $bInfoExists = (length $$pProduct{"OTHER_INFO_PROMPT"} != 0); # see if the info field exists. $bDateExists = (length $$pProduct{"DATE_PROMPT"} != 0); $Values{'PRODUCT_REFERENCE'} = $ProductRef; $Values{'SID'} = $::g_InputHash{'SID'}; $Values{'QDQUALIFY'} = 1; if( $pProduct->{COMPONENTS} ) { if( $pProduct->{PRICING_MODEL} != $ActinicOrder::PRICING_MODEL_STANDARD ) { $Values{'QDQUALIFY'} = 0; } my $bGotHash = $::FALSE; my $k; foreach $k (keys %::g_InputHash) { if( $k =~ /^\Q$ProductRef\E\_/ ) { $Values{'COMPONENT_'.$'} = $::g_InputHash{$k}; $bGotHash = $::TRUE; } } if( !$bGotHash and $bEditMode ) { @Response = ActinicOrder::GetCartID(ACTINIC::GetPath()); if ($Response[0] != $::SUCCESS) { return (@Response); } my ($sCartID) = $Response[2]; my ($pCartList, @EmptyArray); @Response = ActinicOrder::ReadCart($sCartID, ACTINIC::GetPath()); if ($Response[0] != $::SUCCESS) { $pCartList = \@EmptyArray; } else { $pCartList = $Response[2]; } my $i = 0; my $pOrderDetail; foreach $pOrderDetail (@$pCartList) { my %CurrentItem = %$pOrderDetail; if( $CurrentItem{PRODUCT_REFERENCE} eq $ProductRef and $i == $::g_InputHash{ITEMINDEX}) { my $k; foreach $k (keys %CurrentItem) { if( $k =~ /^COMPONENT\_/ ) { $Values{'COMPONENT_'.$'} = $CurrentItem{$k}; } } last; } $i++; } } } my ($sInfo); if ($bInfoExists) { $sInfo = $::g_InputHash{"INFOINPUT"}; if (length $sInfo == 0) { my ($sPrompt); $sPrompt = $$pProduct{"OTHER_INFO_PROMPT"}; $sMessage .= ACTINIC::GetPhrase(-1, 55, "$sPrompt") . "

\n"; } elsif (length $sInfo > 1000) { my ($sPrompt); $sPrompt = $$pProduct{"OTHER_INFO_PROMPT"}; $sMessage .= ACTINIC::GetPhrase(-1, 56, "$sPrompt") . "

\n"; } $sInfo =~ s/\n/%0a/g; $Values{"INFOINPUT"} = $sInfo; } my ($nDay, $sMonth, $nMonth, $nYear, $bBad); $bBad = $::FALSE; if ($bDateExists) { $nDay = $::g_InputHash{"DAY"}; $sMonth = $::g_InputHash{"MONTH"}; $nYear = $::g_InputHash{"YEAR"}; $nMonth = $::g_MonthMap{$sMonth}; if ( ($sMonth eq $::g_InverseMonthMap{'4'} || $sMonth eq $::g_InverseMonthMap{'6'} || $sMonth eq $::g_InverseMonthMap{'9'} || $sMonth eq $::g_InverseMonthMap{'11'}) && $nDay > 30) { $bBad = $::TRUE; } elsif ($sMonth eq $::g_InverseMonthMap{'2'}) { if ($nDay > 29) { $bBad = $::TRUE; } elsif ($nDay == 29) { if ($nYear % 400 == 0) { } elsif ($nYear % 100 == 0) { $bBad = $::TRUE; } elsif ($nYear % 4 == 0) { } else { $bBad = $::TRUE; } } else { } } my $sPrompt = $$pProduct{"DATE_PROMPT"}; if (length $nDay == 0 || length $sMonth == 0 || length $nYear == 0) { $sMessage .= ACTINIC::GetPhrase(-1, 57, "$sPrompt") . "

\n"; } elsif ($bBad) { $sMessage .= ACTINIC::GetPhrase(-1, 58, "$sPrompt") . "

\n"; } $Values{"DATE"} = sprintf("%4.4d/%2.2d/%2.2d", $nYear, $nMonth, $nDay); } my ($nIndex); $nIndex = -1; if ($#::g_PageList != 1) { $nIndex = $::g_InputHash{"ITEMINDEX"}; } my ($nQuantity, $nMaxQuantity, $nMinQuantity); $nMinQuantity = $$pProduct{"MIN_QUANTITY_ORDERABLE"}; # get the min quantity count. this is maintained on a per if ($nIndex == -1) { ($Status, $Message, $nMaxQuantity) = GetMaxRemains($ProductRef, $sSectionBlobName); } else { ($Status, $Message, $nMaxQuantity) = GetMaxRemains($ProductRef, $sSectionBlobName, $nIndex); } if ($Status != $::SUCCESS) { return($Status, $Message, 0, 0); } $nMinQuantity -= ($pProduct->{MAX_QUANTITY_ORDERABLE} - $nMaxQuantity); # adjust the min quantity for items already in the cart (if any) if ($nMinQuantity < 1) { $nMinQuantity = 1; } $nQuantity = $::g_InputHash{"QUANTITY"}; $nQuantity =~ s/^\s//g; $nQuantity =~ s/\s$//g; if ($nMaxQuantity == 0) { $nMaxQuantity = 32767; } if( $nMinQuantity > $nMaxQuantity ) { $nMinQuantity = 1; } if ($nMaxQuantity == -1) { $sMessage .= ACTINIC::GetPhrase(-1, 59) . "

\n"; } elsif ($nQuantity =~ /\D/ || $nQuantity < $nMinQuantity || ($nMaxQuantity != 0 && $nQuantity > $nMaxQuantity) ) { if ($nMaxQuantity > 1) { $sMessage .= ACTINIC::GetPhrase(-1, 60, $nMinQuantity, $nMaxQuantity) . "

\n"; } elsif ($nMaxQuantity == 1) { $sMessage .= ACTINIC::GetPhrase(-1, 61) . "

\n"; } elsif ($nMaxQuantity == 0) { $sMessage .= ACTINIC::GetPhrase(-1, 62, $nMinQuantity) . "

\n"; } } $Values{"QUANTITY"} = $nQuantity; $Values{SID} = $::g_InputHash{SID}; if ($$::g_pSetupBlob{'TAX_AND_SHIP_EARLY'}) { my @aNewCartItems = (); push(@aNewCartItems, \%Values); $sMessage .= ActinicOrder::ValidatePreliminaryInfo($::TRUE, \@aNewCartItems); $sMessage .= ActinicOrder::ValidateTax($::TRUE, $::FALSE); } if (length $sMessage > 0) { $sMessage = "" . "
$sMessage


"; my ($sHTML, $sCartID); @Response = OrderDetails($bEditMode, $nDay, $nMonth, $nYear); ($Status, $Message, $sHTML, $sCartID) = @Response; if ($Status != $::SUCCESS) { return(@Response); } my (%Variables); if (length $Values{"INFOINPUT"} > 0) { my ($sInfoValue); $sInfoValue = $Values{"INFOINPUT"}; $sInfoValue =~ s/%0a/\n/g; $Variables{"NAME=INFOINPUT"} = "NAME=INFOINPUT VALUE=\"$sInfoValue\""; } $Variables{"NAME=QUANTITY VALUE=\"\\d+\""} = "NAME=QUANTITY VALUE=\"$nQuantity\""; $Variables{"Get('UserDigest') || defined $::g_PaymentInfo{'SCHEDULE'}) { $EmptyPaymentInfo{'SCHEDULE'} = $::g_PaymentInfo{'SCHEDULE'}; } @Response = ActinicOrder::SaveCheckoutStatus(ACTINIC::GetPath(), $sCartID, \%::g_BillContact, \%::g_ShipContact, \%::g_ShipInfo, \%::g_TaxInfo, \%::g_GeneralInfo, \%EmptyPaymentInfo, \%::g_LocationInfo); if ($Response[0] != $::SUCCESS) { return ($Response[0], $Response[1], 0, 0); } return ($::SUCCESS, "", %Values); } return ($::FAILURE, "Should never get here (ValidateData)", 0, 0); } sub GetMaxRemains { no strict 'refs'; if ($#_ < 1) { return ($::FAILURE, ACTINIC::GetPhrase(-1, 12, 'GetMaxRemains'), 0, 0); } my (@Response, $Status, $Message, $sCartID, $ProductRef, $Product, $nIndex, $sSectionBlob); $ProductRef = $_[0]; $sSectionBlob = $_[1]; if (defined $_[2]) { $nIndex = $_[2]; } else { $nIndex = -1; } @Response = ACTINIC::GetProduct($ProductRef, $sSectionBlob, ACTINIC::GetPath()); my ($pProduct); ($Status, $Message, $pProduct) = @Response; if ($Status == $::NOTFOUND) { } if ($Status == $::FAILURE) { return (@Response); } if ($$pProduct{'MAX_QUANTITY_ORDERABLE'} == 0) { return ($::SUCCESS, "", 0, 0); } @Response = ActinicOrder::GetCartID(ACTINIC::GetPath()); ($Status, $Message, $sCartID) = @Response; if ($Status != $::SUCCESS) { return (@Response); } my ($pCartList); @Response = ActinicOrder::ReadCart($sCartID, ACTINIC::GetPath()); ($Status, $Message, $pCartList) = @Response; if ($Status == $::EOF) { return($::SUCCESS, "", $$pProduct{'MAX_QUANTITY_ORDERABLE'}, 0); } elsif ($Status != $::SUCCESS) { return(@Response); } my ($OrderDetail, %CurrentItem, $nQuantityLeft, $nCartItemIndex); $nQuantityLeft = $$pProduct{'MAX_QUANTITY_ORDERABLE'}; $nCartItemIndex = -1; foreach $OrderDetail (@$pCartList) { %CurrentItem = %$OrderDetail; $nCartItemIndex++; if ($nCartItemIndex == $nIndex) { next; } if ($CurrentItem{'PRODUCT_REFERENCE'} eq $ProductRef) { $nQuantityLeft -= $CurrentItem{'QUANTITY'}; } } if ($nQuantityLeft <= 0) { $nQuantityLeft = -1; } return ($::SUCCESS, "", $nQuantityLeft, 0); } sub OrderDetails { my ($bEditMode, @Date) = @_; my ($sPath, $bStandAlonePage); $sPath = ACTINIC::GetPath(); my ($sLine, %VariableTable); my ($ProductRef, $key, $value); foreach (keys %::g_InputHash) { if( $_ =~ /^_/ ) { $ProductRef = $'; $ProductRef =~ s/\.[xy]$//; $ProductRef =~ s/_.*//g; last; } } my ($Status, $Message, $sSectionBlobName) = ACTINIC::GetSectionBlobName($::g_InputHash{SID}); if ($Status == $::FAILURE) { return ($Status, $Message); } my ($sImageButtonName, $sSuffix); if( !$ProductRef ) { $ProductRef = $::g_InputHash{"PRODREF"}; } if (length $ProductRef == 0) { while (($key, $value) = each %::g_InputHash) { if (length $::g_sAddToButtonLabel > 0 && $value =~ /\Q$::g_sAddToButtonLabel\E/ && $key !~ /_/) { $ProductRef = $key; last; } if ($key =~ /(.+)\.([xy])$/ && $key !~ /_/) { if($sImageButtonName) { if($sSuffix ne $2) { ($ProductRef) = $sImageButtonName;# use the de-suffixed name last; } } else { $sImageButtonName = $1; $sSuffix = $2; } } if ($key =~ /^ATB_/) { my ($sVariantCode, @Attributes); $key =~ /ATB_(\d+)([_0-9]*)/; my ($nVariantID, $sAttributePart) = ($1, $2); my ($nAttribute, $nValue); while (0 < length $sAttributePart) { $sAttributePart =~ /_(\d+)_(\d+)(.*)/; ($nAttribute, $nValue, $sAttributePart) = ($1, $2, $3); $Attributes[($nAttribute-1)] = $nValue; } my @Keys = sort keys %::g_InputHash; my ($sName); my $sSearchString = "AT_" . $nVariantID . "_(\\d+)"; foreach $sName (@Keys) { if ($sName =~ /$sSearchString/) # if this parameter is an attribute (format AT___) { $Attributes[($1-1)] = $::g_InputHash{$sName}; } } $sVariantCode = $nVariantID . "_"; foreach $nAttribute (@Attributes) { $sVariantCode .= $nAttribute . "_"; } $sVariantCode =~ s/_$//; my @Response = ACTINIC::GetProductReferenceFromVariant($sVariantCode, $sSectionBlobName, $sPath); if ($Response[0] != $::SUCCESS) { return (@Response); } $ProductRef = $Response[2]; last; } } my ($Temp); $Temp = keys %::g_InputHash; $Temp = $Temp; } if (!$ProductRef) { if( $sImageButtonName ) { $ProductRef = $sImageButtonName; } else { return ($::FAILURE, ACTINIC::GetPhrase(-1, 54), 0, 0); } } my ($sCartID, $nMaxQuantity, @Response); @Response = ActinicOrder::GetCartID($sPath); ($Status, $Message, $sCartID) = @Response; if ($Status != $::SUCCESS) { return (@Response); } if ($::g_sCurrentPage eq "PRODUCT") { ($Status, $Message, $nMaxQuantity) = GetMaxRemains($ProductRef, $sSectionBlobName); if ($Status != $::SUCCESS) { return($Status, $Message, 0, 0); } if ($nMaxQuantity == -1) { my ($sLocalPage, $sMessage); $sLocalPage = pop @::g_PageList; push (@::g_PageList, $sLocalPage); push (@::g_PageList, $sLocalPage); $sMessage .= "" . ACTINIC::GetPhrase(-1, 63) . ""; @Response = ReturnToLastPage(5, $sMessage, ACTINIC::GetPhrase(-1, 64)); return ($Response[0], $Response[1], $Response[2], $sCartID); } } my ($pProduct); @Response = ACTINIC::GetProduct($ProductRef, $sSectionBlobName, $sPath); ($Status, $Message, $pProduct) = @Response; if ($Status != $::SUCCESS) { return (@Response); } 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); ($Status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters) = ActinicOrder::DisplayTaxPhase($::FALSE); if ($Status != $::SUCCESS) { return ($Status, $sMessage, $pVarTable, $pDeleteDelimiters, $pKeepDelimiters); } @Array1 = %$pVarTable; @Array2 = %VariableTable; push (@Array1, @Array2); %VariableTable = @Array1; push (@DeleteDelimiters, @$pDeleteDelimiters); push (@KeepDelimiters, @$pKeepDelimiters); ($pDeleteDelimiters, $pKeepDelimiters) = ActinicOrder::ParseDelimiterStatus($::PRELIMINARYINFOPHASE); push (@DeleteDelimiters, @$pDeleteDelimiters); push (@KeepDelimiters, @$pKeepDelimiters); ($pDeleteDelimiters, $pKeepDelimiters) = ActinicOrder::ParseDelimiterStatus($::TAXCHARGEPHASE); push (@DeleteDelimiters, @$pDeleteDelimiters); push (@KeepDelimiters, @$pKeepDelimiters); my $nVarCount = (keys %$pVarTable) + (keys %$pSelectTable); $sLine = ""; $sLine .= ""; my $VariantList; if( $pProduct->{COMPONENTS} ) { if( $::g_InputHash{PAGE} eq 'SHOPPINGCART' ) { my ($pCartList, @EmptyArray); @Response = ActinicOrder::ReadCart($sCartID, ACTINIC::GetPath()); if ($Response[0] != $::SUCCESS) { $pCartList = \@EmptyArray; } else { $pCartList = $Response[2]; } my $i = 0; my $pOrderDetail; foreach $pOrderDetail (@$pCartList) { my %CurrentItem = %$pOrderDetail; if( $CurrentItem{PRODUCT_REFERENCE} eq $ProductRef and $::g_InputHash{$i} ne '') { my $k; foreach $k (keys %CurrentItem) { if( $k =~ /^COMPONENT\_/ ) { $VariantList->[$'] = $CurrentItem{$k}; } } last; } $i++; } } else { my $sProdRefHTML; ($VariantList, $sProdRefHTML) = ACTINIC::GetVariantList($ProductRef); $sLine .= $sProdRefHTML; } } $VariableTable{$::VARPREFIX."PRODUCTREF"} = $sLine; @Response = ACTINIC::ProcessEscapableText($$pProduct{"NAME"}); ($Status, $sLine) = @Response; if ($Status != $::SUCCESS) { return (@Response); } $VariableTable{$::VARPREFIX."PRODUCTNAME"} = $sLine; @Response = FormatProductReference($ProductRef); ($Status, $Message, $sLine) = @Response; if ($Status != $::SUCCESS) { return (@Response); } $VariableTable{$::VARPREFIX."DISPLAYPRODUCTREF"} = ' ' . $sLine; my (%Component, $pAcomponent, $sComponents); foreach $pAcomponent (@{$pProduct->{COMPONENTS}}) { @Response = ActinicOrder::FindComponent($pAcomponent,$VariantList); ($Status, %Component) = @Response; if ($Status != $::SUCCESS) { return ($Status,$Component{text}); } if( $Component{quantity} > 0 ) { $sComponents .= '
' . $pAcomponent->[0]; if( $Component{text} ) { $sComponents .= ' - ' . $Component{text}; } if( $Component{code} ) { @Response = FormatProductReference($Component{code}); ($Status, $Message, $sLine) = @Response; if ($Status == $::SUCCESS) { $sComponents .= ' ' . $sLine; } } } } if ($$::g_pSetupBlob{"PROD_REF_COUNT"} > 0) { $VariableTable{$::VARPREFIX."DISPLAYPRODUCTREF"} .= $sComponents; } else { $VariableTable{$::VARPREFIX."PRODUCTNAME"} .= $sComponents; } my ($bShowRetailPrices, $bShowCustomerPrices, $nAccountSchedule) = ACTINIC::DeterminePricesToShow(); { my $sMessage; my $bNotAllowedToBuy = 0; 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); $bNotAllowedToBuy = 1; } } else { if (0 == scalar(@{$pProduct->{'PRICES'}->{$ActinicOrder::RETAILID}})) { $sMessage = ACTINIC::GetPhrase(-1,333);# 'This product is only avalable to registered customers' $bNotAllowedToBuy = 1; } } if ($bNotAllowedToBuy) { my @Response = ReturnToLastPage(0, $sMessage); return @Response; } } $sLine = ''; if (defined $$pProduct{PRICES}) { my $sPriceLabelText = ACTINIC::GetPhrase(-1, 66); if($bShowRetailPrices && $bShowCustomerPrices) { my $sPriceLabel = ACTINIC::GetPhrase(-1, 294, $sPriceLabelText); @Response = ActinicOrder::FormatSchedulePrices($pProduct, $ActinicOrder::RETAILID, \$VariantList, $sPriceLabel); $sLine .= $Response[2]; $sPriceLabel = ACTINIC::GetPhrase(-1, 293, $sPriceLabelText); @Response = ActinicOrder::FormatSchedulePrices($pProduct, $nAccountSchedule, \$VariantList, $sPriceLabel); $sLine .= $Response[2]; } elsif($bShowCustomerPrices) { @Response = ActinicOrder::FormatSchedulePrices($pProduct, $nAccountSchedule, \$VariantList, $sPriceLabelText); $sLine = $Response[2]; } else { @Response = ActinicOrder::FormatSchedulePrices($pProduct, 1, \$VariantList, $sPriceLabelText); $sLine = $Response[2]; } } $VariableTable{$::VARPREFIX."PRODUCTPRICE"} = $sLine; 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") { if ($nMaxQuantity != $pProduct->{MAX_QUANTITY_ORDERABLE}) { $nDefaultQuantity = 1; } } $VariableTable{$::VARPREFIX."QUANTITY"} = ""; } my ($sDatePrompt); $sDatePrompt = $$pProduct{"DATE_PROMPT"}; $sLine = ""; if (length $sDatePrompt > 0) { my (@TimeList); @TimeList = localtime(time); $sLine = "

".$sDatePrompt."
\n"; my ($nDefaultDay, $nDefaultMonth, $nDefaultYear) = ($TimeList[3], $TimeList[4]+1, $TimeList[5]+1900); 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 ($nDay); my ($sDayLine) = "\n"; my ($nMonth); my ($sMonthLine) = "\n"; my ($nStartYear, $nYear); my ($sYearLine) = "\n"; my $sDatePrompt = ACTINIC::GetPhrase(-1, 1912); if ($sDatePrompt !~ s/dd/$sDayLine/) { ACTINIC::ReportError(ACTINIC::GetPhrase(-1, 1913), ACTINIC::GetPath()); } if ($sDatePrompt !~ s/mm/$sMonthLine/) { ACTINIC::ReportError(ACTINIC::GetPhrase(-1, 1913), ACTINIC::GetPath()); } if ($sDatePrompt !~ s/yy/$sYearLine/) { ACTINIC::ReportError(ACTINIC::GetPhrase(-1, 1913), ACTINIC::GetPath()); } $sLine .= $sDatePrompt . "
\n"; } $VariableTable{$::VARPREFIX."DATEINPUT"} = $sLine; # add the date prompt (if any) to the var table my ($sInfoPrompt); $sInfoPrompt = $$pProduct{"OTHER_INFO_PROMPT"}; $sLine = ""; if (length $sInfoPrompt > 0) { $sLine = "

".$sInfoPrompt."
\n"; $sLine .= "\n"; } $VariableTable{$::VARPREFIX."INFOINPUT"} = $sLine; # add the info prompt (if any) to the var table if (defined $$::g_pSetupBlob{'SUPPRESS_CART_WITH_CONFIRM'} && $$::g_pSetupBlob{'SUPPRESS_CART_WITH_CONFIRM'}) { $VariableTable{$::VARPREFIX.'THEORDERDETAILS'} = ""; # don't display the cart contents } else { my ($pCartList, @EmptyArray); @Response = ActinicOrder::ReadCart($sCartID, $sPath); if ($Response[0] != $::SUCCESS) { $pCartList = \@EmptyArray; } else { $pCartList = $Response[2]; } my $sOrderDetailHTML; if ($#{$pCartList} >= 0) { @Response = ActinicOrder::GenerateShoppingCartLines($pCartList); if ($Response[0] != $::SUCCESS) { return (@Response); } $sOrderDetailHTML = $Response[2]; } $VariableTable{$::VARPREFIX.'THEORDERDETAILS'} = $sOrderDetailHTML; } @Response = ACTINIC::TemplateFile($sPath."ODTemplate.html", \%VariableTable); my ($sHTML); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { return (@Response); } @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

\n" . "\n" . "\n" . "\n" . $sHTMLParams . "
\n" . "\n"; ACTINIC::PrintPage($sHTML, ""); } sub EmptyCart { my $sPath = ACTINIC::GetPath(); my $sHTML; my @Response = ActinicOrder::GetCartID($sPath); my ($Status, $Message, $sCartID) = @Response; if ($Status != $::SUCCESS) { return (@Response); } my ($sCartFileName); @Response = ActinicOrder::GetCartFileName($sCartID, $sPath); if ($Response[0] != $::SUCCESS) { return (@Response); } $sCartFileName = $Response[2]; ACTINIC::ChangeAccess("rw", $sCartFileName); ACTINIC::SecurePath($sCartFileName); if (unlink ($sCartFileName) != 1) { ACTINIC::ChangeAccess('', $sCartFileName); } my $sStatusMessage = ACTINIC::GetPhrase(-1, 48); my $sPageTitle = ACTINIC::GetPhrase(-1, 51); push @::g_PageList, $::g_PageList[$#::g_PageList]; @Response = ReturnToLastPage(3, ACTINIC::GetPhrase(-1, 1962) . $sStatusMessage . ACTINIC::GetPhrase(-1, 1970) . ACTINIC::GetPhrase(-1, 2052), $sPageTitle); ($Status, $Message, $sHTML) = @Response; if ($Status != $::SUCCESS) { ACTINIC::ReportError($Message, ACTINIC::GetPath()); exit; } return (BounceHelper($sHTML), $sCartID); } 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); }