Skip to content

Commit

Permalink
ShippingMethod should now define requiresAddress. issue #22 (#43)
Browse files Browse the repository at this point in the history
Merged #43
  • Loading branch information
sanderha authored and bummzack committed Jul 18, 2017
1 parent dd0de23 commit 7f19c43
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 31 deletions.
2 changes: 1 addition & 1 deletion code/extensions/OrderShippingExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public function setShippingMethod(ShippingMethod $option)
throw new Exception(_t("OrderShippingExtension.NoPackage", "Shipping package information not available"));
}
$address = $this->owner->getShippingAddress();
if (!$address || !$address->exists()) {
if (!$address || !$address->exists() && $option->requiresAddress()) {
throw new Exception(_t("OrderShippingExtension.NoAddress", "No address has been set"));
}
$this->owner->ShippingTotal = $option->calculateRate($package, $address);
Expand Down
10 changes: 10 additions & 0 deletions code/model/ShippingMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ public function getTitle()
$this->extend('updateTitle', $title);
return $title;
}

/**
* Some shipping methods might require an address present on the order.
*
* @return bool
*/
public function requiresAddress()
{
return false;
}
}

/**
Expand Down
8 changes: 8 additions & 0 deletions code/shippingmethods/DistanceShippingMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ public function greatestCostDistance()
->sort("Cost", "DESC")
->first();
}

/**
* @return bool
*/
public function requiresAddress()
{
return true;
}
}

class DistanceShippingFare extends DataObject
Expand Down
86 changes: 56 additions & 30 deletions code/shippingmethods/TableShippingMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class TableShippingMethod extends ShippingMethod
{
private static $defaults = array(
'Name' => 'Table Shipping',
'Name' => 'Table Shipping',
'Description' => 'Works out shipping from a pre-defined table'
);

Expand All @@ -21,26 +21,27 @@ public function getCMSFields()
$fields = parent::getCMSFields();

$fieldList = array(
"Country" => "Country",
"State" => "State",
"City" => "City",
"PostalCode" => "PostCode",
"WeightMin" => "WeightMin",
"WeightMax" => "WeightMax",
"VolumeMin" => "VolumeMin",
"VolumeMax" => "VolumeMax",
"ValueMin" => "ValueMin",
"ValueMax" => "ValueMax",
"Country" => "Country",
"State" => "State",
"City" => "City",
"PostalCode" => "PostCode",
"WeightMin" => "WeightMin",
"WeightMax" => "WeightMax",
"VolumeMin" => "VolumeMin",
"VolumeMax" => "VolumeMax",
"ValueMin" => "ValueMin",
"ValueMax" => "ValueMax",
"QuantityMin" => "QuantityMin",
"QuantityMax" => "QuantityMax",
"Rate" => "Rate"
"Rate" => "Rate"
);

$fields->fieldByName('Root')->removeByName("Rates");
if ($this->isInDB()) {
$tablefield = new GridField("Rates", "TableShippingRate", $this->Rates(), new GridFieldConfig_RecordEditor());
$fields->addFieldToTab("Root.Main", $tablefield);
}

return $fields;
}

Expand All @@ -51,9 +52,9 @@ public function calculateRate(ShippingPackage $package, Address $address)
{
$rate = null;
$packageconstraints = array(
"Weight" => 'weight',
"Volume" => 'volume',
"Value" => 'value',
"Weight" => 'weight',
"Volume" => 'volume',
"Value" => 'value',
"Quantity" => 'quantity'
);
$constraintfilters = array();
Expand All @@ -63,29 +64,53 @@ public function calculateRate(ShippingPackage $package, Address $address)
$maxcol = "\"TableShippingRate\".\"{$db}Max\"";
//constrain to rates with valid constraints
$constraintfilters[] =
"(".
"(" .
"$mincol >= 0" .
" AND $mincol <= " . $package->{$pakval}() .
" AND $maxcol > 0". //ignore constraints with maxvalue = 0
" AND $maxcol > 0" . //ignore constraints with maxvalue = 0
" AND $maxcol >= " . $package->{$pakval}() .
" AND $mincol < $maxcol" . //sanity check
")";
")";
//also include a special case where all constraints are empty
$emptyconstraint[] = "($mincol = 0 AND $maxcol = 0)";
}
$constraintfilters[] = "(".implode(" AND ", $emptyconstraint).")";
$constraintfilters[] = "(" . implode(" AND ", $emptyconstraint) . ")";

$filter = "(".implode(") AND (", array(
"\"ShippingMethodID\" = ".$this->ID,
RegionRestriction::address_filter($address), //address restriction
implode(" OR ", $constraintfilters) //metrics restriction
)).")";
$filter = "(" . implode(") AND (", array(
"\"ShippingMethodID\" = " . $this->ID,
RegionRestriction::address_filter($address), //address restriction
implode(" OR ", $constraintfilters) //metrics restriction
)) . ")";
if ($tr = DataObject::get_one("TableShippingRate", $filter, true, "LENGTH(\"RegionRestriction\".\"PostalCode\") DESC, Rate ASC")) {
$rate = $tr->Rate;
}
$this->CalculatedRate = $rate;

return $rate;
}

/**
* If this shipping method has any @TableShippingRate with any @RegionRestriction where either Country, State, City or PostalCode are submitted, this method returns true
* Else it returns false (@ShippingMethod::requiresAddress());
*
* @return bool
*/
public function requiresAddress()
{
if ($this->Rates()->exists()) {
$defaults = RegionRestriction::config()->get('defaults');
$filter = [];
foreach($defaults as $field => $val){
$filter[$field . ':not'] = $val;
}
$rates = $this->Rates()->filterAny($filter);
if($rates->exists()){
return true;
}
}

return parent::requiresAddress();
}
}

/**
Expand All @@ -95,12 +120,12 @@ class TableShippingRate extends RegionRestriction
{
private static $db = array(
//constraint values
"WeightMin" => "Decimal",
"WeightMax" => "Decimal",
"VolumeMin" => "Decimal",
"VolumeMax" => "Decimal",
"ValueMin" => "Currency",
"ValueMax" => "Currency",
"WeightMin" => "Decimal",
"WeightMax" => "Decimal",
"VolumeMin" => "Decimal",
"VolumeMax" => "Decimal",
"ValueMin" => "Currency",
"ValueMax" => "Currency",
"QuantityMin" => "Int",
"QuantityMax" => "Int",

Expand Down Expand Up @@ -133,6 +158,7 @@ public function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->removeByName('ShippingMethodID');

return $fields;
}
}
8 changes: 8 additions & 0 deletions code/shippingmethods/ZonedShippingMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ public function getCMSFields()
}
return $fields;
}

/**
* @return bool
*/
public function requiresAddress()
{
return true;
}
}

class ZonedShippingRate extends DataObject
Expand Down

0 comments on commit 7f19c43

Please sign in to comment.