<?php /* * This file is part of NOALYSS. * * NOALYSS is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * NOALYSS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NOALYSS; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // Copyright Author Dany De Bontridder danydb@aevalys.eu /*!\file * \brief to compute the different amount of an invoice of an expense, */ /** * @brief this class aims to compute different amount * * This class compute without decimal error the following amount * - vat * - amount without vat * - no deductible vat * - personal part * - no deductible amount * Nothing won't be saved to the database, this class will just * compute and complete the object * if you need to compute the vat and in another place all the * details you'll have to use the clone function 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' ); */ 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.'<br>'; } } public static function test_me () { $a=new Acc_Compute(); echo $a->get_info(); echo '<hr>'; // 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 '<h1> Test VAT </h1>'; echo '<h2> Data </h2>'; $a->display(); echo '<h2> Result </h2>'; $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 '<h1> Test VAT + Perso</h1>'; echo '<h2> Data </h2>'; $a->display(); $b=clone $a; $a->compute_vat(); $a->compute_perso(); $a->correct(); echo '<h2> Result </h2>'; $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 '<h1> Test VAT + ND VAT</h1>'; echo '<h2> Data </h2>'; $a->display(); $a->compute_vat(); $a->compute_nd_vat(); $a->correct(); echo '<h2> Result </h2>'; $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 '<h1> Test VAT + ND VAT + perso</h1>'; echo '<h2> Data </h2>'; $a->display(); $a->compute_vat(); $a->compute_perso(); $a->compute_nd_vat(); $a->correct(); echo '<h2> Result </h2>'; $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 '<h1> Test VAT + ND </h1>'; echo '<h2> Data </h2>'; $a->display(); $a->compute_vat(); $a->compute_nd(); $a->compute_perso(); $a->compute_nd_vat(); $a->correct(); echo '<h2> Result </h2>'; $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 '<h1> Test VAT + ND + Perso</h1>'; echo '<h2> Data </h2>'; $a->display(); $a->compute_vat(); $a->compute_nd(); $a->compute_perso(); $a->compute_nd_vat(); $a->correct(); echo '<h2> Result </h2>'; $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 '<h1> Test VAT + TVA ND DED</h1>'; echo '<h2> Data </h2>'; $a->display(); $a->compute_vat(); $a->compute_nd(); $a->compute_perso(); $a->compute_nd_vat(); $a->compute_ndded_vat(); $a->correct(); echo '<h2> Result </h2>'; $a->display(); $a->verify($b); } }