#-----------------------------------------------------------------------------
#FILE
# LSIxml.pm
#
#AUTHOR
# Chris Dunn
#
#CREATED
# 8/4/2004
#
#DESCRIPTION
# Perl module to handle various operations through the Logistech XML
# interface. Made up of the following subclasses (see each subclass for
# documentation) :
#
# Order
# Item
# Error
# Product
# TScharge
# Shipment
# Package
# OrderStatus
# ItemStatus
# PackageItem
# StatusAcknowledge
# StatusError
# StatusSuccess
#
# The following top-level static methods are provided for convenience :
#
# LSIxml::submitOrders()
# LSIxml::queryOrders()
# LSIxml::queryOrdersByReference()
# LSIxml::queryInventory()
# LSIxml::queryTaxShipping()
# LSIxml::queryShipments()
#
#
#REQUIREMENTS
# This library requires the following modules (available at www.cpan.org if
# not already installed) :
#
# libwww-perl
# URI::Escape
# HTTP::Headers
# XML::Simple
#
#CHANGELOG
# 10/20/2004 -cdunn-
# Added support for status update data structures. Fixed some minor bugs.
#
#-----------------------------------------------------------------------------
use LWP;
use URI::Escape;
use HTTP::Headers;
use XML::Simple;
use Data::Dumper;
package LSIxml;
require Exporter;
@ISA=qw(Exporter);
$BASE_URL = "https://api.logistech.us/lomacs/xml";
$ORDER_PLACE_URL = "$BASE_URL/receive_order";
$ORDER_QUERY_URL = "$BASE_URL/query_order";
$INVENTORY_URL = "$BASE_URL/query_inventory";
$SHIPMENT_QUERY_URL = "$BASE_URL/query_shipment";
$TAX_SHIPPING_URL = "$BASE_URL/tax_shipping";
$STATUS_UPDATE_URL = "$BASE_URL/status_update";
$ORDER_ID_URL = "$BASE_URL/order_id";
# Limit data read by CGI
$CGI_MAX_DATA = 1024000;
#-----------------------------------------------------------------------------
#FUNCTION
# entity_encode(string)
#
#DESCRIPTION
# Given a string that may contain non-alphanumeric character entities,
# encode it for XML transmission
#-----------------------------------------------------------------------------
sub entity_encode {
my $toencode = shift;
my $encoded;
foreach $char (split //, $toencode) {
my $ascii = ord $char;
if ($char =~ /[\<\>\&\"\']/ || $ascii > 127) {
$encoded = $encoded."$ascii;";
} else {
$encoded = $encoded.$char;
}
}
return $encoded;
}
#-----------------------------------------------------------------------------
#FUNCTION
# add_tag(object,xml,tag_name,indent,add_if_null)
#
#DESCRIPTION
# Convenience function for adding an xml tag.
#-----------------------------------------------------------------------------
sub add_tag {
my $object = shift;
my $xml = shift;
my $tag_name = shift;
my $indent = shift;
my $add_if_null = shift;
my $value = $object->{$tag_name};
if (! $add_if_null && length "$value" == 0) {
return $xml;
} else {
$xml = $xml."$indent<$tag_name>".entity_encode($value)."$tag_name>\n";
return $xml;
}
}
#-----------------------------------------------------------------------------
#FUNCTION
# get_set(object,name,value)
#
#DESCRIPTION
# Convenience function to provide get/set methods for subclasses
#-----------------------------------------------------------------------------
sub get_set {
my ($o,$n,$v)=@_;
if (defined $v) {
$o->{$n}=$v;
}
return $o->{$n};
}
#-----------------------------------------------------------------------------
#FUNCTION
# set_if_exists(object,xmldata,tagname)
#
#DESCRIPTION
# Set the given tag from the given xml data in the given object if the data
# is present
#-----------------------------------------------------------------------------
sub set_if_exists {
my $object = shift;
my $xmldata = shift;
my $tagname = shift;
if (exists $$xmldata{$tagname}) {
$object->{$tagname} = $$xmldata{$tagname};
}
}
#-----------------------------------------------------------------------------
#FUNCTION
# submitOrders(client, profile, orders)
#
#DESCRIPTION
# Given an array of orders, submit them as one transaction. Each order
# will have it's error message and response object set. Returns either
# a string if there was a data transmission error, or an empty string if
# transmission was successful.
#
# Upon successful data transmission, individual orders would still need to
# be checked for errors.
#-----------------------------------------------------------------------------
sub submitOrders {
my $client = shift;
my $profile = shift;
my @orders = @_;
my $xml;
my %postvars;
my $response;
my $response_object;
# Build XML
$xml = "\n\n";
foreach $order (@orders) {
$xml = $xml.$order->as_xml(" ");
}
$xml = $xml."\n";
# Construct the post variables
$postvars{'client'} = $client;
$postvars{'profile'} = $profile;
$postvars{'orders'} = $xml;
# Send the request
$response = LSIxml::doPost($LSIxml::ORDER_PLACE_URL, \%postvars);
# Handle transmission error
if (! $response->is_success) {
return $response->status_line;
}
# Parse response
$response_object = parseXML($response->content);
if (ref $response_object eq "LSIxml::Error") {
return $response_object->description." : ".$response_object->message;
# Successful transmission - returned order_list
} elsif (ref $response_object eq "ARRAY") {
for (my $i=0 ; $i<=$#orders ; $i++) {
if (ref $$response_object[$i] eq "LSIxml::Error") {
$orders[$i]->set_response($$response_object[$i]);
} elsif (ref $$response_object[$i] eq "LSIxml::Order") {
$orders[$i]->set_response($$response_object[$i]);
} else {
return "Internal error";
}
}
return "";
# Error message
} else {
return $response_object;
}
}
#-----------------------------------------------------------------------------
#FUNCTION
# queryTaxShipping(client, orders)
#
#DESCRIPTION
# For the given orders and client code, queries tax/shipping charges. Will
# return either a string containing the error message or an empty string
# upon successful transmission.
#
# Each order will have the response (either an Error object or a TScharge
# object if successful) available for checking by calling the response()
# method if transmission was successful.
#-----------------------------------------------------------------------------
sub queryTaxShipping {
my $client = shift;
my @orders = @_;
my $xml;
my %postvars;
my $response;
my $response_object;
# Build XML
$xml = "\n\n";
foreach $order (@orders) {
$xml = $xml.$order->as_xml(" ");
}
$xml = $xml."\n";
# Construct the post variables
$postvars{'client'} = $client;
$postvars{'orders'} = $xml;
# Send the request
$response = LSIxml::doPost($LSIxml::TAX_SHIPPING_URL, \%postvars);
# Handle transmission error
if (! $response->is_success) {
return $response->status_line;
}
# Parse response
$response_object = parseXML($response->content);
if (ref $response_object eq "LSIxml::Error") {
return $response_object->description." : ".$response_object->message;
# Successful transmission - returned ts_charge_list
} elsif (ref $response_object eq "ARRAY") {
for (my $i=0 ; $i<=$#orders ; $i++) {
if (ref $$response_object[$i] eq "LSIxml::Error") {
$orders[$i]->set_response($$response_object[$i]);
} elsif (ref $$response_object[$i] eq "LSIxml::TScharge") {
$orders[$i]->set_response($$response_object[$i]);
} else {
return "Internal error";
}
}
return "";
# Error message
} else {
return $response_object;
}
}
#-----------------------------------------------------------------------------
#FUNCTION
# queryOrders(client, orders_ids)
#
#DESCRIPTION
# Given a list of orders, returns either :
#
# A single order if successful single order query
# An array of order or error objects if a multi-order query
# A single error if error during single order query
# A string containing the error message if a transmission error occurred
#-----------------------------------------------------------------------------
sub queryOrders {
my $client = shift;
my @order_ids = @_;
my $response;
my $url;
# Submit the query
$url = $ORDER_QUERY_URL."?client=$client&order_id=".join(",",@order_ids);
$response = doGet($url);
# Handle the response
if ($response->is_success) {
return parseXML($response->content);
} else {
return $response->status_line;
}
}
#-----------------------------------------------------------------------------
#FUNCTION
# queryOrdersByReference(client, reference_ids)
#
#DESCRIPTION
# Given a list of reference ids, returns either :
#
# A single order if successful single order query
# An array of order or error objects if a multi-order query
# A single error if error during single order query
# A string containing the error message if a transmission error occurred
#-----------------------------------------------------------------------------
sub queryOrdersByReference {
my $client = shift;
my @refs = @_;
my $response;
my $url;
# Submit the query
$url = $ORDER_QUERY_URL."?client=$client&client_ref_id=".join(",",@refs);
$response = doGet($url);
# Handle the response
if ($response->is_success) {
return parseXML($response->content);
} else {
return $response->status_line;
}
}
#-----------------------------------------------------------------------------
#FUNCTION
# queryInventory(client, product_id)
#
#DESCRIPTION
# Given a product ID to query, returns either :
#
# A single product object if successful
# A single error if error during query
# A string containing the error message if a transmission error occurred
#-----------------------------------------------------------------------------
sub queryInventory {
my $client = shift;
my $product_id = shift;
my $response;
my $url;
# Submit the query
$url = $INVENTORY_URL."?client=$client&product_id=$product_id";
$response = doGet($url);
# Handle the response
if ($response->is_success) {
return parseXML($response->content);
} else {
return $response->status_line;
}
}
#-----------------------------------------------------------------------------
#FUNCTION
# queryShipments(client, order_ids)
#
#DESCRIPTION
# Given a list of orders, returns either :
#
# An array of shipment or error objects
# A single error if a global error
# A string containing the error message if a transmission error occurred
#-----------------------------------------------------------------------------
sub queryShipments {
my $client = shift;
my @order_ids = @_;
my $response;
my $url;
# Submit the query
$url = $SHIPMENT_QUERY_URL."?client=$client&order_id=".join(",",@order_ids);
$response = doGet($url);
# Handle the response
if ($response->is_success) {
return parseXML($response->content);
} else {
return $response->status_line;
}
}
#-----------------------------------------------------------------------------
#FUNCTION
# doPost(url, variables)
#
#DESCRIPTION
# Given a hash of key-value pairs, encode and post them to the given URL.
# Returns an HTTP::Response object from LWP.
#-----------------------------------------------------------------------------
sub doPost {
my $url = shift;
my $variables = shift;
my $post_data = "";
my $headers;
my $ua;
# Encode the variables into POST data
foreach $key (keys %$variables) {
my $value = $$variables{$key};
if (length $post_data > 0) {
$post_data = $post_data."&";
}
$key = URI::Escape::uri_escape($key);
$value = URI::Escape::uri_escape($value);
$post_data = $post_data."$key=$value";
}
# Set up user agent and request
$ua = new LWP::UserAgent;
$headers = HTTP::Headers->new;
$headers->header('Content-Type' => 'application/x-www-form-urlencoded');
$request = HTTP::Request->new("POST", $url, $headers, $post_data);
$request = $ua->prepare_request($request);
# Send the request
return $ua->request($request);
}
#-----------------------------------------------------------------------------
#FUNCTION
# doGet(url)
#
#DESCRIPTION
# Do a GET request for the given URL
#-----------------------------------------------------------------------------
sub doGet {
my $url = shift;
my $request;
my $ua;
# Set up user agent and request
$ua = new LWP::UserAgent;
$request = HTTP::Request->new("GET", $url);
$request = $ua->prepare_request($request);
# Send the request
return $ua->request($request);
}
#-----------------------------------------------------------------------------
#FUNCTION
# parseCGI
#
#DESCRIPTION
# Parse STDIN as CGI input to an xml document (or error string)
#-----------------------------------------------------------------------------
sub parseCGI {
my $input;
my $len = $ENV{'CONTENT_LENGTH'};
# Make sure we don't try to read too much data
if ($len > $CGI_MAX_DATA) {
return "ERROR: Document too long";
}
binmode(STDIN);
binmode(STDOUT);
binmode(STDERR);
# Read input
my $nread = read(STDIN, $input, $len);
if ($nread != $len) {
return "ERROR: Read interrupted";
}
# Parse data
return parseXML($input);
}
#-----------------------------------------------------------------------------
#FUNCTION
# parseXML
#
#DESCRIPTION
# Given an XML document as a string, parse it into an LSIxml::* object, an
# array of LSIxml::* objects, or a string containing the parse error
# as appropriate.
#-----------------------------------------------------------------------------
sub parseXML {
my $xmltext = shift;
my $xs;
my $xml;
my $rv;
my @list;
# For lists that may contain more than one kind of element, we need to keep
# the order of elements returned. This is a workaround for the fact that
# XML::Simple only preserves order within subelements of the same name
if ($xmltext =~ /\/ ||
$xmltext =~ /\/ ||
$xmltext =~ /\/ ||
$xmltext =~ /\/ ||
$xmltext =~ /\/) {
my $count = 0;
my $tag;
my $newtag;
while (1) {
if ($xmltext =~ /(\)|(\)|(\)|(\)|(\)|(\)|(\)/) {
$tag = $&;
$newtag = $tag;
$newtag =~ s/\>/ __count=\"$count\"\>/;
$xmltext =~ s/$tag/$newtag/;
$count = $count + 1;
} else {
last;
}
}
}
# Parse the XML
$xs = new XML::Simple(KeepRoot => 1);
my $config = eval { $xml = $xs->XMLin($xmltext); };
if ($@) {
return $@;
}
# Error object
if (exists $$xml{'error'}) {
return LSIxml::Error::parse($$xml{'error'});
# Single order
} elsif (exists $$xml{'order'}) {
return LSIxml::Order::parse($$xml{'order'});
# Order list
} elsif (exists $$xml{'order_list'}) {
# Get error objects
$rv = parseXMLList
($xml,"order_list","error",\&LSIxml::Error::parse,\@list);
if (length $rv > 0) {
return $rv;
}
# Get order objects
$rv = parseXMLList
($xml,"order_list","order",\&LSIxml::Order::parse,\@list);
if (length $rv > 0) {
return $rv;
}
# Return results
return \@list;
# Tax/Shipping charge list
} elsif (exists $$xml{'ts_charge_list'}) {
# Get error objects
$rv = parseXMLList
($xml,"ts_charge_list","error",\&LSIxml::Error::parse,\@list);
if (length $rv > 0) {
return $rv;
}
# Get ts_charge objects
$rv = parseXMLList
($xml,"ts_charge_list","ts_charge",\&LSIxml::TScharge::parse,\@list);
if (length $rv > 0) {
return $rv;
}
# Return results
return \@list;
# Shipment list
} elsif (exists $$xml{'shipment_list'}) {
# Get error objects
$rv = parseXMLList
($xml,"shipment_list","error",\&LSIxml::Error::parse,\@list);
if (length $rv > 0) {
return $rv;
}
# Get shipment objects
$rv = parseXMLList
($xml,"shipment_list","shipment",\&LSIxml::Shipment::parse,\@list);
if (length $rv > 0) {
return $rv;
}
# Return results
return \@list;
# Status list
} elsif (exists $$xml{'status_list'}) {
# Get status objects
$rv = parseXMLList
($xml,"status_list","order_status",\&LSIxml::OrderStatus::parse,\@list);
if (length $rv > 0) {
return $rv;
}
# Return results
return \@list;
# Status acknowledge
} elsif (exists $$xml{'status_acknowledge'}) {
# Get error objects
$rv = parseXMLList
($xml,"status_acknowledge",
"status_error",\&LSIxml::StatusError::parse,\@list);
if (length $rv > 0) {
return $rv;
}
# Get success objects
$rv = parseXMLList
($xml,"status_acknowledge",
"status_success",\&LSIxml::StatusSuccess::parse,\@list);
if (length $rv > 0) {
return $rv;
}
# Create status acknowledge object, return
my $o = new LSIxml::StatusAcknowledge;
$o->{'elements'} = \@list;
return $o;
# Single product information
} elsif (exists $$xml{'product'}) {
return LSIxml::Product::parse($$xml{'product'});
# Unrecognized object
} else {
if (length $xml == 0) {
return "No data returned from query";
} else {
return "Unrecognized root element in document";
}
}
}
#-----------------------------------------------------------------------------
#FUNCTION
# parseXMLList(xml,element_name,subelement_name,parse_routine,list)
#
#DESCRIPTION
# Function to parse an XML list of objects which may contain either the
# given subelement type or an error element
#-----------------------------------------------------------------------------
sub parseXMLList {
my $xml = shift;
my $element_name = shift;
my $subelement_name = shift;
my $parse_routine = shift;
my $list = shift;
my $element = $$xml{$element_name};
# Get objects
if (exists($$element{$subelement_name})) {
# Array of objects
if (ref $$element{$subelement_name} eq "ARRAY") {
foreach $obj (@{$$element{$subelement_name}}) {
if (! exists($$obj{'__count'})) {
return "Internal parse error : missing count";
}
$$list[$$obj{'__count'}] = &$parse_routine($obj);
}
# single object
} else {
my $obj = $$element{$subelement_name};
if (! exists($$obj{'__count'})) {
return "Internal parse error : missing count";
}
$$list[$$obj{'__count'}] = &$parse_routine($obj);
}
}
return "";
}
##############################################################################
##############################################################################
#-----------------------------------------------------------------------------
#CLASS
# LSIxml::Order
#
#DESCRIPTION
# Each field of the order has a corresponding get/set method of the same
# name, which corresponds to the fields defined in Logistech's XML
# documentation available at :
#
# http://www.logistech.us/lsi/customer/xmlspec/
#
# To use, create a new order, set the fields, add the items, and then call
# $order->submit(), check for errors.
#
# Upon successful return, the order will contain LSI order ID, status,
# estimated delivery date, and any other information returned by LSI.
#
# The following are get/set functions for an LSIxml::Order :
#
# service
# cust_ref_id
# po_number
# insurance
# declared_customs
# request_ship_date
# hold_status
# gift_wrap
# gift_wrap_message
# comp_name
# attn_name
# address_1
# address_2
# city
# state
# zip_code
# country_code
# phone
# email
#
# In addition, the following functions are provided :
#
# submit(client,profile)
#
# Submits the order to Logistech. Client and profile must be given, and
# should have been given to you by your CSR. Returns true on success,
# false on error. See the errMsg() function for retrieving the error
# message.
#
# The reponse object will be held (either an LSIxml::Order object upon
# success or possibly an LSIxml::Error object upon failure) and is
# accessible by calling response()
#
# as_xml()
#
# Returns the order in XML format.
#
# errMsg()
#
# Returns the last error message.
#
# error()
#
# Returns true if there was an error
#
# items()
#
# Returns an array of items on this order
#
# add_item(item)
#
# Given an LSIxml::Item object, add it to this order
#
# get_order_id(client)
#
# Attempts to retrieve an order ID for the 2-step method of order
# placement. Returns true on success.
#
#-----------------------------------------------------------------------------
package LSIxml::Order;
@EXPORT=qw(errMsg,
error,
order_id,
status,
est_delivery_date,
service,
avs_code,
cvv2_code,
cust_ref_id,
po_number,
insurance,
declared_customs,
request_ship_date,
hold_status,
gift_wrap,
gift_wrap_message,
comp_name,
attn_name,
address_1,
address_2,
city,
state,
zip_code,
country_code,
phone,
email,
add_item,
items,
response,
get_order_id);
#-----------------------------------------------------------------------------
#FUNCTION
# new
#
#DESCRIPTION
# Create a new LSIxml::Order object
#-----------------------------------------------------------------------------
sub new {
my ($class) = @_;
my @items;
my $self = {};
$self->{'items'} = \@items;
bless $self, ref $class || $class;
}
#-----------------------------------------------------------------------------
#FUNCTION
# error()
#
#DESCRIPTION
# Return true if there was an error placing the order
#-----------------------------------------------------------------------------
sub error {
my $self = shift;
return $self->{'error'};
}
#-----------------------------------------------------------------------------
#FUNCTION
# errMsg()
#
#DESCRIPTION
# Returns the current error message
#-----------------------------------------------------------------------------
sub errMsg {
my $self = shift;
my $msg = shift;
if ($msg) {
$self->{'errMsg'} = $msg;
if ($msg eq "OK") {
$self->{'error'} = 0;
} else {
$self->{'error'} = 1;
}
}
$self->{'errMsg'};
}
#-----------------------------------------------------------------------------
#FUNCTION
# items()
#
#DESCRIPTION
# Returns the array of items for this order
#-----------------------------------------------------------------------------
sub items {
my $self = shift;
return $self->{'items'};
}
#-----------------------------------------------------------------------------
#FUNCTION
# add_item(item)
#
#DESCRIPTION
# Given an LSIxml::Item, add it to this order
#-----------------------------------------------------------------------------
sub add_item {
my $self = shift;
my $item = shift;
push @{$self->{'items'}}, $item;
$item->item_no($#{@{$self->{'items'}}} + 1);
}
sub order_id { return LSIxml::get_set($_[0], "order_id", $_[1]); }
sub status { return LSIxml::get_set($_[0], "status", $_[1]); }
sub avs_code { return LSIxml::get_set($_[0], "avs_code", $_[1]); }
sub cvv2_code { return LSIxml::get_set($_[0], "cvv2_code", $_[1]); }
sub est_delivery_date { return LSIxml::get_set($_[0], "est_delivery_date", $_[1]); }
sub service { return LSIxml::get_set($_[0], "service", $_[1]); }
sub cust_ref_id { return LSIxml::get_set($_[0], "cust_ref_id", $_[1]); }
sub po_number { return LSIxml::get_set($_[0], "po_number", $_[1]); }
sub insurance { return LSIxml::get_set($_[0], "insurance", $_[1]); }
sub declared_customs { return LSIxml::get_set($_[0], "declared_customs", $_[1]); }
sub request_ship_date { return LSIxml::get_set($_[0], "request_ship_date", $_[1]); }
sub hold_status { return LSIxml::get_set($_[0], "hold_status", $_[1]); }
sub gift_wrap { return LSIxml::get_set($_[0], "gift_wrap", $_[1]); }
sub gift_wrap_message { return LSIxml::get_set($_[0], "gift_wrap_message", $_[1]); }
sub comp_name { return LSIxml::get_set($_[0], "comp_name", $_[1]); }
sub attn_name { return LSIxml::get_set($_[0], "attn_name", $_[1]); }
sub address_1 { return LSIxml::get_set($_[0], "address_1", $_[1]); }
sub address_2 { return LSIxml::get_set($_[0], "address_2", $_[1]); }
sub city { return LSIxml::get_set($_[0], "city", $_[1]); }
sub state { return LSIxml::get_set($_[0], "state", $_[1]); }
sub zip_code { return LSIxml::get_set($_[0], "zip_code", $_[1]); }
sub country_code { return LSIxml::get_set($_[0], "country_code", $_[1]); }
sub phone { return LSIxml::get_set($_[0], "phone", $_[1]); }
sub email { return LSIxml::get_set($_[0], "email", $_[1]); }
#-----------------------------------------------------------------------------
#FUNCTION
# as_xml()
#
#DESCRIPTION
# Return this order as an XML document
#-----------------------------------------------------------------------------
sub as_xml {
my $self = shift;
my $indent = shift;
my $xml = "";
# Open tag
$xml = $xml."$indent\n";
# General order tags
$xml = LSIxml::add_tag($self, $xml, "order_id", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "status", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "est_delivery_date", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "service", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "cust_ref_id", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "po_number", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "insurance", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "declared_customs", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "request_ship_date", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "hold_status", "$indent ", 0);
if ($self->gift_wrap eq "YES") {
$xml = $xml."$indent \n";
}
$xml = LSIxml::add_tag($self, $xml, "gift_wrap_message", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "avs_code", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "cvv2_code", "$indent ", 0);
# Address tags
$xml = $xml."$indent \n";
$xml = LSIxml::add_tag($self, $xml, "comp_name", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "attn_name", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "address_1", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "address_2", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "city", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "state", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "zip_code", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "country_code", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "phone", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "email", "$indent ", 0);
$xml = $xml."$indent \n";
# Items
foreach $item (@{$self->{'items'}}) {
$xml = $xml.$item->as_xml("$indent ");
}
# Close tag
$xml = $xml."$indent\n";
return $xml;
}
#-----------------------------------------------------------------------------
#FUNCTION
# submit(client,profile)
#
#DESCRIPTION
# Submit the given order using the given client code and profile number.
# Returns true upon success, false otherwise. If an error occurred,
# $order->errMsg() will give the error message.
#
# If data was transmitted and received, the response object will be
# available by $order->response(). It will either be an LSIxml::Order object
# (if successful), an LSIxml::Error object (if LOMACS returned an error), or
# undefined if there was an error before or during data transmission.
#-----------------------------------------------------------------------------
sub submit {
my $self = shift;
my $client = shift;
my $profile = shift;
my %postvars;
my $response;
my $response_object;
my $xml;
# Construct XML document
$xml = "\n".$self->as_xml("");
# Construct the post variables
$postvars{'client'} = $client;
$postvars{'profile'} = $profile;
$postvars{'orders'} = $xml;
# Send the request
$response = LSIxml::doPost($LSIxml::ORDER_PLACE_URL, \%postvars);
# Handle transmission error
if (! $response->is_success) {
$self->errMsg($response->status_line);
return 0;
}
# Interpret response data
$response_object = LSIxml::parseXML($response->content);
if (ref $response_object eq "ARRAY") {
$response_object = $$response_object[0];
}
# Order data returned
if (ref $response_object eq "LSIxml::Order") {
$self->set_response($response_object);
return 1;
# Error data returned
} elsif (ref $response_object eq "LSIxml::Error") {
$self->set_response($response_object);
return 0;
# Must have been a problem parsing the data
} else {
$self->errMsg($response_object);
return 0;
}
}
#-----------------------------------------------------------------------------
#FUNCTION
# response()
#
#DESCRIPTION
# Return the response object from the last call to submit()
#-----------------------------------------------------------------------------
sub response {
my $self = shift;
return $self->{'response'};
}
#-----------------------------------------------------------------------------
#FUNCTION
# set_response(response)
#
#DESCRIPTION
# Set response object
#-----------------------------------------------------------------------------
sub set_response {
my $self = shift;
my $response = shift;
$self->{'response'} = $response;
if (ref $response eq "LSIxml::Error") {
$self->errMsg($response->description." : ".$response->message);
} elsif (ref $response eq "LSIxml::Order") {
$self->order_id($response->order_id);
$self->status($response->status);
$self->est_delivery_date($response->est_delivery_date);
}
}
#-----------------------------------------------------------------------------
#FUNCTION
# get_order_id(client)
#
#DESCRIPTION
# Queries the server for an order ID for using the 2-step method of order
# placement
#-----------------------------------------------------------------------------
sub get_order_id {
my $self = shift;
my $client = shift;
my $response;
my $url;
my $xs;
my $xml;
$self->{'response'} = undef;
# Submit the query
$url = $LSIxml::ORDER_ID_URL."?client=$client";
$response = LSIxml::doGet($url);
# Transmission error
if (! $response->is_success) {
$self->errMsg($response->status_line);
return 0;
}
# Parse the XML
$xs = new XML::Simple(KeepRoot => 1);
my $config = eval { $xml = $xs->XMLin($response->content); };
if ($@) {
$self->errMsg($@);
return 0;
}
# Error object
if (exists $$xml{'error'}) {
$self->set_response(LSIxml::Error::parse($$xml{'error'}));
$self->errMsg($self->{'response'}->description." : ".
$self->{'response'}->message);
return 0;
# Successful order ID
} elsif (exists $$xml{'order_id'}) {
$self->order_id($$xml{'order_id'});
return 1;
# Unrecognized response
} else {
$self->errMsg("Unrecognized response");
return 0;
}
}
#-----------------------------------------------------------------------------
#FUNCTION
# parse(xmldata)
#
#DESCRIPTION
# Given an XML::Simple returned data structure, create a new object
#-----------------------------------------------------------------------------
sub parse {
my $xml = shift;
my $order = new LSIxml::Order;
# General order fields
LSIxml::set_if_exists($order, $xml, "order_id");
LSIxml::set_if_exists($order, $xml, "status");
LSIxml::set_if_exists($order, $xml, "est_delivery_date");
LSIxml::set_if_exists($order, $xml, "service");
LSIxml::set_if_exists($order, $xml, "cust_ref_id");
LSIxml::set_if_exists($order, $xml, "po_number");
LSIxml::set_if_exists($order, $xml, "insurance");
LSIxml::set_if_exists($order, $xml, "declared_customs");
LSIxml::set_if_exists($order, $xml, "request_ship_date");
LSIxml::set_if_exists($order, $xml, "hold_status");
if (ref $$xml{'gift_wrap'} eq HASH) {
$order->{'gift_wrap'} = "YES";
} else {
LSIxml::set_if_exists($order, $xml, "gift_wrap");
}
LSIxml::set_if_exists($order, $xml, "gift_wrap_message");
# Address
if (exists $$xml{'address'}) {
my $address = $$xml{'address'};
LSIxml::set_if_exists($order, $address, "comp_name");
LSIxml::set_if_exists($order, $address, "attn_name");
LSIxml::set_if_exists($order, $address, "address_1");
LSIxml::set_if_exists($order, $address, "address_2");
LSIxml::set_if_exists($order, $address, "city");
LSIxml::set_if_exists($order, $address, "state");
LSIxml::set_if_exists($order, $address, "zip_code");
LSIxml::set_if_exists($order, $address, "country_code");
LSIxml::set_if_exists($order, $address, "phone");
LSIxml::set_if_exists($order, $address, "email");
}
# Items
if (ref $$xml{'item'} eq "ARRAY") {
foreach $item (@{$$xml{'item'}}) {
$order->add_item(LSIxml::Item::parse($item));
}
} elsif (exists $$xml{'item'}) {
$order->add_item(LSIxml::Item::parse($$xml{'item'}));
}
return $order;
}
##############################################################################
##############################################################################
#-----------------------------------------------------------------------------
#CLASS
# LSIxml::Item
#
#DESCRIPTION
# Items are created giving product ID, quantity, and description as
# arguments to new(). Get/set methods are provided for each field :
#
# product_id
# quantity
# description
# item_no
# unit_price
#
#-----------------------------------------------------------------------------
package LSIxml::Item;
@EXPORT=qw(item_no,
product_id,
quantity,
description,
unit_price,
as_xml);
sub new {
my ($class,$product_id,$quantity,$description,unit_price) = @_;
my $self = {};
bless $self, $class;
$self->{'product_id'} = $product_id;
$self->{'quantity'} = $quantity;
$self->{'description'} = $description;
$self->{'unit_price'} = $unit_price;
return $self;
}
sub item_no { return LSIxml::get_set($_[0], "item_no", $_[1]); }
sub product_id { return LSIxml::get_set($_[0], "product_id", $_[1]); }
sub quantity { return LSIxml::get_set($_[0], "quantity", $_[1]); }
sub description { return LSIxml::get_set($_[0], "description", $_[1]); }
sub unit_price { return LSIxml::get_set($_[0], "unit_price", $_[1]); }
#-----------------------------------------------------------------------------
#FUNCTION
# as_xml(indent)
#
#DESCRIPTION
# Encode the item as an XML element
#-----------------------------------------------------------------------------
sub as_xml {
my $self = shift;
my $indent = shift;
my $xml = "";
$xml = $xml."$indent- \n";
$xml = LSIxml::add_tag($self, $xml, "item_no", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "product_id", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "quantity", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "description", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "unit_price", "$indent ", 0);
$xml = $xml."$indent
\n";
return $xml;
}
#-----------------------------------------------------------------------------
#FUNCTION
# parse(xmldata)
#
#DESCRIPTION
# Given an XML::Simple returned data structure, create a new object
#-----------------------------------------------------------------------------
sub parse {
my $xml = shift;
my $item = new LSIxml::Item;
LSIxml::set_if_exists($item, $xml, "item_no");
LSIxml::set_if_exists($item, $xml, "quantity");
LSIxml::set_if_exists($item, $xml, "description");
LSIxml::set_if_exists($item, $xml, "product_id");
LSIxml::set_if_exists($item, $xml, "unit_price");
return $item;
}
##############################################################################
##############################################################################
#-----------------------------------------------------------------------------
#CLASS
# LSIxml::Error
#
#DESCRIPTION
# This object represents an error returned from an XML transaction. Get/set
# methods are as follows :
#
# code
# description
# message
#-----------------------------------------------------------------------------
package LSIxml::Error;
@EXPORT=qw(code,
description,
message,
as_xml);
sub new {
my ($class) = @_;
my $self = {};
bless $self, ref $class || $class;
}
sub code { return LSIxml::get_set($_[0], "code", $_[1]); }
sub description { return LSIxml::get_set($_[0], "description", $_[1]); }
sub message { return LSIxml::get_set($_[0], "message", $_[1]); }
#-----------------------------------------------------------------------------
#FUNCTION
# as_xml(indent)
#
#DESCRIPTION
# Returns this error object as an XML document
#-----------------------------------------------------------------------------
sub as_xml {
my $self = shift;
my $indent = shift;
my $xml = "";
$xml = $xml."$indent\n";
$xml = LSIxml::add_tag($self, $xml, "code", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "description", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "message", "$indent ", 0);
$xml = $xml."$indent\n";
return $xml;
}
#-----------------------------------------------------------------------------
#FUNCTION
# parse(xmldata)
#
#DESCRIPTION
# Given an XML::Simple returned data structure, create a new object
#-----------------------------------------------------------------------------
sub parse {
my $xml = shift;
my $error = new LSIxml::Error;
LSIxml::set_if_exists($error, $xml, "code");
LSIxml::set_if_exists($error, $xml, "description");
LSIxml::set_if_exists($error, $xml, "message");
return $error;
}
##############################################################################
##############################################################################
#-----------------------------------------------------------------------------
#CLASS
# LSIxml::Product
#
#DESCRIPTION
# Represents a product for return from inventory queries. Get/set methods
# as follows :
#
# product_id
# description
# in_stock
# on_order
#
#-----------------------------------------------------------------------------
package LSIxml::Product;
@EXPORT=qw(product_id,
description,
in_stock,
on_order);
sub new {
my ($class) = @_;
my $self = {};
bless $self, ref $class || $class;
}
sub product_id { return LSIxml::get_set($_[0], "product_id", $_[1]); }
sub description { return LSIxml::get_set($_[0], "description", $_[1]); }
sub in_stock { return LSIxml::get_set($_[0], "in_stock", $_[1]); }
sub on_order { return LSIxml::get_set($_[0], "on_order", $_[1]); }
#-----------------------------------------------------------------------------
#FUNCTION
# as_xml(indent)
#
#DESCRIPTION
# Returns this product object as an XML document
#-----------------------------------------------------------------------------
sub as_xml {
my $self = shift;
my $indent = shift;
my $xml = "";
$xml = $xml."$indent\n";
$xml = LSIxml::add_tag($self, $xml, "product_id", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "description", "$indent ", 0);
$xml = $xml."$indent \n";
$xml = LSIxml::add_tag($self, $xml, "in_stock", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "on_order", "$indent ", 0);
$xml = $xml."$indent \n";
$xml = $xml."$indent\n";
return $xml;
}
#-----------------------------------------------------------------------------
#FUNCTION
# parse(xmldata)
#
#DESCRIPTION
# Given an XML::Simple returned data structure, create a new object
#-----------------------------------------------------------------------------
sub parse {
my $xml = shift;
my $product = new LSIxml::Product;
LSIxml::set_if_exists($product, $xml, "product_id");
LSIxml::set_if_exists($product, $xml, "description");
if (exists $$xml{'quantity'}) {
my $ref = $$xml{'quantity'};
LSIxml::set_if_exists($product, $ref, "in_stock");
LSIxml::set_if_exists($product, $ref, "on_order");
}
return $product;
}
##############################################################################
##############################################################################
#-----------------------------------------------------------------------------
#CLASS
# TScharge
#
#DESCRIPTION
# This class represents tax/shipping charges returned from a query. Get/set
# methods as follows :
#
# tax_charge
# shipping_charge
# handling_charge
#
#-----------------------------------------------------------------------------
package LSIxml::TScharge;
@EXPORT=(tax_charge,
shipping_charge,
handling_charge);
sub new {
my ($class) = @_;
my $self = {};
bless $self, ref $class || $class;
}
sub tax_charge { return LSIxml::get_set($_[0], "tax_charge", $_[1]); }
sub shipping_charge { return LSIxml::get_set($_[0], "shipping_charge", $_[1]); }
sub handling_charge { return LSIxml::get_set($_[0], "handling_charge", $_[1]); }
#-----------------------------------------------------------------------------
#FUNCTION
# as_xml(indent)
#
#DESCRIPTION
# Returns this ts charge object as an XML document
#-----------------------------------------------------------------------------
sub as_xml {
my $self = shift;
my $indent = shift;
my $xml = "";
$xml = $xml."$indent\n";
$xml = LSIxml::add_tag($self, $xml, "tax_charge", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "shipping_charge", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "handling_charge", "$indent ", 0);
$xml = $xml."$indent\n";
return $xml;
}
#-----------------------------------------------------------------------------
#FUNCTION
# parse(xmldata)
#
#DESCRIPTION
# Given an XML::Simple returned data structure, create a new object
#-----------------------------------------------------------------------------
sub parse {
my $xml = shift;
my $tscharge = new LSIxml::TScharge;
LSIxml::set_if_exists($tscharge, $xml, "tax_charge");
LSIxml::set_if_exists($tscharge, $xml, "shipping_charge");
LSIxml::set_if_exists($tscharge, $xml, "handling_charge");
return $tscharge;
}
##############################################################################
##############################################################################
#-----------------------------------------------------------------------------
#CLASS
# Shipment
#
#DESCRIPTION
# Representation of shipment information. Get/set methods as follows :
#
# order_id
# ship_date
# packages
#
#-----------------------------------------------------------------------------
package LSIxml::Shipment;
@EXPORT=(order_id,
ship_date,
packages);
sub new {
my ($class) = @_;
my @packages;
my $self = {};
$self->{'packages'} = \@packages;
bless $self, ref $class || $class;
}
sub order_id { return LSIxml::get_set($_[0], "order_id", $_[1]); }
sub ship_date { return LSIxml::get_set($_[0], "ship_date", $_[1]); }
sub packages {
my $self = shift;
return $self->{'packages'};
}
#-----------------------------------------------------------------------------
#FUNCTION
# as_xml(indent)
#
#DESCRIPTION
# Returns this shipment object as an XML document
#-----------------------------------------------------------------------------
sub as_xml {
my $self = shift;
my $indent = shift;
my $xml = "";
$xml = $xml."$indent\n";
$xml = LSIxml::add_tag($self, $xml, "order_id", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "ship_date", "$indent ", 0);
foreach $pkg (@{$self->{'packages'}}) {
$xml = $xml.$pkg->as_xml("$indent ");
}
$xml = $xml."$indent\n";
return $xml;
}
#-----------------------------------------------------------------------------
#FUNCTION
# parse(xmldata)
#
#DESCRIPTION
# Given an XML::Simple returned data structure, create a new object
#-----------------------------------------------------------------------------
sub parse {
my $xml = shift;
my $shipment = new LSIxml::Shipment;
LSIxml::set_if_exists($shipment, $xml, "order_id");
LSIxml::set_if_exists($shipment, $xml, "ship_date");
if (exists $$xml{'package'}) {
if (ref $$xml{'package'} eq "ARRAY") {
foreach $pkg (@{$$xml{'package'}}) {
push @{$shipment->{'packages'}}, LSIxml::Package::parse($pkg);
}
} else {
push @{$shipment->{'packages'}},LSIxml::Package::parse($$xml{'package'});
}
}
return $shipment;
}
##############################################################################
##############################################################################
#-----------------------------------------------------------------------------
#CLASS
# LSIxml::Package
#
#DESCRIPTION
# Representation of package data in a shipment. Get/set methods as follows :
#
# carrier
# tracking_id
# charges
# items
#
#-----------------------------------------------------------------------------
package LSIxml::Package;
@EXPORT=(carrier,
tracking_id,
charges,
items);
sub new {
my ($class) = @_;
my @items;
my $self = {};
$self->{'items'} = \@items;
bless $self, ref $class || $class;
}
sub carrier { return LSIxml::get_set($_[0], "carrier", $_[1]); }
sub tracking_id { return LSIxml::get_set($_[0], "tracking_id", $_[1]); }
sub charges { return LSIxml::get_set($_[0], "charges", $_[1]); }
sub items {
my $self = shift;
return $self->{'items'};
}
#-----------------------------------------------------------------------------
#FUNCTION
# as_xml(indent)
#
#DESCRIPTION
# Returns this package object as an XML document
#-----------------------------------------------------------------------------
sub as_xml {
my $self = shift;
my $indent = shift;
my $xml = "";
$xml = $xml."$indent\n";
$xml = LSIxml::add_tag($self, $xml, "carrier", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "tracking_id", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "charges", "$indent ", 0);
# Items
foreach $item (@{$self->{'items'}}) {
$xml = $xml.$item->as_xml("$indent ");
}
$xml = $xml."$indent\n";
return $xml;
}
#-----------------------------------------------------------------------------
#FUNCTION
# parse(xmldata)
#
#DESCRIPTION
# Given an XML::Simple returned data structure, create a new object
#-----------------------------------------------------------------------------
sub parse {
my $xml = shift;
my $pkg = new LSIxml::Package;
LSIxml::set_if_exists($pkg, $xml, "carrier");
LSIxml::set_if_exists($pkg, $xml, "tracking_id");
LSIxml::set_if_exists($pkg, $xml, "charges");
# Items
if (ref $$xml{'item'} eq "ARRAY") {
foreach $item (@{$$xml{'item'}}) {
push @{$pkg->{'items'}}, LSIxml::PackageItem::parse($item);
}
} elsif (exists $$xml{'item'}) {
push @{$pkg->{'items'}}, LSIxml::PackageItem::parse($$xml{'item'});
}
return $pkg;
}
#############################################################################
#############################################################################
#-----------------------------------------------------------------------------
#CLASS
# LSIxml::PackageItem
#
#DESCRIPTION
# Representation of a packed item in a package. Get/set methods as follows :
#
# product_id
# quantity
#
#-----------------------------------------------------------------------------
package LSIxml::PackageItem;
@EXPORT=(product_id,
quantity);
sub new {
my ($class) = @_;
my $self = {};
bless $self, ref $class || $class;
}
sub product_id { return LSIxml::get_set($_[0], "product_id", $_[1]); }
sub quantity { return LSIxml::get_set($_[0], "quantity", $_[1]); }
#-----------------------------------------------------------------------------
#FUNCTION
# as_xml(indent)
#
#DESCRIPTION
# Returns this package item object as an XML document
#-----------------------------------------------------------------------------
sub as_xml {
my $self = shift;
my $indent = shift;
my $xml = "";
$xml = $xml."$indent- \n";
$xml = LSIxml::add_tag($self, $xml, "product_id", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "quantity", "$indent ", 0);
$xml = $xml."$indent
\n";
return $xml;
}
#-----------------------------------------------------------------------------
#FUNCTION
# parse(xmldata)
#
#DESCRIPTION
# Given an XML::Simple returned data structure, create a new object
#-----------------------------------------------------------------------------
sub parse {
my $xml = shift;
my $item = new LSIxml::PackageItem;
LSIxml::set_if_exists($item, $xml, "product_id");
LSIxml::set_if_exists($item, $xml, "quantity");
return $item;
}
#############################################################################
#############################################################################
#-----------------------------------------------------------------------------
#CLASS
# LSIxml::OrderStatus
#
#DESCRIPTION
# Representation of order status. Get/set methods as follows :
#
# order_id
# cust_ref_id
# status
# items
# shipments
#
#-----------------------------------------------------------------------------
package LSIxml::OrderStatus;
@EXPORT=(order_id,
cust_ref_id,
status,
items,
shipments);
sub new {
my ($class) = @_;
my @items;
my @shipments;
my $self = {};
$self->{'items'} = \@items;
$self->{'shipments'} = \@shipments;
bless $self, ref $class || $class;
}
sub order_id { return LSIxml::get_set($_[0], "order_id", $_[1]); }
sub cust_ref_id { return LSIxml::get_set($_[0], "quantity", $_[1]); }
sub status { return LSIxml::get_set($_[0], "status", $_[1]); }
sub items {
my $self = shift;
return $self->{'items'};
}
sub shipments {
my $self = shift;
return $self->{'shipments'};
}
#-----------------------------------------------------------------------------
#FUNCTION
# as_xml(indent)
#
#DESCRIPTION
# Returns this order status object as an XML document
#-----------------------------------------------------------------------------
sub as_xml {
my $self = shift;
my $indent = shift;
my $xml = "";
$xml = $xml."$indent\n";
$xml = LSIxml::add_tag($self, $xml, "order_id", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "cust_ref_id", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "status", "$indent ", 0);
# Items
foreach $item (@{$self->{'items'}}) {
$xml = $xml.$item->as_xml("$indent ");
}
# Shipments
foreach $shipment (@{$self->{'shipments'}}) {
$xml = $xml.$shipment->as_xml("$indent ");
}
$xml = $xml."$indent\n";
return $xml;
}
#-----------------------------------------------------------------------------
#FUNCTION
# parse(xmldata)
#
#DESCRIPTION
# Given an XML::Simple returned data structure, create a new object
#-----------------------------------------------------------------------------
sub parse {
my $xml = shift;
my $status = new LSIxml::OrderStatus;
LSIxml::set_if_exists($status, $xml, "order_id");
LSIxml::set_if_exists($status, $xml, "cust_ref_id");
LSIxml::set_if_exists($status, $xml, "status");
# Items
if (ref $$xml{'item'} eq "ARRAY") {
foreach $item (@{$$xml{'item'}}) {
push @{$status->{'items'}}, LSIxml::ItemStatus::parse($item);
}
} elsif (exists $$xml{'item'}) {
push @{$status->{'items'}}, LSIxml::ItemStatus::parse($$xml{'item'});
}
# Shipments
if (ref $$xml{'shipment'} eq "ARRAY") {
foreach $shipment (@{$$xml{'shipment'}}) {
push @{$status->{'shipments'}}, LSIxml::Shipment::parse($shipment);
}
} elsif (exists $$xml{'shipment'}) {
push @{$status->{'shipments'}}, LSIxml::Shipment::parse($$xml{'shipment'});
}
return $status;
}
#############################################################################
#############################################################################
#-----------------------------------------------------------------------------
#CLASS
# LSIxml::ItemStatus
#
#DESCRIPTION
# Representation of item status. Get/set methods as follows :
#
# item_no
# product_id
# item_status
#
#-----------------------------------------------------------------------------
package LSIxml::ItemStatus;
@EXPORT=(item_no,
product_id,
item_status);
sub new {
my ($class) = @_;
my $self = {};
bless $self, ref $class || $class;
}
sub item_no { return LSIxml::get_set($_[0], "item_no", $_[1]); }
sub product_id { return LSIxml::get_set($_[0], "product_id", $_[1]); }
sub item_status { return LSIxml::get_set($_[0], "item_status", $_[1]); }
#-----------------------------------------------------------------------------
#FUNCTION
# as_xml(indent)
#
#DESCRIPTION
# Returns this item status object as an XML document
#-----------------------------------------------------------------------------
sub as_xml {
my $self = shift;
my $indent = shift;
my $xml = "";
$xml = $xml."$indent- \n";
$xml = LSIxml::add_tag($self, $xml, "item_no", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "product_id", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "item_status", "$indent ", 0);
$xml = $xml."$indent
\n";
return $xml;
}
#-----------------------------------------------------------------------------
#FUNCTION
# parse(xmldata)
#
#DESCRIPTION
# Given an XML::Simple returned data structure, create a new object
#-----------------------------------------------------------------------------
sub parse {
my $xml = shift;
my $item = new LSIxml::ItemStatus;
LSIxml::set_if_exists($item, $xml, "item_no");
LSIxml::set_if_exists($item, $xml, "product_id");
LSIxml::set_if_exists($item, $xml, "item_status");
return $item;
}
#############################################################################
#############################################################################
#-----------------------------------------------------------------------------
#CLASS
# LSIxml::StatusAcknowledge
#
#DESCRIPTION
# Create this object to return acknowledgement of a status update. You can
# add LSIxml::StatusSuccess or LSIxml::StatusError objects to the list, and
# then use the as_xml() routine to get an XML document
#-----------------------------------------------------------------------------
package LSIxml::StatusAcknowledge;
@EXPORT=(add,
elements);
sub new {
my ($class)= @_;
my @elements;
my $self = {};
$self->{'elements'} = \@elements;
bless $self, ref $class || $class;
}
sub elements {
my $self = shift;
return $self->{'elements'};
}
sub add {
my $self = shift;
my $element = shift;
push @{$self->{'elements'}}, $element;
}
#-----------------------------------------------------------------------------
#FUNCTION
# as_xml(indent)
#
#DESCRIPTION
# Returns this status acknowledgement object as an XML document
#-----------------------------------------------------------------------------
sub as_xml {
my $self = shift;
my $indent = shift;
my $xml = "";
$xml = $xml."$indent\n";
foreach $element (@{$self->{'elements'}}) {
$xml = $xml.$element->as_xml("$indent ");
}
$xml = $xml."$indent\n";
return $xml;
}
#############################################################################
#############################################################################
#-----------------------------------------------------------------------------
#CLASS
# LSIxml::StatusSuccess
#
#DESCRIPTION
# Successful status update. Get/set methods as follows :
#
# order_id
#
#-----------------------------------------------------------------------------
package LSIxml::StatusSuccess;
@EXPORT=(order_id);
sub new {
my ($class) = @_;
my $self = {};
bless $self, ref $class || $class;
}
sub order_id { return LSIxml::get_set($_[0], "order_id", $_[1]); }
#-----------------------------------------------------------------------------
#FUNCTION
# as_xml(indent)
#
#DESCRIPTION
# Return this status success object as an XML document
#-----------------------------------------------------------------------------
sub as_xml {
my $self = shift;
my $indent = shift;
my $xml = "";
$xml = $xml."$indent\n";
$xml = LSIxml::add_tag($self, $xml, "order_id", "$indent ", 0);
$xml = $xml."$indent\n";
return $xml;
}
#-----------------------------------------------------------------------------
#FUNCTION
# parse(xmldata)
#
#DESCRIPTION
# Given an XML::Simple returned data structure, create a new object
#-----------------------------------------------------------------------------
sub parse {
my $xml = shift;
my $success = new LSIxml::StatusSuccess;
LSIxml::set_if_exists($success, $xml, "order_id");
return $success;
}
#############################################################################
#############################################################################
#-----------------------------------------------------------------------------
#CLASS
# LSIxml::StatusError
#
#DESCRIPTION
# Error in status update. Get/set methods as follows :
#
# order_id
# message
#
#-----------------------------------------------------------------------------
package LSIxml::StatusError;
@EXPORT=(order_id,
message);
sub new {
my ($class) = @_;
my $self = {};
bless $self, ref $class || $class;
}
sub order_id { return LSIxml::get_set($_[0], "order_id", $_[1]); }
sub message { return LSIxml::get_set($_[0], "message", $_[1]); }
#-----------------------------------------------------------------------------
#FUNCTION
# as_xml(indent)
#
#DESCRIPTION
# Return this status error object as an XML document
#-----------------------------------------------------------------------------
sub as_xml {
my $self = shift;
my $indent = shift;
my $xml = "";
$xml = $xml."$indent\n";
$xml = LSIxml::add_tag($self, $xml, "order_id", "$indent ", 0);
$xml = LSIxml::add_tag($self, $xml, "message", "$indent ", 0);
$xml = $xml."$indent\n";
return $xml;
}
#-----------------------------------------------------------------------------
#FUNCTION
# parse(xmldata)
#
#DESCRIPTION
# Given an XML::Simple returned data structure, create a new object
#-----------------------------------------------------------------------------
sub parse {
my $xml = shift;
my $error = new LSIxml::StatusError;
LSIxml::set_if_exists($error, $xml, "order_id");
LSIxml::set_if_exists($error, $xml, "message");
return $error;
}
1;
# --- END ---