File Coverage

blib/lib/Amazon/MWS/XML/ShippedOrder.pm
Criterion Covered Total %
statement 15 58 25.8
branch 0 26 0.0
condition 0 9 0.0
subroutine 5 8 62.5
pod 1 1 100.0
total 21 102 20.5


line stmt bran cond sub pod time code
1             package Amazon::MWS::XML::ShippedOrder;
2              
3 1     1   110087 use strict;
  1         13  
  1         44  
4 1     1   8 use warnings;
  1         3  
  1         40  
5 1     1   714 use DateTime;
  1         569179  
  1         74  
6 1     1   560 use DateTime::Format::ISO8601;
  1         138835  
  1         71  
7 1     1   544 use Moo;
  1         7939  
  1         10  
8              
9             =head1 NAME
10              
11             Amazon::MWS::XML::ShippedOrder
12              
13             =head1 DESCRIPTION
14              
15             Class to validate and generate a shipping confirmation feed. While
16             L<Amazon::MWS::XML::Order> is meant to be used to parse the response,
17             this is meant to produce the XML, generating a structure suitable to
18             satisfy the Amazon XSD.
19              
20             =head1 SYNOPSIS
21              
22             my $shipped = Amazon::MWS::XML::ShippedOrder->new(....); # see below the accessors
23             print Dumper($shipped->as_shipping_confirmation_hashref);
24              
25             =head1 CONSTRUCTOR ARGUMENTS/ACCESSORS
26              
27             =head2 amazon_order_id
28              
29             =head2 merchant_order_id
30              
31             This will be used if amazon_order_id is not provided. This should work
32             as long as the order aknowledgement sent it back, so Amazon is able to
33             pair it with its own id.
34              
35             =head2 merchant_fulfillment_id
36              
37             Optional and not used by Amazon
38              
39             =head2 fulfillment_date
40              
41             The date the item was actually shipped or picked up, depending on the
42             fulfillment method specified in the order.
43              
44             A DateTime object is required. It will default to the current datetime
45             if not provided.
46              
47             =head2 carrier
48              
49             The "standard" carrier code or the carrier name. The module will try
50             to match it with the Amazon codes.
51              
52             =head2 shipping_method
53              
54             The shipping method for the carrier. Optional.
55              
56             =head2 shipping_tracking_number
57              
58             The tracking number. Optional.
59              
60             =head2 items
61              
62             A arrayref of hashrefs with the codes and quantities of shipped items.
63             The following keys (most of them optional) are expected:
64              
65             =over 4
66              
67             =item amazon_order_item_code
68              
69             If not provided will use C<merchant_order_item_code> instead (provided
70             that the orderline id was passed in the aknowledgement).
71              
72             =item merchant_order_item_code
73              
74             Our orderline ID which should have been passed to in the order
75             aknowledgement.
76              
77             =item merchant_fulfillment_item_id
78              
79             Optional.
80              
81             =item quantity
82              
83             The quantity shipped (if more than one of a given item was
84             purchased, and all of them are not shipped together).
85              
86             =back
87              
88              
89             =cut
90              
91             has amazon_order_id => (is => 'ro');
92             has merchant_order_id => (is => 'ro');
93             has merchant_fulfillment_id => (is => 'ro');
94             has fulfillment_date => (is => 'ro',
95             isa => sub {
96             my $dt = $_[0];
97             die "Not a DateTime object"
98             unless ref($dt) && $dt->isa('DateTime');
99             },
100             default => sub { DateTime->now(time_zone => 'Europe/Berlin')},
101             );
102             has carrier => (is => 'ro', required => 1);
103             has shipping_method => (is => 'ro');
104             has shipping_tracking_number => (is => 'ro');
105             has items => (is => 'ro',
106             isa => \&_validate_items,
107             required => 1,
108             );
109              
110             sub _validate_items {
111 0     0     my $items = $_[0];
112 0 0 0       die "items should be an hashref"
113             unless ($items and ref($items) eq 'ARRAY');
114 0           foreach my $item (@$items) {
115 0 0 0       die "An item passed is not an hashref"
116             unless ($item and ref($item) eq 'HASH');
117              
118             die "An item is missing amazon_order_item_code or merchant_order_item_code"
119             unless
120 0 0 0       $item->{amazon_order_item_code} || $item->{merchant_order_item_code};
121             }
122             }
123              
124             =head1 METHODS
125              
126             =head2 as_shipping_confirmation_hashref
127              
128             Return an hashref which can be fed into an Amazon message XSD.
129              
130             =cut
131              
132             sub as_shipping_confirmation_hashref {
133 0     0 1   my $self = shift;
134 0           my %struct;
135             # priority goes to the amazon id
136 0 0         if ($self->amazon_order_id) {
    0          
137 0           $struct{AmazonOrderID} = $self->amazon_order_id;
138             }
139             elsif ($self->merchant_order_id) {
140 0           $struct{MerchantOrderID} = $self->merchant_order_id;
141             }
142             else {
143 0           die "Missing amazon_order_id or merchant_order_id";
144             }
145              
146 0 0         if ($self->merchant_fulfillment_id) {
147 0           $struct{MerchantFulfillmentID} = $self->merchant_fulfillment_id;
148             }
149 0           my $shipping_date = $self->fulfillment_date->iso8601;
150             # little hack to have the timezone
151 0           my $tz = $self->fulfillment_date->strftime('%z');
152 0           $tz =~ s/(\d\d)(\d\d)/$1:$2/;
153              
154 0           $struct{FulfillmentDate} = $shipping_date.$tz;
155              
156 0 0         if ($self->_carrier_is_recognized) {
157 0           $struct{FulfillmentData}{CarrierCode} = $self->carrier;
158             }
159             else {
160 0           $struct{FulfillmentData}{CarrierName} = $self->carrier;
161             }
162              
163 0 0         if ($self->shipping_method) {
164 0           $struct{FulfillmentData}{ShippingMethod} = $self->shipping_method;
165             }
166 0 0         if ($self->shipping_tracking_number) {
167 0           $struct{FulfillmentData}{ShipperTrackingNumber} = $self->shipping_tracking_number;
168             }
169 0           my @items;
170 0           foreach my $item (@{ $self->items }) {
  0            
171 0           my %item_struct;
172             # precedence to amazon order item
173 0 0         if ($item->{amazon_order_item_code}) {
    0          
174 0           $item_struct{AmazonOrderItemCode} = $item->{amazon_order_item_code};
175             }
176             elsif ($item->{merchant_order_item_code}) {
177 0           $item_struct{MerchantOrderItemID} = $item->{merchant_order_item_code};
178             }
179             else {
180 0           die "This shouldn't happen, item was validated";
181             }
182 0 0         if ($item->{merchant_fulfillment_item_id}) {
183 0           $item_struct{MerchantFulfillmentItemID} = $item->{merchant_fulfillment_item_id};
184             }
185             # more items and partial shipping
186 0 0         if ($item->{quantity}) {
187 0           $item_struct{Quantity} = $item->{quantity};
188             }
189 0           push @items, \%item_struct;
190             }
191 0           $struct{Item} = \@items;
192 0           return \%struct;
193             }
194              
195             sub _carrier_is_recognized {
196 0     0     my $self = shift;
197 0           my $carrier = $self->carrier;
198 0           my %carriers = (
199             'AFL/Fedex' => 1,
200             Aramex => 1,
201             "Blue Package" => 1,
202             BlueDart => 1,
203             "Canada Post" => 1,
204             Chronopost => 1,
205             "City Link" => 1,
206             DHL => 1,
207             "DHL Global Mail" => 1,
208             DPD => 1,
209             DTDC => 1,
210             Delhivery => 1,
211             "Deutsche Post" => 1,
212             FEDEX_JP => 1,
213             Fastway => 1,
214             FedEx => 1,
215             "FedEx SmartPost" => 1,
216             "First Flight" => 1,
217             GLS => 1,
218             'GO!' => 1,
219             "Hermes Logistik Gruppe" => 1,
220             "India Post" => 1,
221             JP_EXPRESS => 1,
222             "La Poste" => 1,
223             Lasership => 1,
224             NITTSU => 1,
225             Newgistics => 1,
226             NipponExpress => 1,
227             OSM => 1,
228             OnTrac => 1,
229             Other => 1,
230             "Overnite Express" => 1,
231             Parcelforce => 1,
232             Parcelnet => 1,
233             "Poste Italiane" => 1,
234             Professional => 1,
235             "Royal Mail" => 1,
236             SAGAWA => 1,
237             SDA => 1,
238             SagawaExpress => 1,
239             Smartmail => 1,
240             Streamlite => 1,
241             TNT => 1,
242             Target => 1,
243             UPS => 1,
244             "UPS Mail Innovations" => 1,
245             UPSMI => 1,
246             USPS => 1,
247             YAMATO => 1,
248             YamatoTransport => 1,
249             Yodel => 1,
250             );
251 0           return $carriers{$carrier};
252             }
253              
254              
255             1;