'amount', 'amount_vat'=>'amount_vat', 'amount_vat_rate'=>'amount_vat_rate', 'nd_vat'=>'nd_vat', 'nd_vat_rate'=>'nd_vat_rate', 'nd_ded_vat'=>'nd_ded_vat', 'nd_ded_vat_rate'=>'nd_ded_vat_rate', 'amount_nd'=>'amount_nd', 'amount_nd_rate'=>'amount_nd_rate', 'nd_vat_rate'=>'nd_vat_rate', 'amount_perso'=>'amount_perso', 'amount_perso_rate'=>'amount_perso_rate' ); */ class Acc_Compute { private static $variable=array( 'amount'=>'amount', 'amount_vat'=>'amount_vat', 'amount_vat_rate'=>'amount_vat_rate', 'nd_vat'=>'nd_vat', 'nd_vat_rate'=>'nd_vat_rate', 'nd_ded_vat'=>'nd_ded_vat', 'nd_ded_vat_rate'=>'nd_ded_vat_rate', 'amount_nd'=>'amount_nd', 'amount_nd_rate'=>'amount_nd_rate', 'nd_vat_rate'=>'nd_vat_rate', 'amount_perso'=>'amount_perso', 'amount_perso_rate'=>'amount_perso_rate' ); private $order; // check that the compute // function are called in the // good order var $check; // activate the check of the // order, valid value are // false or true function __construct () { bcscale(4); foreach (self::$variable as $key=>$value) $this->$key=0; $this->order=0; $this->check=true; } public function get_parameter($p_string) { if ( array_key_exists($p_string,self::$variable) ) { $idx=self::$variable[$p_string]; return $this->$idx; } else throw new Exception (__FILE__.":".__LINE__._('Erreur attribut inexistant')); } public function set_parameter($p_string,$p_value) { if ( array_key_exists($p_string,self::$variable) ) { $idx=self::$variable[$p_string]; $this->$idx=$p_value; } else throw new Exception (__FILE__.":".__LINE__._('Erreur attribut inexistant')); } public function get_info() { return var_export(self::$variable,true); } function compute_vat() { if ( $this->check && $this->order != 0 ) throw new Exception ('ORDER NOT RESPECTED'); $this->amount_vat=bcmul($this->amount,$this->amount_vat_rate); $this->amount_vat=round($this->amount_vat,2); $this->order=1; } /*!\brief Compute the no deductible part of the amount, it reduce *also the vat */ function compute_nd() { if ( $this->check && $this->order > 2 ) throw new Exception ('ORDER NOT RESPECTED'); $this->amount_nd=bcmul($this->amount,$this->amount_nd_rate); $this->amount_nd=bcdiv($this->amount_nd,100); $this->amount_nd=round($this->amount_nd,2); // the nd part for the vat $nd_vat=bcmul($this->amount_vat,$this->amount_nd_rate); $nd_vat=bcdiv($nd_vat,100); $nd_vat=round($nd_vat,2); } function compute_nd_vat() { if ( $this->check && $this->order > 3 ) throw new Exception ('ORDER NOT RESPECTED'); $this->order=4; if ($this->amount_vat == 0 ) $this->compute_vat(); $this->nd_vat=bcmul($this->amount_vat,$this->nd_vat_rate); $this->nd_vat=bcdiv($this->nd_vat,100); $this->nd_vat=round($this->nd_vat,2); } function compute_ndded_vat() { if ( $this->check && $this->order > 4 ) throw new Exception ('ORDER NOT RESPECTED'); $this->order=5; if ($this->amount_vat == 0 ) $this->compute_vat(); $this->nd_ded_vat=bcmul($this->amount_vat,$this->nd_ded_vat_rate); $this->nd_ded_vat=bcdiv($this->nd_ded_vat,100); $this->nd_ded_vat=round($this->nd_ded_vat,2); } function compute_perso() { if ( $this->check && $this->order != 1 ) throw new Exception ('ORDER NOT RESPECTED'); $this->order=2; if ( $this->amount == 0 ) return; $this->amount_perso=bcmul($this->amount,$this->amount_perso_rate); $this->amount_perso=bcdiv($this->amount_perso,100); $this->amount_perso=round($this->amount_perso,2); } function correct() { $this->amount=bcsub($this->amount,$this->amount_perso); // correct the others amount $this->amount=bcsub($this->amount,$this->amount_nd); $this->amount_vat=bcsub($this->amount_vat,$this->nd_ded_vat); $this->amount_vat=round($this->amount_vat,2); $this->amount_vat=bcsub($this->amount_vat,$this->nd_vat); $this->amount_vat=round($this->amount_vat,2); } /**! * \brief verify that all the amount are positive or null * otherwise throw a exception and the sum of amount + vat must * equal to the sum of all the amount of the current object * so you have to copy the object before computing anything and pass * it as parameter * \param compare with a object copied before computing, if null * there is no comparison */ function verify($p_obj=null) { foreach (self::$variable as $key=>$value) if ( $this->$value < 0 ) throw new Exception (_("Montant invalide")); if ( $p_obj != null ) { $sum=0; foreach ( array( 'amount','amount_vat','amount_nd','nd_vat','amount_perso','nd_ded_vat') as $value) $sum=bcadd($sum,$this->$value); if ( $p_obj->amount_vat == 0 ) $p_obj->compute_vat(); $cmp=bcadd($p_obj->amount,$p_obj->amount_vat); $diff=bcsub($sum,$cmp); if ( $diff != 0.0 ) throw new Exception (_("ECHEC VERIFICATION : valeur totale = $sum valeur attendue = $cmp diff = $diff")); } } function display() { foreach (self::$variable as $key=>$value) { echo 'key '.$key.' Description '.$value.' value is '.$this->$key.'
'; } } public static function test_me () { $a=new Acc_Compute(); echo $a->get_info(); echo '
'; // Compute some operation to see if the computed amount are // correct //Test VAT $a->set_parameter('amount',1.23); $a->set_parameter('amount_vat_rate',0.21); echo '

Test VAT

'; echo '

Data

'; $a->display(); echo '

Result

'; $a->compute_vat(); $a->display(); $a->verify(); // Test VAT + perso $a=new Acc_Compute(); $a->set_parameter('amount',1.23); $a->set_parameter('amount_vat_rate',0.21); $a->set_parameter('amount_perso_rate',0.5); echo '

Test VAT + Perso

'; echo '

Data

'; $a->display(); $b=clone $a; $a->compute_vat(); $a->compute_perso(); $a->correct(); echo '

Result

'; $a->display(); $a->verify($b); // TEST VAT + ND // Test VAT + perso $a=new Acc_Compute(); $a->set_parameter('amount',1.23); $a->set_parameter('amount_vat_rate',0.21); $a->set_parameter('nd_vat_rate',0.5); $b=clone $a; echo '

Test VAT + ND VAT

'; echo '

Data

'; $a->display(); $a->compute_vat(); $a->compute_nd_vat(); $a->correct(); echo '

Result

'; $a->display(); $a->verify($b); // TEST VAT + ND // Test VAT + perso $a=new Acc_Compute(); $a->set_parameter('amount',1.23); $a->set_parameter('amount_vat_rate',0.21); $a->set_parameter('nd_vat_rate',0.5); $a->set_parameter('amount_perso_rate',0.5); $b=clone $a; echo '

Test VAT + ND VAT + perso

'; echo '

Data

'; $a->display(); $a->compute_vat(); $a->compute_perso(); $a->compute_nd_vat(); $a->correct(); echo '

Result

'; $a->display(); $a->verify($b); // TEST VAT + ND $a=new Acc_Compute(); $a->set_parameter('amount',1.23); $a->set_parameter('amount_vat_rate',0.21); $a->set_parameter('amount_nd_rate',0.5); $b=clone $a; echo '

Test VAT + ND

'; echo '

Data

'; $a->display(); $a->compute_vat(); $a->compute_nd(); $a->compute_perso(); $a->compute_nd_vat(); $a->correct(); echo '

Result

'; $a->display(); $a->verify($b); // TEST VAT + ND // + Perso $a=new Acc_Compute(); $a->set_parameter('amount',1.23); $a->set_parameter('amount_vat_rate',0.21); $a->set_parameter('amount_nd_rate',0.5); $a->set_parameter('amount_perso_rate',0.2857); $b=clone $a; echo '

Test VAT + ND + Perso

'; echo '

Data

'; $a->display(); $a->compute_vat(); $a->compute_nd(); $a->compute_perso(); $a->compute_nd_vat(); $a->correct(); echo '

Result

'; $a->display(); $a->verify($b); // TEST VAT + ND // + Perso $a=new Acc_Compute(); $a->set_parameter('amount',1.23); $a->set_parameter('amount_vat_rate',0.21); $a->set_parameter('nd_ded_vat_rate',0.5); $b=clone $a; echo '

Test VAT + TVA ND DED

'; echo '

Data

'; $a->display(); $a->compute_vat(); $a->compute_nd(); $a->compute_perso(); $a->compute_nd_vat(); $a->compute_ndded_vat(); $a->correct(); echo '

Result

'; $a->display(); $a->verify($b); } }