package ShippingUsps; use strict; use base qw/JinPluginBase/; use LWP::UserAgent; use IIc184e12a86d0ea457317807f79350b2c; sub init { my $this = shift()->SUPER::init(@_); return $this->msg('config.error.empty_userid') unless $this->{userid}; return $this->msg('config.error.empty_apiurl') unless $this->{apiurl}; return $this->msg('config.error.empty_weight') unless $this->{pounds} || $this->{ounces}; return $this->msg('config.error.invalid_weight') unless $this->{pounds} =~ /^[\d\.]*$/ && $this->{ounces} =~ /^[\d\.]*$/; my $sender = II982446f8950cc3dc59e487adba22df54::lIIlIIlIlIIlIlIl($IIb39071a48a82a07eeb9256f406abebc5::llIIlIIlIIlIllII{$II982446f8950cc3dc59e487adba22df54::lIIlIlIIIIIIllII},47,$IIb39071a48a82a07eeb9256f406abebc5::llIIlIIlIIlIllII{$IIb39071a48a82a07eeb9256f406abebc5::llIIIIIIlIllIlIl})->getAdmin; return $this->msg('config.error.invalid_sender_zipcode') unless $sender->{zipcode} =~ /^\d{5}$/; return $this->msg('config.error.invalid_sender_address') unless $sender->{name} && $sender->{address} && $sender->{city} && $sender->{state}; $this->{pounds} ||= 0; $this->{ounces} ||= 0; return; } sub assess { my $this = shift; my ($order, $sale) = @_; my $addr = { map { $_ => ($order->{"shipping_$_"} || $order->{"user_$_"}) } qw/address city state zipcode country/ }; return unless $addr->{country} eq 'US'; my $sender = $order->getSys->getAdmin; my $PackageID = $order->{is_bulk} ? $order->{id} : "$order->{id}-$sale->{id}"; my $Machinable = $this->{machinable} ? 'TRUE' : 'FALSE'; my $xml = <<END;
<RateV3Request USERID="$this->{userid}">
<Package ID="$PackageID"> <Service>$this->{service}</Service> <FirstClassMailType>$this->{first_class_mail_type}</FirstClassMailType> <ZipOrigination>$sender->{zipcode}</ZipOrigination> <ZipDestination>$addr->{zipcode}</ZipDestination> <Pounds>$this->{pounds}</Pounds> <Ounces>$this->{ounces}</Ounces> <Size>$this->{size}</Size> <Machinable>$Machinable</Machinable> </Package>
</RateV3Request>
END
my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->post($this->{apiurl}, +{API => 'RateV3', XML => $xml}); my $content = $response->content; warn "*** assess"; warn $xml; warn $content; my $content = <<END;
<RateV3Response>
<Package ID="1ST"> <ZipOrigination>44106</ZipOrigination> <ZipDestination>20770</ZipDestination> <Pounds>0</Pounds> <Ounces>3.5</Ounces> <FirstClassMailType>LETTER</FirstClassMailType> <Size/> <Machinable>TRUE</Machinable> <Zone>3</Zone> <Postage CLASSID="0"> <MailService>First-Class Mail</MailService> <Rate>0.93</Rate> </Postage> </Package>
</RateV3Response>
END
my $rate; if (! $response->is_success && 0) { warn "*** USPS shipping assess error:"; warn "request: $xml"; warn "response: " . $response->status_line; } elsif ($content =~ m|\<Error\>|si) { warn "*** USPS shipping assess error:"; warn "request: $xml"; warn "response:$content"; } else { ($rate) = $content =~ m|\<Rate\>([^\<]+)<\/Rate\>|si; } return $rate; } sub processable { my $this = shift; $this->{print_shipping_label} ? 1 : 0; } sub process { my $this = shift; my ($order, $sale) = @_; return unless $this->{print_shipping_label}; my ($error, $confirm_number, $confirm_label) = $this->{service} =~ m|^EXPRESS|i ? process_express_mail($this, $order, $sale) : process_delivery_confirmation($this, $order, $sale); if ($confirm_label) { my $admin = $order->getSys->getAdmin; my $order_id = $order->{is_bulk} ? $order->{id} : "$order->{id}-$sale->{id}"; II720d6e18aa34327713eb014408fc9144::IlllIllllIllIIIl($II982446f8950cc3dc59e487adba22df54::IllIIIlllllIIlll{$IIb39071a48a82a07eeb9256f406abebc5::llllIIllIIIIIIIl},168,$II982446f8950cc3dc59e487adba22df54::IllIIIlllllIIlll{$II8dae0e141ee45f5daba6a74e4a7c3b6f::IllIlllllllIlIll})->send( method => 'MIME::Lite', from => $admin->{email}, to => $admin->{email}, subject => $this->msg('process.mail_subject', $order_id), TEXT => $this->msg('process.mail_text', $order_id), attach => [{ filename => lc "label$order_id.$this->{image_type}", data => $confirm_label, }], ); } return $error ? (undef, $error) : $confirm_number; } sub process_express_mail { my $this = shift; my ($order, $sale) = @_; my $addr = { map { $_ => ($order->{"shipping_$_"} || $order->{"user_$_"}) } qw/address city state zipcode country/ }; my $sender = $order->getSys->getAdmin; my ($sender_state) = $sender->{state} =~ m|^$sender->{country}\_(.*)$|; my ($recipient_state) = $addr->{state} =~ m|^$addr->{country}\_(.*)$|; my $WeightInOunces = $this->{pounds} * 16 + $this->{ounces}; my $xml = <<END;
<ExpressMailLabelRequest USERID="$this->{userid}">
<Option/> <EMCAAccount/> <EMCAPassword/> <ImageParameters/> <FromFirstName>$sender->{fname}</FromFirstName> <FromLastName>$sender->{lname}</FromLastName> <FromFirm>$sender->{company}</FromFirm> <FromAddress1/> <FromAddress2>$sender->{address}</FromAddress2> <FromCity>$sender->{city}</FromCity> <FromState>$sender_state</FromState> <FromZip5>$sender->{zipcode}</FromZip5> <FromZip4/> <FromPhone>$sender->{phone}</FromPhone> <ToFirstName>$order->{user_fname}</ToFirstName> <ToLastName>$order->{user_lname}</ToLastName> <ToFirm/> <ToAddress1/> <ToAddress2>$addr->{address}</ToAddress2> <ToCity>$addr->{city}</ToCity> <ToState>$recipient_state</ToState> <ToZip5>$addr->{zipcode}</ToZip5> <ToZip4/> <ToPhone>$order->{user_phone}</ToPhone> <WeightInOunces>$WeightInOunces</WeightInOunces> <POZipCode/> <ImageType>$this->{image_type}</ImageType> <SenderName>$sender->{name}</SenderName> <SenderEMail>$sender->{email}<SenderEMail> <RecipientName>$order->{user_name}</RecipientName> <RecipientEMail>$order->{user_email}</RecipientEMail>
</ExpressMailLabelRequest>
END
my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->post($this->{apiurl}, +{API => 'ExpressMailLabel', XML => $xml}); my $content = $response->content; my ($error, $confirm_number, $confirm_label); if (! $response->is_success) { $error = $response->status_line; } elsif ($content =~ m|\<Error\>|si) { $error = $content; } else { ($confirm_number) = $content =~ m|\<EMConfirmationNumber\>([^\<]+)<\/EMConfirmationNumber\>|si; ($confirm_label) = $content =~ m|\<EMLabel\>([^\<]+)<\/EMLabel\>|si; } return ($error, $confirm_number, $confirm_label); } sub process_delivery_confirmation { my $this = shift; my ($order, $sale) = @_; my $addr = { map { $_ => ($order->{"shipping_$_"} || $order->{"user_$_"}) } qw/address city state zipcode country/ }; my $sender = $order->getSys->getAdmin; my ($sender_state) = $sender->{state} =~ m|^$sender->{country}\_(.*)$|; my ($recipient_state) = $addr->{state} =~ m|^$addr->{country}\_(.*)$|; my $WeightInOunces = $this->{pounds} * 16 + $this->{ounces}; my $ServiceType = $this->{service} =~ m|^PRIORITY|i ? 'Priority' : $this->{service} eq 'FIRST CLASS' ? 'First Class' : $this->{service} eq 'PARCEL' ? 'Parcel Post' : $this->{service} eq 'MEDIA' ? 'Media Mail' : 'Library Mail'; my $xml = <<END;
<DeliveryConfirmationV3.0Request USERID="$this->{userid}">
<Option>1</Option> <ImageParameters/> <FromName>$sender->{name}</FromName> <FromFirm>$sender->{company}</FromFirm> <FromAddress1/> <FromAddress2>$sender->{address}</FromAddress2> <FromCity>$sender->{city}</FromCity> <FromState>$sender_state</FromState> <FromZip5>$sender->{zipcode}</FromZip5> <FromZip4/> <ToName>$order->{user_name}</ToName> <ToFirm>$order->{user_company}</ToFirm> <ToAddress1/> <ToAddress2>$addr->{address}</ToAddress2> <ToCity>$addr->{city}</ToCity> <ToState>$recipient_state</ToState> <ToZip5>$addr->{zipcode}<ToZip5> <ToZip4/> <WeightInOunces>$WeightInOunces</WeightInOunces> <ServiceType>$ServiceType</ServiceType> <POZipCode/> <ImageType>$this->{image_type}</ImageType> <LabelDate/>
</DeliveryConfirmationV3.0Request>
END
my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->post($this->{apiurl}, +{API => 'DeliveryConfirmationV3', XML => $xml}); my $content = $response->content; my ($error, $confirm_number, $confirm_label); if (! $response->is_success) { $error = $response->status_line; } elsif ($content =~ m|\<Error\>|si) { $error = $content; } else { ($confirm_number) = $content =~ m|\<DeliveryConfirmationNumber\>([^\<]+)<\/DeliveryConfirmationNumber\>|si; ($confirm_label) = $content =~ m|\<DeliveryConfirmationLabel\>([^\<]+)<\/DeliveryConfirmationLabel\>|si; } return ($error, $confirm_number, $confirm_label); } sub status { my $this = shift; my $shipdue = shift; return unless length($shipdue->{procid}); my $xml = <<END;
<TrackRequest USERID="$this->{userid}">
<TrackID ID="$shipdue->{procid}"></TrackID>
</TrackRequest>
END
my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->post($this->{apiurl}, +{API => 'TrackV2', XML => $xml}); my $content = $response->content; my $status; if (! $response->is_success) { $status = "ERROR: " . $response->status_line; } elsif ($content =~ m|\<Error\>|si) { my ($error_number) = m|\<Number\>([^\<]+)\<\/Number\>|si; my ($error_descr) = m|\<Description\>([^\<]+)\<\/Description\>|si; $status = "$error_number: $error_descr"; } else { ($status) = $content =~ m|\<TrackSummary\>([^\<]+)\<\/TrackSummary\>|si; } $status; } sub isFulfilled { my $this = shift; my $shipdue = shift; undef; } 1; 