$versions{'USPS_ship-lib.pl'} = '06.6.00.0000';

#######################################################################
#
# AgoraCart and all associated files, except where noted, are
# Copyright 2001 to Present jointly by K-Factor Technologies, Inc.
# and by C E Mayo (aka Mister Ed) at AgoraCart.com & K-Factor.net
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

# http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# This copyright notice may not be removed or altered in any way.
#
#######################################################################

#
#
# Contains the subroutines/functions for the
# XML version for United States Postal Service (USPS)
# by Mister Ed 2005
# Updated for Route 66, May 2019
#
#

#######################################################################
#                    calc_usps
#######################################################################

sub calc_usps {
    my ( $method, $origin, $dest, $destcountry, $shipping_total, $weight_data ) = @_;
    my ( $err_printed, $err, $temp_zip_thingy ) = q{};
    my (
        $product,         $alt_origin, $alt_stateprov,
        $alt_origin_temp, $weight,     $ship_cost,
        $junk,            $thezone,    $errmsg,
        $foundit,         $item_info,  $origin_passby,
        $new_weight_data, $item_wt,    $item_qty,
        $splitanswer,     $item_cost,  @ship_list
    );
    my ( $pounds, $ounces, $usps_prot, $usps_site, $usps_cgi, $answer );
    my ( $error, $orig_ans );
    my ( $country, $oversized, $cod );
    my (%zip_list);

    $ship_cost = 0;    # handling charge added in define_shipping_logic

    ( $usps_prot, $junk, $usps_site, $usps_cgi ) =
      split( /\//, $sc_USPS_host_URL, 4 );
    $usps_prot .= '//';
    $usps_cgi = '/' . $usps_cgi;

    if ( ( $destcountry =~ /kingdom/i ) && ( $destcountry =~ /united/i ) )
    {                  # convert UK to England for USPS only
        $destcountry = 'England';
    }

    # Look for code: value ="USPS xyz (PRODUCT)"
    ( $junk,  $stuff ) = split( /\(/, $method, 2 );
    ( $stuff, $junk )  = split( /\)/, $stuff,  2 );
    if ( $stuff ) {    #assume we have a valid product code
        $product           = $stuff;
        $foundit           = 'yes';
    }
    local $productindicator = uc("$product");
    if ( ( $product =~ /Express Mail/i ) && ( $product !~ /international/i ) ) {
        $productindicator = 'EXPRESS';
    }
    if ( ( $product =~ /First Class/i ) && ( $product !~ /international/i ) ) {
        $productindicator = 'FIRST CLASS';
    }
    if ( $product =~ /Parcel Post/i ) { $productindicator = 'PARCEL'; }
    if ( ( $product =~ /Priority Mail/i ) && ( $product !~ /international/i ) )
    {
        $productindicator = 'PRIORITY';
    }

    if (   ( $destcountry )
        && ( $destcountry !~ /united states/i )
        && ( $destcountry !~ /puerto rico/i ) )
    {
        if ( ( $product !~ /international|Global Express Guaranteed/i ) ) {
            $err_printed               = 'yes';
            $order_error_do_not_finish = 'yes';
            print "<p>USPS shipping error: $product $agora_shiplib_message13</p><p>$agora_shiplib_message14</p><p>$err</p>\n";
            $ship_cost = 0;
            return $ship_cost;
        }
    }

    #Taint mode stuff ...
    $dest =~ /(\w+)/;
    $dest = $1;

    $sc_verify_boxes_max_wt = $sc_USPS_max_wt;

    my @ship_list = split( /\|/, $weight_data );

    # new stuff for alt origination. use even without alt origination
    foreach $ship_list (@ship_list) {
        ( $item_qty, $item_wt, $item_val, $alt_origin, $junk ) =
          split( /\*/, $ship_list, 5 );
        if ( $alt_origin ) {
            if ( $zip_list{$alt_origin} eq '' ) {
                $zip_list{$alt_origin} = $ship_list;
            }
            else {
                $temp_zip_thingy = "$zip_list{$alt_origin}";
                $temp_zip_thingy .= '|' . "$ship_list";
                $zip_list{$alt_origin} = "$temp_zip_thingy";
            }
        }
        else {
            if ( $zip_list{$origin} eq '' ) {
                $zip_list{$origin} = $ship_list;
            }
            else {
                $temp_zip_thingy = "$zip_list{$origin}";
                $temp_zip_thingy .= '|' . "$ship_list";
                $zip_list{$origin} = "$temp_zip_thingy";
            }
        }
    }

    # runs each origination
    foreach $origin_product_list ( sort ( keys %zip_list ) ) {
        my $packageID = '0';

        # All products from this origin assigned to variable
        # in order to split into separate boxes if needed.
        $weight_data = $zip_list{$origin_product_list};

        if (   ( $destcountry eq '' )
            || ( $destcountry =~ /united states/i )
            || ( $destcountry =~ /puerto/i ) )
        {
            $workString = 'API=RateV4&XML=<RateV4Request ';
        }
        else {
            $workString = "API=IntlRateV2&XML=<IntlRateV2Request ";
        }

        $workString .= "USERID=\"$sc_USPS_userid\">";

        if ( ( $USPS_insure_shipments eq 'yes' ) || ( $USPS_signature_confirmation eq 'yes' ) || ( $USPS_delivery_confirmation eq 'yes' ) || ( $destcountry =~ /canada/i ) ) {
                $workString .= "<Revision>2</Revision>";
        }

        # Split the order out into boxes using logic of ship_put_in_boxes
        ( $new_weight_data, $ship_ins ) = ship_put_in_boxes(
            $weight_data, $weight_data,
            $origin_product_list, $sc_USPS_max_wt
        );

        $sc_shipping_thing .= $new_weight_data;

        # split by boxes.
        @ship_list = split( /\|/, $new_weight_data );

        my $temp_num_packs = $#ship_list + 1;
        if ( $#ship_list > 24 ) {
            $err_printed               = 'yes';
            $order_error_do_not_finish = 'yes';
            print
qq|<p>USPS shipping error:<br>$agora_shiplib_message15 $temp_num_packs $agora_shiplib_message16<br>$err</p>\n|;
            $ship_cost = 0;
            return $ship_cost;
        }

        # create package string for each box individually.
        # also assign package ID for each box in this origination.
        foreach $item_info (@ship_list) {
            my ( $length, $width, $height, $girth ) = q{};
            (
                $item_qty,      $item_wt,   $box_total_value, $alt_origin,
                $alt_stateprov, $length,    $width,           $height,
                $girth,         $myBoxType, $junk
            ) = split( /\*/, $item_info, 11 );

         # changed by Mister Ed Dec 17, 2006 to allow for First Class and ounces
            ( $pounds, $ounces ) = split( /\./, $item_wt );
            $ounces = ( '.' . $ounces ) * 16;

            #Taint mode stuff ...
            $ounces = $ounces + 0.9999999999;    # round her up!
            $ounces =~ /(\w+)/;
            $ounces = $1;
            $pounds = $pounds + 0.9999999999;    # round her up!
            $pounds =~ /(\w+)/;
            $pounds = $1;

            if ( $ounces eq 16 ) {
                $pounds++;
                $ounces = '0';
            }

            if ( ( $product =~ /First Class/i ) && ( $product !~ /Class Package International/i)
                && ( ( ( $destcountry !~ /united states/i ) && ( $destcountry !~ /puerto rico/i ) )
                     || ( ( $pounds > 0 ) || ( $ounces > 13 ) ) )
               )
            {
                $err_printed               = 'yes';
                $order_error_do_not_finish = 'yes';
                print
"USPS shipping error: $agora_shiplib_message17 $pounds $agora_shiplib_message18 $ounces $agora_shiplib_message19",
                  "$agora_shiplib_message20<br><br>$err<br>\n";
                $ship_cost = 0;
                return $ship_cost;
            }

            # alt origination assignment fer the box
            if ( ( $alt_origin ) && ( $sc_alt_origin_enabled =~ /yes/i ) )
            {
                $origin_passby = $alt_origin;
            }
            else {
                $origin_passby = $sc_USPS_Origin_ZIP;
            }

            #Taint mode stuff ...
            $origin_passby =~ /(\w+)/;
            $origin_passby = $1;

            #### Container logic ####
            my $container = "$myBoxType";
            my $containersize = 'REGULAR';
            my $USPS_machineable = 'False';
            my $package_services_string = q{};
            my $package_value_string = q{};

            if ( $length eq '' ) { $length = $sc_USPS_avg_package_length; }
            if ( $width  eq '' ) { $width  = $sc_USPS_avg_package_width; }
            if ( $height eq '' ) { $height = $sc_USPS_avg_package_height; }
            if ( $girth  eq '' ) { $girth  = $sc_USPS_avg_package_girth; }
            if ( $girth  eq '' ) { $girth  = ( $length + ( 2 * $height ) + ( 2 * $width ) ); }

            my $package_dimensions_string = '';
            if ( $height && $width && $length ) {
                $package_dimensions_string = qq|<Width>$width</Width><Length>$length</Length><Height>$height</Height>|;
                if ( $girth ) {
                    $package_dimensions_string .= qq|<Girth>$girth</Girth>|;
                }
            }


            if (   ( $destcountry eq '' )
                || ( $destcountry =~ /united states/i )
                || ( $destcountry =~ /puerto/i ) )
            {    # USA and PR
                if ( ( $USPS_insure_shipments eq 'yes' ) || ( $USPS_signature_confirmation eq 'yes' ) ) {
                    $package_services_string = "<Value>$box_total_value</Value><SpecialServices>";
                    if ( $USPS_insure_shipments eq 'yes' ) {
                        $package_services_string .= '<SpecialService>100</SpecialService>';
                    }

                    if ( ( $USPS_signature_confirmation eq 'yes' ) && ( $product !~ /Express/i ) ) {
                        $package_services_string .= '<SpecialService>108</SpecialService>';
                    }

                    $package_services_string .= '</SpecialServices>';
                }
            }
            else {
                $package_value_string = "<ValueOfContents>$box_total_value</ValueOfContents>";
                if ( ( $USPS_insure_shipments eq 'yes' ) || ( $USPS_signature_confirmation eq 'yes' ) || ( $USPS_delivery_confirmation eq 'yes' ) ) {
                    $package_services_string = '<ExtraServices>';
                    if ( $USPS_insure_shipments eq 'yes' ) {
                        $package_services_string .= '<ExtraService>1</ExtraService>';
                    }

                    if ( ( $USPS_delivery_confirmation eq 'yes' ) || ( $USPS_signature_confirmation eq 'yes' ) ) {
                        $package_services_string .= '<ExtraService>2</ExtraService>';
                    }

                    $package_services_string .= '</ExtraServices>';
                }
            }

            if ( ( $USPS_PackageType !~ /flat rate/i )
                && ( ( $myBoxType eq '' ) || ( $myBoxType !~ /flat rate/i ) ) )
            {

                if ( $myBoxType eq '' ) {
                    $container = "$USPS_PackageType";
                }

                if ( ( ( $length > 12 ) || ( $width > 12 ) || ( $height > 12 ) ) && ( ( $container eq 'NONRECTANGULAR' ) || ( $container eq 'RECTANGULAR' ) ) ) {
                    $containersize = 'LARGE';

                }
                elsif ( ( $length < 12.01 ) && ( $width < 12.01 ) && ( $height < 12.01 ) && ( $container eq 'RECTANGULAR' ) && ( $productindicator eq 'PRIORITY' || $productindicator eq 'EXPRESS' ) ) {
                    $container = 'VARIABLE';

                }

                # Max size (and/or weight) of package screening
                if ( ( ( $product =~ /Express Mail/i ) && ( $girth > 108 ) )
                    || ( ( $product =~ /Express Mail International/i ) && ( ( $girth > 79 ) || ( $length > 36 ) ) )
                  )
                {
                    $err_printed               = 'yes';
                    $order_error_do_not_finish = 'yes';
                    print qq|<p>USPS shipping error: $agora_shiplib_message21</p><p>$err</p>\n|;
                    $ship_cost = 0;
                    return $ship_cost;
                }
                if ( ( ( $product =~ /Priority Mail/i ) && ( $girth > 130 ) )
                    || (  ( $product =~ /Priority Mail International/i )
                        && ( ( $girth > 108 ) || ( $length > 60 ) )
                        && ( $product !~ /flat rate/i ) )
                    || ( ( ( $product =~ /Global Express/i ) && ( $girth > 108 ) )
                        || ( ( $length > 46 ) && ( $width > 35 ) && ( $height > 46 ) ) )
                  )
                {
                    $err_printed               = 'yes';
                    $order_error_do_not_finish = 'yes';
                    print qq|<p>$agora_shiplib_message22</p><p>$err</p>\n|;
                    $ship_cost = 0;
                    return $ship_cost;
                }
                if ( ( $girth > 84 ) && ( $girth < 130.001 ) ) {
                    if ( ( $pounds + $ounces ) < 15 ) {
                        $pounds = '15', $ounces = q{};
                    }
                }
                my $temp_whd = $length + $width + $height;
                if ( ( $product =~ /Class Package International/i) && ( ( $temp_whd > 36 ) || ( $pounds > 4 ) ) ) {
                    $err_printed   = 'yes';
                    $order_error_do_not_finish = 'yes';
                    print "<p>USPS shipping error: $agora_shiplib_message17a</p><p>$agora_shiplib_message20</p>\n";
                    $ship_cost = 0;
                    return $ship_cost;
                }


            }    #end of "if not USPS flat rate container" conditional

            # auto detect flat rate box size
            #added by Mister Ed of AgoraCart - January 15, 2011
            elsif (  ( $USPS_PackageType =~ /flat rate/i )
                && ( ( $myBoxType eq '' ) || ( $myBoxType =~ /flat rate/i ) ) )
            {
                $container = "$USPS_PackageType";

                if ( ( $length ) && ( $width ) && ( $height ) )
                {
                    # small box
                    if ( ( $length <= 8.63 )
                      && ( $width <= 5.38 )
                      && ( $height <= 1.63 ) )
                    {
                        $container = 'SM FLAT RATE BOX';
                    }
                    # medium box
                    elsif ( ( ( $length <= 11 )
                      && ( $width <= 8.5 )
                      && ( $height <= 5.5 ) )
                      || ( ( $length <= 13.63 )
                      && ( $width <= 11.88 )
                      && ( $height <= 3.38 ) ) )
                    {
                        $container = 'MD FLAT RATE BOX';
                    }

                    # large box
                    elsif (  #( $pounds < 35 ) &&
                      ( $length <= 12 )
                      && ( $width <= 12 )
                      && ( $height <= 5.5 ) )
                    {
                        $container = 'LG FLAT RATE BOX';
                    }

                } # end of if dimensions are filled in
            } #end of "if USPS flat rate container" conditional
            #### End of Container logic ####

            # create each package for XML string
            if (   ( $destcountry eq '' )
                || ( $destcountry =~ /united states/i )
                || ( $destcountry =~ /puerto/i ) )
            {    # USA and PR
                $workString .= "<Package ID=\"$packageID\">";
                $workString .= "<Service>$productindicator</Service>";
                if ( $product =~ /First Class/i ) {
                    $workString .= "<FirstClassMailType>PARCEL</FirstClassMailType>";
                }
                $workString .=
                  "<ZipOrigination>$origin_passby</ZipOrigination>";
                $workString .= "<ZipDestination>$dest</ZipDestination>";
                $workString .= "<Pounds>$pounds</Pounds>";
                $workString .= "<Ounces>$ounces</Ounces>";
                $workString .= "<Container>$container</Container>";
                $workString .= "<Size>$containersize</Size>";
                $workString .= "$package_dimensions_string";
                $workString .= "$package_services_string";
                $workString .=
                  "<Machinable>$USPS_machineable</Machinable></Package>";
            }
            else {    # international string
                $workString .= "<Package ID=\"$packageID\">";
                $workString .= "<Pounds>$pounds</Pounds>";
                $workString .= "<Ounces>$ounces</Ounces>";
                $workString .= '<MailType>Package</MailType><GXG><POBoxFlag>N</POBoxFlag><GiftFlag>Y</GiftFlag></GXG>';
                $workString .= "$package_value_string";
                $workString .= "<Country>$destcountry</Country>";
                $workString .= "<Container>$container</Container>";
                $workString .= "<Size>$containersize</Size>";
                $workString .= "$package_dimensions_string";
                $workString .= "$package_services_string";
                if ( $destcountry =~ /canada/i ) {
                    $workString .= "<OriginZip>$origin_passby</OriginZip>";
                }
                $workString .= '</Package>';
            }

            $packageID++;

        }    # end of each box

        if (   ( $destcountry eq '' )
            || ( $destcountry =~ /united states/i )
            || ( $destcountry =~ /puerto/i ) )
        {    # USA and PR
            $workString .= '</RateV4Request>';
        }
        else {    # international string
            $workString .= '</IntlRateV2Request>';
        }

        $doworkString = "$usps_prot$usps_site$usps_cgi\?${workString}";

        if ( $sc_use_socket =~ /lwp/i ) {    # use LWP library POST
             # By calling this way, no error generated if library is missing
             # when the library is first loaded up or at runtime of this routine

            $answer = eval("use LWP::UserAgent;");
            if ( $@ eq '' ) {
                #$answer = LWP_post($doworkString);

                #my $contents;
                use LWP::UserAgent;
                my $ua = new LWP::UserAgent;
                $ua->agent( 'AgoraCart/Route66 ' . $ua->agent );    # Create request
                my $req = new HTTP::Request POST => "$doworkString";
                $req->content_type('application/xml');
                $req->content($work_string);

                # Send request to user agent, get response
                my $res  = $ua->request($req);                  # Check response
                my $code = $res->code;
                $answer = $res->content;

            }
            else {
                print "<br><left>$@</left><br>\n";
                $answer = q{};
            }
        }

        $answer =~ s/\&amp;lt;sup\&amp;gt;&amp;amp;reg;&amp;lt;\/sup\&amp;gt;//ig;
        $answer =~ s/\&amp;lt;sup\&amp;gt;&amp;amp;trade;&amp;lt;\/sup\&amp;gt;//ig;
        $answer =~ s/\&lt;sup\&gt;\&amp;trade;\&lt;\/sup\&gt;//ig;

        # incase we need to call sumtin after XML data received
        codehook( 'USPS_XML_data_dump' );

        # For now used old method to get rate from XML
        $orig_ans = $answer;

        if (   ( $destcountry eq '' )
            || ( $destcountry =~ /united states/i )
            || ( $destcountry =~ /puerto/i )
            || ( $destcountry =~ /^us$/i )
            || ( $destcountry =~ /^pr$/i )
          )
        {    # USA and PR
            while ( $answer =~ /<Rate>/ig ) {
                ( $junk,        $answer ) = split( /<Rate>/i,   $answer, 2 );
                ( $splitanswer, $answer ) = split( /<\/Rate>/i, $answer, 2 );
                $item_cost += $splitanswer;

                if ($answer =~ /Express Mail/) {
                    if ( $USPS_insure_shipments eq 'yes' ) {
                        ( $junk, $splitanswer ) = split( /Insurance/i, $answer, 2 );
                        ( $junk, $splitanswer ) = split( /<Price>/i, $splitanswer, 2 );
                        ( $splitanswer, $answer ) = split( /<\/Price>/i, $splitanswer, 2 );
                        $item_cost += $splitanswer;
                    }

                    if ( ( $USPS_signature_confirmation eq 'yes' ) || ( $USPS_delivery_confirmation eq 'yes' ) ) {
                        ( $junk, $splitanswer ) = split( /Return Receipt/i, $answer, 2 );
                        ( $junk, $splitanswer ) = split( /<Price>/i, $splitanswer, 2 );
                        ( $splitanswer, $answer ) = split( /<\/Price>/i, $splitanswer, 2 );
                        $item_cost += $splitanswer;
                    }
                }
                else {
                    # add Certificate of Mailing
                    if ( ( $USPS_delivery_confirmation eq 'yes' ) && ( $answer =~ /Certificate of Mailing/i ) ) {
                        ( $junk, $splitanswer ) = split( /Certificate of Mailing/i, $answer, 2 );
                        ( $junk, $splitanswer ) = split( /<Price>/i, $splitanswer, 2 );
                        ( $splitanswer, $answer ) = split( /<\/Price>/i, $splitanswer, 2 );
                        $item_cost += $splitanswer;
                    }
                    # add Insurance
                    if ( ( $USPS_insure_shipments eq 'yes' ) && ( $answer =~ /Insurance/i ) ) {
                        ( $junk, $splitanswer ) = split( /Insurance/i, $answer, 2 );
                        ( $junk, $splitanswer ) = split( /<Price>/i, $splitanswer, 2 );
                        ( $splitanswer, $answer ) = split( /<\/Price>/i, $splitanswer, 2 );
                        $item_cost += $splitanswer;
                    }
                    # add Delivery Confirmation
                    if ( ( $USPS_delivery_confirmation eq 'yes' ) && ( $answer =~ /Delivery Confirmation/i ) ) {
                        ( $junk, $splitanswer ) = split( /Delivery Confirmation/, $answer, 2 );
                        ( $junk, $splitanswer ) = split( /<Price>/i, $splitanswer, 2 );
                        ( $splitanswer, $answer ) = split( /<\/Price>/i, $splitanswer, 2 );
                        $item_cost += $splitanswer;
                    }
                    # add Signature Confirmation
                    if ( ( $USPS_signature_confirmation eq 'yes' )  && ( $answer =~ /Signature Confirmation/i ) ) {
                        ( $junk, $splitanswer ) = split( /Signature Confirmation/, $answer, 2 );
                        ( $junk, $splitanswer ) = split( /<Price>/i, $splitanswer, 2 );
                        ( $splitanswer, $answer ) = split( /<\/Price>/i, $splitanswer, 2 );
                        $item_cost += $splitanswer;
                    }
                }
            }
        } # USA / PR
        else {    # international string
            ( $splitanswer, $answer ) = split( /<\/AreasServed>/i, $answer, 2 );
            while ( $answer =~ /<Service/ig ) {
                ( $splitanswer, $answer ) = split( /<\/Service>/i, $answer, 2 );

                if (   ( $splitanswer =~ /$product/i )
                    && ( $splitanswer !~ /flat rate/i )
                   )
                {
                    ( $junk, $splitanswer ) =
                      split( /<Postage>/i, $splitanswer, 2 );
                    ( $splitanswer, $junk ) =
                      split( /<\/Postage>/i, $splitanswer, 2 );

                    $item_cost += $splitanswer;

                    if ( ( $USPS_insure_shipments eq 'yes' )  && ( $answer =~ /Insurance/i ) ) {
                        ( $junk, $splitanswer ) = split( /Insurance/i, $junk, 2 );
                        ( $junk, $splitanswer ) = split( /<Price>/i, $splitanswer, 2 );
                        $item_cost += $splitanswer;
                    }

                    if ( ( $product =~ /Priority Mail International/i ) && ( ( $USPS_signature_confirmation eq 'yes' ) || ( $USPS_delivery_confirmation eq 'yes' ) ) ) {
                        ( $junk, $splitanswer ) = split( /Certificate of Mailing/i, $junk, 2 );
                        ( $junk, $splitanswer ) = split( /<Price>/i, $splitanswer, 2 );
                        ( $splitanswer, $answer ) = split( /<\/Price>/i, $splitanswer, 2 );
                        $item_cost += $splitanswer;
                    }
                    else {
                        if ( $USPS_signature_confirmation eq 'yes' )  {
                            $item_cost += 1.42;
                         }
                        if ($USPS_delivery_confirmation eq 'yes' )  {
                            $item_cost += 2.51;
                        }
                    }

                }
                elsif ( ( $splitanswer =~ /$product/i )
                    && ( $product     =~ /flat rate/i )
                    && ( $splitanswer =~ /flat rate/i )
                    && ( $splitanswer !~ /envelope/i ) )
                {
                    ( $junk, $splitanswer ) =
                      split( /<Postage>/i, $splitanswer, 2 );
                    ( $splitanswer, $answer ) =
                      split( /<\/Postage>/i, $splitanswer, 2 );

                    $item_cost += $splitanswer;
                }
            }
        }

        if ( $answer eq '' ) {
            $error = $orig_ans;
        }

        if ( $item_cost == 0 && $err_printed eq '' ) {
            $err_printed               = 'yes';
            $order_error_do_not_finish = 'yes';
            print
              "USPS module error: $agora_shiplib_message23<br><br>$err<br>\n";
        }
        $ship_cost += $item_cost;
        $item_cost = 0;
    }    # end of each origination

    # incase we need to call sumtin before final cost returned
    codehook( 'UPS_USPS_cost_return' );

    return $ship_cost;
}

#########################################################################

1;
