Merge branch 'master' of git@github.com:plainblack/webgui
This commit is contained in:
commit
aab3a74026
43 changed files with 2335 additions and 519 deletions
42
README
Normal file
42
README
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
This repo holds a UPS shipping driver for WebGUI, developed against
|
||||
WebGUI 7.7.8. To install it, you only need to run the install script
|
||||
in the sbin directory, or, manually add "WebGUI::Shop::ShipDriver::UPS"
|
||||
to the shippingDrivers entry in your WebGUI config file.
|
||||
|
||||
Instructions for registering with the UPS are in the Shipping driver
|
||||
edit screen.
|
||||
|
||||
The driver is currently limited to shipping originating in the United
|
||||
States only. Here is what is required to make it handle all available UPS
|
||||
shipping services internationally.
|
||||
|
||||
* The Product needs to be modified to have units for weight. Currently,
|
||||
they are unitless, and likewise, this driver assumes that all weights are in pounds
|
||||
(the current default weight unit in the United States). The chosen unit is added
|
||||
to the PackageWeight XML tag, in buildXML.
|
||||
|
||||
* The driver code itself needs to be extended to add the shipping services.
|
||||
1) Add i18n for the names of the new services, and a shipping type. See
|
||||
the code in the defintion subroutine.
|
||||
2) Add a new key/value pair to the %shippingTypes hash.
|
||||
3) The %shippingServices hash has a unique list of shipping services by code. If you
|
||||
introduce new codes, add the appropriate key/value pairs to the hash. This is
|
||||
required to get the selected code into the generated HTML, regardless of the
|
||||
shippingType chosen.
|
||||
4) There is javascript inside of www/extras/yui-webgui/ShipDriver/UPS.js that will
|
||||
alter the set of shipping services displayed to the user, based on which shipping
|
||||
type they have chosen. It in internationalized.
|
||||
* Inside WebGUI.ShipDriver.UPS.initServiceTables, add a new object to hold codes
|
||||
and i18n labels to describe the services.
|
||||
* Add a new service to the switch (newService) statement. Make sure the new case
|
||||
matches the keys you added to the shippingTypes hash in the definition subroutine.
|
||||
5) Add a new definition property that allows the user to choose the type of currency
|
||||
to use for their shipping rate quote.
|
||||
|
||||
Country names and codes, and currency codes are ISO standards. Country codes are provided
|
||||
by the Locales module, ISO 3166. This module already has translations for 13 languages.
|
||||
For additional languages, they should be added as modules and sent to the Locales module
|
||||
maintainer.
|
||||
|
||||
Currency codes are not currently supported by this driver, nor is there an existing internationalized
|
||||
currency module. This should be a simple extension to Locales.
|
||||
|
|
@ -1,4 +1,13 @@
|
|||
7.8.4
|
||||
- Fixed a compatibility problem between WRE and new Spectre code.
|
||||
- fixed #11198: Typo in i18n
|
||||
- fixed #11202: USPS driver does not log authentication errors
|
||||
- fixed #10985: Survey: can't add multiple choice answer
|
||||
- fixed #11197: Survey Edit Console is not i18n'ed
|
||||
|
||||
7.8.3
|
||||
- Rewrote Spectre's workflow queues to prevent it from "forgetting" about some workflows.
|
||||
- fixed: RSS feeds generated with incorrect link for channel
|
||||
- Fixed an error being thrown by the CalendarUpdateFeeds workflow activity.
|
||||
- The auto add to group and auto delete from group operations that are used with the GroupAdd and GroupDelete macros were fixed to make the user log in if they aren't already.
|
||||
- fixed #11074: Links to CS posts not working
|
||||
|
|
@ -31,6 +40,13 @@
|
|||
- fixed #10984: Edit Survey Screen isn't right in demo
|
||||
- added: getTopKeywords method to Keywords API
|
||||
- added: print remaining tickets feature to EMS
|
||||
- fixed #11188: Incoherence in Navigation edit form
|
||||
- fixed #11189: Controls variable missing in image asset in AssetProxy
|
||||
- fixed #11190: event tmpl_var in help but not available
|
||||
- fixed #11194: Event Asset Recurrence form is not i18n'ed
|
||||
- fixed #11192: newByLineage tries to instantiate asset even if no assetId found
|
||||
- fixed #11195: Shop, sometimes free checkout does not work
|
||||
- added: UPS Shipping Driver
|
||||
|
||||
7.8.2
|
||||
- Added scheduled vendor payout workflow activity. (Special thanks to Martin @ Oqapi)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -7,6 +7,11 @@ upgrading from one version to the next, or even between multiple
|
|||
versions. Be sure to heed the warnings contained herein as they will
|
||||
save you many hours of grief.
|
||||
|
||||
7.8.3
|
||||
--------------------------------------------------------------------
|
||||
* WebGUI now requires Locales::Country 0.05 or higher to use
|
||||
the UPS shipping driver.
|
||||
|
||||
7.8.2
|
||||
--------------------------------------------------------------------
|
||||
* WebGUI now requires Business::PayPal::API 0.62 or higher.
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -41,6 +41,7 @@ addPickLanguageMacro($session);
|
|||
installSetLanguage($session);
|
||||
i18nAbleToBeFriend($session);
|
||||
addEMSEnhancements($session);
|
||||
installUPSDriver($session);
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
|
@ -55,6 +56,16 @@ sub addEMSEnhancements {
|
|||
print "Done.\n" unless $quiet;
|
||||
}
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
sub installUPSDriver {
|
||||
my $session = shift;
|
||||
print "\tAdding UPS Shipping Driver... " unless $quiet;
|
||||
$session->config->addToArray('shippingDrivers', 'WebGUI::Shop::ShipDriver::UPS');
|
||||
|
||||
print "Done.\n" unless $quiet;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
sub i18nAbleToBeFriend {
|
||||
my $session = shift;
|
||||
|
|
@ -131,6 +142,7 @@ sub addPickLanguageMacro {
|
|||
print "Done.\n" unless $quiet;
|
||||
}
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
sub installSetLanguage {
|
||||
my $session = shift;
|
||||
print "\tAdding SetLanguage content handler... " unless $quiet;
|
||||
|
|
|
|||
139
docs/upgrades/upgrade_7.8.3-7.8.4.pl
Normal file
139
docs/upgrades/upgrade_7.8.3-7.8.4.pl
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
||||
#-------------------------------------------------------------------
|
||||
# Please read the legal notices (docs/legal.txt) and the license
|
||||
# (docs/license.txt) that came with this distribution before using
|
||||
# this software.
|
||||
#-------------------------------------------------------------------
|
||||
# http://www.plainblack.com info@plainblack.com
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
our ($webguiRoot);
|
||||
|
||||
BEGIN {
|
||||
$webguiRoot = "../..";
|
||||
unshift (@INC, $webguiRoot."/lib");
|
||||
}
|
||||
|
||||
use strict;
|
||||
use Getopt::Long;
|
||||
use WebGUI::Session;
|
||||
use WebGUI::Storage;
|
||||
use WebGUI::Asset;
|
||||
|
||||
|
||||
my $toVersion = '7.8.4';
|
||||
my $quiet; # this line required
|
||||
|
||||
|
||||
my $session = start(); # this line required
|
||||
|
||||
# upgrade functions go here
|
||||
dropSkipNotification($session);
|
||||
|
||||
finish($session); # this line required
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Describe what our function does
|
||||
#sub exampleFunction {
|
||||
# my $session = shift;
|
||||
# print "\tWe're doing some stuff here that you should know about... " unless $quiet;
|
||||
# # and here's our code
|
||||
# print "DONE!\n" unless $quiet;
|
||||
#}
|
||||
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
sub dropSkipNotification {
|
||||
my $session = shift;
|
||||
print "\tRemoving duplicate skipNotification field from the Subscribable aspect... " unless $quiet;
|
||||
$session->db->write('alter table assetAspect_Subscribable drop column skipNotification');
|
||||
print "Done.\n" unless $quiet;
|
||||
}
|
||||
|
||||
# -------------- DO NOT EDIT BELOW THIS LINE --------------------------------
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Add a package to the import node
|
||||
sub addPackage {
|
||||
my $session = shift;
|
||||
my $file = shift;
|
||||
|
||||
# Make a storage location for the package
|
||||
my $storage = WebGUI::Storage->createTemp( $session );
|
||||
$storage->addFileFromFilesystem( $file );
|
||||
|
||||
# Import the package into the import node
|
||||
my $package = eval { WebGUI::Asset->getImportNode($session)->importPackage( $storage, { overwriteLatest => 1 } ); };
|
||||
|
||||
if ($package eq 'corrupt') {
|
||||
die "Corrupt package found in $file. Stopping upgrade.\n";
|
||||
}
|
||||
if ($@ || !defined $package) {
|
||||
die "Error during package import on $file: $@\nStopping upgrade\n.";
|
||||
}
|
||||
|
||||
# Turn off the package flag, and set the default flag for templates added
|
||||
my $assetIds = $package->getLineage( ['self','descendants'] );
|
||||
for my $assetId ( @{ $assetIds } ) {
|
||||
my $asset = WebGUI::Asset->newByDynamicClass( $session, $assetId );
|
||||
if ( !$asset ) {
|
||||
print "Couldn't instantiate asset with ID '$assetId'. Please check package '$file' for corruption.\n";
|
||||
next;
|
||||
}
|
||||
my $properties = { isPackage => 0 };
|
||||
if ($asset->isa('WebGUI::Asset::Template')) {
|
||||
$properties->{isDefault} = 1;
|
||||
}
|
||||
$asset->update( $properties );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub start {
|
||||
my $configFile;
|
||||
$|=1; #disable output buffering
|
||||
GetOptions(
|
||||
'configFile=s'=>\$configFile,
|
||||
'quiet'=>\$quiet
|
||||
);
|
||||
my $session = WebGUI::Session->open($webguiRoot,$configFile);
|
||||
$session->user({userId=>3});
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->set({name=>"Upgrade to ".$toVersion});
|
||||
return $session;
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub finish {
|
||||
my $session = shift;
|
||||
updateTemplates($session);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
$versionTag->commit;
|
||||
$session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".time().")");
|
||||
$session->close();
|
||||
}
|
||||
|
||||
#-------------------------------------------------
|
||||
sub updateTemplates {
|
||||
my $session = shift;
|
||||
return undef unless (-d "packages-".$toVersion);
|
||||
print "\tUpdating packages.\n" unless ($quiet);
|
||||
opendir(DIR,"packages-".$toVersion);
|
||||
my @files = readdir(DIR);
|
||||
closedir(DIR);
|
||||
my $newFolder = undef;
|
||||
foreach my $file (@files) {
|
||||
next unless ($file =~ /\.wgpkg$/);
|
||||
# Fix the filename to include a path
|
||||
$file = "packages-" . $toVersion . "/" . $file;
|
||||
addPackage( $session, $file );
|
||||
}
|
||||
}
|
||||
|
||||
#vim:ft=perl
|
||||
|
|
@ -190,7 +190,8 @@
|
|||
|
||||
"shippingDrivers" : [
|
||||
"WebGUI::Shop::ShipDriver::FlatRate",
|
||||
"WebGUI::Shop::ShipDriver::USPS"
|
||||
"WebGUI::Shop::ShipDriver::USPS",
|
||||
"WebGUI::Shop::ShipDriver::UPS"
|
||||
],
|
||||
|
||||
# Specify the list of template parsers available in the system.
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ use strict;
|
|||
use HTTP::Request::Common;
|
||||
use HTTP::Cookies;
|
||||
use POE qw(Component::Client::HTTP);
|
||||
use POE::Queue::Array;
|
||||
use Tie::IxHash;
|
||||
use JSON qw/ encode_json /;
|
||||
use Clone qw(clone);
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
|
|
@ -31,12 +31,12 @@ Initializes the workflow manager.
|
|||
=cut
|
||||
|
||||
sub _start {
|
||||
my ( $kernel, $self, $publicEvents) = @_[ KERNEL, OBJECT, ARG0 ];
|
||||
my ( $kernel, $self, $publicEvents) = @_[ KERNEL, OBJECT, ARG0 ];
|
||||
$self->debug("Starting workflow manager.");
|
||||
my $serviceName = "workflow";
|
||||
$kernel->alias_set($serviceName);
|
||||
$kernel->call( IKC => publish => $serviceName, $publicEvents );
|
||||
$kernel->yield("checkInstances");
|
||||
my $serviceName = "workflow";
|
||||
$kernel->alias_set($serviceName);
|
||||
$kernel->call( IKC => publish => $serviceName, $publicEvents );
|
||||
$kernel->yield("checkInstances");
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -81,11 +81,13 @@ sub addInstance {
|
|||
my ($self, $instance) = @_[OBJECT, ARG0];
|
||||
if ($instance->{priority} < 1 || $instance->{instanceId} eq "" || $instance->{sitename} eq "") {
|
||||
$self->error("Can't add workflow instance with missing data: ". $instance->{sitename}." - ".$instance->{instanceId});
|
||||
} else {
|
||||
my $priority = ($instance->{priority} -1) * 10;
|
||||
$instance->{lastState} = "never run";
|
||||
$self->debug("Adding workflow instance ".$instance->{instanceId}." from ".$instance->{sitename}." to queue at priority ".$priority.".");
|
||||
$self->getWaitingQueue->enqueue($priority, $instance);
|
||||
}
|
||||
else {
|
||||
$instance->{workingPriority} = ($instance->{priority} -1) * 10;
|
||||
$instance->{lastState} = 'never run';
|
||||
$instance->{status} = 'waiting';
|
||||
$self->debug("Adding workflow instance ".$instance->{instanceId}." from ".$instance->{sitename}." to queue at priority ".$instance->{workingPriority}.".");
|
||||
$self->{_queue}{$instance->{instanceId}} = $instance;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,7 +103,6 @@ sub checkInstances {
|
|||
my ($kernel, $self) = @_[KERNEL, OBJECT];
|
||||
$self->debug("Checking to see if we can run anymore instances right now.");
|
||||
if ($self->countRunningInstances < $self->config->get("maxWorkers")) {
|
||||
$self->debug("Total workflows waiting to run: ".$self->getWaitingQueue->get_item_count);
|
||||
my $instance = $self->getNextInstance;
|
||||
if (defined $instance) {
|
||||
$kernel->yield("runWorker",$instance);
|
||||
|
|
@ -133,9 +134,14 @@ Returns an integer representing the number of running instances.
|
|||
|
||||
sub countRunningInstances {
|
||||
my $self = shift;
|
||||
my $instanceCount = $self->getRunningQueue->get_item_count;
|
||||
$self->debug("There are $instanceCount running instances.");
|
||||
return $instanceCount;
|
||||
my $count = 0;
|
||||
foreach my $instance ($self->getInstances) {
|
||||
if ($instance->{status} eq 'running') {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
$self->debug("There are $count running instances.");
|
||||
return $count;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -170,14 +176,7 @@ Removes a workflow instance from the processing queue.
|
|||
sub deleteInstance {
|
||||
my ($self, $instanceId,$kernel, $session ) = @_[OBJECT, ARG0, KERNEL, SESSION];
|
||||
$self->debug("Deleting workflow instance $instanceId from queue.");
|
||||
$self->getWaitingQueue->remove_items(
|
||||
sub {
|
||||
my $instance = shift;
|
||||
return 1 if ($instance->{instanceId} eq $instanceId);
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
$self->removeInstanceFromRunningQueue($instanceId);
|
||||
delete $self->{_queue}{$instanceId};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -209,35 +208,20 @@ sub editWorkflowPriority {
|
|||
|
||||
$self->debug("Updating the priority of $instanceId to $newPriority.");
|
||||
|
||||
# I'm guessing that the payload can't change queues on us
|
||||
my $found = 0;
|
||||
my $filterCref = sub { shift->{instanceId} eq $instanceId };
|
||||
for my $getQueueMethod (map "get${_}Queue", qw( Suspended Waiting Running )) {
|
||||
my $q = $self->$getQueueMethod;
|
||||
my($itemAref) = $q->peek_items($filterCref); # there should be only one
|
||||
my $instance = $self->getInstance($instanceId);
|
||||
|
||||
next unless (ref $itemAref eq 'ARRAY' and @$itemAref);
|
||||
|
||||
my($priority, $id, $payload) = @$itemAref;
|
||||
my $ackPriority = $q->set_priority($id, $filterCref, $newPriority);
|
||||
if ($ackPriority != $newPriority) {
|
||||
# return an error
|
||||
my $error = 'edit priority setting error';
|
||||
$kernel->call(IKC=>post=>$rsvp, encode_json({message => $error}));
|
||||
}
|
||||
$found = 1;
|
||||
last;
|
||||
if (defined $instance) {
|
||||
$instance->{priority} = $newPriority;
|
||||
$instance->{workingPriority} = ($instance->{priority} -1) * 10;
|
||||
$self->updateInstance($instance);
|
||||
# return success message
|
||||
$kernel->call(IKC=>post=>$rsvp, encode_json({message => 'edit priority success'}));
|
||||
}
|
||||
|
||||
if (! $found) {
|
||||
else {
|
||||
# return an error message
|
||||
my $error = 'edit priority instance not found error';
|
||||
$kernel->call(IKC=>post=>$rsvp, encode_json({message => $error}));
|
||||
}
|
||||
else {
|
||||
# return success message
|
||||
$kernel->call(IKC=>post=>$rsvp, encode_json({message => 'edit priority success'}));
|
||||
}
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -253,8 +237,7 @@ The error message to be printed if debug is enabled.
|
|||
=cut
|
||||
|
||||
sub error {
|
||||
my $self = shift;
|
||||
my $output = shift;
|
||||
my ($self, $output) = @_;
|
||||
if ($self->{_debug}) {
|
||||
print "WORKFLOW: [Error] ".$output."\n";
|
||||
}
|
||||
|
|
@ -263,86 +246,90 @@ sub error {
|
|||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getInstance ( instanceId )
|
||||
|
||||
Returns the properties of an instance.
|
||||
|
||||
=head3 instanceId
|
||||
|
||||
The id of the instance to retrieve.
|
||||
|
||||
=cut
|
||||
|
||||
sub getInstance {
|
||||
my ($self, $instanceId) = @_;
|
||||
return clone($self->{_queue}{$instanceId});
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getInstances ( )
|
||||
|
||||
Returns the array of instances from the queue.
|
||||
|
||||
=cut
|
||||
|
||||
sub getInstances {
|
||||
my ($self) = @_;
|
||||
my @instances = values %{$self->{_queue}};
|
||||
return @{clone(\@instances)};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getJsonStatus ( )
|
||||
|
||||
Returns JSON report about the workflow engine.
|
||||
Returns JSON report about the workflow engine. Depricated, use getStatus() instead.
|
||||
|
||||
=cut
|
||||
|
||||
sub getJsonStatus {
|
||||
my ($kernel, $request, $self) = @_[KERNEL,ARG0,OBJECT];
|
||||
my ($sitename, $rsvp) = @$request;
|
||||
|
||||
my %queues = ();
|
||||
tie %queues, 'Tie::IxHash';
|
||||
%queues = (
|
||||
Suspended => $self->getSuspendedQueue,
|
||||
Waiting => $self->getWaitingQueue,
|
||||
Running => $self->getRunningQueue,
|
||||
);
|
||||
|
||||
my %output = ();
|
||||
foreach my $queueName (keys %queues) {
|
||||
|
||||
# get the queue name, and how many items it has
|
||||
my $queue = $queues{$queueName};
|
||||
my $count = $queue->get_item_count;
|
||||
|
||||
# list of instances to be added to the %output structure in the event
|
||||
# that a site name is provided
|
||||
my @instances;
|
||||
|
||||
# and if there are items in that queue, add them to our data structure
|
||||
if ($count > 0) {
|
||||
|
||||
# if a site name is provided, only process data for that site name,
|
||||
# and only construct data for that site name
|
||||
if($sitename ne '') {
|
||||
foreach my $itemAref ($queue->peek_items(sub { shift()->{sitename} eq $sitename })) {
|
||||
push @instances, $itemAref;
|
||||
}
|
||||
$output{$queueName} = \@instances;
|
||||
}
|
||||
|
||||
# otherwise, process data for all sites.
|
||||
else {
|
||||
foreach my $queueItem ($queue->peek_items(sub {1})) {
|
||||
my($priority, $id, $instance) = @{$queueItem};
|
||||
|
||||
# The site's name in the list of %output keys isn't a hashref;
|
||||
# we haven't seen it yet
|
||||
if(ref $output{$instance->{sitename}} ne 'HASH') {
|
||||
$output{$instance->{sitename}} = {};
|
||||
}
|
||||
|
||||
# The queue name in the $output{sitename} hashref isn't an
|
||||
# arrayref; we haven't seen it yet
|
||||
if(ref $output{$instance->{sitename}}{$queueName} ne 'ARRAY') {
|
||||
$output{$instance->{sitename}}{$queueName} = [];
|
||||
}
|
||||
|
||||
# calculate originalPriority separately
|
||||
$instance->{originalPriority} = ($instance->{priority} - 1) * 10;
|
||||
|
||||
# finally, add the instance to the returned data structure
|
||||
push @{$output{$instance->{sitename}}{$queueName}}, $instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
# there's no items in this queue, but the version of this call that
|
||||
# accepts a sitename expects an empty array ref anyway. Give it one.
|
||||
else {
|
||||
if($sitename) {
|
||||
$output{$queueName} = \@instances;
|
||||
}
|
||||
my %queues = (
|
||||
Waiting => [],
|
||||
Suspended => [],
|
||||
Running => [],
|
||||
);
|
||||
my %output;
|
||||
if ($sitename) { #must have entry for each queue
|
||||
%output = %queues;
|
||||
foreach my $instance ($self->getInstances) {
|
||||
my $queue = ucfirst($instance->{status});
|
||||
push @{$output{$queue}}, [$instance->{workingPriority}, $instance->{instanceId}, $instance];
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach my $instance ($self->getInstances) {
|
||||
my $site = $instance->{sitename};
|
||||
unless (exists $output{$site}) { # must have an entry for each queue in each site
|
||||
$output{$site} = \%queues;
|
||||
}
|
||||
my $queue = ucfirst($instance->{status});
|
||||
push @{$output{$site}{$queue}}, $instance;
|
||||
}
|
||||
}
|
||||
|
||||
$kernel->call(IKC=>post=>$rsvp, encode_json(\%output));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getStatus ( )
|
||||
|
||||
Returns JSON report about the workflow engine. Returns an array reference of hash references of instance data. Each instance contains the following fields: instanceId, status, lastState, sitename, priority, and workingPriority.
|
||||
|
||||
=cut
|
||||
|
||||
sub getStatus {
|
||||
my ($kernel, $request, $self) = @_[KERNEL,ARG0,OBJECT];
|
||||
my ($data, $rsvp) = @$request;
|
||||
my @instances = $self->getInstances;
|
||||
$kernel->call(IKC=>post=>$rsvp, encode_json(\@instances));
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getLogger ( )
|
||||
|
||||
Returns a reference to the logger.
|
||||
|
|
@ -365,99 +352,29 @@ Returns the next available instance.
|
|||
sub getNextInstance {
|
||||
my $self = shift;
|
||||
$self->debug("Looking for a workflow instance to run.");
|
||||
my $waiting = $self->getWaitingQueue;
|
||||
if ($waiting->get_item_count > 0) {
|
||||
my ($priority, $id, $instance) = $waiting->dequeue_next;
|
||||
$instance->{workingPriority} = $priority;
|
||||
$self->getRunningQueue->enqueue($priority, $instance);
|
||||
$self->debug("Looks like ".$instance->{instanceId}." at priority $priority would be a good workflow instance to run.");
|
||||
return $instance;
|
||||
my @instances = $self->getInstances;
|
||||
if (scalar(@instances) > 0) {
|
||||
my $lowInstance = {};
|
||||
my $lowPriority = 999999999999;
|
||||
my $waitingCount = 0;
|
||||
foreach my $instance (@instances) {
|
||||
next unless $instance->{status} eq 'waiting';
|
||||
$waitingCount++;
|
||||
if ($instance->{workingPriority} < $lowPriority) {
|
||||
$lowInstance = $instance;
|
||||
$lowPriority = $instance->{workingPriority};
|
||||
}
|
||||
}
|
||||
$self->debug("Total workflows waiting to run: ".$waitingCount);
|
||||
if ($lowInstance->{instanceId} ne '') {
|
||||
$self->debug("Looks like ".$lowInstance->{instanceId}." would be a good workflow instance to run.");
|
||||
return $lowInstance;
|
||||
}
|
||||
}
|
||||
$self->debug("Didn't see any workflow instances to run.");
|
||||
return undef;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getRunningQueue ( )
|
||||
|
||||
Returns a reference to the queue of workflow instances that are running now.
|
||||
|
||||
=cut
|
||||
|
||||
sub getRunningQueue {
|
||||
my $self = shift;
|
||||
return $self->{_runningQueue};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getStatus ( )
|
||||
|
||||
Returns a formatted text status report about the workflow engine.
|
||||
|
||||
=cut
|
||||
|
||||
sub getStatus {
|
||||
my ($kernel, $request, $self) = @_[KERNEL,ARG0,OBJECT];
|
||||
my $pattern = "\t%8.8s %-30.30s %-22.22s %-15.15s %-20.20s\n";
|
||||
my $summaryPattern = "%19.19s %4d\n";
|
||||
my %queues = ();
|
||||
tie %queues, 'Tie::IxHash';
|
||||
%queues = (
|
||||
"Suspended" => $self->getSuspendedQueue,
|
||||
"Waiting" => $self->getWaitingQueue,
|
||||
"Running" => $self->getRunningQueue,
|
||||
);
|
||||
my $total = 0;
|
||||
my $output = "";
|
||||
foreach my $queueName (keys %queues) {
|
||||
my $queue = $queues{$queueName};
|
||||
my $count = $queue->get_item_count;
|
||||
$output .= sprintf $summaryPattern, $queueName." Workflows", $count;
|
||||
if ($count > 0) {
|
||||
$output .= sprintf $pattern, "Priority", "Sitename", "Instance Id", "Last State", "Last Run Time";
|
||||
foreach my $item ($queue->peek_items(sub {1})) {
|
||||
my ($priority, $id, $instance) = @{$item};
|
||||
my $originalPriority = ($instance->{priority} - 1) * 10;
|
||||
$output .= sprintf $pattern, $priority."/".$originalPriority, $instance->{sitename}, $instance->{instanceId}, $instance->{lastState}, $instance->{lastRunTime};
|
||||
}
|
||||
$output .= "\n";
|
||||
}
|
||||
$total += $count;
|
||||
}
|
||||
$output .= sprintf $summaryPattern, "Total Workflows", $total;
|
||||
my ($data, $rsvp) = @$request;
|
||||
$kernel->call(IKC=>post=>$rsvp,$output);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getSuspendedQueue ( )
|
||||
|
||||
Returns a reference to the queue of workflow instances that have been suspended due to error or wait timeouts.
|
||||
|
||||
=cut
|
||||
|
||||
sub getSuspendedQueue {
|
||||
my $self = shift;
|
||||
return $self->{_suspendedQueue};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getWaitingQueue ( )
|
||||
|
||||
Returns a reference to the queue of workflow instances waiting to run.
|
||||
|
||||
=cut
|
||||
|
||||
sub getWaitingQueue {
|
||||
my $self = shift;
|
||||
return $self->{_waitingQueue};
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 new ( config, logger, [ , debug ] )
|
||||
|
|
@ -496,34 +413,10 @@ sub new {
|
|||
Alias => 'workflow-ua',
|
||||
CookieJar => $cookies
|
||||
);
|
||||
$self->{_runningQueue} = POE::Queue::Array->new;
|
||||
$self->{_waitingQueue} = POE::Queue::Array->new;
|
||||
$self->{_suspendedQueue} = POE::Queue::Array->new;
|
||||
$self->{_queue} = {};
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 removeInstanceFromRunningQueue ( )
|
||||
|
||||
Removes a workflow instance from the queue that tracks what's running and returns a reference to it.
|
||||
|
||||
=cut
|
||||
|
||||
sub removeInstanceFromRunningQueue {
|
||||
my $self = shift;
|
||||
my $instanceId = shift;
|
||||
my @items = $self->getRunningQueue->remove_items(
|
||||
sub {
|
||||
my $payload = shift;
|
||||
return 1 if ($payload->{instanceId} eq $instanceId);
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
my $instance = $items[0][2];
|
||||
return $instance;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 returnInstanceToRunnableState ( )
|
||||
|
|
@ -535,14 +428,8 @@ Returns a workflow instance back to runnable queue.
|
|||
sub returnInstanceToRunnableState {
|
||||
my ($self, $instance) = @_[OBJECT, ARG0];
|
||||
$self->debug("Returning ".$instance->{instanceId}." to runnable state.");
|
||||
$self->getSuspendedQueue->remove_items(
|
||||
sub {
|
||||
my $payload = shift;
|
||||
return 1 if ($payload->{instanceId} eq $instance->{instanceId});
|
||||
return 0;
|
||||
}
|
||||
);
|
||||
$self->getWaitingQueue->enqueue($instance->{workingPriority}+1, $instance);
|
||||
$instance->{status} = 'waiting';
|
||||
$self->updateInstance($instance);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
|
@ -556,6 +443,10 @@ Calls a worker to execute a workflow activity.
|
|||
sub runWorker {
|
||||
my ($kernel, $self, $instance, $session) = @_[KERNEL, OBJECT, ARG0, SESSION];
|
||||
$self->debug("Preparing to run workflow instance ".$instance->{instanceId}.".");
|
||||
$self->debug("Incrementing ".$instance->{instanceId}." priority from ".$instance->{workingPriority});
|
||||
$instance->{workingPriority}++;
|
||||
$instance->{status} = 'running';
|
||||
$self->updateInstance($instance);
|
||||
my $url = "http://".$instance->{sitename}.':'.$self->config->get("webguiPort").$instance->{gateway};
|
||||
my $request = POST $url, [op=>"runWorkflow", instanceId=>$instance->{instanceId}];
|
||||
my $cookie = $self->{_cookies}{$instance->{sitename}};
|
||||
|
|
@ -576,14 +467,33 @@ Suspends a workflow instance for a number of seconds defined in the config file,
|
|||
=cut
|
||||
|
||||
sub suspendInstance {
|
||||
my ($self, $instance, $waitTimeout, $kernel) = @_[OBJECT, ARG0, ARG1, KERNEL];
|
||||
my ($self, $kernel, $instance, $waitTimeout) = @_[OBJECT, KERNEL, ARG0, ARG1];
|
||||
$waitTimeout ||= $self->config->get("suspensionDelay");
|
||||
$self->debug("Suspending workflow instance ".$instance->{instanceId}." for ".$waitTimeout." seconds.");
|
||||
my $priority = ($instance->{priority} - 1) * 10;
|
||||
$self->getSuspendedQueue->enqueue($priority, $instance);
|
||||
$instance->{status} = 'suspended';
|
||||
$self->updateInstance($instance);
|
||||
$kernel->delay_set("returnInstanceToRunnableState", $waitTimeout, $instance);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 updateInstance ( properties )
|
||||
|
||||
Updates an instance's properties.
|
||||
|
||||
=head3 properties
|
||||
|
||||
A hash reference of the properties of the instance.
|
||||
|
||||
=cut
|
||||
|
||||
sub updateInstance {
|
||||
my ($self, $instance) = @_;
|
||||
$self->debug("Updating ".$instance->{instanceId}."'s properties.");
|
||||
$self->{_queue}{$instance->{instanceId}} = $instance;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 workerResponse ( )
|
||||
|
|
@ -596,10 +506,14 @@ sub workerResponse {
|
|||
my ($self, $kernel, $requestPacket, $responsePacket) = @_[OBJECT, KERNEL, ARG0, ARG1];
|
||||
$self->debug("Retrieving response from workflow instance.");
|
||||
my $request = $requestPacket->[0];
|
||||
my $response = $responsePacket->[0];
|
||||
my $response = $responsePacket->[0];
|
||||
my $instanceId = $request->header("X-instanceId"); # got to figure out how to get this from the request, cuz the response may die
|
||||
$self->debug("Response retrieved is for $instanceId.");
|
||||
my $instance = $self->removeInstanceFromRunningQueue($instanceId);
|
||||
my $instance = $self->getInstance($instanceId);
|
||||
unless (defined $instance) {
|
||||
$self->debug("Instance $instanceId no longer exist in my queue, so there's no reason to process the response.");
|
||||
return;
|
||||
}
|
||||
if ($response->is_success) {
|
||||
$self->debug("Response for $instanceId retrieved successfully.");
|
||||
if ($response->header("Set-Cookie") ne "") {
|
||||
|
|
@ -613,8 +527,8 @@ sub workerResponse {
|
|||
$instance->{lastState} = $state;
|
||||
$instance->{lastRunTime} = localtime(time());
|
||||
if ($state =~ m/^waiting\s*(\d+)?$/) {
|
||||
my $waitTime = $1;
|
||||
$self->debug("Was told to wait on $instanceId because we're still waiting on some external event.");
|
||||
my $waitTime = $1;
|
||||
$self->debug("Was told to suspend $instanceId because we're still waiting on some external event.");
|
||||
$kernel->yield("suspendInstance",$instance, $waitTime);
|
||||
}
|
||||
elsif ($state eq "complete") {
|
||||
|
|
@ -634,7 +548,7 @@ sub workerResponse {
|
|||
$kernel->yield("suspendInstance",$instance);
|
||||
}
|
||||
else {
|
||||
$self->error("Something bad happened on the return of $instance->{sitename} - $instanceId. ".$response->error_as_HTML);
|
||||
$self->error("Something bad happened on the return of $instance->{sitename} - $instanceId. ".$response->code.": ".$response->message);
|
||||
$kernel->yield("suspendInstance",$instance);
|
||||
}
|
||||
}
|
||||
|
|
@ -642,11 +556,12 @@ sub workerResponse {
|
|||
$self->error("Response for $instance->{sitename} - $instanceId was redirected. This should never happen if configured properly!!!");
|
||||
$instance->{lastState} = "redirect";
|
||||
$instance->{lastRunTime} = localtime(time());
|
||||
$kernel->yield("suspendInstance",$instance)
|
||||
}
|
||||
elsif ($response->is_error) {
|
||||
$instance->{lastState} = "comm error";
|
||||
$instance->{lastRunTime} = localtime(time());
|
||||
$self->error("Response for $instance->{sitename} - $instanceId had a communications error. ".$response->error_as_HTML);
|
||||
$self->error("Response for $instance->{sitename} - $instanceId had a communications error. ".$response->code.": ".$response->message);
|
||||
$kernel->yield("suspendInstance",$instance)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package WebGUI;
|
||||
|
||||
|
||||
our $VERSION = '7.8.3';
|
||||
our $VERSION = '7.8.4';
|
||||
our $STATUS = 'beta';
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1096,7 +1096,7 @@ sub getEditForm {
|
|||
}
|
||||
}
|
||||
|
||||
# send back the rendered form
|
||||
# send back the object
|
||||
return $tabform;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2063,6 +2063,13 @@ sub www_edit {
|
|||
size => 22,
|
||||
});
|
||||
|
||||
# synopsis
|
||||
$var->{"formSynopsis"}
|
||||
= WebGUI::Form::textarea($session, {
|
||||
name => "synopsis",
|
||||
value => $form->process("synopsis") || $self->get("synopsis"),
|
||||
});
|
||||
|
||||
# Group to View
|
||||
$var->{"formGroupIdView"}
|
||||
= WebGUI::Form::Group($session, {
|
||||
|
|
@ -2202,22 +2209,23 @@ sub www_edit {
|
|||
: $self->isAllDay
|
||||
;
|
||||
|
||||
my $i18n = WebGUI::International->new($session, 'Asset_Event');
|
||||
$var->{"formTime"}
|
||||
= q|<input id="allday_yes" type="radio" name="allday" value="yes" |
|
||||
. ($allday ? 'checked="checked"' : '')
|
||||
. q| />
|
||||
<label for="allday_yes">No specific time (All day event)</label>
|
||||
<label for="allday_yes">|. $i18n->get('No specific time'). q|</label>
|
||||
<br/>
|
||||
<input id="allday_no" type="radio" name="allday" value="" |
|
||||
. (!$allday ? 'checked="checked"' : '')
|
||||
. q| />
|
||||
<label for="allday_no">Specific start/end time</label>
|
||||
<label for="allday_no">|. $i18n->get('Specific start/end time'). q|</label>
|
||||
<br />
|
||||
<div id="times">|
|
||||
. q|Start: |.$var->{"formStartTime"}
|
||||
. q|<br/>End: |.$var->{"formEndTime"}
|
||||
. q|<br/>Time Zone: |.$var->{formTimeZone}
|
||||
. q|</div>|;
|
||||
. $i18n->get('start') . q|: | . $var->{"formStartTime"} . q|<br/>|
|
||||
. $i18n->get('end') . q|: | . $var->{"formEndTime"} . q|<br/>|
|
||||
. $i18n->get('timezone', 'DateTime'). q|: | . $var->{formTimeZone} . q|</div>|
|
||||
;
|
||||
|
||||
###### related links
|
||||
my $relatedLinks = $self->getRelatedLinks();
|
||||
|
|
@ -2234,8 +2242,8 @@ sub www_edit {
|
|||
value => $form->process("rel_group_id_".$_->{eventlinkId}) || $_->{groupIdView} || $self->getParent->get("groupIdView"),
|
||||
defaultValue => $self->getParent->get("groupIdView"),
|
||||
});
|
||||
$_->{seq_num_name} = "rel_seq_".$_->{eventlinkId};
|
||||
$_->{seq_num_id} = "rel_seq_id_".$_->{eventlinkId};
|
||||
$_->{seq_num_name} = "rel_seq_".$_->{eventlinkId};
|
||||
$_->{seq_num_id} = "rel_seq_id_".$_->{eventlinkId};
|
||||
$_->{seq_num_value} = $seqNum++;
|
||||
}
|
||||
$var->{"relatedLinks"} = $relatedLinks;
|
||||
|
|
@ -2258,90 +2266,88 @@ sub www_edit {
|
|||
= q|
|
||||
<div id="recurPattern">
|
||||
<p><input type="radio" name="recurType" id="recurType_none" value="none" onclick="toggleRecur()" />
|
||||
<label for="recurType_none">None</label></p>
|
||||
<label for="recurType_none">|. $i18n->get(881,'WebGUI'). q|</label></p>
|
||||
|
||||
|
||||
<p><input type="radio" name="recurType" id="recurType_daily" value="daily" onclick="toggleRecur()" |.($recur{recurType} =~ /^(daily|weekday)$/ ? q|checked="checked"| : q||).q|/>
|
||||
<label for="recurType_daily">Daily</label></p>
|
||||
<label for="recurType_daily">|. $i18n->get('Daily'). q|</label></p>
|
||||
<div style="margin-left: 4em;" id="recurPattern_daily">
|
||||
Every <input type="text" name="recurDay" size="3" value="|.$recur{every}.q|" /><br/>
|
||||
|. $i18n->get('Every'). q| <input type="text" name="recurDay" size="3" value="|.$recur{every}.q|" /><br/>
|
||||
<input type="radio" name="recurSubType" id="recurSubType_daily" value="daily" |.($recur{recurType} eq "daily" ? q|checked="checked"| : q||).q|/>
|
||||
<label for="recurSubType_daily">Day(s)</label><br />
|
||||
<label for="recurSubType_daily">|. $i18n->get(700, 'WebGUI'). q|</label><br />
|
||||
<input type="radio" name="recurSubType" id="recurSubType_weekday" value="weekday" |.($recur{recurType} eq "weekday" ? q|checked="checked"| : q||).q|/>
|
||||
<label for="recurSubType_weekday">Weekday(s)</label>
|
||||
<label for="recurSubType_weekday">|. $i18n->get('Weekday(s)'). q|</label>
|
||||
</div>
|
||||
|
||||
|
||||
<p><input type="radio" name="recurType" id="recurType_weekly" value="weekly" onclick="toggleRecur()" |.($recur{recurType} eq "weekly" ? q|checked="checked"| : q||).q|/>
|
||||
<label for="recurType_weekly">Weekly</label></p>
|
||||
<label for="recurType_weekly">|. $i18n->get('Weekly'). q|</label></p>
|
||||
<div style="margin-left: 4em;" id="recurPattern_weekly">
|
||||
Every <input type="text" name="recurWeek" size="3" value="|.$recur{every}.q|" /> week(s) on<br/>
|
||||
|. sprintf($i18n->get('Every N weeks on'), q|<input type="text" name="recurWeek" size="3" value="|.$recur{every}.q|" />|). q|<br/>
|
||||
<input type="checkbox" name="recurWeekDay" value="u" id="recurWeekDay_U" |.(grep(/u/,@{$recur{dayNames}}) ? 'checked="checked"' : '' ).q|/>
|
||||
<label for="recurWeekDay_U">Sunday</label><br/>
|
||||
<label for="recurWeekDay_U">|. $i18n->get('sunday', 'DateTime'). q|</label><br/>
|
||||
<input type="checkbox" name="recurWeekDay" value="m" id="recurWeekDay_M" |.(grep(/m/,@{$recur{dayNames}}) ? 'checked="checked"' : '' ).q|/>
|
||||
<label for="recurWeekDay_M">Monday</label><br/>
|
||||
<label for="recurWeekDay_M">|. $i18n->get('monday', 'DateTime'). q|</label><br/>
|
||||
<input type="checkbox" name="recurWeekDay" value="t" id="recurWeekDay_T" |.(grep(/t/,@{$recur{dayNames}}) ? 'checked="checked"' : '' ).q|/>
|
||||
<label for="recurWeekDay_T">Tuesday</label><br/>
|
||||
<label for="recurWeekDay_T">|. $i18n->get('tuesday', 'DateTime'). q|</label><br/>
|
||||
<input type="checkbox" name="recurWeekDay" value="w" id="recurWeekDay_W" |.(grep(/w/,@{$recur{dayNames}}) ? 'checked="checked"' : '' ).q|/>
|
||||
<label for="recurWeekDay_W">Wednesday</label><br/>
|
||||
<label for="recurWeekDay_W">|. $i18n->get('wednesday', 'DateTime'). q|</label><br/>
|
||||
<input type="checkbox" name="recurWeekDay" value="r" id="recurWeekDay_R" |.(grep(/r/,@{$recur{dayNames}}) ? 'checked="checked"' : '' ).q|/>
|
||||
<label for="recurWeekDay_R">Thursday</label><br/>
|
||||
<label for="recurWeekDay_R">|. $i18n->get('thursday', 'DateTime'). q|</label><br/>
|
||||
<input type="checkbox" name="recurWeekDay" value="f" id="recurWeekDay_F" |.(grep(/f/,@{$recur{dayNames}}) ? 'checked="checked"' : '' ).q|/>
|
||||
<label for="recurWeekDay_F">Friday</label><br/>
|
||||
<label for="recurWeekDay_F">|. $i18n->get('friday', 'DateTime'). q|</label><br/>
|
||||
<input type="checkbox" name="recurWeekDay" value="s" id="recurWeekDay_S" |.(grep(/s/,@{$recur{dayNames}}) ? 'checked="checked"' : '' ).q|/>
|
||||
<label for="recurWeekDay_S">Saturday</label><br/>
|
||||
<label for="recurWeekDay_S">|. $i18n->get('saturday', 'DateTime'). q|</label><br/>
|
||||
</div>
|
||||
|
||||
|
||||
<p><input type="radio" name="recurType" id="recurType_monthly" value="monthly" onclick="toggleRecur()" |.($recur{recurType} =~ /^month/ ? q|checked="checked"| : q||).q|/>
|
||||
<label for="recurType_monthly">Monthly</label></p>
|
||||
<label for="recurType_monthly">|. $i18n->get('Monthly'). q|</label></p>
|
||||
<div style="margin-left: 4em;" id="recurPattern_monthly">
|
||||
<p>Every <input type="text" name="recurMonth" size="3" value="|.$recur{every}.q|" /> month(s) on</p>
|
||||
<p>|. sprintf($i18n->get('Every N months on'), q|<input type="text" name="recurMonth" size="3" value="|.$recur{every}.q|" />|). q|</p>
|
||||
<p><input type="radio" name="recurSubType" id="recurSubType_monthDay" value="monthDay" |.($recur{recurType} eq "monthDay" ? q|checked="checked"| : q||).q|/>
|
||||
<label for="recurSubType_monthDay">day </label>
|
||||
<label for="recurSubType_monthDay">|. $i18n->get('day'). q| </label>
|
||||
<input type="text" name="recurMonthDay" size="3" value="|.$recur{dayNumber}.q|"></p>
|
||||
|
||||
<p>
|
||||
<input style="vertical-align: top;" type="radio" name="recurSubType" id="recurSubType_monthWeek" value="monthWeek" |.($recur{recurType} eq "monthWeek" ? q|checked="checked"| : q||).q|/>
|
||||
<select style="vertical-align: top;" name="recurMonthWeekNumber">
|
||||
<option |.(grep(/first/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>first</option>
|
||||
<option |.(grep(/second/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>second</option>
|
||||
<option |.(grep(/third/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>third</option>
|
||||
<option |.(grep(/fourth/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>fourth</option>
|
||||
<option |.(grep(/fifth/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>last</option>
|
||||
</select> week on
|
||||
<option value="first" |.(grep(/first/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>|. $i18n->get('first'). q|</option>
|
||||
<option value="second" |.(grep(/second/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>|. $i18n->get('second'). q|</option>
|
||||
<option value="third" |.(grep(/third/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>|. $i18n->get('third'). q|</option>
|
||||
<option value="fourth" |.(grep(/fourth/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>|. $i18n->get('fourth'). q|</option>
|
||||
<option value="fifth" |.(grep(/fifth/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>|. $i18n->get('last'). q|</option>
|
||||
</select> |. $i18n->get('week on'). q|
|
||||
<select style="vertical-align: top;" name="recurMonthWeekDay">
|
||||
<option value="u" |.(grep(/u/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>Sunday</option>
|
||||
<option value="m" |.(grep(/m/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>Monday</option>
|
||||
<option value="t" |.(grep(/t/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>Tuesday</option>
|
||||
<option value="w" |.(grep(/w/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>Wednesday</option>
|
||||
<option value="r" |.(grep(/r/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>Thursday</option>
|
||||
<option value="f" |.(grep(/f/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>Friday</option>
|
||||
<option value="s" |.(grep(/s/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>Saturday</option>
|
||||
<option value="u" |.(grep(/u/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('sunday', 'DateTime'). q|</option>
|
||||
<option value="m" |.(grep(/m/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('monday', 'DateTime'). q|</option>
|
||||
<option value="t" |.(grep(/t/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('tuesday', 'DateTime'). q|</option>
|
||||
<option value="w" |.(grep(/w/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('wednesday', 'DateTime'). q|</option>
|
||||
<option value="r" |.(grep(/r/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('thursday', 'DateTime'). q|</option>
|
||||
<option value="f" |.(grep(/f/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('friday', 'DateTime'). q|</option>
|
||||
<option value="s" |.(grep(/s/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('saturday', 'DateTime'). q|</option>
|
||||
</select>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
<p><input type="radio" name="recurType" id="recurType_yearly" value="yearly" onclick="toggleRecur()" |.($recur{recurType} =~ /^year/ ? q|checked="checked"| : q||).q|/>
|
||||
<label for="recurType_yearly">Yearly</label></p>
|
||||
<label for="recurType_yearly">|. $i18n->get('Yearly'). q|</label></p>
|
||||
<div style="margin-left: 4em;" id="recurPattern_yearly">
|
||||
<p>Every <input type="text" name="recurYear" size="3" value="|.$recur{every}.q|" /> years(s) on</p>
|
||||
<p>|. sprintf($i18n->get('Every N years on'),q|<input type="text" name="recurYear" size="3" value="|.$recur{every}.q|" />|). q|</p>
|
||||
<p>
|
||||
<input type="radio" name="recurSubType" id="recurSubType_yearDay" value="yearDay" |.($recur{recurType} eq "yearDay" ? q|checked="checked"| : q||).q|/>
|
||||
<select name="recurYearDayMonth">
|
||||
<option value="jan" |.(grep(/jan/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>January</option>
|
||||
<option value="feb" |.(grep(/feb/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>February</option>
|
||||
<option value="mar" |.(grep(/mar/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>March</option>
|
||||
<option value="apr" |.(grep(/apr/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>April</option>
|
||||
<option value="may" |.(grep(/may/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>May</option>
|
||||
<option value="jun" |.(grep(/jun/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>June</option>
|
||||
<option value="jul" |.(grep(/jul/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>July</option>
|
||||
<option value="aug" |.(grep(/aug/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>August</option>
|
||||
<option value="sep" |.(grep(/sep/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>September</option>
|
||||
<option value="oct" |.(grep(/oct/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>October</option>
|
||||
<option value="nov" |.(grep(/nov/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>November</option>
|
||||
<option value="dec" |.(grep(/dec/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>December</option>
|
||||
<option value="jan" |.(grep(/jan/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('january','DateTime'). q|</option>
|
||||
<option value="feb" |.(grep(/feb/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('february','DateTime'). q|</option>
|
||||
<option value="mar" |.(grep(/mar/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('march','DateTime'). q|</option>
|
||||
<option value="apr" |.(grep(/apr/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('april','DateTime'). q|</option>
|
||||
<option value="may" |.(grep(/may/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('may','DateTime'). q|</option>
|
||||
<option value="jun" |.(grep(/jun/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('june','DateTime'). q|</option>
|
||||
<option value="jul" |.(grep(/jul/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('july','DateTime'). q|</option>
|
||||
<option value="aug" |.(grep(/aug/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('august','DateTime'). q|</option>
|
||||
<option value="sep" |.(grep(/sep/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('september','DateTime'). q|</option>
|
||||
<option value="oct" |.(grep(/oct/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('october','DateTime'). q|</option>
|
||||
<option value="nov" |.(grep(/nov/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('november','DateTime'). q|</option>
|
||||
<option value="dec" |.(grep(/dec/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('december','DateTime'). q|</option>
|
||||
</select>
|
||||
<input type="text" name="recurYearDay" size="3" value="|.$recur{dayNumber}.q|"/>
|
||||
</p>
|
||||
|
|
@ -2349,34 +2355,34 @@ sub www_edit {
|
|||
<p>
|
||||
<input style="vertical-align: top;" type="radio" name="recurSubType" id="recurSubType_yearWeek" value="yearWeek" |.($recur{recurType} eq "yearWeek" ? q|checked="checked"| : q||).q|/>
|
||||
<select style="vertical-align: top;" name="recurYearWeekNumber">
|
||||
<option |.(grep(/first/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>first</option>
|
||||
<option |.(grep(/second/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>second</option>
|
||||
<option |.(grep(/third/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>third</option>
|
||||
<option |.(grep(/fourth/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>fourth</option>
|
||||
<option |.(grep(/fifth/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>last</option>
|
||||
<option value="first" |.(grep(/first/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>|. $i18n->get('first'). q|</option>
|
||||
<option value="second" |.(grep(/second/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>|. $i18n->get('second'). q|</option>
|
||||
<option value="third" |.(grep(/third/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>|. $i18n->get('third'). q|</option>
|
||||
<option value="fourth" |.(grep(/fourth/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>|. $i18n->get('fourth'). q|</option>
|
||||
<option value="fifth" |.(grep(/fifth/, @{$recur{weeks}}) ? 'selected="selected"' : '').q|>|. $i18n->get('last'). q|</option>
|
||||
</select>
|
||||
<select style="vertical-align: top;" name="recurYearWeekDay">
|
||||
<option value="u" |.(grep(/u/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>Sunday</option>
|
||||
<option value="m" |.(grep(/m/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>Monday</option>
|
||||
<option value="t" |.(grep(/t/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>Tuesday</option>
|
||||
<option value="w" |.(grep(/w/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>Wednesday</option>
|
||||
<option value="r" |.(grep(/r/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>Thursday</option>
|
||||
<option value="f" |.(grep(/f/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>Friday</option>
|
||||
<option value="s" |.(grep(/s/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>Saturday</option>
|
||||
</select> of
|
||||
<option value="u" |.(grep(/u/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('sunday', 'DateTime'). q|</option>
|
||||
<option value="m" |.(grep(/m/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('monday', 'DateTime'). q|</option>
|
||||
<option value="t" |.(grep(/t/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('tuesday', 'DateTime'). q|</option>
|
||||
<option value="w" |.(grep(/w/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('wednesday', 'DateTime'). q|</option>
|
||||
<option value="r" |.(grep(/r/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('thursday', 'DateTime'). q|</option>
|
||||
<option value="f" |.(grep(/f/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('friday', 'DateTime'). q|</option>
|
||||
<option value="s" |.(grep(/s/,@{$recur{dayNames}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('saturday', 'DateTime'). q|</option>
|
||||
</select> |. $i18n->get('of'). q|
|
||||
<select name="recurYearWeekMonth">
|
||||
<option value="jan" |.(grep(/jan/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>January</option>
|
||||
<option value="feb" |.(grep(/feb/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>February</option>
|
||||
<option value="mar" |.(grep(/mar/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>March</option>
|
||||
<option value="apr" |.(grep(/apr/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>April</option>
|
||||
<option value="may" |.(grep(/may/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>May</option>
|
||||
<option value="jun" |.(grep(/jun/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>June</option>
|
||||
<option value="jul" |.(grep(/jul/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>July</option>
|
||||
<option value="aug" |.(grep(/aug/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>August</option>
|
||||
<option value="sep" |.(grep(/sep/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>September</option>
|
||||
<option value="oct" |.(grep(/oct/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>October</option>
|
||||
<option value="nov" |.(grep(/nov/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>November</option>
|
||||
<option value="dec" |.(grep(/dec/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>December</option>
|
||||
<option value="jan" |.(grep(/jan/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('january','DateTime'). q|</option>
|
||||
<option value="feb" |.(grep(/feb/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('february','DateTime'). q|</option>
|
||||
<option value="mar" |.(grep(/mar/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('march','DateTime'). q|</option>
|
||||
<option value="apr" |.(grep(/apr/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('april','DateTime'). q|</option>
|
||||
<option value="may" |.(grep(/may/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('may','DateTime'). q|</option>
|
||||
<option value="jun" |.(grep(/jun/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('june','DateTime'). q|</option>
|
||||
<option value="jul" |.(grep(/jul/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('july','DateTime'). q|</option>
|
||||
<option value="aug" |.(grep(/aug/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('august','DateTime'). q|</option>
|
||||
<option value="sep" |.(grep(/sep/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('september','DateTime'). q|</option>
|
||||
<option value="oct" |.(grep(/oct/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('october','DateTime'). q|</option>
|
||||
<option value="nov" |.(grep(/nov/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('november','DateTime'). q|</option>
|
||||
<option value="dec" |.(grep(/dec/,@{$recur{months}}) ? 'selected="selected"' : '' ).q|>|. $i18n->get('december','DateTime'). q|</option>
|
||||
</select>
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -2396,18 +2402,18 @@ sub www_edit {
|
|||
$var->{"formRecurEnd"}
|
||||
= q|
|
||||
<div><input type="radio" name="recurEndType" id="recurEndType_none" value="none" |.(!$recur{endDate} && !$recur{endAfter} ? 'checked="checked"' : '').q|/>
|
||||
<label for="recurEndType_none">No end</label><br />
|
||||
<label for="recurEndType_none">|. $i18n->get('No end'). q|</label><br />
|
||||
|
||||
<input type="radio" name="recurEndType" id="recurEndType_date" value="date" |.($recur{endDate} ? 'checked="checked"' : '' ).q| />
|
||||
<label for="recurEndType_date">By date </label>|
|
||||
<label for="recurEndType_date">|. $i18n->get('By date'). q| </label>|
|
||||
. WebGUI::Form::date($session,{ name => "recurEndDate", value => $recur{endDate}, defaultValue => $recur{endDate} })
|
||||
. q|
|
||||
<br />
|
||||
|
||||
<input type="radio" name="recurEndType" id="recurEndType_after" value="after" |.($recur{endAfter} ? 'checked="checked"' : '' ).q| />
|
||||
<label for="recurEndType_after">After </label>
|
||||
<label for="recurEndType_after">|. $i18n->get('After'). q| </label>
|
||||
<input type="text" size="3" name="recurEndAfter" value="|.$recur{endAfter}.q|" />
|
||||
occurences.
|
||||
|. $i18n->get('occurences'). q|.
|
||||
</div>
|
||||
|;
|
||||
|
||||
|
|
@ -2423,14 +2429,14 @@ sub www_edit {
|
|||
$var->{"formSave"}
|
||||
= WebGUI::Form::submit($session, {
|
||||
name => "save",
|
||||
value => "save",
|
||||
value => $i18n->get('62', 'WebGUI'),
|
||||
});
|
||||
|
||||
# Cancel button
|
||||
$var->{"formCancel"}
|
||||
= WebGUI::Form::button($session, {
|
||||
name => "cancel",
|
||||
value => "cancel",
|
||||
value => $i18n->get('cancel', 'WebGUI'),
|
||||
extras => 'onClick="window.history.go(-1)"',
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1296,11 +1296,8 @@ sub viewList {
|
|||
### Get the events
|
||||
my $dtStart = WebGUI::DateTime->new( $session, $params->{start} );
|
||||
$dtStart->set_time_zone($tz);
|
||||
$dtStart->truncate( to => 'day' );
|
||||
my $dtEnd = $dtStart->clone->add( seconds => $self->get('listViewPageInterval') );
|
||||
|
||||
warn 'truncated: '.$dtStart->toDatabase;
|
||||
warn 'end date: '.$dtEnd->toDatabase;
|
||||
my @events
|
||||
= $self->getEventsIn(
|
||||
$dtStart->toDatabase,
|
||||
|
|
@ -1910,8 +1907,6 @@ sub www_ical {
|
|||
$dt_start->set_time_zone( $session->datetime->getTimeZone );
|
||||
}
|
||||
|
||||
$session->log->warn("start1: ". $dt_start->toMysql);
|
||||
|
||||
my $dt_end;
|
||||
my $end = $form->param("end");
|
||||
if ($end) {
|
||||
|
|
@ -1925,10 +1920,6 @@ sub www_ical {
|
|||
$dt_end = $dt_start->clone->add( seconds => $self->get('icalInterval') );
|
||||
}
|
||||
|
||||
$session->log->warn("start2: ". $dt_start->toMysql);
|
||||
$session->log->warn("end2: ". $dt_end->toMysql);
|
||||
|
||||
|
||||
# Get all the events we're going to display
|
||||
my @events = $self->getEventsIn($dt_start->toMysql,$dt_end->toMysql);
|
||||
|
||||
|
|
@ -1938,11 +1929,8 @@ sub www_ical {
|
|||
. qq{VERSION:2.0\r\n};
|
||||
|
||||
# VEVENT:
|
||||
$session->log->warn("before event processing");
|
||||
EVENT: for my $event (@events) {
|
||||
$session->log->warn("have event: ");
|
||||
next EVENT unless $event->canView();
|
||||
$session->log->warn($event->getTitle);
|
||||
$ical .= qq{BEGIN:VEVENT\r\n};
|
||||
|
||||
### UID
|
||||
|
|
|
|||
|
|
@ -2491,6 +2491,7 @@ sub www_printRemainingTickets {
|
|||
EMSTicket.location as ticketLocation,
|
||||
EMSTicket.relatedBadgeGroups,
|
||||
EMSTicket.relatedRibbons,
|
||||
EMSTicket.eventMetaData,
|
||||
(seatsAvailable - (select count(*) from EMSRegistrantTicket where ticketAssetId = asset.assetId)) as seatsRemaining
|
||||
FROM
|
||||
asset
|
||||
|
|
@ -2511,6 +2512,19 @@ sub www_printRemainingTickets {
|
|||
$var->{'tickets_loop'} = [];
|
||||
while (my $hash = $sth->hashRef) {
|
||||
my $seatsRemaining = $hash->{seatsRemaining};
|
||||
#Put start time in the correct timezone
|
||||
my $startTime = WebGUI::DateTime->new($hash->{ticketStart})->set_time_zone($self->get('timezone'));
|
||||
$hash->{ticketStart} = $startTime->strftime('%F %R');
|
||||
$hash->{ticketStart_epoch} = $startTime->epoch;
|
||||
#Add meta data fields
|
||||
my $data = $hash->{eventMetaData} || '{}';
|
||||
my $meta = JSON->new->decode($data);
|
||||
foreach my $key (keys %{$meta}) {
|
||||
my $tmplKey = $key;
|
||||
$tmplKey =~ s/[\s\W]/_/g;
|
||||
$hash->{'ticketMeta_'.$tmplKey} = $meta->{$key};
|
||||
}
|
||||
#Add to the loop
|
||||
for (my $i = 0; $i < $seatsRemaining; $i++ ) {
|
||||
push(@{$var->{'tickets_loop'}},$hash);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -281,20 +281,6 @@ sub getEditForm {
|
|||
".($ancestorsChecked ? "" : "toggleAncestorEndPoint();")."
|
||||
//]]>
|
||||
</script>");
|
||||
my $previewButton;# = qq{
|
||||
# <INPUT TYPE="button" VALUE="Preview" NAME="preview"
|
||||
# OnClick="
|
||||
# window.open('', 'navPreview', 'toolbar=no,status=no,location=no,scrollbars=yes,resizable=yes');
|
||||
# this.form.func.value='preview';
|
||||
# this.form.target = 'navPreview';
|
||||
# this.form.submit()">};
|
||||
my $saveButton = ' <input type="button" class="forwardButton" value="'.$i18n->get(62,'WebGUI').'" onclick="
|
||||
this.value=\''.$i18n->get(452,'WebGUI').'\';
|
||||
this.form.func.value=\'editSave\';
|
||||
this.form.target=\'_self\';
|
||||
this.form.submit();
|
||||
" />';
|
||||
$tabform->{_submit} = $previewButton." ".$saveButton;
|
||||
return $tabform;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -483,7 +483,7 @@ sub getFeed {
|
|||
$feed->description( $self->get('feedDescription') || $self->get('synopsis') );
|
||||
$feed->pubDate( $self->getContentLastModified );
|
||||
$feed->copyright( $self->get('feedCopyright') );
|
||||
$feed->link( $self->getUrl );
|
||||
$feed->link( $self->session->url->getSiteURL . $self->getUrl );
|
||||
# $feed->language( $lang );
|
||||
if ($self->get('feedImage')) {
|
||||
my $storage = WebGUI::Storage->get($self->session, $self->get('feedImage'));
|
||||
|
|
|
|||
|
|
@ -44,11 +44,6 @@ sub definition {
|
|||
label => $i18n->get("Email Template"),
|
||||
hoverHelp => $i18n->get("Email Template help"),
|
||||
},
|
||||
skipNotification => {
|
||||
autoGenerate => 0,
|
||||
noFormPost => 1,
|
||||
fieldType => 'yesNo',
|
||||
},
|
||||
);
|
||||
|
||||
push @{ $definition }, {
|
||||
|
|
@ -441,27 +436,6 @@ sub purge {
|
|||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 setSkipNotification ( )
|
||||
|
||||
Set a flag so that this asset does not send out notifications for this
|
||||
revision.
|
||||
|
||||
=cut
|
||||
|
||||
sub setSkipNotification {
|
||||
my $self = shift;
|
||||
my $value = shift;
|
||||
$value = defined $value ? $value : 1;
|
||||
|
||||
$self->update( {
|
||||
skipNotification => $value,
|
||||
} );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
=head2 shouldSkipNotification ( )
|
||||
|
||||
Returns true if the asset should skip notifications.
|
||||
|
|
|
|||
|
|
@ -821,6 +821,11 @@ sub newByLineage {
|
|||
$class = $assetLineage->{$lineage}{class};
|
||||
unless ($id && $class) {
|
||||
($id,$class) = $session->db->quickArray("select assetId, className from asset where lineage=?",[$lineage]);
|
||||
if (!$id || !$class) {
|
||||
$session->errorHandler->error("Couldn't instantiate asset from lineage: ".$lineage. ": class name or assetId missing");
|
||||
return undef;
|
||||
}
|
||||
return undef if !$id || !$class;
|
||||
$assetLineage->{$lineage}{id} = $id;
|
||||
$assetLineage->{$lineage}{class} = $class;
|
||||
$session->stow->set("assetLineage",$assetLineage);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ our $HELP = {
|
|||
'required' => 1,
|
||||
},
|
||||
{ 'name' => 'formMenuTitle', },
|
||||
{ 'name' => 'formSynopsis', },
|
||||
{ 'name' => 'formLocation', },
|
||||
{ 'name' => 'formDescription', },
|
||||
{ 'name' => 'formGroupToView', },
|
||||
|
|
|
|||
|
|
@ -239,11 +239,13 @@ our $HELP = {
|
|||
{ 'name' => 'ticketDuration'},
|
||||
{ 'name' => 'ticketLocation'},
|
||||
{ 'name' => 'ticketEventNumber'},
|
||||
{ 'name' => 'ticketMeta_[LABEL]'},
|
||||
{ 'name' => 'seatsRemaining'},
|
||||
{ 'name' => 'seatsAvailable'},
|
||||
{ 'name' => 'price'},
|
||||
{ 'name' => 'relatedRibbons'},
|
||||
{ 'name' => 'relatedBadgeGroups'},
|
||||
{ 'name' => 'eventMetaData'},
|
||||
{ 'name' => 'title'},
|
||||
{ 'name' => 'menuTitle'},
|
||||
{ 'name' => 'url'},
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ Macro for displaying the output of an Asset in another location.
|
|||
|
||||
=head3 url | assetId
|
||||
|
||||
My specify either the asset url or the asset id. If no Asset with that URL or id can be found, an internationalized error message will be returned instead.
|
||||
Specify either the asset url or the asset id. If no Asset with that URL or id can be found, an internationalized error message will be returned instead.
|
||||
|
||||
No editing controls (toolbar) will be displayed in the Asset output, even if Admin is turned on.
|
||||
Editing controls (toolbar) may or may not be displayed in the Asset output, even if Admin is turned on.
|
||||
|
||||
The Not Found Page may not be Asset Proxied.
|
||||
|
||||
|
|
|
|||
|
|
@ -294,13 +294,13 @@ sub www_runCronJob {
|
|||
if ($session->stow->get('singletonWorkflowClash')) {
|
||||
$session->errorHandler->warn(
|
||||
"Could not create workflow instance for workflowId '" . $task->get( "workflowId" )
|
||||
. "': It is a singleton workflow and is still running from the last invocation."
|
||||
. "' from taskId '".$taskId."': It is a singleton workflow and is still running from the last invocation."
|
||||
);
|
||||
return "done";
|
||||
}
|
||||
$session->errorHandler->error(
|
||||
"Could not create workflow instance for workflowId '" . $task->get( "workflowId" )
|
||||
. "': The result was undefined"
|
||||
. "' from taskId '".$taskId."': The result was undefined"
|
||||
);
|
||||
return "done";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -409,7 +409,7 @@ sub www_selectPaymentGateway {
|
|||
|
||||
# Complete Transaction if it's a $0 transaction.
|
||||
my $total = $cart->calculateTotal;
|
||||
if (($total + $cart->calculateShopCreditDeduction($total)) == 0) {
|
||||
if (sprintf('%.2f', $total + $cart->calculateShopCreditDeduction($total)) eq '0.00') {
|
||||
my $transaction = WebGUI::Shop::Transaction->create($session, {cart => $cart});
|
||||
$transaction->completePurchase('zero', 'success', 'success');
|
||||
$cart->onCompletePurchase;
|
||||
|
|
@ -430,7 +430,6 @@ sub www_selectPaymentGateway {
|
|||
}
|
||||
$var->{ paymentGateways } = \@paymentGateways;
|
||||
$var->{ choose } = $i18n->get('choose payment gateway message');
|
||||
$session->log->warn('###'.$session->setting->get("selectGatewayTemplateId"));
|
||||
my $template = WebGUI::Asset::Template->new($session, $session->setting->get("selectGatewayTemplateId"));
|
||||
return $session->style->userStyle($template->process($var));
|
||||
}
|
||||
|
|
|
|||
533
lib/WebGUI/Shop/ShipDriver/UPS.pm
Normal file
533
lib/WebGUI/Shop/ShipDriver/UPS.pm
Normal file
|
|
@ -0,0 +1,533 @@
|
|||
package WebGUI::Shop::ShipDriver::UPS;
|
||||
|
||||
use strict;
|
||||
use base qw/WebGUI::Shop::ShipDriver/;
|
||||
use WebGUI::Exception;
|
||||
use WebGUI::Exception::Shop;
|
||||
use XML::Simple;
|
||||
use LWP;
|
||||
use Tie::IxHash;
|
||||
use Locales::Country qw/ en /;
|
||||
use Class::InsideOut qw/ :std /;
|
||||
use Data::Dumper;
|
||||
|
||||
public testMode => my %testMode;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Package WebGUI::Shop::ShipDriver::UPS
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Shipping driver for the United Parcel Service, for US Domestic shipping only.
|
||||
|
||||
The UPS XML interface will only do a lookup for one destination at a time. However,
|
||||
each destination may have multiple packages. This means that if a cart holds packages
|
||||
with multiple destinations, that multiple requests must be sent to the UPS server.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
See the master class, WebGUI::Shop::ShipDriver for information about
|
||||
base methods. These methods are customized in this class:
|
||||
|
||||
=cut
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 buildXML ( $cart, @packages )
|
||||
|
||||
Returns XML for submitting to the UPS servers
|
||||
|
||||
=head3 $cart
|
||||
|
||||
A WebGUI::Shop::Cart object. This allows us access to the user's
|
||||
address book
|
||||
|
||||
=head3 $packages
|
||||
|
||||
An array reference. Each array element is 1 set of items. The
|
||||
quantity of items will vary in each set. All packages in the set must
|
||||
go to the same zipcode.
|
||||
|
||||
=cut
|
||||
|
||||
sub buildXML {
|
||||
my ($self, $cart, $packages) = @_;
|
||||
#tie my %xmlHash, 'Tie::IxHash';
|
||||
my %xmlHash = (
|
||||
AccessRequest => {},
|
||||
);
|
||||
my $xmlAcc = $xmlHash{AccessRequest};
|
||||
$xmlAcc->{'xml:lang'} = 'en-US';
|
||||
$xmlAcc->{AccessLicenseNumber} = [ $self->get('licenseNo') ];
|
||||
$xmlAcc->{UserId} = [ $self->get('userId') ];
|
||||
$xmlAcc->{Password} = [ $self->get('password') ];
|
||||
my $localizedCountry = Locales::Country->new('en');
|
||||
my $xml = XMLout(\%xmlHash,
|
||||
KeepRoot => 1,
|
||||
NoSort => 1,
|
||||
SuppressEmpty => 0,
|
||||
XMLDecl => 1,
|
||||
);
|
||||
my $destination = $packages->[0]->[0]->getShippingAddress;
|
||||
%xmlHash = (
|
||||
RatingServiceSelectionRequest => {},
|
||||
);
|
||||
my $xmlRate = $xmlHash{RatingServiceSelectionRequest };
|
||||
$xmlRate->{'xml:lang'} = 'en-US';
|
||||
$xmlRate->{Request} = {
|
||||
# Shown in example request, but optional
|
||||
# TransactionReference => {
|
||||
# CustomerContext => [ 'Rating and Service' ],
|
||||
# XpciVersion => [ 1.0001 ],
|
||||
# },
|
||||
RequestAction => [ 'Rate' ],
|
||||
# RequestOption => [ 'shop' ],
|
||||
};
|
||||
$xmlRate->{PickupType} = {
|
||||
Code => [ $self->get('pickupType') ],
|
||||
};
|
||||
$xmlRate->{CustomerClassification} = {
|
||||
Code => [ $self->get('customerClassification') ],
|
||||
};
|
||||
$xmlRate->{Shipment} = {
|
||||
Shipper => {
|
||||
Address => [ {
|
||||
PostalCode => [ $self->get('sourceZip' ) ],
|
||||
CountryCode => [ $localizedCountry->country2code($self->get('sourceCountry'), 'alpha2') ],
|
||||
}, ],
|
||||
},
|
||||
ShipTo => {
|
||||
Address => [ {
|
||||
PostalCode => [ $destination->get('code') ],
|
||||
CountryCode => [ $localizedCountry->country2code($destination->get('country'), 'alpha2') ],
|
||||
} ],
|
||||
},
|
||||
Service => {
|
||||
Code => [ $self->get('shipService') ],
|
||||
},
|
||||
Package => [],
|
||||
};
|
||||
if ($self->get('residentialIndicator') eq 'residential') {
|
||||
$xmlRate->{Shipment}->{ShipTo}->{Address}->[0]->{ResidentialAddressIndicator} = [''];
|
||||
}
|
||||
my $packHash = $xmlRate->{Shipment}->{Package};
|
||||
PACKAGE: foreach my $package (@{ $packages }) {
|
||||
my $weight = 0;
|
||||
ITEM: foreach my $item (@{ $package }) {
|
||||
my $sku = $item->getSku();
|
||||
next ITEM unless $sku->isShippingRequired;
|
||||
##If shipsSeparately is set, the item was placed N times in the shippingBundles,
|
||||
##where N is the quantity. This means that the quantity is wrong for
|
||||
##any item where that option is set.
|
||||
my $skuWeight = $sku->getWeight;
|
||||
if (! $sku->shipsSeparately() ) {
|
||||
$skuWeight *= $item->get('quantity');
|
||||
}
|
||||
$weight += $skuWeight;
|
||||
}
|
||||
next PACKAGE unless $weight;
|
||||
$weight = sprintf "%.1f", $weight;
|
||||
$weight = '0.1' if $weight == 0;
|
||||
my $options = {
|
||||
PackagingType => [ {
|
||||
Code => [ '02' ],
|
||||
} ],
|
||||
PackageWeight => [ {
|
||||
Weight => [ $weight ], ##Required formatting from spec
|
||||
} ],
|
||||
};
|
||||
push @{ $packHash }, $options;
|
||||
}
|
||||
return '' unless scalar @{ $packHash }; ##Nothing to calculate shipping for.
|
||||
$xml .= XMLout(\%xmlHash,
|
||||
KeepRoot => 1,
|
||||
NoSort => 1,
|
||||
SuppressEmpty => '',
|
||||
XMLDecl => 1,
|
||||
);
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 calculate ( $cart )
|
||||
|
||||
Returns a shipping price. Since the UPS will only allow a lookup from one source
|
||||
to one destination at a time, this method may make several XML requests from the
|
||||
UPS server.
|
||||
|
||||
=head3 $cart
|
||||
|
||||
A WebGUI::Shop::Cart object. The contents of the cart are analyzed to calculate
|
||||
the shipping costs. If no items in the cart require shipping, then no shipping
|
||||
costs are assessed.
|
||||
|
||||
=cut
|
||||
|
||||
sub calculate {
|
||||
my ($self, $cart) = @_;
|
||||
if (! $self->get('sourceZip')) {
|
||||
WebGUI::Error::InvalidParam->throw(error => q{Driver configured without a source zipcode.});
|
||||
}
|
||||
if (! $self->get('sourceCountry')) {
|
||||
WebGUI::Error::InvalidParam->throw(error => q{Driver configured without a source country.});
|
||||
}
|
||||
if (! $self->get('userId')) {
|
||||
WebGUI::Error::InvalidParam->throw(error => q{Driver configured without a UPS userId.});
|
||||
}
|
||||
if (! $self->get('password')) {
|
||||
WebGUI::Error::InvalidParam->throw(error => q{Driver configured without a UPS password.});
|
||||
}
|
||||
if (! $self->get('licenseNo')) {
|
||||
WebGUI::Error::InvalidParam->throw(error => q{Driver configured without a UPS license number.});
|
||||
}
|
||||
my $cost = 0;
|
||||
##Sort the items into shippable bundles.
|
||||
my @shippableUnits = $self->_getShippableUnits($cart);
|
||||
my $packageCount = scalar @shippableUnits;
|
||||
my $anyShippable = $packageCount > 0 ? 1 : 0;
|
||||
return $cost unless $anyShippable;
|
||||
#$cost = scalar @shippableUnits * $self->get('flatFee');
|
||||
##Build XML ($cart, @shippableUnits)
|
||||
foreach my $unit (@shippableUnits) {
|
||||
if ($packageCount > 200) {
|
||||
WebGUI::Error::InvalidParam->throw(error => q{Cannot do UPS lookups for more than 200 items.});
|
||||
}
|
||||
my $xml = $self->buildXML($cart, $unit);
|
||||
##Do request ($xml)
|
||||
my $response = $self->_doXmlRequest($xml);
|
||||
##Error handling
|
||||
if (! $response->is_success) {
|
||||
WebGUI::Error::Shop::RemoteShippingRate->throw(error => 'Problem connecting to UPS Web Tools: '. $response->status_line);
|
||||
}
|
||||
my $returnedXML = $response->content;
|
||||
my $xmlData = XMLin($returnedXML, ForceArray => [qw/RatedPackage/]);
|
||||
if (! $xmlData->{Response}->{ResponseStatusCode}) {
|
||||
WebGUI::Error::Shop::RemoteShippingRate->throw(error => 'Problem with UPS Online Tools XML: '. $xmlData->{Response}->{Error}->{ErrorDescription});
|
||||
}
|
||||
##Summarize costs from returned data
|
||||
$cost += $self->_calculateFromXML($xmlData);
|
||||
}
|
||||
return $cost;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 _calculateFromXML ( $xmlData )
|
||||
|
||||
Takes data from the UPS and returns the calculated shipping price.
|
||||
|
||||
=head3 $xmlData
|
||||
|
||||
Processed data from an XML rate request, as a perl data structure. The data is expected to
|
||||
have this structure:
|
||||
|
||||
{
|
||||
RatedShipment => {
|
||||
TotalCharges => {
|
||||
MonetaryValue => xx.yy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
=cut
|
||||
|
||||
sub _calculateFromXML {
|
||||
my ($self, $xmlData) = @_;
|
||||
##Additional error checking on the XML data can be done in here. Or, in the future,
|
||||
##individual elements of the cost can be parsed and returned.
|
||||
return $xmlData->{RatedShipment}->{TotalCharges}->{MonetaryValue};
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 definition ( $session )
|
||||
|
||||
This subroutine returns an arrayref of hashrefs, used to validate data put into
|
||||
the object by the user, and to automatically generate the edit form to show
|
||||
the user.
|
||||
|
||||
=cut
|
||||
|
||||
sub definition {
|
||||
my $class = shift;
|
||||
my $session = shift;
|
||||
WebGUI::Error::InvalidParam->throw(error => q{Must provide a session variable})
|
||||
unless ref $session eq 'WebGUI::Session';
|
||||
my $definition = shift || [];
|
||||
my $i18n = WebGUI::International->new($session, 'ShipDriver_UPS');
|
||||
|
||||
tie my %shippingTypes, 'Tie::IxHash';
|
||||
##Other shipping types can be added below, but also need to be handled by the
|
||||
##javascript.
|
||||
$shippingTypes{'us domestic'} = $i18n->get('us domestic');
|
||||
$shippingTypes{'us international'} = $i18n->get('us international');
|
||||
|
||||
tie my %shippingServices, 'Tie::IxHash';
|
||||
##Note, these keys are required XML keywords in the UPS XML API.
|
||||
##It needs a one of every key, regardless of the correct label.
|
||||
##The right set of options is set via JavaScript in the form.
|
||||
$shippingServices{'01'} = $i18n->get('us domestic 01');
|
||||
$shippingServices{'02'} = $i18n->get('us domestic 02');
|
||||
$shippingServices{'03'} = $i18n->get('us domestic 03');
|
||||
$shippingServices{'07'} = $i18n->get('us international 07');
|
||||
$shippingServices{'08'} = $i18n->get('us international 08');
|
||||
$shippingServices{'11'} = $i18n->get('us international 11');
|
||||
$shippingServices{'12'} = $i18n->get('us domestic 12');
|
||||
$shippingServices{'13'} = $i18n->get('us domestic 13');
|
||||
$shippingServices{'14'} = $i18n->get('us domestic 14');
|
||||
$shippingServices{'54'} = $i18n->get('us international 54');
|
||||
$shippingServices{'59'} = $i18n->get('us domestic 59');
|
||||
$shippingServices{'65'} = $i18n->get('us international 65');
|
||||
|
||||
tie my %pickupTypes, 'Tie::IxHash';
|
||||
##Note, these keys are required XML keywords in the UPS XML API.
|
||||
$pickupTypes{'01'} = $i18n->get('pickup code 01');
|
||||
$pickupTypes{'03'} = $i18n->get('pickup code 03');
|
||||
$pickupTypes{'06'} = $i18n->get('pickup code 06');
|
||||
$pickupTypes{'07'} = $i18n->get('pickup code 07');
|
||||
$pickupTypes{'11'} = $i18n->get('pickup code 11');
|
||||
$pickupTypes{'19'} = $i18n->get('pickup code 19');
|
||||
$pickupTypes{'20'} = $i18n->get('pickup code 20');
|
||||
|
||||
tie my %customerClassification, 'Tie::IxHash';
|
||||
##Note, these keys are required XML keywords in the UPS XML API.
|
||||
$customerClassification{'01'} = $i18n->get('customer classification 01');
|
||||
$customerClassification{'03'} = $i18n->get('customer classification 03');
|
||||
$customerClassification{'04'} = $i18n->get('customer classification 04');
|
||||
|
||||
my $localizedCountries = Locales::Country->new('en'); ##Note, for future i18n change the locale
|
||||
tie my %localizedCountries, 'Tie::IxHash';
|
||||
%localizedCountries = map { $_ => $_ } grep { !ref $_ } $localizedCountries->all_country_names();
|
||||
|
||||
tie my %fields, 'Tie::IxHash';
|
||||
%fields = (
|
||||
instructions => {
|
||||
fieldType => 'readOnly',
|
||||
label => $i18n->get('instructions'),
|
||||
defaultValue => $i18n->get('ups instructions'),
|
||||
noFormProcess => 1,
|
||||
},
|
||||
userId => {
|
||||
fieldType => 'text',
|
||||
label => $i18n->get('userid'),
|
||||
hoverHelp => $i18n->get('userid help'),
|
||||
defaultValue => '',
|
||||
},
|
||||
password => {
|
||||
fieldType => 'password',
|
||||
label => $i18n->get('password'),
|
||||
hoverHelp => $i18n->get('password help'),
|
||||
defaultValue => '',
|
||||
},
|
||||
licenseNo => {
|
||||
fieldType => 'text',
|
||||
label => $i18n->get('license'),
|
||||
hoverHelp => $i18n->get('license help'),
|
||||
defaultValue => '',
|
||||
},
|
||||
sourceZip => {
|
||||
fieldType => 'zipcode',
|
||||
label => $i18n->get('source zipcode'),
|
||||
hoverHelp => $i18n->get('source zipcode help'),
|
||||
defaultValue => '',
|
||||
},
|
||||
sourceCountry => {
|
||||
fieldType => 'selectBox',
|
||||
label => $i18n->get('source country'),
|
||||
hoverHelp => $i18n->get('source country help'),
|
||||
options => \%localizedCountries,
|
||||
defaultValue => 'US',
|
||||
},
|
||||
shipType => {
|
||||
fieldType => 'selectBox',
|
||||
label => $i18n->get('ship type'),
|
||||
hoverHelp => $i18n->get('ship type help'),
|
||||
options => \%shippingTypes,
|
||||
defaultValue => 'us domestic',
|
||||
extras => q{onchange="WebGUI.ShipDriver.UPS.changeServices(this.options[this.selectedIndex].value,'shipService_formId')"},
|
||||
},
|
||||
shipService => {
|
||||
fieldType => 'selectBox',
|
||||
label => $i18n->get('ship service'),
|
||||
hoverHelp => $i18n->get('ship service help'),
|
||||
options => \%shippingServices,
|
||||
defaultValue => '03',
|
||||
},
|
||||
pickupType => {
|
||||
fieldType => 'selectBox',
|
||||
label => $i18n->get('pickup type'),
|
||||
hoverHelp => $i18n->get('pickup type help'),
|
||||
options => \%pickupTypes,
|
||||
defaultValue => '01',
|
||||
},
|
||||
customerClassification => {
|
||||
fieldType => 'selectBox',
|
||||
label => $i18n->get('customer classification'),
|
||||
hoverHelp => $i18n->get('customer classification help'),
|
||||
options => \%customerClassification,
|
||||
defaultValue => '01',
|
||||
},
|
||||
residentialIndicator => {
|
||||
fieldType => 'radioList',
|
||||
label => $i18n->get('residential'),
|
||||
hoverHelp => $i18n->get('residential help'),
|
||||
options => {
|
||||
residential => $i18n->get('residential'),
|
||||
commercial => $i18n->get('commercial'),
|
||||
},
|
||||
defaultValue => 'commercial',
|
||||
},
|
||||
##Note, if a flat fee is added to this driver, then according to the license
|
||||
##terms the website must display a note to the user (shop customer) that additional
|
||||
##fees have been added.
|
||||
# flatFee => {
|
||||
# fieldType => 'float',
|
||||
# label => $i18n->get('flatFee'),
|
||||
# hoverHelp => $i18n->get('flatFee help'),
|
||||
# defaultValue => 0,
|
||||
# },
|
||||
);
|
||||
my %properties = (
|
||||
name => 'UPS',
|
||||
properties => \%fields,
|
||||
);
|
||||
push @{ $definition }, \%properties;
|
||||
return $class->SUPER::definition($session, $definition);
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 _doXmlRequest ( $xml )
|
||||
|
||||
Contact the UPS website and submit the XML for a shipping rate lookup.
|
||||
Returns a LWP::UserAgent response object.
|
||||
|
||||
=head3 $xml
|
||||
|
||||
XML to send. It has some very high standards, including XML components in
|
||||
the right order and sets of allowed tags.
|
||||
|
||||
=cut
|
||||
|
||||
sub _doXmlRequest {
|
||||
my ($self, $xml) = @_;
|
||||
my $userAgent = LWP::UserAgent->new;
|
||||
$userAgent->env_proxy;
|
||||
$userAgent->agent('WebGUI');
|
||||
#
|
||||
my $url;
|
||||
if ($self->testMode) {
|
||||
$url = 'https://wwwcie.ups.com/ups.app/xml/Rate';
|
||||
}
|
||||
else {
|
||||
$url = 'https://wwwcie.ups.com/ups.app/xml/Rate';
|
||||
}
|
||||
my $request = HTTP::Request->new(POST => $url);
|
||||
$request->content_type( 'text/xml' );
|
||||
$request->content( $xml );
|
||||
|
||||
my $response = $userAgent->request($request);
|
||||
return $response;
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 getEditForm ( )
|
||||
|
||||
Override the master method to stuff in some javascript.
|
||||
|
||||
=cut
|
||||
|
||||
sub getEditForm {
|
||||
my $self = shift;
|
||||
$self->session->style->setScript(
|
||||
$self->session->url->extras('yui/build/utilities/utilities.js'),
|
||||
{ type => 'text/javascript', },
|
||||
);
|
||||
$self->session->style->setScript(
|
||||
$self->session->url->extras('yui/build/yahoo-dom-event/yahoo-dom-event.js'),
|
||||
{ type => 'text/javascript', },
|
||||
);
|
||||
$self->session->style->setScript(
|
||||
$self->session->url->extras('yui/build/json/json-min.js'),
|
||||
{ type => 'text/javascript', },
|
||||
);
|
||||
$self->session->style->setScript(
|
||||
$self->session->url->extras('yui-webgui/build/i18n/i18n.js'),
|
||||
{ type => 'text/javascript', },
|
||||
);
|
||||
$self->session->style->setScript(
|
||||
$self->session->url->extras('yui-webgui/build/ShipDriver/UPS.js'),
|
||||
{ type => 'text/javascript', },
|
||||
);
|
||||
$self->session->style->setRawHeadTags(<<EOL);
|
||||
<script type="text/javascript">
|
||||
YAHOO.util.Event.onDOMReady( WebGUI.ShipDriver.UPS.initI18n );
|
||||
</script>
|
||||
EOL
|
||||
return $self->SUPER::getEditForm();
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
=head2 _getShippableUnits ( $cart )
|
||||
|
||||
This is a private method.
|
||||
|
||||
Sorts items into the cart by how they must be shipped; together, separate,
|
||||
etc, following these rules:
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
Each item which ships separately is 1 shippable unit.
|
||||
|
||||
=item *
|
||||
|
||||
All loose items are bundled together by zip code.
|
||||
|
||||
=back
|
||||
|
||||
This method returns a
|
||||
|
||||
For an empty cart (which shouldn't ever happen), it would return an empty array.
|
||||
|
||||
=head3 $cart
|
||||
|
||||
A WebGUI::Shop::Cart object. It provides access to the items in the cart
|
||||
that must be sorted.
|
||||
|
||||
=cut
|
||||
|
||||
sub _getShippableUnits {
|
||||
my ($self, $cart) = @_;
|
||||
##All units sorted by zip code. Loose units kept separately so they
|
||||
##can be easily bundled together by zip code.
|
||||
my %shippableUnits = ();
|
||||
my %looseUnits = ();
|
||||
ITEM: foreach my $item (@{$cart->getItems}) {
|
||||
my $sku = $item->getSku;
|
||||
next ITEM unless $sku->isShippingRequired;
|
||||
my $zip = $item->getShippingAddress->get('code');
|
||||
if ($sku->shipsSeparately) {
|
||||
push @{ $shippableUnits{$zip} }, ( [ $item ] ) x $item->get('quantity');
|
||||
}
|
||||
else {
|
||||
push @{ $looseUnits{$zip} }, $item;
|
||||
}
|
||||
}
|
||||
##Merge the two together now
|
||||
while (my ($zip, $units) = each %looseUnits) {
|
||||
push @{ $shippableUnits{$zip} }, $units;
|
||||
}
|
||||
return values %shippableUnits;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
@ -6,6 +6,7 @@ use WebGUI::Exception;
|
|||
use XML::Simple;
|
||||
use LWP;
|
||||
use Tie::IxHash;
|
||||
use Data::Dumper;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
|
|
@ -142,12 +143,12 @@ sub calculate {
|
|||
my $response = $self->_doXmlRequest($xml);
|
||||
##Error handling
|
||||
if (! $response->is_success) {
|
||||
WebGUI::Error::RemoteShippingRate->throw(error => 'Problem connecting to USPS Web Tools: '. $response->status_line);
|
||||
WebGUI::Error::Shop::RemoteShippingRate->throw(error => 'Problem connecting to USPS Web Tools: '. $response->status_line);
|
||||
}
|
||||
my $returnedXML = $response->content;
|
||||
my $xmlData = XMLin($returnedXML, ForceArray => [qw/Package/]);
|
||||
my $xmlData = XMLin($returnedXML, KeepRoot => 1, ForceArray => [qw/Package/]);
|
||||
if (exists $xmlData->{Error}) {
|
||||
WebGUI::Error::RemoteShippingRate->throw(error => 'Problem with USPS Web Tools XML: '. $xmlData->{Description});
|
||||
WebGUI::Error::Shop::RemoteShippingRate->throw(error => 'Problem with USPS Web Tools XML: '. $xmlData->{Error}->{Description});
|
||||
}
|
||||
##Summarize costs from returned data
|
||||
$cost = $self->_calculateFromXML($xmlData, @shippableUnits);
|
||||
|
|
@ -167,14 +168,16 @@ Processed XML data from an XML rate request, processed in perl data structure.
|
|||
have this structure:
|
||||
|
||||
{
|
||||
Package => [
|
||||
{
|
||||
ID => 0,
|
||||
Postage => {
|
||||
Rate => some_number
|
||||
}
|
||||
},
|
||||
]
|
||||
RateV3Response => {
|
||||
Package => [
|
||||
{
|
||||
ID => 0,
|
||||
Postage => {
|
||||
Rate => some_number
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
=head3 @shippableUnits
|
||||
|
|
@ -186,12 +189,12 @@ The set of shippable units, which are required to do quantity lookups.
|
|||
sub _calculateFromXML {
|
||||
my ($self, $xmlData, @shippableUnits) = @_;
|
||||
my $cost = 0;
|
||||
foreach my $package (@{ $xmlData->{Package} }) {
|
||||
foreach my $package (@{ $xmlData->{RateV3Response}->{Package} }) {
|
||||
my $id = $package->{ID};
|
||||
my $rate = $package->{Postage}->{Rate};
|
||||
##Error check for invalid index
|
||||
if ($id < 0 || $id > $#shippableUnits) {
|
||||
WebGUI::Error::RemoteShippingRate->throw(error => "Illegal package index returned by USPS: $id");
|
||||
WebGUI::Error::Shop::RemoteShippingRate->throw(error => "Illegal package index returned by USPS: $id");
|
||||
}
|
||||
my $unit = $shippableUnits[$id];
|
||||
if ($unit->[0]->getSku->shipsSeparately) {
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@ throughout the site. Check yes if you want this Asset to be available as a pack
|
|||
'asset' => {
|
||||
message => q|Asset|,
|
||||
lastUpdated => 1100463645,
|
||||
context => 'The default name of all assets.'
|
||||
context => 'The default name of all assets. Asset, as in resource, part, object, item, or piece'
|
||||
},
|
||||
|
||||
'extra head tags' => {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,11 @@ our $I18N = {
|
|||
lastUpdated => 1171067211,
|
||||
},
|
||||
|
||||
'formSynopsis' => {
|
||||
message => q|HTML form for entering or editing the Event Synopsis.|,
|
||||
lastUpdated => 1171067211,
|
||||
},
|
||||
|
||||
'formLocation' => {
|
||||
message => q|HTML form for entering or editing the Event Location.|,
|
||||
lastUpdated => 1171067211,
|
||||
|
|
@ -695,6 +700,127 @@ be useful, others may not.|,
|
|||
lastUpdated => 1204668000,
|
||||
},
|
||||
|
||||
'No specific time' => {
|
||||
message => q{No specific time (all day event)},
|
||||
lastUpdated => 1257188155,
|
||||
},
|
||||
|
||||
'Specific start/end time' => {
|
||||
message => q{Specific start/end time},
|
||||
lastUpdated => 1257188155,
|
||||
},
|
||||
|
||||
'day' => {
|
||||
message => q{day},
|
||||
lastUpdated => 1257188155,
|
||||
},
|
||||
|
||||
'Daily' => {
|
||||
message => q{Daily},
|
||||
lastUpdated => 1257188155,
|
||||
context => q{An event that occurs every day},
|
||||
},
|
||||
|
||||
'Weekday(s)' => {
|
||||
message => q{Weekday(s)},
|
||||
lastUpdated => 1257188155,
|
||||
context => q{May occur on one or more weekdays (Monday through Friday)},
|
||||
},
|
||||
|
||||
'Weekly' => {
|
||||
message => q{Weekly},
|
||||
lastUpdated => 1257188155,
|
||||
},
|
||||
|
||||
'Monthly' => {
|
||||
message => q{Monthly},
|
||||
lastUpdated => 1257188155,
|
||||
},
|
||||
|
||||
'Yearly' => {
|
||||
message => q{Yearly},
|
||||
lastUpdated => 1257188155,
|
||||
},
|
||||
|
||||
'first' => {
|
||||
message => q{first},
|
||||
lastUpdated => 1257188155,
|
||||
},
|
||||
|
||||
'second' => {
|
||||
message => q{second},
|
||||
lastUpdated => 1257188155,
|
||||
},
|
||||
|
||||
'third' => {
|
||||
message => q{third},
|
||||
lastUpdated => 1257188155,
|
||||
},
|
||||
|
||||
'fourth' => {
|
||||
message => q{fourth},
|
||||
lastUpdated => 1257188155,
|
||||
},
|
||||
|
||||
'last' => {
|
||||
message => q{last},
|
||||
lastUpdated => 1257188155,
|
||||
},
|
||||
|
||||
'of' => {
|
||||
message => 'of',
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'No end' => {
|
||||
message => 'No end',
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'By date' => {
|
||||
message => 'By date',
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'After' => {
|
||||
message => 'After',
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'occurences' => {
|
||||
message => 'occurences',
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'Every' => {
|
||||
message => 'Every',
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'Every N weeks on' => {
|
||||
message => 'Every %s week(s) on',
|
||||
lastUpdated => 0,
|
||||
context => '%s is filled with an HTML Form control',
|
||||
},
|
||||
|
||||
'Every N months on' => {
|
||||
message => 'Every %s month(s) on',
|
||||
lastUpdated => 0,
|
||||
context => '%s is filled with an HTML Form control',
|
||||
},
|
||||
|
||||
'Every N years on' => {
|
||||
message => 'Every %s year(s) on',
|
||||
lastUpdated => 0,
|
||||
context => '%s is filled with an HTML Form control',
|
||||
},
|
||||
|
||||
'week on' => {
|
||||
message => 'week on',
|
||||
lastUpdated => 0,
|
||||
context => 'follows a select list with ordinals, first, second, etc. To form the phrase, First week on, Second week on',
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
|
|
@ -2154,8 +2154,8 @@ normal templates.|,
|
|||
},
|
||||
|
||||
'extraHeadTagsPacked' => {
|
||||
message => q|Extra tags that should be displayed in the header that this tikcet is displayed on minimized so no whitespace exists|,
|
||||
lastUpdated => 1147050475,
|
||||
message => q|Extra tags that should be displayed in the header that this ticket is displayed on minimized so no whitespace exists|,
|
||||
lastUpdated => 1257349398,
|
||||
context => q|help text label|,
|
||||
},
|
||||
|
||||
|
|
@ -2255,6 +2255,17 @@ normal templates.|,
|
|||
context => q|Field Label|,
|
||||
},
|
||||
|
||||
'eventMetaData' => {
|
||||
message => q|Meta data for the event returned as a JSON data structure|,
|
||||
lastUpdated => 1147050475,
|
||||
context => q|Field Label|,
|
||||
},
|
||||
|
||||
'ticketMeta_[LABEL]' => {
|
||||
message => q|Value for the meta data field [LABEL]. Non word and whitespace characters in [LABEL] should be replaced with an underscore. <br/><br/>Ex: Meta Data Label: "First Name" should be referenced: <tmpl_var ticketMeta_First_Name> and so on|,
|
||||
lastUpdated => 1147050475,
|
||||
context => q|Field Label|,
|
||||
},
|
||||
|
||||
# 'TODO' => {
|
||||
# message => q|TODO|,
|
||||
|
|
|
|||
|
|
@ -923,37 +923,37 @@ directly inside the answer_loop for other types of questions.|,
|
|||
context => q|Description of a template variable for a template Help page.|,
|
||||
lastUpdated => 1149654771,
|
||||
},
|
||||
|
||||
|
||||
response_feedback_url => {
|
||||
message => q|The URL of the individual response feedback page.|,
|
||||
context => q|Description of a template variable for a template Help page.|,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
response_id => {
|
||||
message => q|The unique ID of the response.|,
|
||||
context => q|Description of a template variable for a template Help page.|,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
response_userId => {
|
||||
message => q|The userId of the user that completed the response.|,
|
||||
context => q|Description of a template variable for a template Help page.|,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
response_ip => {
|
||||
message => q|The IP Address of the user that completed the response.|,
|
||||
context => q|Description of a template variable for a template Help page.|,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
response_startDate => {
|
||||
message => q|The Start Date of the response.|,
|
||||
context => q|Description of a template variable for a template Help page.|,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
response_endDate => {
|
||||
message => q|The End Date of the response.|,
|
||||
context => q|Description of a template variable for a template Help page.|,
|
||||
|
|
@ -981,7 +981,7 @@ directly inside the answer_loop for other types of questions.|,
|
|||
message => q|A boolean flag indicating whether the Survey Response completed|,
|
||||
lastUpdated => 1242180657,
|
||||
},
|
||||
|
||||
|
||||
'responseId help' => {
|
||||
message => q|The unique GUID for the response|,
|
||||
lastUpdated => 1242180657,
|
||||
|
|
@ -1031,7 +1031,7 @@ directly inside the answer_loop for other types of questions.|,
|
|||
message => q|All data tagged in survey expressions is also made available as template variables|,
|
||||
lastUpdated => 1242180657,
|
||||
},
|
||||
|
||||
|
||||
'survey test results template title' => {
|
||||
message => q|Survey Test Results Template Variables|,
|
||||
lastUpdated => 1242256111,
|
||||
|
|
@ -1579,117 +1579,132 @@ section/answer.|,
|
|||
context => q|Finish button label on Take Survey page|,
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'add a test' => {
|
||||
message => q{Add a test},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'confirm delete test' => {
|
||||
message => q{Are you sure you want to delete this test?},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'test suite' => {
|
||||
message => q{Test Suite},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'edit test' => {
|
||||
message => q{Edit Test},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'run test' => {
|
||||
message => q{Run Test},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'test name' => {
|
||||
message => q{Test Name},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'tests run' => {
|
||||
message => q{Tests Run},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'test name help' => {
|
||||
message => q{A descriptive name for this test},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'test spec' => {
|
||||
message => q{Test Spec},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'test spec help' => {
|
||||
message => q{The JSON-encoded specification for your test(s)},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'run all tests' => {
|
||||
message => q{Run All Tests},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'pass' => {
|
||||
message => q{Pass},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'fail' => {
|
||||
message => q{Fail},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'test results template' => {
|
||||
message => q{Test Results Template},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'test results template help' => {
|
||||
message => q{Template used to display individual test and aggregate test results},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'test results' => {
|
||||
message => q{Test Results},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'test result' => {
|
||||
message => q{Test Result},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'details' => {
|
||||
message => q{Details},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'tests passed' => {
|
||||
message => q{Tests Passed},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'tests failed' => {
|
||||
message => q{Tests Failed},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'start date' => {
|
||||
message => q{Start Date},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
|
||||
'end date' => {
|
||||
message => q{End Date},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'Add Question' => {
|
||||
message => q{Add Question},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'Add Answer' => {
|
||||
message => q{Add Answer},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
'Survey Objects' => {
|
||||
message => q{Survey Objects},
|
||||
lastUpdated => 0,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
|
|||
295
lib/WebGUI/i18n/English/ShipDriver_UPS.pm
Normal file
295
lib/WebGUI/i18n/English/ShipDriver_UPS.pm
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
package WebGUI::i18n::English::ShipDriver_UPS;
|
||||
|
||||
use strict;
|
||||
|
||||
our $I18N = {
|
||||
|
||||
'userid' => {
|
||||
message => q|UPS UserId|,
|
||||
lastUpdated => 1203569535,
|
||||
context => q|Label in the ShipDriver edit form.|,
|
||||
},
|
||||
|
||||
'userid help' => {
|
||||
message => q|You can get a UserId by first registering with the UPS.|,
|
||||
lastUpdated => 1203569511,
|
||||
},
|
||||
|
||||
'password' => {
|
||||
message => q|UPS Password|,
|
||||
lastUpdated => 1203569535,
|
||||
context => q|Label in the ShipDriver edit form.|,
|
||||
},
|
||||
|
||||
'password help' => {
|
||||
message => q|You will recieve a password along with your UserId when you register.|,
|
||||
lastUpdated => 1203569511,
|
||||
},
|
||||
|
||||
'license' => {
|
||||
message => q|UPS Access License Number|,
|
||||
lastUpdated => 1203569535,
|
||||
context => q|Label in the ShipDriver edit form.|,
|
||||
},
|
||||
|
||||
'license help' => {
|
||||
message => q|You will recieve a license along with your UserId and password when you register.|,
|
||||
lastUpdated => 1203569511,
|
||||
},
|
||||
|
||||
'instructions' => {
|
||||
message => q|Registration Instructions|,
|
||||
lastUpdated => 1203569535,
|
||||
context => q|Label in the ShipDriver edit form.|,
|
||||
},
|
||||
|
||||
'ups instructions' => {
|
||||
lastUpdated => 1241028258,
|
||||
message => q|<p>In order to use the UPS Shipping Driver, you must first register with the UPS on their <a href="http://www.ups.com/e_comm_access/gettools_index?loc=en_US">website</a>. When you get to the step for an access key, be sure to get an XML access key. Enter your UPS username and password and access key into the form.</p><p>The driver currently supports domestic and international shipping from the United States. The weight property of a Product is considered to be in pounds. All currencies are in United States dollars. The package for shipping is a generic package, and there are no options for tubes, envelopes or fixed size packages available from the UPS.</p>|,
|
||||
},
|
||||
|
||||
'ship service' => {
|
||||
message => q|Shipping service|,
|
||||
lastUpdated => 1203569535,
|
||||
context => q|Label in the ShipDriver edit form.|,
|
||||
},
|
||||
|
||||
'ship service help' => {
|
||||
message => q|Select one from the list of options. If you wish to provide multiple types of shipping, create one additional shipping driver instance for each option.|,
|
||||
lastUpdated => 1203569511,
|
||||
},
|
||||
|
||||
'pickup type' => {
|
||||
message => q|Pickup Type|,
|
||||
lastUpdated => 1243006539,
|
||||
context => q|Label in the ShipDriver edit form.|,
|
||||
},
|
||||
|
||||
'pickup type help' => {
|
||||
message => q|Select how the packages will be delivered to the UPS for shipping.|,
|
||||
lastUpdated => 1203569511,
|
||||
},
|
||||
|
||||
'source zipcode' => {
|
||||
message => q|Shipping Zipcode|,
|
||||
lastUpdated => 1203569535,
|
||||
context => q|Label in the ShipDriver edit form.|,
|
||||
},
|
||||
|
||||
'source zipcode help' => {
|
||||
message => q|The zipcode of the location you will be shipping from.|,
|
||||
lastUpdated => 1203569511,
|
||||
},
|
||||
|
||||
'source country' => {
|
||||
message => q|Shipping Country|,
|
||||
lastUpdated => 1242945847,
|
||||
context => q|Label in the ShipDriver edit form.|,
|
||||
},
|
||||
|
||||
'source country help' => {
|
||||
message => q|The country you will be shipping from.|,
|
||||
lastUpdated => 1242945844,
|
||||
},
|
||||
|
||||
'customer classification' => {
|
||||
message => q|Customer Classification|,
|
||||
lastUpdated => 1241214572,
|
||||
context => q|What kind or type of customer are you?|,
|
||||
},
|
||||
|
||||
'customer classification help' => {
|
||||
message => q|The kind or type of customer you are.|,
|
||||
lastUpdated => 1247110533,
|
||||
},
|
||||
|
||||
'residentialIndicator' => {
|
||||
message => q|Residential or Commercial?|,
|
||||
lastUpdated => 1248113596,
|
||||
context => q|Residential (a person's home) versus Commercial, a business address.|,
|
||||
},
|
||||
|
||||
'residential help' => {
|
||||
message => q|The UPS rates for delivering to a residential address, or a commercial address differ. WebGUI will not ask the user which is which, so you will need to configure drivers for both kinds of destinations.|,
|
||||
lastUpdated => 1248113598,
|
||||
},
|
||||
|
||||
'residential' => {
|
||||
message => q|Residential|,
|
||||
lastUpdated => 1248113596,
|
||||
context => q|Residential (a person's home)|,
|
||||
},
|
||||
|
||||
'commercial' => {
|
||||
message => q|Commercial|,
|
||||
lastUpdated => 1248113596,
|
||||
context => q|A business address|,
|
||||
},
|
||||
|
||||
'customer classification 01' => {
|
||||
message => q|Wholesale|,
|
||||
lastUpdated => 1247110533,
|
||||
},
|
||||
|
||||
'customer classification 03' => {
|
||||
message => q|Occasional|,
|
||||
lastUpdated => 1247110533,
|
||||
},
|
||||
|
||||
'customer classification 04' => {
|
||||
message => q|Retail|,
|
||||
lastUpdated => 1247110533,
|
||||
},
|
||||
|
||||
'flatFee' => {
|
||||
message => q|Flat Fee|,
|
||||
lastUpdated => 1241214572,
|
||||
context => q|A fixed amount of money added to a purchase for shipping.|,
|
||||
},
|
||||
|
||||
'flatFee help' => {
|
||||
message => q|A fixed amount of money added to a purchase for shipping, covering shipping materials and handling.|,
|
||||
lastUpdated => 1241214575,
|
||||
},
|
||||
|
||||
'us domestic 01' => {
|
||||
message => q|UPS Next Day Air|,
|
||||
lastUpdated => 1203569511,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'us domestic 02' => {
|
||||
message => q|UPS Second Day Air|,
|
||||
lastUpdated => 1203569511,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'us domestic 03' => {
|
||||
message => q|UPS Ground|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'us domestic 12' => {
|
||||
message => q|UPS Three-Day Select|,
|
||||
lastUpdated => 1203569511,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'us domestic 13' => {
|
||||
message => q|UPS Next Day Air Saver|,
|
||||
lastUpdated => 1203569511,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'us domestic 14' => {
|
||||
message => q|UPS Next Day Air Early A.M.|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'us domestic 59' => {
|
||||
message => q|UPS Second Day Air A.M.|,
|
||||
lastUpdated => 1203569511,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'pickup code 01' => {
|
||||
message => q|Daily Pickup|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'pickup code 03' => {
|
||||
message => q|Customer Counter|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'pickup code 06' => {
|
||||
message => q|One Time Pickup|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'pickup code 07' => {
|
||||
message => q|On Call Air|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'pickup code 11' => {
|
||||
message => q|Suggested Retail Rates|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'pickup code 19' => {
|
||||
message => q|Letter Center|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'pickup code 20' => {
|
||||
message => q|Air Service Center|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'us domestic' => {
|
||||
message => q|US Domestic|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'us international' => {
|
||||
message => q|US International|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'ship type' => {
|
||||
message => q|Shipping Type|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'ship type help' => {
|
||||
message => q|Pick a type of shipping that will be used. The different types have different services available. Not all services are available in all types, or in all countries. Changing the service will change the Ship Service options below.|,
|
||||
lastUpdated => 1247111015,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'us international 07' => {
|
||||
message => q|UPS Worldwide Express|,
|
||||
lastUpdated => 1203569511,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'us international 08' => {
|
||||
message => q|UPS Worldwide Expedited|,
|
||||
lastUpdated => 1203569511,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'us international 11' => {
|
||||
message => q|UPS Standard|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'us international 54' => {
|
||||
message => q|UPS Worldwide Express Plus|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
'us international 65' => {
|
||||
message => q|UPS Saver|,
|
||||
lastUpdated => 1242166045,
|
||||
context => q|Label for a type of shipping from the UPS.|,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
1;
|
||||
|
|
@ -113,8 +113,8 @@ our $I18N = {
|
|||
},
|
||||
|
||||
'insurance rates help' => {
|
||||
message => q|Enter in one field per line with the format, value:cost.<br />value is the value of the contents.<br />cost is the cost of insurance at that value.<br />value and cost should look like numbers with a decimal point, like 0.50 or 1.00|,
|
||||
lastUpdated => 1253988884,
|
||||
message => q|Enter in one field per line with the format, value:cost.<br />value is the value of the contents.<br />cost is the cost of insurance at that value.<br />value and cost should look like numbers with a decimal point, like 0.50 or 1.00.<br />For values of contents inbetween points, use the next highest value. If the value of the contents exceeds the highest listed value, it will use the cost of insurance at the highest listed value.|,
|
||||
lastUpdated => 1257369016,
|
||||
context => q|Help for the insurance rate field.|,
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ use Getopt::Long;
|
|||
use POE::Component::IKC::ClientLite;
|
||||
use Spectre::Admin;
|
||||
use WebGUI::Config;
|
||||
use JSON;
|
||||
|
||||
$|=1; # disable output buffering
|
||||
my $help;
|
||||
|
|
@ -158,7 +159,17 @@ sub getStatusReport {
|
|||
return $POE::Component::IKC::ClientLite::error unless defined $result;
|
||||
$remote->disconnect;
|
||||
undef $remote;
|
||||
return $result;
|
||||
my $pattern = "%8.8s %-9.9s %-30.30s %-22.22s %-15.15s %-20.20s\n";
|
||||
my $total = 0;
|
||||
my $output = sprintf $pattern, "Priority", "Status", "Sitename", "Instance Id", "Last Run", "Last Run Time";
|
||||
foreach my $instance (@{JSON->new->decode($result)}) {
|
||||
my $originalPriority = ($instance->{priority} - 1) * 10;
|
||||
my $priority = $instance->{workingPriority}."/".$originalPriority;
|
||||
$output .= sprintf $pattern, $priority, $instance->{status}, $instance->{sitename}, $instance->{instanceId}, $instance->{lastState}, $instance->{lastRunTime};
|
||||
$total++;
|
||||
}
|
||||
$output .= sprintf "\n%19.19s %4d\n", "Total Workflows", $total;
|
||||
return $output;
|
||||
}
|
||||
|
||||
__END__
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ checkModule("CSS::Minifier::XS", "0.03" );
|
|||
checkModule("JavaScript::Minifier::XS", "0.05" );
|
||||
checkModule("Readonly", "1.03" );
|
||||
checkModule("Business::PayPal::API", "0.62" );
|
||||
checkModule("Locales::Country", "0.05" );
|
||||
|
||||
failAndExit("Required modules are missing, running no more checks.") if $missingModule;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use WebGUI::Session;
|
|||
use WebGUI::User;
|
||||
|
||||
use WebGUI::Asset;
|
||||
use Test::More tests => 90; # increment this value for each test you create
|
||||
use Test::More tests => 92; # increment this value for each test you create
|
||||
use Test::Deep;
|
||||
|
||||
# Test the methods in WebGUI::AssetLineage
|
||||
|
|
@ -388,16 +388,19 @@ my $snippet4 = WebGUI::Asset->newByLineage($session, $snippets[4]->get('lineage'
|
|||
is ($snippet4->getId, $snippets[4]->getId, 'newByLineage returns correct Asset');
|
||||
|
||||
$snippet4 = WebGUI::Asset->newByLineage($session, $snippets[4]->get('lineage'));
|
||||
is ($snippet4->getId, $snippets[4]->getId, 'newByLineage: cached lookup');
|
||||
is ($snippet4->getId, $snippets[4]->getId, '... cached lookup');
|
||||
|
||||
my $cachedLineage = $session->stow->get('assetLineage');
|
||||
delete $cachedLineage->{$snippet4->get('lineage')}->{id};
|
||||
my $snippet4 = WebGUI::Asset->newByLineage($session, $snippets[4]->get('lineage'));
|
||||
is ($snippet4->getId, $snippets[4]->getId, 'newByLineage: failing id cache forces lookup');
|
||||
is ($snippet4->getId, $snippets[4]->getId, '... failing id cache forces lookup');
|
||||
|
||||
delete $cachedLineage->{$snippet4->get('lineage')}->{class};
|
||||
my $snippet4 = WebGUI::Asset->newByLineage($session, $snippets[4]->get('lineage'));
|
||||
is ($snippet4->getId, $snippets[4]->getId, 'newByLineage: failing class cache forces lookup');
|
||||
is ($snippet4->getId, $snippets[4]->getId, '... failing class cache forces lookup');
|
||||
|
||||
is(WebGUI::Asset->newByLineage($session, 'notALineage'), undef, '... returns undef');
|
||||
ok(!exists $session->stow->get('assetLineage')->{assetLineage}, '... no entry for the bad lineage in stow');
|
||||
|
||||
####################################################
|
||||
#
|
||||
|
|
|
|||
|
|
@ -29,7 +29,11 @@ addToCleanup($versionTag);
|
|||
|
||||
my $wiki = $node->addChild({className=>'WebGUI::Asset::Wobject::WikiMaster'});
|
||||
$versionTag->commit;
|
||||
my $wikipage = $wiki->addChild({className=>'WebGUI::Asset::WikiPage'}, undef, undef, {skipAutoCommitWorkflows => 1});
|
||||
my $wikipage = $wiki->addChild(
|
||||
{className=>'WebGUI::Asset::WikiPage'},
|
||||
undef, undef,
|
||||
{skipAutoCommitWorkflows => 1, skipNotification => 1}
|
||||
);
|
||||
|
||||
# Wikis create and autocommit a version tag when a child is added. Lets get the name so we can roll it back.
|
||||
my $secondVersionTag = WebGUI::VersionTag->new($session,$wikipage->get("tagId"));
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ isa_ok($ems, 'WebGUI::Asset::Wobject::EventManagementSystem');
|
|||
|
||||
# Test to see if we can set new values
|
||||
my $newEMSSettings = {
|
||||
timezone => 'America/New York',
|
||||
timezone => 'America/New_York',
|
||||
};
|
||||
|
||||
# update the new values for this instance
|
||||
|
|
@ -222,12 +222,14 @@ $templateMock->mock('process', sub { $templateVars = $_[1]; } );
|
|||
'isPackage' => ignore(),
|
||||
'usePackedHeadTags' => ignore(),
|
||||
'encryptPage' => ignore(),
|
||||
'eventMetaData' => ignore(),
|
||||
'tagId' => ignore(),
|
||||
'seatsAvailable' => '5',
|
||||
'revisedBy' => ignore(),
|
||||
'isExportable' => ignore(),
|
||||
'creationDate' => ignore(),
|
||||
'ticketStart' => '2009-01-01 14:00:00'
|
||||
'ticketStart' => '2009-01-01 09:00',
|
||||
'ticketStart_epoch' => '1230818400',
|
||||
};
|
||||
|
||||
my $ticket2 = {
|
||||
|
|
@ -262,11 +264,13 @@ $templateMock->mock('process', sub { $templateVars = $_[1]; } );
|
|||
'usePackedHeadTags' => ignore(),
|
||||
'encryptPage' => ignore(),
|
||||
'tagId' => ignore(),
|
||||
'eventMetaData' => ignore(),
|
||||
'seatsAvailable' => '3',
|
||||
'revisedBy' => ignore(),
|
||||
'isExportable' => ignore(),
|
||||
'creationDate' => ignore(),
|
||||
'ticketStart' => '2009-01-01 14:00:00'
|
||||
'ticketStart' => '2009-01-01 09:00',
|
||||
'ticketStart_epoch' => '1230818400',
|
||||
};
|
||||
|
||||
my @ticketArray = ();
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ cmp_deeply(
|
|||
methods(
|
||||
title => 'Dummy Title',
|
||||
description => 'Dummy Synopsis', ##Not description
|
||||
link => '/home/shawshank',
|
||||
link => $session->url->getSiteURL . '/home/shawshank',
|
||||
copyright => undef,
|
||||
),
|
||||
'... title, description, link inherit from asset by default, copyright unset'
|
||||
|
|
@ -139,7 +139,7 @@ cmp_deeply(
|
|||
methods(
|
||||
title => 'Rita Hayworth and the Shawshank Redemption',
|
||||
description => 'A good movie, providing loads of testing collateral',
|
||||
link => '/home/shawshank',
|
||||
link => $session->url->getSiteURL . '/home/shawshank',
|
||||
copyright => 'copyright 2009 Plain Black Corporation',
|
||||
),
|
||||
'... feed settings override asset defaults, copyright'
|
||||
|
|
|
|||
|
|
@ -93,8 +93,9 @@ cmp_bag(
|
|||
[
|
||||
'WebGUI::Shop::ShipDriver::FlatRate',
|
||||
'WebGUI::Shop::ShipDriver::USPS',
|
||||
'WebGUI::Shop::ShipDriver::UPS',
|
||||
],
|
||||
'getDrivers: WebGUI only ships with 1 default shipping driver',
|
||||
'getDrivers: WebGUI ships with 3 default shipping drivers',
|
||||
);
|
||||
|
||||
#######################################################################
|
||||
|
|
|
|||
556
t/Shop/ShipDriver/UPS.t
Normal file
556
t/Shop/ShipDriver/UPS.t
Normal file
|
|
@ -0,0 +1,556 @@
|
|||
# vim:syntax=perl
|
||||
#-------------------------------------------------------------------
|
||||
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
|
||||
#-------------------------------------------------------------------
|
||||
# Please read the legal notices (docs/legal.txt) and the license
|
||||
# (docs/license.txt) that came with this distribution before using
|
||||
# this software.
|
||||
#------------------------------------------------------------------
|
||||
# http://www.plainblack.com info@plainblack.com
|
||||
#------------------------------------------------------------------
|
||||
|
||||
# Write a little about what this script tests.
|
||||
#
|
||||
#
|
||||
|
||||
use FindBin;
|
||||
use strict;
|
||||
use lib "$FindBin::Bin/../../lib";
|
||||
use Test::More;
|
||||
use Test::Deep;
|
||||
use XML::Simple;
|
||||
use Data::Dumper;
|
||||
use Locales::Country qw/en/;
|
||||
|
||||
use WebGUI::Test; # Must use this before any other WebGUI modules
|
||||
use WebGUI::Session;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Init
|
||||
my $session = WebGUI::Test->session;
|
||||
my $user = WebGUI::User->create($session);
|
||||
WebGUI::Test->usersToDelete($user);
|
||||
$session->user({user => $user});
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
|
||||
my $tests = 41;
|
||||
plan tests => 1 + $tests;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# put your tests here
|
||||
|
||||
my $loaded = use_ok('WebGUI::Shop::ShipDriver::UPS');
|
||||
|
||||
my $storage;
|
||||
my ($driver, $cart);
|
||||
my $versionTag = WebGUI::VersionTag->getWorking($session);
|
||||
|
||||
my $home = WebGUI::Asset->getDefault($session);
|
||||
|
||||
my $rockHammer = $home->addChild({
|
||||
className => 'WebGUI::Asset::Sku::Product',
|
||||
isShippingRequired => 1, title => 'Rock Hammers',
|
||||
shipsSeparately => 0,
|
||||
});
|
||||
|
||||
my $smallHammer = $rockHammer->setCollateral('variantsJSON', 'variantId', 'new',
|
||||
{
|
||||
shortdesc => 'Small rock hammer', price => 7.50,
|
||||
varSku => 'small-hammer', weight => 1.5,
|
||||
quantity => 9999,
|
||||
}
|
||||
);
|
||||
|
||||
my $bigHammer = $rockHammer->setCollateral('variantsJSON', 'variantId', 'new',
|
||||
{
|
||||
shortdesc => 'Big rock hammer', price => 19.99,
|
||||
varSku => 'big-hammer', weight => 12,
|
||||
quantity => 9999,
|
||||
}
|
||||
);
|
||||
|
||||
my $bible = $home->addChild({
|
||||
className => 'WebGUI::Asset::Sku::Product',
|
||||
isShippingRequired => 1, title => 'Bibles, individuall wrapped and shipped',
|
||||
shipsSeparately => 1,
|
||||
});
|
||||
|
||||
my $kjvBible = $bible->setCollateral('variantsJSON', 'variantId', 'new',
|
||||
{
|
||||
shortdesc => 'King James Bible', price => 17.50,
|
||||
varSku => 'kjv-bible', weight => 2.5,
|
||||
quantity => 99999,
|
||||
}
|
||||
);
|
||||
|
||||
my $nivBible = $bible->setCollateral('variantsJSON', 'variantId', 'new',
|
||||
{
|
||||
shortdesc => 'NIV Bible', price => 22.50,
|
||||
varSku => 'niv-bible', weight => 2.0,
|
||||
quantity => 999999,
|
||||
}
|
||||
);
|
||||
|
||||
my $feather = $home->addChild({
|
||||
className => 'WebGUI::Asset::Sku::Product',
|
||||
isShippingRequired => 1, title => 'Feathers',
|
||||
shipsSeparately => 0,
|
||||
});
|
||||
|
||||
my $blueFeather = $feather->setCollateral('variantsJSON', 'variantId', 'new',
|
||||
{
|
||||
shortdesc => 'blue feather', price => 1.00,
|
||||
varSku => 'blue', weight => 0.001,
|
||||
quantity => 999999,
|
||||
}
|
||||
);
|
||||
|
||||
$versionTag->commit;
|
||||
WebGUI::Test->tagsToRollback($versionTag);
|
||||
|
||||
SKIP: {
|
||||
|
||||
skip 'Unable to load module WebGUI::Shop::ShipDriver::UPS', $tests unless $loaded;
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# definition
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
my $definition;
|
||||
my $e; ##Exception variable, used throughout the file
|
||||
|
||||
eval { $definition = WebGUI::Shop::ShipDriver::UPS->definition(); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'definition takes an exception to not giving it a session variable');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
error => 'Must provide a session variable',
|
||||
),
|
||||
'... checking error message',
|
||||
);
|
||||
|
||||
|
||||
isa_ok(
|
||||
$definition = WebGUI::Shop::ShipDriver::UPS->definition($session),
|
||||
'ARRAY'
|
||||
);
|
||||
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# create
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
my $options = {
|
||||
label => 'UPS Driver',
|
||||
enabled => 1,
|
||||
};
|
||||
|
||||
$driver = WebGUI::Shop::ShipDriver::UPS->create($session, $options);
|
||||
|
||||
isa_ok($driver, 'WebGUI::Shop::ShipDriver::UPS');
|
||||
isa_ok($driver, 'WebGUI::Shop::ShipDriver');
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# getName
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
is (WebGUI::Shop::ShipDriver::UPS->getName($session), 'UPS', 'getName returns the human readable name of this driver');
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# delete
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
my $driverId = $driver->getId;
|
||||
$driver->delete;
|
||||
|
||||
my $count = $session->db->quickScalar('select count(*) from shipper where shipperId=?',[$driverId]);
|
||||
is($count, 0, 'delete deleted the object');
|
||||
|
||||
undef $driver;
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# calculate, and private methods.
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
$driver = WebGUI::Shop::ShipDriver::UPS->create($session, {
|
||||
label => 'Shipping from Shawshank',
|
||||
enabled => 1,
|
||||
shipType => 'PARCEL',
|
||||
});
|
||||
|
||||
eval { $driver->calculate() };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'calculate throws an exception when no zipcode has been set');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
error => 'Driver configured without a source zipcode.',
|
||||
),
|
||||
'... checking error message',
|
||||
);
|
||||
|
||||
my $properties = $driver->get();
|
||||
$properties->{sourceZip} = '97123';
|
||||
$driver->update($properties);
|
||||
eval { $driver->calculate() };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'calculate throws an exception when no source country');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
error => 'Driver configured without a source country.',
|
||||
),
|
||||
'... checking error message',
|
||||
);
|
||||
|
||||
$properties = $driver->get();
|
||||
$properties->{sourceCountry} = 'United States';
|
||||
$driver->update($properties);
|
||||
eval { $driver->calculate() };
|
||||
$e = WebGUI::Error->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'calculate throws an exception when no userId');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
error => 'Driver configured without a UPS userId.',
|
||||
),
|
||||
'... checking error message',
|
||||
);
|
||||
|
||||
$properties = $driver->get();
|
||||
$properties->{userId} = 'Me';
|
||||
$driver->update($properties);
|
||||
eval { $driver->calculate() };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'calculate throws an exception when no password');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
error => 'Driver configured without a UPS password.',
|
||||
),
|
||||
'... checking error message',
|
||||
);
|
||||
|
||||
$properties = $driver->get();
|
||||
$properties->{password} = 'knock knock';
|
||||
$driver->update($properties);
|
||||
eval { $driver->calculate() };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'calculate throws an exception when no license number');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
error => 'Driver configured without a UPS license number.',
|
||||
),
|
||||
'... checking error message',
|
||||
);
|
||||
|
||||
$cart = WebGUI::Shop::Cart->newBySession($session);
|
||||
my $addressBook = $cart->getAddressBook;
|
||||
my $workAddress = $addressBook->addAddress({
|
||||
label => 'work',
|
||||
organization => 'Plain Black Corporation',
|
||||
address1 => '1360 Regent St. #145',
|
||||
city => 'Madison', state => 'WI', code => '53715',
|
||||
country => 'USA',
|
||||
});
|
||||
my $wucAddress = $addressBook->addAddress({
|
||||
label => 'wuc',
|
||||
organization => 'Madison Concourse Hotel',
|
||||
address1 => '1 W Dayton St',
|
||||
city => 'Madison', state => 'WI', code => '53703',
|
||||
country => 'USA',
|
||||
});
|
||||
$cart->update({shippingAddressId => $workAddress->getId});
|
||||
|
||||
cmp_deeply(
|
||||
[$driver->_getShippableUnits($cart)],
|
||||
[(), ],
|
||||
'_getShippableUnits: empty cart'
|
||||
);
|
||||
|
||||
$rockHammer->addToCart($rockHammer->getCollateral('variantsJSON', 'variantId', $smallHammer));
|
||||
cmp_deeply(
|
||||
[$driver->_getShippableUnits($cart)],
|
||||
[ [ [ ignore() ], ], ],
|
||||
'_getShippableUnits: one loose item in the cart'
|
||||
);
|
||||
|
||||
$rockHammer->addToCart($rockHammer->getCollateral('variantsJSON', 'variantId', $bigHammer));
|
||||
cmp_bag(
|
||||
[$driver->_getShippableUnits($cart)],
|
||||
[ [ [ ignore(), ignore() ], ], ],
|
||||
'_getShippableUnits: two loose items in the cart'
|
||||
);
|
||||
|
||||
$bible->addToCart($bible->getCollateral('variantsJSON', 'variantId', $kjvBible));
|
||||
cmp_bag(
|
||||
[$driver->_getShippableUnits($cart)],
|
||||
[ bag( [ ignore(), ignore() ], [ ignore() ], ), ],
|
||||
'_getShippableUnits: two loose items, and 1 ships separately item in the cart'
|
||||
);
|
||||
|
||||
my $bibleItem = $bible->addToCart($bible->getCollateral('variantsJSON', 'variantId', $nivBible));
|
||||
$bibleItem->setQuantity(3);
|
||||
cmp_bag(
|
||||
[$driver->_getShippableUnits($cart)],
|
||||
[ bag( [ ignore(), ignore() ], [ ignore() ], [ ignore() ], [ ignore() ], [ ignore() ] ) ],
|
||||
'_getShippableUnits: two loose items, and 4 ships separately item in the cart, due to quantity'
|
||||
);
|
||||
|
||||
my $rockHammer2 = $bible->addToCart($rockHammer->getCollateral('variantsJSON', 'variantId', $smallHammer));
|
||||
$rockHammer2->update({shippingAddressId => $wucAddress->getId});
|
||||
cmp_bag(
|
||||
[$driver->_getShippableUnits($cart)],
|
||||
[
|
||||
bag( [ ignore(), ignore() ], [ ignore() ], [ ignore() ], [ ignore() ], [ ignore() ] ),
|
||||
[ [ ignore() ], ],
|
||||
],
|
||||
'_getShippableUnits: two loose items, and 4 ships separately item in the cart, and another loose item sorted by zipcode'
|
||||
);
|
||||
|
||||
$cart->empty;
|
||||
$bible->addToCart($bible->getCollateral('variantsJSON', 'variantId', $nivBible));
|
||||
cmp_deeply(
|
||||
[$driver->_getShippableUnits($cart)],
|
||||
[ [ ignore() ], ],
|
||||
'_getShippableUnits: only 1 ships separately item in the cart'
|
||||
);
|
||||
$cart->empty;
|
||||
|
||||
my $userId = $session->config->get('testing/UPS_userId');
|
||||
my $hasUPSCredentials = 1;
|
||||
##If there isn't a userId, set a fake one for XML testing.
|
||||
if (! $userId) {
|
||||
$hasUPSCredentials = 0;
|
||||
$userId = "blahBlahBlah";
|
||||
}
|
||||
|
||||
my $password = $session->config->get('testing/UPS_password');
|
||||
##If there isn't a password, set a fake one for XML testing.
|
||||
if (! $password) {
|
||||
$hasUPSCredentials = 0;
|
||||
$password = "nyaahNyaah";
|
||||
}
|
||||
|
||||
my $license = $session->config->get('testing/UPS_licenseNo');
|
||||
##If there isn't a license, set a fake one for XML testing.
|
||||
if (! $license) {
|
||||
$hasUPSCredentials = 0;
|
||||
$license = "bogey";
|
||||
}
|
||||
|
||||
$properties = $driver->get();
|
||||
$properties->{userId} = $userId;
|
||||
$properties->{password} = $password;
|
||||
$properties->{licenseNo} = $license;
|
||||
$properties->{sourceZip} = '97123';
|
||||
$properties->{sourceCountry} = 'United States';
|
||||
$properties->{shipService} = '03';
|
||||
$properties->{pickupType} = '01';
|
||||
$properties->{customerClassification} = '04';
|
||||
$properties->{residentialIndicator} = 'residential';
|
||||
$driver->update($properties);
|
||||
|
||||
$driver->testMode(1);
|
||||
|
||||
my $rockItem = $rockHammer->addToCart($rockHammer->getCollateral('variantsJSON', 'variantId', $smallHammer));
|
||||
my @shippableUnits = $driver->_getShippableUnits($cart);
|
||||
|
||||
##Must look them up one zip at a time
|
||||
my $xml = $driver->buildXML($cart, $shippableUnits[0]);
|
||||
like($xml, qr/^<.xml version='1.0'.+?<.xml version=/ms, 'buildXML: has two xml declarations');
|
||||
like($xml, qr/<AccessRequest xml:lang/, '... xml:lang is an attribute of AccessRequest');
|
||||
#diag $xml;
|
||||
|
||||
my ($xmlA, $xmlR) = split /\n(?=<\?xml)/, $xml;
|
||||
|
||||
my $xmlAcc = XMLin($xmlA,
|
||||
KeepRoot => 1,
|
||||
);
|
||||
|
||||
cmp_deeply(
|
||||
$xmlAcc,
|
||||
{
|
||||
AccessRequest => {
|
||||
Password => $password,
|
||||
UserId => $userId,
|
||||
'xml:lang' => 'en-US',
|
||||
AccessLicenseNumber => $license,
|
||||
},
|
||||
},
|
||||
'... correct access request data structure for 1 package'
|
||||
);
|
||||
|
||||
my $xmlRate = XMLin($xmlR,
|
||||
KeepRoot => 1,
|
||||
);
|
||||
|
||||
cmp_deeply(
|
||||
$xmlRate, {
|
||||
RatingServiceSelectionRequest => {
|
||||
'xml:lang' => 'en-US',
|
||||
PickupType => { Code => '01', },
|
||||
CustomerClassification => { Code => '04', },
|
||||
Request => { RequestAction => 'Rate', },
|
||||
Shipment => {
|
||||
Shipper => {
|
||||
Address => { PostalCode => 97123, CountryCode => 'us', },
|
||||
},
|
||||
ShipTo => {
|
||||
Address => { PostalCode => 53715, CountryCode => 'us', ResidentialAddressIndicator => {}, },
|
||||
},
|
||||
Service => { Code => '03', },
|
||||
Package => {
|
||||
PackagingType => { Code => '02', },
|
||||
PackageWeight => { Weight => '1.5', },
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
'... correct access rating request structure for 1 package'
|
||||
);
|
||||
|
||||
SKIP: {
|
||||
|
||||
skip 'No UPS credentials for testing', 3 unless $hasUPSCredentials;
|
||||
|
||||
my $response = $driver->_doXmlRequest($xml);
|
||||
ok($response->is_success, '_doXmlRequest to UPS successful for 1 package');
|
||||
#diag $response->content;
|
||||
my $xmlData = XMLin($response->content, ForceArray => [qw/RatedPackage/],);
|
||||
ok($xmlData->{Response}->{ResponseStatusCode}, '... responseCode is successful');
|
||||
ok($xmlData->{RatedShipment}->{TotalCharges}->{MonetaryValue}, '... total charges returned');
|
||||
#diag($xmlData->{RatedShipment}->{TotalCharges}->{MonetaryValue});
|
||||
|
||||
}
|
||||
|
||||
$rockItem->setQuantity(2);
|
||||
@shippableUnits = $driver->_getShippableUnits($cart);
|
||||
$xml = $driver->buildXML($cart, $shippableUnits[0]);
|
||||
SKIP: {
|
||||
|
||||
skip 'No UPS credentials for testing', 3 unless $hasUPSCredentials;
|
||||
|
||||
my $response = $driver->_doXmlRequest($xml);
|
||||
ok($response->is_success, '_doXmlRequest to UPS successful for 1 item, quantity=2');
|
||||
#diag $response->content;
|
||||
my $xmlData = XMLin($response->content, ForceArray => [qw/RatedPackage/],);
|
||||
ok($xmlData->{Response}->{ResponseStatusCode}, '... responseCode is successful');
|
||||
ok($xmlData->{RatedShipment}->{TotalCharges}->{MonetaryValue}, '... total charges returned');
|
||||
#diag($xmlData->{RatedShipment}->{TotalCharges}->{MonetaryValue});
|
||||
|
||||
}
|
||||
|
||||
|
||||
TODO: {
|
||||
local $TODO = 'single item shipping cost calculation';
|
||||
ok(0, 'call _calculateFromXML with arranged data');
|
||||
}
|
||||
|
||||
|
||||
$bibleItem = $bible->addToCart($bible->getCollateral('variantsJSON', 'variantId', $nivBible));
|
||||
@shippableUnits = $driver->_getShippableUnits($cart);
|
||||
$xml = $driver->buildXML($cart, @shippableUnits);
|
||||
|
||||
($xmlA, $xmlR) = split /\n(?=<\?xml)/, $xml;
|
||||
|
||||
#diag $xmlR;
|
||||
|
||||
$xmlRate = XMLin( $xmlR,
|
||||
KeepRoot => 1,
|
||||
ForceArray => ['Package'],
|
||||
);
|
||||
|
||||
#diag Dumper $xmlRate;
|
||||
|
||||
cmp_deeply(
|
||||
$xmlRate, {
|
||||
RatingServiceSelectionRequest => {
|
||||
'xml:lang' => 'en-US',
|
||||
PickupType => { Code => '01', },
|
||||
CustomerClassification => { Code => '04', },
|
||||
Request => { RequestAction => 'Rate', },
|
||||
Shipment => {
|
||||
Shipper => {
|
||||
Address => { PostalCode => 97123, CountryCode => 'us', },
|
||||
},
|
||||
ShipTo => {
|
||||
Address => { PostalCode => 53715, CountryCode => 'us', ResidentialAddressIndicator => {}, },
|
||||
},
|
||||
Service => { Code => '03', },
|
||||
Package => bag(
|
||||
{
|
||||
PackagingType => { Code => '02', },
|
||||
PackageWeight => { Weight => '3.0', },
|
||||
},
|
||||
{
|
||||
PackagingType => { Code => '02', },
|
||||
PackageWeight => { Weight => '2.0', },
|
||||
},
|
||||
),
|
||||
},
|
||||
}
|
||||
},
|
||||
'... correct access rating request structure for two packages in cart'
|
||||
);
|
||||
|
||||
SKIP: {
|
||||
|
||||
skip 'No UPS credentials for testing', 3 unless $hasUPSCredentials;
|
||||
|
||||
my $response = $driver->_doXmlRequest($xml);
|
||||
ok($response->is_success, '_doXmlRequest to UPS successful for two package in 1 request');
|
||||
my $xmlData = XMLin($response->content, ForceArray => [qw/RatedPackage/],);
|
||||
ok($xmlData->{Response}->{ResponseStatusCode}, '... responseCode is successful');
|
||||
ok($xmlData->{RatedShipment}->{TotalCharges}->{MonetaryValue}, '... total charges returned');
|
||||
#diag $xmlData->{RatedShipment}->{TotalCharges}->{MonetaryValue};
|
||||
|
||||
}
|
||||
|
||||
ok($driver->getEditForm(), 'getEditForm');
|
||||
|
||||
$cart->empty;
|
||||
$feather->addToCart($feather->getCollateral('variantsJSON', 'variantId', $blueFeather));
|
||||
$xml = $driver->buildXML($cart, $driver->_getShippableUnits($cart));
|
||||
($xmlA, $xmlR) = split /\n(?=<\?xml)/, $xml;
|
||||
|
||||
$xmlRate = XMLin( $xmlR,
|
||||
KeepRoot => 1,
|
||||
ForceArray => ['Package'],
|
||||
);
|
||||
|
||||
is (
|
||||
$xmlRate->{RatingServiceSelectionRequest}->{Shipment}->{Package}->[0]->{PackageWeight}->{Weight},
|
||||
'0.1',
|
||||
'Weight is clipped at 0.1 pounds.'
|
||||
);
|
||||
|
||||
$cart->empty;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Cleanup
|
||||
END {
|
||||
if (defined $driver && $driver->isa('WebGUI::Shop::ShipDriver')) {
|
||||
$driver->delete;
|
||||
}
|
||||
if (defined $cart && $cart->isa('WebGUI::Shop::Cart')) {
|
||||
my $addressBook = $cart->getAddressBook();
|
||||
$addressBook->delete if $addressBook;
|
||||
$cart->delete;
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,7 @@ use Data::Dumper;
|
|||
use WebGUI::Test; # Must use this before any other WebGUI modules
|
||||
use WebGUI::Session;
|
||||
|
||||
plan tests => 64;
|
||||
plan tests => 65;
|
||||
use_ok('WebGUI::Shop::ShipDriver::USPS')
|
||||
or die 'Unable to load module WebGUI::Shop::ShipDriver::USPS';
|
||||
|
||||
|
|
@ -377,15 +377,18 @@ SKIP: {
|
|||
|
||||
}
|
||||
|
||||
my $cost = $driver->_calculateFromXML({
|
||||
Package => [
|
||||
{
|
||||
ID => 0,
|
||||
Postage => {
|
||||
Rate => 5.25,
|
||||
},
|
||||
my $cost = $driver->_calculateFromXML(
|
||||
{
|
||||
RateV3Response => {
|
||||
Package => [
|
||||
{
|
||||
ID => 0,
|
||||
Postage => {
|
||||
Rate => 5.25,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
@shippableUnits
|
||||
);
|
||||
|
|
@ -471,21 +474,24 @@ SKIP: {
|
|||
|
||||
}
|
||||
|
||||
$cost = $driver->_calculateFromXML({
|
||||
Package => [
|
||||
{
|
||||
ID => 0,
|
||||
Postage => {
|
||||
Rate => 7.00,
|
||||
},
|
||||
$cost = $driver->_calculateFromXML(
|
||||
{
|
||||
RateV3Response => {
|
||||
Package => [
|
||||
{
|
||||
ID => 0,
|
||||
Postage => {
|
||||
Rate => 7.00,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID => 1,
|
||||
Postage => {
|
||||
Rate => 5.25,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
ID => 1,
|
||||
Postage => {
|
||||
Rate => 5.25,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
@shippableUnits
|
||||
);
|
||||
|
|
@ -497,21 +503,24 @@ $bibleItem->setQuantity(2);
|
|||
|
||||
is(calculateInsurance($driver), 8, '_calculateInsurance: two items in cart with quantity=2, calculates insurance');
|
||||
|
||||
$cost = $driver->_calculateFromXML({
|
||||
Package => [
|
||||
{
|
||||
ID => 0,
|
||||
Postage => {
|
||||
Rate => 7.00,
|
||||
},
|
||||
$cost = $driver->_calculateFromXML(
|
||||
{
|
||||
RateV3Response => {
|
||||
Package => [
|
||||
{
|
||||
ID => 0,
|
||||
Postage => {
|
||||
Rate => 7.00,
|
||||
},
|
||||
},
|
||||
{
|
||||
ID => 1,
|
||||
Postage => {
|
||||
Rate => 5.25,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
ID => 1,
|
||||
Postage => {
|
||||
Rate => 5.25,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
@shippableUnits
|
||||
);
|
||||
|
|
@ -811,6 +820,24 @@ SKIP: {
|
|||
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# Check for throwing an exception
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
my $userId = $driver->get('userId');
|
||||
$properties = $driver->get();
|
||||
$properties->{userId} = '__NEVER_GOING_TO_HAPPEN__';
|
||||
$driver->update($properties);
|
||||
|
||||
$cost = eval { $driver->calculate($cart); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::Shop::RemoteShippingRate', 'calculate throws an exception when a bad userId is used');
|
||||
|
||||
$properties->{userId} = $userId;
|
||||
$driver->update($properties);
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# _calculateInsurance edge case
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ Survey.Data = (function(){
|
|||
draggable: true
|
||||
});
|
||||
|
||||
Survey.Data.ddContainer.setHeader("Survey Objects...");
|
||||
Survey.Data.ddContainer.setHeader(Survey.i18n.get('Asset_Survey','Survey Objects');
|
||||
Survey.Data.ddContainer.setBody(d.ddhtml);
|
||||
Survey.Data.ddContainer.setFooter(document.getElementById("buttons"));
|
||||
Survey.Data.ddContainer.render();
|
||||
|
|
@ -146,7 +146,7 @@ Survey.Data = (function(){
|
|||
|
||||
if (!sButton) {
|
||||
sButton = new YAHOO.widget.Button({
|
||||
label: "Add Section",
|
||||
label: Survey.i18n.get('Asset_Survey','Add Section'),
|
||||
id: "addSection",
|
||||
container: "addSection"
|
||||
});
|
||||
|
|
@ -155,12 +155,14 @@ Survey.Data = (function(){
|
|||
|
||||
if (!qButton) {
|
||||
qButton = new YAHOO.widget.Button({
|
||||
label: "Add Question",
|
||||
label: Survey.i18n.get('Asset_Survey', 'Add Question'),
|
||||
id: "addQuestion",
|
||||
container: "addQuestion"
|
||||
});
|
||||
qButton.on("click", this.addQuestion, d.buttons.question);
|
||||
}
|
||||
qButton.removeListener("click", this.addQuestion);
|
||||
qButton.on("click", this.addQuestion, d.buttons.question);
|
||||
|
||||
if (d.buttons.answer) {
|
||||
YAHOO.util.Dom.setStyle('addAnswer', 'display', 'inline');
|
||||
|
|
@ -170,8 +172,9 @@ Survey.Data = (function(){
|
|||
id: "addAnswer",
|
||||
container: "addAnswer"
|
||||
});
|
||||
aButton.on("click", this.addAnswer, d.buttons.answer);
|
||||
}
|
||||
aButton.removeListener("click", this.addAnswer);
|
||||
aButton.on("click", this.addAnswer, d.buttons.answer);
|
||||
}else{
|
||||
YAHOO.util.Dom.setStyle('addAnswer', 'display', 'none');
|
||||
}
|
||||
|
|
@ -209,6 +212,20 @@ Survey.Data = (function(){
|
|||
// Initialize survey
|
||||
YAHOO.util.Event.onDOMReady(function(){
|
||||
//var ddTarget = new YAHOO.util.DDTarget("sections", "sections");
|
||||
Survey.Comm.loadSurvey();
|
||||
Survey.ObjectTemplate.initObjectEditor();
|
||||
Survey.i18n = new WebGUI.i18n( {
|
||||
'namespaces' : {
|
||||
'Asset_Survey' : [
|
||||
'Add Question',
|
||||
'Add Answer',
|
||||
'Add Section',
|
||||
'Survey Objects'
|
||||
]
|
||||
},
|
||||
onpreload : {
|
||||
fn : function () {
|
||||
Survey.Comm.loadSurvey();
|
||||
Survey.ObjectTemplate.initObjectEditor();
|
||||
}
|
||||
}
|
||||
} );
|
||||
});
|
||||
|
|
|
|||
100
www/extras/yui-webgui/build/ShipDriver/UPS.js
vendored
Normal file
100
www/extras/yui-webgui/build/ShipDriver/UPS.js
vendored
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
|
||||
// Requires YUI Connection and JSON
|
||||
|
||||
if ( typeof WebGUI == "undefined" ) {
|
||||
WebGUI = {};
|
||||
}
|
||||
if ( typeof WebGUI.ShipDriver == "undefined" ) {
|
||||
WebGUI.ShipDriver = {};
|
||||
}
|
||||
if ( typeof WebGUI.ShipDriver.UPS == "undefined" ) {
|
||||
WebGUI.ShipDriver.UPS = {};
|
||||
}
|
||||
|
||||
WebGUI.ShipDriver.UPS.changeServices
|
||||
= function ( newService, elementId ) {
|
||||
|
||||
var el = document.getElementById(elementId);
|
||||
//Delete old options
|
||||
var wasSelected = el.options[el.selectedIndex].value;
|
||||
while ( el.options.length >= 1 ) {
|
||||
el.remove(0);
|
||||
}
|
||||
var fields = {};
|
||||
switch (newService) {
|
||||
case 'us domestic' : fields = WebGUI.ShipDriver.UPS.US_Domestic;
|
||||
break;
|
||||
case 'us international' : fields = WebGUI.ShipDriver.UPS.US_International;
|
||||
break;
|
||||
default : fields = WebGUI.ShipDriver.UPS.US_Domestic;
|
||||
}
|
||||
//Add new options to the same form element
|
||||
for ( var key in fields ) {
|
||||
var isSelected = key == wasSelected ? true : false;
|
||||
el.options[el.options.length]
|
||||
= new Option( fields[key], key, isSelected, isSelected );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
WebGUI.ShipDriver.UPS.initI18n ( )
|
||||
Initialize the i18n interface
|
||||
*/
|
||||
WebGUI.ShipDriver.UPS.initI18n = function (o) {
|
||||
WebGUI.ShipDriver.UPS.i18n
|
||||
= new WebGUI.i18n( {
|
||||
namespaces : {
|
||||
'ShipDriver_UPS' : [
|
||||
"us domestic 01",
|
||||
"us domestic 02",
|
||||
"us domestic 03",
|
||||
"us domestic 12",
|
||||
"us domestic 13",
|
||||
"us domestic 14",
|
||||
"us domestic 59",
|
||||
"us international 07",
|
||||
"us international 08",
|
||||
"us international 11",
|
||||
"us international 54",
|
||||
"us international 65",
|
||||
]
|
||||
},
|
||||
onpreload : {
|
||||
fn : WebGUI.ShipDriver.UPS.initServiceTables
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
||||
WebGUI.ShipDriver.UPS.initServiceTables = function () {
|
||||
//These objects provide dropdown list labels and values. The values
|
||||
//are API defined UPS Service codes.
|
||||
WebGUI.ShipDriver.UPS.US_Domestic = {
|
||||
'01' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us domestic 01'),
|
||||
'02' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us domestic 02'),
|
||||
'03' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us domestic 03'),
|
||||
'12' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us domestic 12'),
|
||||
'13' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us domestic 13'),
|
||||
'14' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us domestic 14'),
|
||||
'59' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us domestic 59')
|
||||
};
|
||||
|
||||
WebGUI.ShipDriver.UPS.US_International = {
|
||||
'01' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us domestic 01' ),
|
||||
'02' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us domestic 02' ),
|
||||
'03' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us domestic 03' ),
|
||||
'07' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us international 07'),
|
||||
'08' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us international 08'),
|
||||
'11' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us international 11'),
|
||||
'12' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us domestic 12' ),
|
||||
'14' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us domestic 14' ),
|
||||
'54' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us international 54'),
|
||||
'59' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us domestic 59' ),
|
||||
'65' : WebGUI.ShipDriver.UPS.i18n.get('ShipDriver_UPS', 'us international 65')
|
||||
};
|
||||
|
||||
var shipType = document.getElementById('shipType_formId');
|
||||
var selectedType = shipType.options[shipType.selectedIndex].value;
|
||||
WebGUI.ShipDriver.UPS.changeServices(selectedType, 'shipService_formId');
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue