################################################################################
##  General TODO
################################################################################

    * Remove t/manual/test-data... what is it?

    * Add multiple source zips to the testing for offline ups: e.g. 33124

    * Use Pod::Readme
    
    * Use Test::Spelling
    
    * UPS_Offline: Zone finder doesn't get correct zone record for 97015 zip.
    
    * UPS_Offline: In the tests, check to see if support for UPS_Online has been
      disabled.  If so, don't run tests that use it.  (Then again, for most 
      users, those tests wont be run anyway because they haven't setup the 
      credentials).

    * UPS_Offline: add a "adder_margin" to hundredweight shipments.  
      Increases the price by x% percent (10% default) as a safety against the
      very low default rates.

    * Checkout CPAN tests.  It appears that t/16 is failing because it lacks a
      plan.

    * [P1] [Enh] Build a replacement for ClassInfo and ClassAttribs that will be
      more simple, efficient, and portable.  Should work for static or dynamic 
      generation of Required, Optional, Unique, and other metadata.
      - Should solve installation problem for environments that fail when 
        'requiring' a module that doesn't exist.  (As reported by
        Micah Gersten <micah@davka.com>).
      - Simple solution: just add Required(), Optional(), Unique() to the 
        RateRequest classes with calls to SUPER?
      - Can remove dependancy on Scalar::Util after this is complete (since
        we'll no longer need the 'blessed' function).
	
    * Remove old versions from CPAN (up to 1.06) to ease the requirements of 
      mirrors.  Backpan will still carry the old versions.
      
    * UPS_Offline: Extended Area Surcharges: International and Domestic

    * Makefile.PL: Automatically determine if the user has write permissions
      for /usr/local.  If so, default to that directory.  Otherwise, default
      to something in the home directory, and if that isn't accessible, default
      to the parent directory (ugh).
    
    * Look for a way to move MANIFEST and Meta.yml to doc/ or etc/ so that the
      root directory can be less cluttered.

    * DataTools: Remove the data from the "unknown" section since it is unused.
    
    * Remove files that we don't use from the DataFiles distribution

    * DataTools: wweas.csv has two difficult characters:
      - Causes CSV module to "fail" on those lines.
      grep 'Colombia,,COV' data/*.csv
      grep 'Colombia,,SAL' data/*.csv
    
    * DataTools: Excel documents
      The following files are actually MS Excel documents.  Put a note in 
      the docs somewhere that specifies they must be manually converted.
      
      akz_48.csv akz_air.csv hiz_48pr.csv hiz_ak.csv hiz_hi.csv
      
    * Interchange Usertag: Store rate_request objects of like types between
      requests.  So that, for example, two requests that are run from the same
      Prefork'ed daemon will not have to load the Storable objects seperately.
    
    * UPS_Offline: Don't convert letter to 0, because letter means it is
      enclosed in an envelope which may actually weigh more (for WW express, not
      sure about other methods).
      
    * UPS_Offline: canstnd doesn't convert exactly right.
      (500+, and the many 'Min' sections).
      
    * UPS_Offline: residential surcharge
      - Is the 1.75 surcharge added per-shipment or per-package?  I think it may 
        be per-package, but is currently calculated per-shipment.

    * Catch up on POD coverage.
    
    * Support multiple packages for remaining shippers
      - UPS Online (Intl and Domestic)
      - USPS Online (Intl and Domestic)
      - For shippers that don't support multiple packages (USPS Intl), 
        automatically convert multiple packages into multiple shipments, if
        possible.

    * Set default maximum weights per shipper and service:
      - USPS:
        Express, Priority, Parcel Post, Media Mail, Library Mail, All: 70 lbs
        First Class: 13 oz
        Bound Printed Matter: 15 lbs
      - UPS:
        150 lbs for all service types and countries. (Actually, most countries
        allow 70 kg, which is 154.32 lbs.)
	
    * Tests for recently-added functionality
    
    * Get UPS_Offline down to as few required modules as possible, then make 
      that the standard required modules list.  The modules for the online 
      shippers are for in the "optional" section.
    
    * Don't load the modules until they are needed.  If the Cache::FileCache is
      being used on a given query, then XML::DOM, etc. aren't needed.  However,
      the preload option still needs to load XML::DOM and friends.

    * Remove UPS_Online from the CPAN distro
      - Some kind of option in 'make tardist'?
      - Add a note to the documentation about how it's gone as of x version, 
        and why.
      - Or, just "disable" the code so that users cannot use it.

    * [P1] [Enh] Country Support
      - Determine which origin countries do UPS_Online and UPS_Offline support?
      - Update documentation and code.
    
    * Implement USPS_Offline
        
    * [P3] [Enh] Enhance the CPAN distro
      - Test::Distribution - Various tests
      - Test::Signature - makes sure your SIGNATURE file is cryptographically valid.
      - Module::Signature

    * [P3] [Enh] Devel::Cover

    * [Enh] Switch to Config::General or Config::Scoped
      - Use a more advanced configuration system, with more config-file
        flexibility.
    
    * [Enh] Evaluate OODoc

    * [Enh] Look into Params::Validate and/or Class::Contract
 
    * [Enh] Add Test::Inline tests

    * [Enh] Consider using Locale::Country (5.8.x+) & Locale::SubCountry (CPAN),
      or Geography::States & Geography::Countries.

    * Module::Build
      - use create_makefile_pl => 'traditional' (because of this post:)
      - http://perlmonks.org/?node_id=458282

    * Bundle::Business::Shipping requires DataFiles, but DataFiles requires 
      Business::Shipping during installation... so it recurses.  
      - Just let it pick the directory instead of requiring Business::Shipping,
        because it seems that requiring the module is enough to send CPAN off 
        looking.

    * [P3] Build a test that will state with modules are missing at the 
      beginning, then the rest of the tests can be quiet.

    * [P3] [Enh] Remove requirement for Cache::FileCache
      - If users do not specify their cache preference, check if the module 
        exists and try to do the cache.
      - If the user specifies to not use the cache, do not check for the module.
      - Make it optional for the Tracking modules too
      - Add an "optional modules" section to the installation documentation
  
    * [Bug] Bundle::Business::Shipping::*
      - It tries to build and install Business::Shipping before anything else,
        when that should be the last module that it installs.  If CPAN is set 
        to install modules that are listed in the makefile, then it will proceed
        correctly, but is there some way to specify the order so it doesn't have
        to?
        
    * [Bug] On a clean 5.8.5, trying to install 
      Bundle::Business::Shipping::UPS_Offlineresults in:
        - tests that try to load Cache::FileCache:
          10
          21
          22
        t/10_init    tries to load Cache::FileCache (un-necessary for UPS_Offline).
        t/21_preload tries to load Cache::FileCache.
        (because of Business::Shipping::Tracking, perhaps?)
     
    * [Enh] Move main documentation into 'Business::Shipping::Manual'?
    
    * [Enh] Allow a "Company" name to be placed in the results.  So that some of
      the results can have the company field.  That way, user code can display
      the company name in the results.  For example, "UPS" instead of 
      "UPS_Online".

    * [Enh] Instead of returning a results hash, allow the user to request a results
      object.  It could overcome the inelegance of dereferencing the AOH.
      
    * [Enh] Logging enhancement: allow printf() style message passing arguments
      (%s) so that if a value is undefined, there will not be an error.
    
    * Check the ppm.activestate.com Build Status and see if the errors can be
      corrected for other platforms.
    
    * [Enh] Test on Sourceforge Compile Farm systems.
      - Also test using older perl versions (e.g. 5.6.x).
 
    * [Enh] Auto-generate a todo-list addendum from the "# TODO:" comments 
      strewn throughout the source code.

    * [Enh] Profile the application
      - How long does it take to load the required modules?
      - What are the slowest parts of the system?
      - Memory usage:
        +6.5 MB at the time of "use Business::Shipping::UPS_Offline::RateRequest"
        +1.5 MB at the time of submit() for an UPS_Offline::RateRequest. 
    
    * [Enh] Unit tests for each class.
      - Preferably stored in the .pm with the class.
      
    * Make the configuration file optional for *_Online shipping classes.
      - But still have new, additional configuration parameters, e.g.:
        + How long to wait for a response (sometimes 30 seconds is too long)
        + How long between retries
        + How many retries
      - Have a configuration object ($Business::Shipping::Cfg) that starts out
        with default values (stored in Config.pm), but can be overridden by 
	    installing the Config::Ini module, and then using config/*.ini files. 
	    However, if the Config::Ini module is not installed, then everything 
	    will still work via the defaults.  (Offline modules have too much 
	    configuration data to work without a configuration module).
  
    * [Enh] Conform to coding style: private methods should be prefixed with an
      underscore. 
 
    * [Enh] Handle alternate units (kilograms, etc.).

    * [Enh] KLogging: Allow error format to be specified 
      - With/without caller
      - With/withoutline numbers.

    * [Enh] Is non-ssl communication with either online provider possible?
 
* [Enh] Business::Shipping::UPS_Legacy (or UPS_WebForm)
    - Doesn't require signup (no username/password, etc.)
    - Wrapper for Business::UPS 2.0.
 
* [Enh] New feature ideas:
 	- Address Verification
	- Service Availability
	- Electronic Merchandise Return?
	- Shipping label generation?
	- Customs forms?
	- Shipping time (how long till it gets there)?
	- Delivery/Signature confirmation?

* [P5] [Enh] Allow the user to enable one shipper as a secondary shipper, if the 
  first should fail.  For example, if the UPS/USPS servers are down, it will
  automatically utilize the table-lookup method.
   
* [Enh] OO Design: move Shipment-only methods out of RateRequest package.
  Many of the functions that are currently in 
  Shipping::RateRequest::UPS_Offline should probably be moved somewhere else.
  They work on one shipment at a time, and having them in the RateRequest 
  object makes it seem like they should be able to work on multiple shipments
  at once.
 
* [Enh] Auto-update version
  Find or create some module that will automatically update the "=head1 
  VERSION" POD based on the CVS "Revision" keyword or the perl $VERSION 
  variable in the same file.
  
* [Doc] Need to create a list of common errors that will be encountered.
 
* [Enh] Setup proper "announce", "commits", and "discussion" mailing lists 
  where users can sign up for updates and get information.
 
* [Enh] Test for thread-safety-ness.

* [Enh] Add support back in for multi-package API.

* [Enh] Put all the currently supported modules in the config.ini file, to make
  them easier to add. 
  
* [Enh] Have an API for "give me all shipping options and prices for this 
  source, destination, and weight".
  
	use Business::Shipping;
	
	my $rate_request = Business::Shipping->rate_request(
		shipper 	=> 'All',
		to_zip 		=> '...',
		from_zip	=> '...',
	);
	
	my $results = $rate_request->go() or die $rate_requet->error();
	
	foreach my $shipper ( $@results ) {
		print "Shipper Name: $shipper->{name}\n";
		
		foreach my $service ( $shipper->{ 'services' } ) {
			print "  Service: $service->{name}\n";
			print "  Price:   $service->{total_charges}\n";
		}
	}
 
    * [Doc] Documentation Ehancements:
      - Look into OODoc or Pod::Tree
      - Try generating HTML using CPAN style:
        "generated by TUCS::Pod2HTML v, using Pod::Simple::PullParser v2.02"
      - Pod::HtmlEasy?
        
    * [Enh] Log4Perl enhancement
      - Remove "Business::Shipping" from the first part of logging output.
      - Perhaps via Log::Log4perl::NDC->pop() ?
      - Perhaps via a Filter object?
      
################################################################################
##  USPS_Offline TODO
################################################################################
 
    * [Enh] Add First-Class Mail
      - http://www.usps.com/consumers/domestic.htm#first
      - Can be done via an off-line calculation.

################################################################################
##  USPS_Online TODO
################################################################################
    
    * [Enh] New 'All' domestic service type returns all rates with one call.
      - See new docs

    * [Bug] USPS_Online EMS bug reported by Micah Gersten <micah@davka.com>
      > It is using the 'Economy (Surface) Parcel Post' rate instead of 'Global 
      > Express Mail (EMS)'.

      The bug is somewhere near this:

      File: lib/Business/Shipping/RateRequest/Online/USPS.pm
      Line: 300

   * [Bug] Find a better way to correlate "Air mail" with all the various names
     it is called by each country.
 
   * [Bug] Not correctly realizing when there is an error (<Error><Number>...)
     - Perhaps because we don't ( KeepRoot => 1, ) on the XMLin()?

   * [Enh] Enable Cache for USPS.
  
   * [Enh] Support get_charges( 'service' ) for domestic types.

   * [Enh] Use the International Country Listing
     - http://pe.usps.gov/cpim/ftp/manuals/Imm/Immctry.pdf
     
   * [Enh] USPS_Online::Shipment: Move the country translator data into config. 

   * [Known Bug] USPS_Online and no internet connection.
     - You will get the following error if there is no connection to the net 
       when using USPS_Online:
       + Business::Shipping::USPS_Online::RateRequest::_handle_response: ()
         File does not exist:  at .../USPS_Online/RateRequest.pm ...
	 
   * [Enh] Printable labels
   
   * Change USPS error from 'charges are 0, error out' to something better.

   * Andy Grundman <andy@hybridized.org> [2005-04-25 16:54]:
    > Here are a couple of other things I thought of:
    > 
    > USPS international weight calculations are rounded up to 1 pound even 
    > though it supports ounces.
    > 
    > I think you could add First Class support without any additional code if 
    > you fixed the rounding up to 1 pound.  I think you should maybe never 
    > round up to 1 pound, and always just pass the exact pounds/ounces the 
    > user supplies.  Or you could round up if service is not First Class or 
    > International.
    > 
    > I commented out the line $in_weight = 1.00; in USPS_Online::Package line 
    > 113 and it seems to take care of both above issues.
   
################################################################################
##  UPS_Offline TODO
################################################################################
    * Implement the following logic:
    
	- For UPS GND and 3DS, to determine the rate for multi-pacakge shipments weight 
	  200 pounds or more, refer to UPS Hundredweight Service
	
	- For 1DA and 2da with multi-package shipments weighing over 100 lbs total: 
	  use ups hundredweight service.
	
	- Hundredweight service is for shipments that are less than 1000 totla.
	- (Some hundred weight shipments will actually be cheaper when estimated at
	  500 pounds since it uses a rate, so check that if it's close).
	  
	- 1da early am not available for hundredweight.
	
	- DAS (delivery area) nor residential surcharges apply.
	
	- minimum charge for 1da and 2da is based on an average weight of 10
	  lbs/package.  minimums also apply for certain zone (see page 60)

    * [Bug] New 'Ground Residential' service name doesn't work for UPS_Offline:
      Error: Zone 'u' lookup failed, type 'Ground Residential' not found

    * Error: No zone found for geo code (key) South Africa, type ExpeditedSM_WC.
    


    * UPS_Offline fuel surcharge enhancement:
      - If the current date is less or equal to the "through" date, use that.
      - If the current date is greater than or equal to the effective date, use that.
      - Key: if the current date is more than 28 days greater than the effective date,
        get new data from the website.  (This should result in queries only being
        sent once a month.)  (If new data can't be found, use the old data)

    * [Enh] Generate advanced table representations from source material
      - Convert the files that are recieved from shippers into a format that 
        provides a faster lookup mechanism, such as SQLLite, Storable, etc.
      - The converted version of the files will be the ones that are distributed
        with Business::Shipping::Data.
      - (This would work well for the zone files, but I'm not sure about the
         rate files.)
    
    * [Enh] Allow customization of memory usage / execution speed 
      -  "optimize for smaller memory footprint, slower execution speed"
      -  "optimize for faster execution speed, larger memory footprint"
      -  If it is optimized for memory footprint, then it will read the 
         representation off the disk, (getting a benefit from OS filesystem 
	 cache, probably), then run the calculation, then delete the in-memory
	 representation (which perl may or may not free immediately).
  
      -  If optimized for speed, then it will read the representation off the 
	 disk and keep it in memory.

 * [Bug] Serbia: see t/manual/offline_ups_intl_other.pl

 * [Enh] http://perlmonks.org/index.pl?node_id=366587

 * [Enh] Add charges based on pickup type.  
   An alternate set of data is available for people who don't have an account 
   with UPS.  Is the only difference a $4.00 surcharge?

 * [Enh] From Canada to Alaska (and other destinations)
                99663 = Seldovia, Alaska
		my $rate_request = Business::Shipping->rate_request(
                       shipper         => 'Online::UPS',
                       from_canada     => 'CA',
                       from_country    => 'CA',
                       from_zip        => 'v6h3y8',
                       to_country      => 'US',
                       to_zip          => '99663',
                       weight          =>  5.00,
                       user_id         => 'userid',
                       password        => 'pass',
                       service         => 'XPD',
                       access_key       => 'XXXXXX',
               );
				
 * [Enh] Performance enhancement: instead of transforming the data with
   calc_zone_data() everytime, just re-write the data file.
 
 * [Enh] Allow user to specify "use default" or "quiet" for Makefile.PL, which 
   will cause it to use defaults.
 
 * [Enh] Change from_state to a Shipment function, which will calculate and set 
   the is_from_west_coast() value, instead of doing from within 
   massage_values().

 * [Enh] Add a simple example script in the bin directory.

 * [Enh] How to find the current fuel surcharge rate:
   - http://www.ups.com/content/us/en/resources/find/cost/fuel_surcharge.html	
   - m/Effective.+: ?(\d\.\d\d\)%/
   
 * [Enh] Modify the system so that the easy-to-read data is read into memory
         just once, and then is optimized for lookup speed, so the sequential
         lookups will be as fast as possible.  (Increases memory footprint, but
         it should be worth it).
 
 * [Enh] Canada needs to check for EAS surcharge (see canww.csv->'EAS' column)
 
 * [Enh] Add test for the support files directory.  (Just warn, because they 
         may be running the test as a non-priveledged user).
 
 * [Enh] Re-write the calc_zone_data() and calc_cost() routines.

 * [Enh] New table design?

        zone table:
		
 	zone_from_exactly	zone_from_lt	zone_from_gt	zip_to_exactly
	zip_to_lt	zip_to_gt	service
	
        weight table:
	
        weight	zone	amt

 * [Enh] Add tests for Alaska, Hawaii, Canada, and International.
         Add tests for 1DAP.

 * [Enh] Look at the zone file comments to determine which zone file to use.
   (i.e. 970.csv has "970-01 to 972-99" -- means it actually does 972.csv too).
 
 * [Enh] Utilize GDBM or SQL, if available, to speed up lookups.

   * Louie Martinez <louie@kopykake.com> - Check for additional surcharges
    > I was wondering if anyone has tackled these additional surcharges with interchange. Right now I have
    > been adding (@@TOTAL@@ * .025) in the additional shipping calculation to cover the ground surcharge
    > and (@@TOTAL@@ * .095) to handle air and international surcharges, but there is also an extended
    > area surcharge overseas and in Canada which is basically another fuel charge once your package gets
    > into that country based on if your package is going to a major city or if it's headed to some small
    > town out in the middle of nowhere. I can't just charge everyone the surcharge because it sometimes
    > adds up to an additional $20 to the shipping price depending on where it's being sent. In major
    > cities there isn't a surcharge. So has anyone tackled this problem yet or will we be stuck with the
    > daunting task of creating zone lookup charts for each country with the shipping to reflect the
    > extended area surcharges.

   * zone_file and zone_name don't really need to be stored in the RateRequest
     object, do they?

   * UPS_Offline: Very low priority: Compile data files during installation 
      - During installation of Business::Shipping::DataFiles, read the Storable
        objects and compile them into platform-specific (i.e. faster) versions.
	
    * UPS_Offline: Add more sophisticated dimensional weight handling
      - All each package to have a "demensions" parameter, so that the various
        dimensional weights can be automatically calculated (it is different 
	for air than it is for ground).  How can this be done if the only 
	parameter sent to BSHIPPING is weight, and half of the items (in one 
	package) might be dimensional, and the other half not?

################################################################################
##  UPS_Online TODO
################################################################################
 
    * [Bug] Return error message if trying to ship to military americas:
      - USP does not ship to APO or FPO addresses.
   
    * [Bug] Be able to handle "mal-formed XML doc" error return from UPS.  
      - Right now, it still tries to parse as an XML doc.

    * [Enh] Allow user-friendly names, like "One Day Air" instead of 1DA.
      - Names for packaging instead of numbers.
 
    * [Enh] UPS support for sending multiple simultaneous requests
      - (USPS had built-in support in the API for Intl)
      - If they don't support it, try LWP::Parallel::UserAgent.
      - Selena Brewington: better yet, use "Rate Shopping"
 
    * [Enh] Implement a multi-package API for UPS.   
      Move to a different XML generation scheme, since all the packages 
      in a multi-package shipment currently have the name "Package".
   
    * [Enh] Business::Shipping::UPS_XML
      - Add to documentation as an alternative to Business::Shipping
      - Maybe utilize the Parser code?

    * [Enh] Ed LaFrance UPS usertag
      - Maybe utilize Ed's Parser code?
	
################################################################################
##  Interchange UserTag TODO
################################################################################

    * [Enh] Test for ability to use within Safe?

    * Option to disable errors that aren't important

    * [business-shipping] Error: No zone found for geo code (key) Qatar, 
      type ExpeditedSM_WC.

    * Allow the business-shipping usertag to set the current debug level via 
      $Variable->{ BS_DEBUG }
      
    * Rename the variables from BS to BSHIPPING.

################################################################################
##  Other Shippers to consider 
################################################################################


    * FedEx
      - http://www.fedex.com/us/solutions/wis/index.html/
      - http://www.synesmedia.com/twiki/bin/view/Cyc/FedExShipManager      
      - [Enh] FedEx module: Christopher L Wenham from Synesmedia has created an 
        Interchange usertag that uses FedEx::DirectConnect for various functions.
      - [Enh] Francois Belanger, francois@sitepak.com has also created a FedEx 
        module (see FedEx.pm).
      - See FedEx::DirectConnect
      - Business::FedEx (Win32 Only, unless you configure a proxy)
      - PHP: http://freshmeat.net/projects/fedexdc/
      - PHP: http://freshmeat.net/projects/phpfedex/
      - PHP: http://freshmeat.net/projects/phorsale/
    * DHL & Airborne
      - API docs available, but no one has expressed interest.
    * CanadaPost
      - PHP module: http://freshmeat.net/projects/canship/
    * FreightQuote

      
################################################################################
##  Tracking
################################################################################

    * Tests

    * UPS Tracking Numbers appear in the following formats:
       1Z 999 999 99 9999 999 9
       9999 9999 999 9
       T999 9999 999 

    * USPS tracking formats:
      - http://hdusps.esecurecare.net/cgi-bin/hdusps.cfg/php/enduser/std_adp.php?p_faqid=1125&p_created=1052781743&p_sid=LjOKtaqh&p_lva=&p_sp=cF9zcmNoPSZwX3NvcnRfYnk9JnBfZ3JpZHNvcnQ9JnBfcm93X2NudD0zNiZwX3Byb2RfbHZsMT01MSZwX3Byb2RfbHZsMj0mcF9wYWdlPTE*&p_li=
    
################################################################################
##  General Ideas
################################################################################

    * Similar software in other languages:
      - Cold Fushion: UPSRateMonger by Matt Robertson (http://www.mysecretbase.com)
      - Cold Fushion: FedExMonger by Matt Robertson (http://www.mysecretbase.com)
