Amazon-MWS
view release on metacpan or search on metacpan
lib/Amazon/MWS/Uploader.pm view on Meta::CPAN
error_msg => $error->{type} . ' ' . $error->{message} . ' ' . $error->{code},
error_code => $error->{code},
);
}
else {
%update = (
error_msg => $result->errors,
error_code => AMW_ORDER_WILDCARD_ERROR,
);
}
if (%update) {
$self->_exe_query($self->sqla->update('amazon_mws_orders',
\%update,
{ amws_job_id => $job_id,
shop_id => $self->_unique_shop_id }));
}
else {
warn "register_order_ack_errors couldn't parse " . Dumper($result);
}
# then get the amazon order number and recheck
my $sth = $self->_exe_query($self->sqla->select('amazon_mws_orders',
[qw/amazon_order_id
shop_order_id
/],
{
amws_job_id => $job_id,
shop_id => $self->_unique_shop_id,
}));
my ($amw_order_number, $shop_order_id) = $sth->fetchrow_array;
if ($sth->fetchrow_array) {
warn "Multiple jobs found for $job_id in amazon_mws_orders!";
}
$sth->finish;
if (my $status = $self->update_amw_order_status($amw_order_number)) {
warn "$amw_order_number ($shop_order_id) has now status $status!\n";
}
}
sub register_ship_order_errors {
my ($self, $job_id, $result) = @_;
# here we get the amazon ids,
my @orders = $self->orders_in_shipping_job($job_id);
my $errors = $result->orders_errors;
# filter
my @errors_with_order = grep { $_->{order_id} } @$errors;
my %errs = map { $_->{order_id} => {job_id => $job_id, code => $_->{code}, error => $_->{error}} } @errors_with_order;
foreach my $ord (@orders) {
if (my $fault = $errs{$ord}) {
$self->_exe_query($self->sqla->update('amazon_mws_orders',
{
shipping_confirmation_error => "$fault->{code} $fault->{error}",
},
{
amazon_order_id => $ord,
shipping_confirmation_job_id => $job_id,
shop_id => $self->_unique_shop_id,
}));
}
else {
# this looks good
$self->_exe_query($self->sqla->update('amazon_mws_orders',
{
shipping_confirmation_ok => 1,
},
{
amazon_order_id => $ord,
shipping_confirmation_job_id => $job_id,
shop_id => $self->_unique_shop_id
}));
}
}
}
=head2 register_errors($job_id, $result)
The first argument is the job ID. The second is a
L<Amazon::MWS::XML::Response::FeedSubmissionResult> object.
This method will update the status of the products (either C<failed>
or C<redo>) in C<amazon_mws_products>.
=head2 register_order_ack_errors($job_id, $result);
Same arguments as above, but for order acknowledgements.
=head2 register_ship_order_errors($job_id, $result);
Same arguments as above, but for shipping notifications.
=cut
sub register_errors {
my ($self, $job_id, $result) = @_;
# first, get the list of all the skus which were scheduled for this job
# we don't have a products hashref anymore.
# probably we could parse back the produced xml, but looks like an overkill.
# just mark them as redo and wait for the next cron call.
my @products = $self->skus_in_job($job_id);
my $errors = $result->skus_errors;
my @errors_with_sku = grep { $_->{sku} } @$errors;
# turn it into an hash
my %errs = map { $_->{sku} => {job_id => $job_id, code => $_->{code}, error => $_->{error}} } @errors_with_sku;
foreach my $sku (@products) {
if ($errs{$sku}) {
$self->_exe_query($self->sqla->update('amazon_mws_products',
{
status => 'failed',
error_code => $errs{$sku}->{code},
error_msg => "$errs{$sku}->{job_id} $errs{$sku}->{code} $errs{$sku}->{error}",
},
{
sku => $sku,
shop_id => $self->_unique_shop_id,
}));
}
else {
# this is good, mark it to be redone
$self->_exe_query($self->sqla->update('amazon_mws_products',
{
status => 'redo',
},
{
sku => $sku,
shop_id => $self->_unique_shop_id,
}));
print "Scheduling $sku for redoing\n";
}
}
}
=head2 skus_in_job($job_id)
Check the amazon_mws_product for the SKU which were uploaded by the
given job ID.
=cut
sub skus_in_job {
my ($self, $job_id) = @_;
my $sth = $self->_exe_query($self->sqla->select('amazon_mws_products',
[qw/sku/],
{
amws_job_id => $job_id,
shop_id => $self->_unique_shop_id,
}));
my @skus;
while (my $row = $sth->fetchrow_hashref) {
push @skus, $row->{sku};
}
return @skus;
}
=head2 get_asin_for_eans(@eans)
Accept a list of EANs and return an hashref where the keys are the
lib/Amazon/MWS/Uploader.pm view on Meta::CPAN
}
return $feeder->create_feed(OrderFulfillment => \@messages);
}
=head2 send_shipping_confirmation($shipped_orders)
Schedule the shipped orders (an L<Amazon::MWS::XML::ShippedOrder>
object) for the uploading.
=head2 order_already_shipped($shipped_order)
Check if the shipped orders (an L<Amazon::MWS::XML::ShippedOrder> was
already notified as shipped looking into our table, returning the row
with the order.
To see the status, check shipping_confirmation_ok (already done),
shipping_confirmation_error (faulty), shipping_confirmation_job_id (pending).
=cut
sub order_already_shipped {
my ($self, $order) = @_;
my $condition = $self->_condition_for_shipped_orders($order);
my $sth = $self->_exe_query($self->sqla->select(amazon_mws_orders => '*', $condition));
if (my $row = $sth->fetchrow_hashref) {
die "Multiple results found in amazon_mws_orders for " . Dumper($condition)
if $sth->fetchrow_hashref;
return $row;
}
else {
return;
}
}
sub send_shipping_confirmation {
my ($self, @orders) = @_;
my @orders_to_notify;
foreach my $ord (@orders) {
if (my $report = $self->order_already_shipped($ord)) {
if ($report->{shipping_confirmation_ok}) {
print "Skipping ship-confirm for order $report->{amazon_order_id} $report->{shop_order_id}: already notified\n";
}
elsif (my $error = $report->{shipping_confirmation_error}) {
if ($self->reset_all_errors) {
warn "Submitting again previously failed job $report->{amazon_order_id} $report->{shop_order_id}\n";
push @orders_to_notify, $ord;
}
else {
warn "Skipping ship-confirm for order $report->{amazon_order_id} $report->{shop_order_id} with error $error\n";
}
}
elsif ($report->{shipping_confirmation_job_id}) {
print "Skipping ship-confirm for order $report->{amazon_order_id} $report->{shop_order_id}: pending\n";
}
else {
push @orders_to_notify, $ord;
}
}
else {
die "It looks like you are trying to send a shipping confirmation "
. " without prior order acknowlegdement. "
. "At least in the amazon_mws_orders there is no trace of "
. "$report->{amazon_order_id} $report->{shop_order_id}";
}
}
return unless @orders_to_notify;
my $feed_content = $self->shipping_confirmation_feed(@orders_to_notify);
# here we have only one feed to upload and check
my $job_id = $self->prepare_feeds(shipping_confirmation => [{
name => 'shipping_confirmation',
content => $feed_content,
}]);
# and store the job id in the table
foreach my $ord (@orders_to_notify) {
$self->_exe_query($self->sqla->update(amazon_mws_orders => {
shipping_confirmation_job_id => $job_id,
shipping_confirmation_error => undef,
},
$self->_condition_for_shipped_orders($ord)));
}
}
sub _condition_for_shipped_orders {
my ($self, $order) = @_;
die "Missing order" unless $order;
my %condition = (shop_id => $self->_unique_shop_id);
if (my $amazon_order_id = $order->amazon_order_id) {
$condition{amazon_order_id} = $amazon_order_id;
}
elsif (my $order_id = $order->merchant_order_id) {
$condition{shop_order_id} = $order_id;
}
else {
die "Missing amazon_order_id or merchant_order_id";
}
return \%condition;
}
=head2 orders_waiting_for_shipping
Return a list of hashref with two keys, C<amazon_order_id> and
C<shop_order_id> for each order which is waiting confirmation.
This is implemented looking into amazon_mws_orders where there is no
shipping confirmation job id.
The confirmed flag (which means we acknowledged the order) is ignored
to avoid stuck order_ack jobs to prevent the shipping confirmation.
=cut
sub orders_waiting_for_shipping {
my $self = shift;
my $sth = $self->_exe_query($self->sqla->select('amazon_mws_orders',
[qw/amazon_order_id
shop_order_id/],
{
shop_id => $self->_unique_shop_id,
shipping_confirmation_job_id => undef,
( run in 0.483 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )