I copied the ups.inc file in the shipcalc partners folder and am modifying it to create my own basic shipping calculation.

I am just wondering what exactly the $rate array needs to look like when it comes out of the get_rates function? Are there nested arrays or does it matter?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

alynner’s picture

Title: I'm creating basic shipcalc setting and I have a question... » well i figured it out...

and it works like a charm:

<?php
// $Id: basic.inc,v 1.1 2006/05/27 06:30:01 gordon Exp $

/**
 * @file
 * Functions to communicate with basic API.
 *
 * Derived from the basic document titled:
 *    Rates Calculators
 *    basic Web Tools(TM)
 *    Application Programming Interface
 *    User's Guide
 *    Document Version 1.0 (11/8/04)
 *
 * Additional information:
 *  http://www.basic.com/webtools/
 */

/**
 * Shipcalc _shipping_methods hook.
 *
 * Define the basic shipping methods.
 */
function basic_shipping_methods($type = 'domestic') {
  // TODO: Add descriptions of various shipping methods.
  $methods = array();

  $methods['basic'] = array(
    '#title' => t('basic'),
    '#description' => t('Basic Shipping.'),
  );

  switch ($type) {
    case 'domestic':
    default:
      $methods['basic']['Flat Rate'] = array(
        '#title' => t('Flat Rate'),
      );
      break;
    case 'international':
      $methods['basic']['Flat Rate'] = array(
        '#title' => t('Flat Rate International'),
      );
  }

  return $methods;
}

/**
 * Shipcalc _settings_form hook.
 *
 * Create a form for basic-specific configuration.
 */
function basic_settings_form(&$form) {
  $form['basic'] = array(
    '#type' => 'fieldset',
    '#title' => t('basic settings')
  );
  $form['basic']['basic_region_1_charge'] = array(
    '#type' => 'textfield',
    '#title' => t('Region One Charge'),
    '#default_value' => variable_get('shipcalc_basic_region_1_charge', ''),
    '#required' => TRUE
  );
   $form['basic']['basic_region_1_states'] = array(
  '#type' => 'select',
  '#title' => t('Select Region One States'),
  '#default_value' => variable_get('shipcalc_basic_region_1_states',''),
  '#options' => array(
	 'AL' => t('Alabama'),
	 'AK' => t('Alaska'),
	 'AS' => t('American Samoa'),
	 'AZ' => t('Arizona'),
	 'AR' => t('Arkansas'),
	 'CA' => t('California'),
	 'CO' => t('Colorado'),
	 'CT' => t('Connecticut'),
	 'DE' => t('Delaware'),
	 'DC' => t('District Of Columbia'),
	 'FM' => t('Federated States of Micronesia'),
	 'FL' => t('Florida'),
	 'GA' => t('Georgia'),
	 'GU' => t('Guam'),
	 'HI' => t('Hawaii'),
	 'ID' => t('Idaho'),
	 'IL' => t('Illinois'),
	 'IN' => t('Indiana'),
	 'IA' => t('Iowa'),
	 'KS' => t('Kansas'),
	 'KY' => t('Kentucky'),
	 'LA' => t('Louisiana'),
	 'ME' => t('Maine'),
	 'MH' => t('Marshall Islands'),
	 'MD' => t('Maryland'),
	 'MA' => t('Massachusetts'),
	 'MI' => t('Michigan'),
	 'MN' => t('Minnesota'),
	 'MS' => t('Mississippi'),
	 'MO' => t('Missouri'),
	 'MT' => t('Montana'),
	 'NE' => t('Nebraska'),
	 'NV' => t('Nevada'),
	 'NH' => t('New Hampshire'),
	 'NJ' => t('New Jersey'),
	 'NM' => t('New Mexico'),
	 'NY' => t('New York'),
	 'NC' => t('North Carolina'),
	 'ND' => t('North Dakota'),
	 'MP' => t('Northern Mariana Islands'),
	 'OH' => t('Ohio'),
	 'OK' => t('Oklahoma'),
	 'OR' => t('Oregon'),
	 'PW' => t('Palau'),
	 'PA' => t('Pennsylvania'),
	 'PR' => t('Puerto Rico'),
	 'RI' => t('Rhode Island'),
	 'SC' => t('South Carolina'),
	 'SD' => t('South Dakota'),
	 'TN' => t('Tennessee'),
	 'TX' => t('Texas'),
	 'UT' => t('Utah'),
	 'VT' => t('Vermont'),
	 'VA' => t('Virginia'),
	 'VI' => t('Virgin Islands'),
	 'WA' => t('Washington'),
	 'WV' => t('West Virginia'),
	 'WI' => t('Wisconsin'),
	 'WY' => t('Wyoming')
	    ),
	
  '#multiple' => TRUE,
  '#description' => t('description.'),
);
  $form['basic']['basic_region_2_charge'] = array(
    '#type' => 'textfield',
    '#title' => t('Everywhere Else Charge'),
    '#default_value' => variable_get('shipcalc_basic_region_2_charge', ''),
    '#required' => TRUE
  );

  return $form;
}

