Business-TNT-ExpressConnect

 view release on metacpan or  search on metacpan

lib/Business/TNT/ExpressConnect.pm  view on Meta::CPAN

sub _price_request_out_xsd {
    my ($self) = @_;
    my $file = _xsd_basedir->file('PriceResponseOUT.xsd');

    die "cannot read request OUT xsd file " . $file unless (-r $file);

    return $file;
}

sub _price_request_common_xsd {
    my ($self) = @_;

    my $file = _xsd_basedir->file('commonDefinitions.xsd');

    die "cannot read common definitions xsd file " . $file unless (-r $file);

    return $file;
}

sub tnt_get_price_url {
    return 'https://express.tnt.com/expressconnect/pricing/getprice';
}

sub hash_to_price_request_xml {
    my ($self, $params) = @_;

    my $xml_schema = $self->xml_schema;
    $xml_schema->importDefinitions($self->_price_request_in_xsd);

    # create and use a writer
    my $doc = XML::LibXML::Document->new('1.0', 'UTF-8');
    my $write = $xml_schema->compile(WRITER => '{}priceRequest');

    my %priceCheck = (
        rateId   => 1,                     #unique within priceRequest
        sender   => $params->{sender},
        delivery => $params->{delivery},
        collectionDateTime => ($params->{collection_datetime} // DateTime->now()),
        currency => ($params->{currency} // 'EUR'),
        product => {type => ($params->{product_type} // 'N')}
        ,    #“D” Document(paper/manuals/reports) or “N” Non-document (packages)
    );

    $priceCheck{consignmentDetails} = $params->{consignmentDetails}
        if ($params->{consignmentDetails});
    $priceCheck{seq_pieceLine} = $params->{pieceLines} if ($params->{pieceLines});
    $priceCheck{account}       = $params->{account}    if ($params->{account});

    my %hash = (appId => 'PC', appVersion => '3.0', priceCheck => [\%priceCheck]);

    my $xml = $write->($doc, \%hash);
    $doc->setDocumentElement($xml);

    return $doc;
}

sub get_prices {
    my ($self, $args) = @_;

    my $user_agent = $self->user_agent;
    my $req = HTTP::Request->new(POST => $self->tnt_get_price_url);
    $req->authorization_basic($self->username, $self->password);
    $req->header('Content-Type' => 'text/xml; charset=utf-8');

    if (my $file = $args->{file}) {
        $req->content('' . file($file)->slurp);
    }
    elsif (my $params = $args->{params}) {
        my $xml = $self->hash_to_price_request_xml($params);
        $req->content($xml->toString(1));
    }
    else {
        $self->error(1);
        $self->errors(['missing price request data']);
        return undef;
    }

    my $response = $user_agent->request($req);

    if ($response->is_error) {
        $self->error(1);
        $self->errors(['Request failed: ' . $response->status_line]);
        return undef;
    }

    my $response_xml = $response->content;

    #parse schema
    my $xml_schema = $self->xml_schema;
    $xml_schema->importDefinitions($self->_price_request_out_xsd);

    #read xml file
    my $elem = XML::Compile::Util::pack_type '', 'document';
    my $read = $xml_schema->compile(READER => $elem);

    my $data = $read->($response_xml);

    my @errors;
    my @warnings;
    foreach my $error (@{$data->{errors}->{brokenRule}}) {
        if ($error->{messageType} eq "W") {
            push @warnings, $error->{description};
        } else {
            push @errors, $error->{description};
        }
    }

    if (@warnings) {
        $self->warnings(\@warnings);
    }
    if (@errors) {
        $self->error(1);
        $self->errors(\@errors);
        return undef;
    }

    my $ratedServices = $data->{priceResponse}->[0]->{ratedServices};
    my $currency      = $ratedServices->{currency};
    my $ratedService  = $ratedServices->{ratedService};

    my %prices;



( run in 0.937 second using v1.01-cache-2.11-cpan-acf6aa7dc9e )