Tag Archive for Shipping

Royal Mail Postage by Weight – Zend Framework Module

For a recent project I have had to calculate weight based shipping costs. Before I had this as a db table, but that became a mess to manage.

So I’ve created this small shipping calculator. It’s set to use KG in weight and prices inclusive of vat taken from the Royal Mail’s 2011 Prices.

Follows are the config ini file, the class and a basic usage.

[EUR]
prices[0.01] =1.79
prices[0.12] =1.94
prices[0.14] =2.15
prices[0.16] =2.32
prices[0.18] =2.54
prices[0.2] =2.63
prices[0.22] =2.75
prices[0.24] =2.87
prices[0.26] =2.99
prices[0.28] =3.08
prices[0.3] =3.14
prices[0.32] =3.8
prices[0.42] =4.46
prices[0.52] =5.12
prices[0.62] =5.78
prices[0.72] =6.44
prices[0.82] =7.1
prices[0.92] =7.76
prices[1] =7.76

above.start = 1.1
above.increment = 0.1
above.valuePerIncrement = 0.55

[ITL]
prices[0.01] =2.49
prices[0.12] =2.79
prices[0.14] =3.12
prices[0.16] =3.48
prices[0.18] =3.84
prices[0.2] =4.2
prices[0.22] =4.56
prices[0.24] =4.76
prices[0.26] =4.88
prices[0.28] =5
prices[0.3] =5.12
prices[0.32] =6.45
prices[0.42] =7.78
prices[0.52] =9.11
prices[0.62] =10.44
prices[0.72] =11.78
prices[0.82] =13.11
prices[0.92] =14.44
prices[1] =14.44

above.start = 1.1
above.increment = 0.1
above.valuePerIncrement = 0.66

[UK]
prices[0.1] =1.9
prices[0.25] =2.36
prices[0.5] =2.98
prices[0.75] =3.66
prices[1] =4.46
prices[1.25] =5.88
prices[1.5] =6.8
prices[1.75] =7.71
prices[2] =8.62
prices[4] =10.74

above.start = 6
above.increment = 2
above.valuePerIncrement = 3.66
<?php
class BinaryKitten_Shipping {
    private $_cfg;
    private $_curCfg;
    public function __construct($postalZone=null) {
        $this->_curCfg = $this->_cfg = new Zend_Config_Ini(APPLICATION_PATH .'/configs/postal.ini');
        if (isset($postalZone)) {
            $this->setPostalZone($postalZone);
        }
    }
    public function setPostalZone($postalZone)
    {
        if (self::validatePostalZone($postalZone)) {
            $this->_curCfg = $this->_cfg->get($postalZone, $this->_cfg);
        }

    }
    public static function validatePostalZone($postalZone)
    {
        return in_array(strtoupper($postalZone), array('UK','EUR','ITL'));
    }
    public function getPriceForWeight($weight)
    {
        $priceOut = -1;
        foreach($this->_curCfg->prices as $weightBoundary=>$price) {
            if ($weightBoundary < $weight) continue;
            if ($weightBoundary >= $weight) {
                $priceOut = $price;
                break;
            }
        }
        if ($priceOut == -1) {
            for($weightBoundary = (float)$this->_curCfg->above->start;$weightBoundary < $weight;$weightBoundary += $this->_curCfg->above->increment) {
                $price+=$this->_curCfg->above->valuePerIncrement;
            }

            $priceOut = $price;
            //try to calculate the difference
        }
        return (float)$priceOut;
    }
}
$prices = new BinaryKitten_Shipping();
$prices->setPostalZone('EUR');
$price = $prices->getPriceForWeight(5);