/**
 * Shipcalc _settings_form_submit hook.
 *
 * Save data from our basic-specific configuration form.
 */
function basic_settings_form_submit(&$form) {
  global $form_values;

  if ($form_values['shipping_partner'] == 'basic') {
    variable_set('shipcalc_basic_region_1_charge', $form_values['basic_region_1_charge']);
    variable_set('shipcalc_basic_region_1_states', $form_values['basic_region_1_states']);
    variable_set('shipcalc_basic_region_2_charge', $form_values['basic_region_2_charge']);
  }
}

/**
 * Shipcalc _product_form hook.
 *
 * Update the product form with fields that we need.  It is possible for 
 * multiple carriers to define the same field -- that is fine.  So long as
 * the field as the same name (ie 'product_weight'), it will only be displayed
 * once, and the data will be saved and restored for use by all shipping
 * partners that define it.
 */
function basic_product_form(&$form) {
  $form['shipping_data']['product_weight'] = array(
    '#type' => 'textfield',
    '#title' => t('Product weight'),
    '#description' => t('The weight of the product (in %unit)', array('%unit'=> (variable_get('shipcalc_units', 'LBS')) ? t('pounds') : t('kilograms'))),
    '#default_value' => $form['#node']->product_weight
  );
}

/**
 * Shipcalc _get_rates_form hook.
 *
 * 
 */
function basic_get_rates($txn) {
	  
  if ($txn->address['shipping']->country == 'us') {
  	$ship_state = $txn->address['shipping']->state;
	if (variable_get('shipcalc_basic_region_1_states', $ship_state)) {
		$rates[basic] = array(
            '#key' => basic,
            '#cost' => variable_get('shipcalc_basic_region_1_charge', ''),
            '#currency' => 'USD',
            '#method' => 'ground'
          );
	}
	else {
		$rates[basic] = array(
            '#key' => basic,
            '#cost' => variable_get('shipcalc_basic_region_2_charge', ''),
            '#currency' => 'USD',
            '#method' => 'ground'
          );
	}
  }
	else {
		$rates[basic] = array(
            '#key' => basic,
            '#cost' => variable_get('shipcalc_basic_region_2_charge', ''),
            '#currency' => 'USD',
            '#method' => 'ground'
          );
	}
  
  return $rates;
  //return -1; // returning -1 results in a 'Configuration error.'
}

?>
gordon’s picture

This looks good, call you please add this as an attachment, so that it can be included in cvs.

Darren Oh’s picture

Title: well i figured it out... » Custom ShipCalc Setting
alynner’s picture

FileSize
5.92 KB

I have attached. Try it out and let me know, I'm sure it can use some tweaks.

alynner

Darren Oh’s picture

Category: support » feature
Status: Active » Needs review
stella’s picture

This basic shipping functionality looks very useful. However it assumes that region 1 has to be a state in the US. What about online stores based outside the US? For them, their local country would be region 1, then there might be a region 2 for neighbouring countries and region 3 for the rest of the world (incl the States). I think the e-commerce module should be able to work for all countries, not just the US.

As a side note, I'd like to be able to associate a weight with each product and then apply the shipping cost based on what weight range the product falls into. If I get this working, I'll let you know!

Cheers,
Stella

stella’s picture

FileSize
9.96 KB

I created a new file "weight.inc" to handle a basic flat fee per region and a weight based shipping rate per region. There are 3 different regions (region 1, region 2 and everywhere else). The shipping cost is calculated like : region_flat_rate + (region_weight_rate * total_weight).

For both region 1 and 2 you can choose multiple countries from each list. If the US is chosen, then another select box for the list of states appears. The showing of the states list requires javascript, which meant I had to make the following changes to shipcalc.module:

new function:

/**
 * Invoke _settings_form_javascript in shipping partner .inc files.
 *
 */
function shipcalc_settings_form_javascript($partner) {
  $partners = _shipcalc_partners();
  $settings_form_javascript = $partner .'_settings_form_javascript';
  if (function_exists($settings_form_javascript)) {
      return $settings_form_javascript();
  }
  return '';
}

changes to shipcalc_settings_form():

    $javascript = shipcalc_settings_form_javascript($partner);

    return drupal_get_form('shipcalc_settings_form', $form) . $javascript;

The weight.inc file is attached.

Hope this is of use to someone else.

Cheers,
Stella

stella’s picture

FileSize
10.12 KB

