view release on metacpan or search on metacpan
},
"configure" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
}
},
"runtime" : {
"requires" : {
"Class::InsideOut" : "0",
"DBI" : "0",
"DateTime" : "0",
"DateTime::Format::ISO8601" : "0",
"Digest::HMAC_SHA1" : "0",
"Digest::MD5" : "0",
"Exception::Class" : "0",
"Exporter" : "0",
"HTTP::Request" : "0",
"LWP::Protocol::https" : "0",
"LWP::UserAgent" : "0",
"MIME::Base64" : "0",
"Moo" : "0",
"MooX::Types::MooseLike" : "0",
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: '1.4'
name: Amazon-MWS
no_index:
directory:
- t
- inc
requires:
Class::InsideOut: '0'
DBI: '0'
DateTime: '0'
DateTime::Format::ISO8601: '0'
Digest::HMAC_SHA1: '0'
Digest::MD5: '0'
Exception::Class: '0'
Exporter: '0'
HTTP::Request: '0'
LWP::Protocol::https: '0'
LWP::UserAgent: '0'
MIME::Base64: '0'
Moo: '0'
MooX::Types::MooseLike: '0'
Makefile.PL view on Meta::CPAN
'DBD::SQLite' => 0,
},
PREREQ_PM => {
'URI' => 0,
'URI::Escape' => 0,
'HTTP::Request' => 0,
'LWP::UserAgent' => 0,
'LWP::Protocol::https' => 0,
'XML::Simple' => 0,
'DateTime' => 0,
'DateTime::Format::ISO8601' => 0,
'Readonly' => 0,
'Class::InsideOut' => 0,
'Exception::Class' => 0,
'Exporter' => 0,
'MIME::Base64' => 0,
'Digest::MD5' => 0,
'Digest::HMAC_SHA1' => 0,
'namespace::clean' => 0,
'Moo' => 0,
'MooX::Types::MooseLike' => 0,
'DBI' => 0,
'DateTime' => 0,
'SQL::Abstract' => 0,
'Try::Tiny' => 0,
'Path::Tiny' => 0,
'XML::Compile::Schema' => 1.46,
'DateTime::Format::ISO8601' => 0,
'XML::LibXML::Simple' => 0,
},
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'Amazon-MWS-*' },
META_MERGE => {
resources => {
repository => 'https://github.com/interchange/Amazon-MWS',
bugtracker => 'https://github.com/interchange/Amazon-MWS/issues',
IRC => 'irc://irc.freenode.net/#interchange',
},
examples/request-FBA-fulfillment-report.pl view on Meta::CPAN
# Initiate FBA fulfillment report generation
use strict;
use Amazon::MWS::Client;
use DateTime;
my $mws = Amazon::MWS::Client->new(access_key_id=>"XXX",
secret_key => "YYY",
merchant_id => "ZZZ",
marketplace_id => "VVV");
my $req = $mws->RequestReport(ReportType => '_GET_AMAZON_FULFILLED_SHIPMENTS_DATA_',
StartDate => DateTime->now->add(weeks => -1),
EndDate => DateTime->now);
if (my $req_id = $req->{ReportRequestInfo}->[0]->{ReportRequestId}) {
open my $req, "> request.${req_id}";
close $req;
}
lib/Amazon/MWS/FulfillmentInventory.pm view on Meta::CPAN
};
define_api_method ListInventorySupply =>
raw_body => 1,
version => '2010-10-01',
service => "$fulfillment_service",
parameters => {
SellerSkus => {
type => 'MemberList'
},
QueryStartDateTime => { type => 'datetime' },
ResponseGroup => { type => 'List', values=>['Basic','Detailed'] }
};
define_api_method ListInventorySupplyByNextToken =>
raw_body => 1,
version => '2010-10-01',
service => "$fulfillment_service",
parameters => {
NextToken => {
type => 'string',
lib/Amazon/MWS/Routines.pm view on Meta::CPAN
package Amazon::MWS::Routines;
use URI;
use DateTime;
use XML::Simple;
use URI::Escape;
use MIME::Base64;
use Digest::SHA;
use HTTP::Request;
use LWP::UserAgent;
use Digest::MD5 qw(md5_base64);
use Amazon::MWS::TypeMap qw(:all);
use Amazon::MWS::Exception;
use Data::Dumper;
lib/Amazon/MWS/Routines.pm view on Meta::CPAN
my $args = slurp_kwargs(@_);
my $body = '';
my %form = (
Action => $method_name,
AWSAccessKeyId => $self->{access_key_id},
Merchant => $self->{merchant_id},
SellerId => $self->{merchant_id},
SignatureVersion => 2,
SignatureMethod => 'HmacSHA256',
Timestamp => to_amazon('datetime', DateTime->now),
);
foreach my $name (keys %$params) {
my $param = $params->{$name};
unless (exists $args->{$name}) {
Amazon::MWS::Exception::MissingArgument->throw(name => $name) if $param->{required};
next;
}
my $type = $param->{type};
lib/Amazon/MWS/Routines.pm view on Meta::CPAN
my $agent_string = "$appname/$version ($attr_str)";
die 'No access key id' unless $opts{access_key_id};
die 'No secret key' unless $opts{secret_key};
die 'No merchant id' unless $opts{merchant_id};
die 'No marketplace id' unless $opts{marketplace_id};
if ($opts{debug}) {
open LOG, ">$opts{logfile}" or die "Cannot open logfile.";
print LOG DateTime->now();
print LOG "\nNew instance created. \n";
print LOG Dumper(\%opts);
close LOG;
}
# https://github.com/interchange/Amazon-MWS/issues/9
$opts{endpoint} ||= 'https://mws.amazonaws.com';
# strip the trailing slashes
$opts{endpoint} =~ s/\/+\z//;
lib/Amazon/MWS/TypeMap.pm view on Meta::CPAN
package Amazon::MWS::TypeMap;
use warnings;
use strict;
use DateTime;
use DateTime::Format::ISO8601;
use Exporter qw(import);
our @EXPORT_OK = qw(from_amazon to_amazon);
our %EXPORT_TAGS = ( all => \@EXPORT_OK );
sub identity { shift }
my %from_map = (
'string' => \&identity,
'boolean' => sub { lc(shift) eq 'true' },
'nonNegativeInteger' => \&identity,
'datetime' => sub {
return DateTime::Format::ISO8601->parse_datetime(shift);
},
);
sub from_amazon {
my ($type, $value) = @_;
return $from_map{$type}->($value);
}
my %to_map = (
'string' => \&identity,
'boolean' => sub { $_[0] ? 'true' : 'false' },
'nonNegativeInteger' => sub {
my $int = int(shift);
$int = 1 unless $int > 0;
return $int;
},
'datetime' => sub {
return DateTime::Format::ISO8601->parse_datetime(shift);
},
);
sub to_amazon {
my ($type, $value) = @_;
return $to_map{$type}->($value);
}
1;
lib/Amazon/MWS/TypeMap.pm view on Meta::CPAN
A plain perl string.
=head2 boolean
When sent by amazon, true is converted to 1 and false to the empty string.
When sent to amazon, any true value or false value will be properly converted.
=head2 datetime
Converted to and from DateTime objects.
=head1 AUTHOR
Paul Driver C<< frodwith@cpan.org >>
=head1 LICENCE AND COPYRIGHT
Copyright (c) 2009, Plain Black Corporation L<http://plainblack.com>.
All rights reserved
lib/Amazon/MWS/Uploader.pm view on Meta::CPAN
use warnings;
use DBI;
use Amazon::MWS::XML::Feed;
use Amazon::MWS::XML::Order;
use Amazon::MWS::Client;
use Amazon::MWS::XML::Response::FeedSubmissionResult;
use Amazon::MWS::XML::Response::OrderReport;
use Data::Dumper;
use File::Spec;
use DateTime;
use SQL::Abstract;
use Try::Tiny;
use Path::Tiny;
use Scalar::Util qw/blessed/;
use XML::Compile::Schema;
use Moo;
use MooX::Types::MooseLike::Base qw(:all);
use namespace::clean;
lib/Amazon/MWS/Uploader.pm view on Meta::CPAN
$self->_exe_query($self->sqla->insert(amazon_mws_products => { %identifier, %data }));
}
}
}
sub prepare_feeds {
my ($self, $task, $feeds) = @_;
die "Missing task ($task) and feeds ($feeds)" unless $task && $feeds;
return unless @$feeds; # nothing to do
my $job_id = $task . "-" . DateTime->now->strftime('%F-%H-%M-%S');
my $job_started_epoch = time();
$self->_exe_query($self->sqla
->insert(amazon_mws_jobs => {
amws_job_id => $job_id,
shop_id => $self->_unique_shop_id,
task => $task,
job_started_epoch => $job_started_epoch,
}));
lib/Amazon/MWS/Uploader.pm view on Meta::CPAN
$self->_print_or_warn_error("Job $job_id aborted!\n");
}
elsif ($success == $total) {
$update = { success => 1 };
print "Job successful!\n";
# if we're here, all the products are fine, so mark them as
# such if it's an upload job
if ($row->{task} eq 'upload') {
$self->_exe_query($self->sqla->update('amazon_mws_products',
{ status => 'ok',
listed_date => DateTime->now,
listed => 1,
},
{
amws_job_id => $job_id,
shop_id => $self->_unique_shop_id,
}));
}
}
else {
print "Job still to be processed\n";
lib/Amazon/MWS/Uploader.pm view on Meta::CPAN
return Amazon::MWS::XML::Response::FeedSubmissionResult
->new(
xml => $xml,
xml_reader => $self->xml_reader,
);
}
=head2 get_orders($from_date)
This is a self-contained method and doesn't require a product list.
The from_date must be a L<DateTime> object. If not provided, it will
the last week.
Returns a list of Amazon::MWS::XML::Order objects.
Beware that it's possible you get some items with 0 quantity, i.e.
single items cancelled. The application code needs to be prepared to
deal with such phantom items. You can check each order looping over
C<$order->items> checking for C<$item->quantity>.
=cut
sub get_orders {
my ($self, $from_date) = @_;
unless ($from_date) {
$from_date = DateTime->now;
$from_date->subtract(days => $self->order_days_range);
}
my @order_structs;
my $res;
try {
$res = $self->client->ListOrders(
MarketplaceId => [$self->marketplace_id],
CreatedAfter => $from_date,
);
push @order_structs, @{ $res->{Orders}->{Order} };
lib/Amazon/MWS/XML/Order.pm view on Meta::CPAN
package Amazon::MWS::XML::Order;
use Amazon::MWS::XML::Address;
use Amazon::MWS::XML::OrderlineItem;
use strict;
use warnings;
use DateTime;
use DateTime::Format::ISO8601;
use Data::Dumper;
use Moo;
use MooX::Types::MooseLike::Base qw(:all);
use namespace::clean;
=head1 NAME
Amazon::MWS::XML::Order
lib/Amazon/MWS/XML/Order.pm view on Meta::CPAN
=cut
sub items {
my $self = shift;
return @{ $self->items_ref };
}
=head2 order_date
Return a L<DateTime> object with th purchase date.
=cut
sub order_date {
my ($self) = @_;
return $self->_get_dt($self->order->{PurchaseDate});
}
sub _get_dt {
my ($self, $date) = @_;
return DateTime::Format::ISO8601->parse_datetime($date);
}
=head2 shipping_cost
The total shipping cost, built summing up the shipping cost of each
item.
=cut
lib/Amazon/MWS/XML/Product.pm view on Meta::CPAN
Valid values are: AUD BRL CAD CNY DEFAULT EUR GBP INR JPY MXN USD.
Defaults to EUR.
=item sale_price
A sale price (optional)
=item sale_start
A DateTime object with the sale start date
=item sale_end
A DateTime object with the sale end date
=item images
An (optional) arrayref of image urls. The first will become the main
image, the other one will become the PT1, etc.
Please note that B<only http:// links> are allowed. If you pass https://
links, they will be rejected by Amazon.
=item children
lib/Amazon/MWS/XML/Product.pm view on Meta::CPAN
die "$price is negative" if $price < 0;
}
has sale_price => (is => 'ro',
isa => \&_validate_price);
has sale_start => (is => 'ro',
isa => sub {
die "Not a datetime"
unless $_[0]->isa('DateTime');
});
has sale_end => (is => 'ro',
isa => sub {
die "Not a datetime"
unless $_[0]->isa('DateTime');
});
has currency => (is => 'ro',
isa => sub {
my %currency = map { $_ => 1 } (qw/AUD BRL CAD CNY DEFAULT
EUR GBP INR JPY MXN USD/);
die "Not a valid currency" unless $currency{$_[0]};
},
default => sub { 'EUR' });
lib/Amazon/MWS/XML/Response/OrderReport.pm view on Meta::CPAN
package Amazon::MWS::XML::Response::OrderReport;
use utf8;
use strict;
use warnings;
use DateTime;
use DateTime::Format::ISO8601;
use Data::Dumper;
use Amazon::MWS::XML::Response::OrderReport::Item;
use Amazon::MWS::XML::Address;
use Moo;
use MooX::Types::MooseLike::Base qw(HashRef ArrayRef Str Int);
use namespace::clean;
=head1 NAME
Amazon::MWS::XML::Response::OrderReport
lib/Amazon/MWS/XML/Response/OrderReport.pm view on Meta::CPAN
=head2 amazon_order_number
=head2 email
The buyer email.
=head2 order_date
The date when the order processing was complete or when the order was
placed as a L<DateTime> object.
=head2 items
Return a list of L<Amazon::MWS::XML::Response::OrderReport::Item>,
which acts (more or less) like L<Amazon::MWS::XML::OrderlineItem>.
=cut
sub amazon_order_number {
return shift->struct->{AmazonOrderID};
lib/Amazon/MWS/XML/Response/OrderReport.pm view on Meta::CPAN
# OrderDate The date the order was placed
# OrderPostedDate The date the buyer's credit card was charged and order processing was completed
sub order_date {
my $self = shift;
my $struct = $self->struct;
# maybe this would need a different method, but we don't know what
# to do with it anyway.
my $date = $struct->{OrderPostedDate} || $struct->{OrderDate};
return DateTime::Format::ISO8601->parse_datetime($date);
}
sub items {
return @{ shift->_items_ref };
}
=head2 as_ack_order_hashref
Return a structure suitable create an the acknowledge feed.
lib/Amazon/MWS/XML/ShippedOrder.pm view on Meta::CPAN
package Amazon::MWS::XML::ShippedOrder;
use strict;
use warnings;
use DateTime;
use DateTime::Format::ISO8601;
use Moo;
=head1 NAME
Amazon::MWS::XML::ShippedOrder
=head1 DESCRIPTION
Class to validate and generate a shipping confirmation feed. While
L<Amazon::MWS::XML::Order> is meant to be used to parse the response,
lib/Amazon/MWS/XML/ShippedOrder.pm view on Meta::CPAN
=head2 merchant_fulfillment_id
Optional and not used by Amazon
=head2 fulfillment_date
The date the item was actually shipped or picked up, depending on the
fulfillment method specified in the order.
A DateTime object is required. It will default to the current datetime
if not provided.
=head2 carrier
The "standard" carrier code or the carrier name. The module will try
to match it with the Amazon codes.
=head2 shipping_method
The shipping method for the carrier. Optional.
lib/Amazon/MWS/XML/ShippedOrder.pm view on Meta::CPAN
=cut
has amazon_order_id => (is => 'ro');
has merchant_order_id => (is => 'ro');
has merchant_fulfillment_id => (is => 'ro');
has fulfillment_date => (is => 'ro',
isa => sub {
my $dt = $_[0];
die "Not a DateTime object"
unless ref($dt) && $dt->isa('DateTime');
},
default => sub { DateTime->now(time_zone => 'Europe/Berlin')},
);
has carrier => (is => 'ro', required => 1);
has shipping_method => (is => 'ro');
has shipping_tracking_number => (is => 'ro');
has items => (is => 'ro',
isa => \&_validate_items,
required => 1,
);
sub _validate_items {
t/SubmitFeed.t view on Meta::CPAN
use warnings;
use strict;
use Amazon::MWS::Client;
use Amazon::MWS::Enumeration::FeedType qw(:all);
use Amazon::MWS::Enumeration::FeedProcessingStatus qw(:all);
use Test::MockObject::Extends;
use Test::MockObject;
use HTTP::Response;
use Test::More tests => 4;
use DateTime;
use Data::Dumper;
my $client = Amazon::MWS::Client->new(
access_key_id => 'foo',
secret_key => 'bar',
merchant_id => 'baz',
marketplace_id => 'goo',
);
my $agent = Test::MockObject->new->mock(
t/SubmitFeed.t view on Meta::CPAN
</AmazonEnvelope>
FEED_CONTENT
);
};
diag Dumper($@) if $@;
is $response->{FeedProcessingStatus}, _SUBMITTED_;
is $response->{FeedSubmissionId}, '11223344';
is $response->{FeedType}, _POST_ORDER_FULFILLMENT_DATA_;
is $response->{SubmittedDate}, DateTime->new(
year => 2011,
month => 2,
day => 8,
hour => 9,
minute => 49,
second => 35
);
t/job-selection.t view on Meta::CPAN
#!perl
use utf8;
use strict;
use warnings;
use Amazon::MWS::Uploader;
use Data::Dumper;
use Test::More;
use DateTime;
use DBI;
binmode STDOUT, ':utf8';
binmode STDERR, ':utf8';
my $feed_dir = 't/feeds';
if (-d 'schemas') {
plan tests => 12;
}
t/order-reports.t view on Meta::CPAN
ok(@orders == 2, "Got the orders");
my $count = 0;
foreach my $order (@orders) {
$count++;
ok ($order, "object ok");
ok ($order->amazon_order_number, "Got order number") and diag $order->amazon_order_number;
ok ($order->struct, "struct ok");
my $order_date = $order->order_date;
ok($order_date->isa('DateTime'), "datetime object returned");
foreach my $method (qw/name city zip country address_line region/) {
ok ($order->shipping_address->$method, "shipping $method ok")
and diag $order->shipping_address->$method;
# only our example have a billing address
if ($count == 1) {
ok ($order->billing_address->$method, "billing $method ok")
and diag $order->billing_address->$method;
}
else {
ok (!$order->billing_address);
t/shipping-confirmation.t view on Meta::CPAN
#!perl
use utf8;
use strict;
use warnings;
use Test::More;
use Amazon::MWS::XML::ShippedOrder;
use Amazon::MWS::Uploader;
use DateTime;
my $test_extended;
my $schema_dir = 'schemas';
if (-d $schema_dir) {
plan tests => 5;
$test_extended = 1;
}
else {
plan tests => 2;
}
my %shipped = (
# amazon_order_id => '12341234',
merchant_order_id => '8888888',
merchant_fulfillment_id => '666666', # optional
fulfillment_date => DateTime->new(
year => 2014,
month => 11,
day => 14,
hour => 11,
minute => 11,
second => 0,
time_zone => 'Europe/Berlin',
),
carrier => 'UPS',
shipping_method => 'Second Day',
t/shipping-confirmation.t view on Meta::CPAN
<Quantity>2</Quantity>
</Item>
</OrderFulfillment>
</Message>
</AmazonEnvelope>
XML
%shipped = (
merchant_order_id => 1234567,
merchant_fulfillment_id => 1234567,
fulfillment_date => DateTime->new(year => 2002,
month => 5,
day => 1,
hour => 15,
minute => 36,
second => 33,
time_zone => '-08:00',
),
carrier => 'UPS',
shipping_method => 'Second Day',
shipping_tracking_number => 1234567890,
t/uploader.t view on Meta::CPAN
#!perl
use utf8;
use strict;
use warnings;
use Amazon::MWS::Uploader;
use Data::Dumper;
use Test::More;
use DateTime;
binmode STDOUT, ':utf8';
binmode STDERR, ':utf8';
my $feed_dir = 't/feeds';
if (-d 'schemas') {
plan tests => 26;
}
else {
t/uploader.t view on Meta::CPAN
foreach my $code (qw/8001 8002 8003 8008/) {
$uploader->_error_logger(warning => $code => "$code Ä warn");
}
is (scalar(@warned), 2) or diag Dumper(\@warned);
is_deeply(\@warned, [
"Invalid mode invalid for warning: 8001 Ä warn (8001)\n",
"warning: 8002 Ä warn (8002)\n",
]);
}
my $now = DateTime->now;
my $old = $now->clone->subtract(hours => 2);
ok (!$uploader->job_timed_out({
task => 'order_ack',
job_started_epoch => $old->epoch,
}),
"order_ack doesn't timeout in 2 hours since " . $old->ymd);
ok (!$uploader->job_timed_out({