modified weight.inc, so the first pound has one rate, and then each additional pound is charged differently.

updated file attached.

stella’s picture

FileSize
18.22 KB

ok final version of weight.inc attached. I made some changes to allow the user to specify different rates dependant on whether the method chosen is parcel or large envelope. This last change is slightly hacky and i'm not sure what happens if the user picks both postal options. Perhaps someone else can suggest a better method.

Cheers,
Stella

Darren Oh’s picture

Component: shipping.module » shipcalc
nedjo’s picture

I'd like to see this committed to shipcalc as currently we have no basic shipping options. Can someone who's used this give a detailed review? Are there any significant outstanding issues? Then we can fix any remaining issues and get this in.

Some quick comments:

* Looks generally good, I've not tested.
* There are some minor formatting issues: else or elseif should be on a separate line, there's inconsistency in the indents of e.g. form arrays, etc.
* The Javascript is a bit clunky, though I know we're doing similar things elsewhere in ecommerce. It would be nice to have a Drupal-like approach, where we used classes to attach behaviours to elements, and the js in a separate file. But, since we're only copying and not introducing this approach, it's a separate issue I guess.

nedjo’s picture

Some further questions:

Why is shipcalc the place to implement this? I had assumed previously that we would do basic shipping directly as an additional shipping-based module, rather than through shipcalc (which I though of as for interacting with web services, e.g., UPS, USPS, Canada Post).

How does this relate to the shipbasic work at http://drupal.org/node/68363? Is the basic shipping need now covered off by flexicharge, or do we still need a basic shipping module (or extension to an existing module)?

nedjo’s picture

Some further questions:

Why is shipcalc the place to implement this? I had assumed previously that we would do basic shipping directly as an additional shipping-based module, rather than through shipcalc (which I though of as for interacting with web services, e.g., UPS, USPS, Canada Post).

How does this relate to the shipbasic work at http://drupal.org/node/68363? Is the basic shipping need now covered off by flexicharge, or do we still need a basic shipping module (or extension to an existing module)?

sime’s picture

Hi nedjo

I think it's the "scratch your itch" effect. The people with time to develop will choose what they develop.

I will commit this if you think it is ok as a new shipcalc provider.

Re. flexicharge. I personally will be using it for basic charges (like shipping) - the foundation has been laid ready for various projects that are coming up. I wish I could say it's ready to go and really sell it to everyone, but since I can't do that yet, I understand why people are picking their own course.

sime’s picture

Oh wait, you have CVS access. You just need a review, I will try and do this soon.

sime’s picture

Status: Needs review » Reviewed & tested by the community

Works. I'll be using this! Thanks @snpower.

nedjo, re flexicharge:
I actually think this is better in shipcalc rather than flexicharge because it avoids me having to emulate the weight stuff that shipcalc is doing so well. I'll leave the final decision to you.

chueewowee’s picture

Title: Custom ShipCalc Setting » Custom ShipCalc Setting - weight
Category: feature » bug

I have weight_1.inc and basic.inc installed. When I select weight_1 and shipcalc settings I only get the 'save weight_1 settings' button in the form, but no settings to select.

Also, in the create product (apperel or shippable , I get no weight attributes in the form.

Naturally I have modified the shipcal.module as advised. What must I do to get it working, and what should I see?

gordon’s picture

Status: Reviewed & tested by the community » Needs work

The javascript needs to be put into it's own file, and then loaded the drupal way.

chueewowee’s picture

Thank you gordon. How do I load the javascript 'the Drupal way', and where should I place the file containing:

/**
* Invoke _settings_form_javascript in shipping partner .inc files.
*
*/
function shipcalc_settings_form_javascript($partner) {
$partners = _shipcalc_partners();
$settings_form_javascript = $partner .'_settings_form_javascript';
if (function_exists($settings_form_javascript)) {
return $settings_form_javascript();
}
return '';
}

chueewowee’s picture

I created a separate file 'shipcalc_settings_form.js' in the partners folder. But his doean't work. I am not sure precisely how to place the drupal_call_js() function
I still need step by step instructions, even after reading relavant posts:

http://drupal.org/node/45531
http://drupal.org/node/42544
http://drupal.org/node/57760

sime’s picture

Use drupal_add_js().
http://api.drupal.org/api/4.7/function/drupal_add_js

You want to pass the path of javascript file in such a way that it doesn't matter where ecommerce is installed.
http://api.drupal.org/api/4.7/function/drupal_get_path

Hope these help

chueewowee’s picture

Thanks, they help to a point, but also means I just need to learn more and search more. A step by step example for the case in hand would be great: what to put where and how.

Otherwise I think sadly I shal have to abandon this effort to produce a cart with Drupal with proper checkout for weight and zone. The time spent soars unless you get direct help with a problem in some cases, and the errors are merely the effect of not being able to take on much more self-tuition at that time.

chueewowee’s picture

WHat I did is as follows, placeing the code in the shipcalc moduleafter line 70, but I get a 'Parse error: syntax error, unexpected T_RETURN on line 72'

[71]drupal_get_path($module, $shipcalc_settings_form_javascript.js)     
[72]drupal_add_js('modules/ecommerce/contrib/shipcalc/shipcalc_settings_form_javascript.js') 
[73]$javascript = shipcalc_settings_form_javascript($partner);
[74]return drupal_get_form('shipcalc_settings_form', $form) . $javascript;  
                 

Your help is most appreciated.
Sincerely,
John plumridge.

sime’s picture

Sorry, it will need nedjo to have a good look at this I think.

alynner’s picture

Title: Custom ShipCalc Setting - weight » Custom ShipCalc Setting - weight, quantity
FileSize
10.47 KB

I just tried out the weight.inc version of my original post and its great! thanks!

I have also decided I wanted to do the shipping for my most recent cart by quantity, so I copied the weight.inc file and made it quantity instead. I just had to change the get_rates function a bit and bingo bango bongo there we have it.

alynner

dkashen’s picture

Hi,
I'd like to modify quantity to have a cost= base+$/lb
that would involved 3 distinct regions: 1 US, and 2 overseas.

In playing with quantity.inc's setup,
it looks like only adjacent states and countries can be selected with mouse clicks.
Is that true ?

If so (and maybe regardless),
I might prefer to hard code the cost function and countries per region .

Can someone point me to the best examples of a hardcoded .inc file that avoids
the javascript ?

I'm trying to avoid JS and learn just enough PHP (for now) .

Thank you,

chueewowee’s picture

FileSize
18.22 KB

OK. I found a weight.inc which works, posted in the ecommerce mail list (see attached file). I tried the versions above, which do not work, with the latest ecommerce from 4.7 depository.

I 'll also say that I found it doesn't work with apperell and sub-products, but only 'shippable items' (even though sub-products are shippable items, I see, in practise)

I haven't tried the quantity.inc module yet.

Also:

I noticed the weight attribute disappeared from the product form when both ups.inc and canada.inc were removed.
The Shipcalc _product_form hook was not doing its job:

function weight_product_form(&$form) {
$form['shipping_data']['product_weight'] = array(
'#type' => 'textfield',
'#title' => t('Product weight'),
'#description' => t('The weight of the product (in %unit)', array('%unit'=> (variable_get('shipcalc_units', 'LBS')) ? t('pounds') : t('kilograms'))),
'#default_value' => $form['#node']->product_weight
);
}

Instead, if modified to be the same as the ups and canada files, it does indeed enhance the product form, and weight.inc does its job of adding a shipping charge to the cart:

function weight_product_attributes($form) {
$fields = array();
$fields['weight'] = array(
'#type' => 'textfield',
'#title' => t('Product weight'),
'#description' => t('The weight of the product (in %unit)', array('%unit'=> (variable_get('shipcalc_units', 'LBS')) ? t('pounds') : t('kilograms'))),
'#default_value' => $form['#node']->product_attributes['weight']
);
return $fields;
}

The original code seems to be copied from 'usps.inc', which may not work either.

Thanks.

dkashen’s picture

To get weight_2.inc working
do we replace the definition of
function weight_product_form(&$form){...}
with
function weight_product_attributes($form){...}

or do we add
function weight_product_attributes($form){...}

?

Thank you,

dkashen’s picture

FileSize
24.42 KB

oh, here's a snapshot
when I insert the above weight_2.inc file
at shipcalc/partners/
None of the settings are accessible.
is this along the lines of the problems you were seeing ?

ñull’s picture

In the Invoice there is supposed to be the shipping method displayed. This remains blank however and I cannot find this information anywhere else in the transaction administration. Where is this set? What is missing in the partners module? Or is this a bug in shipcalc or shipping module?

ñull’s picture

I your code is a confusion about the use of #key #service and #method. The error of not appearing the shipping method in the Invoice has to do with this.

I try to explain:

#service must be the same as the key defined in _shipping_methods(), in your case it should be 'weight'
#key must be the same as the key of the used method as defined in _shipping_methods(), in your case it should be 'Flat Rate & Weight Based'.
#method is the string that would appear in the checkout shipping choice.

In this issue I explain more about it and the confusion I see between #key and #method and my proposal to get rid of #key.

Darren Oh’s picture

Got tired of small print.

Darren Oh’s picture

?>?>?>

Darren Oh’s picture

Status: Needs work » Closed (fixed)

Let's open a new issue.

Thomas Sewell’s picture

For those who just wanted local or instore pickup for v3, see http://drupal.org/node/379572.