Merging version 2.1 RC to main trunk.
[fa-stable.git] / taxes / tax_calc.inc
1 <?php
2 /**********************************************************************
3     Copyright (C) FrontAccounting, LLC.
4         Released under the terms of the GNU General Public License, GPL, 
5         as published by the Free Software Foundation, either version 3 
6         of the License, or (at your option) any later version.
7     This program is distributed in the hope that it will be useful,
8     but WITHOUT ANY WARRANTY; without even the implied warranty of
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
10     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ***********************************************************************/
12 include_once($path_to_root . "/taxes/db/tax_groups_db.inc");
13 include_once($path_to_root . "/taxes/db/tax_types_db.inc");
14 include_once($path_to_root . "/taxes/db/item_tax_types_db.inc");
15
16 //---------------------------------------------------------------------------------
17
18 // returns the tax cost for a given item
19 /*
20 function get_tax_value_for_item($stock_id, $price, $tax_group)
21 {
22         // if price is zero, then can't be taxed
23         if ($price == 0)
24                 return 0;
25                 
26         $ret_tax_array = get_tax_group_items_as_array($tax_group);                      
27                 
28         $tax_array = get_taxes_for_item($stock_id, $ret_tax_array);
29         if ($tax_array == null)
30                 return 0;
31         
32         $tax_multiplier = 0;    
33
34         // loop for all items
35         foreach ($tax_array as $taxitem) {
36                 $tax_multiplier += $taxitem["rate"];
37         }
38         
39         return $price * ($tax_multiplier / 100);        
40 }
41 */
42 //---------------------------------------------------------------------------------
43
44 // returns the price of a given item minus any included taxes
45 // for item $stock_id with line price $price,
46 // with applicable tax rates $tax_group_array or group id $tax_group
47 //
48
49 function get_tax_free_price_for_item($stock_id, $price, $tax_group, $tax_included, $tax_group_array=null)
50 {
51         // if price is zero, then can't be taxed !
52         if ($price == 0)
53                 return 0;
54
55         if ($tax_included==0) return $price;
56         
57         // if array already read, then make a copy and use that
58         if ($tax_group_array)
59                 $ret_tax_array = $tax_group_array;
60         else
61                 $ret_tax_array = get_tax_group_items_as_array($tax_group);
62         
63         //print_r($ret_tax_array);
64
65         $tax_array = get_taxes_for_item($stock_id, $ret_tax_array);
66         // if no exemptions or taxgroup is empty, then no included/excluded taxes
67         if ($tax_array == null)
68                 return $price;
69         
70         $tax_multiplier = 0;    
71
72         // loop for all items
73
74         foreach ($tax_array as $taxitem) 
75         {
76                         $tax_multiplier += $taxitem["rate"];
77         }
78         
79         return round($price / (1 + ($tax_multiplier / 100)),  user_price_dec());
80 }
81 //
82 //      Full price (incl. VAT) for item $stock_id with line price $price,
83 //      with tax rates $tax_group_array or applicable group $tax_group
84 //
85 function get_full_price_for_item($stock_id, $price, $tax_group, $tax_included, $tax_group_array=null)
86 {
87         // if price is zero, then can't be taxed !
88         if ($price == 0)
89                 return 0;
90
91         if ($tax_included==1) return $price;
92
93         // if array already read, then make a copy and use that
94         if ($tax_group_array)
95                 $ret_tax_array = $tax_group_array;
96         else
97                 $ret_tax_array = get_tax_group_items_as_array($tax_group);
98         
99         //print_r($ret_tax_array);
100
101         $tax_array = get_taxes_for_item($stock_id, $ret_tax_array);
102         // if no exemptions or taxgroup is empty, then no included/excluded taxes
103         if ($tax_array == null)
104                 return $price;
105         
106         $tax_multiplier = 0;    
107
108         // loop for all items
109
110         foreach ($tax_array as $taxitem) 
111         {
112                         $tax_multiplier += $taxitem["rate"];
113         }
114         
115         return round($price * (1 + ($tax_multiplier / 100)),  user_price_dec());
116 }
117
118 //---------------------------------------------------------------------------------
119 // return an array of (tax_type_id, tax_type_name, sales_gl_code, purchasing_gl_code, rate)
120
121 function get_taxes_for_item($stock_id, $tax_group_items_array)
122 {
123         $item_tax_type = get_item_tax_type_for_item($stock_id);
124         
125         // if the item is exempt from all taxes then return 0
126         if ($item_tax_type["exempt"])
127                 return null;
128                 
129         // get the exemptions for this item tax type
130         $item_tax_type_exemptions_db = get_item_tax_type_exemptions($item_tax_type["id"]);
131         
132         // read them all into an array to minimize db querying
133         $item_tax_type_exemptions = array();
134         while ($item_tax_type_exemp = db_fetch($item_tax_type_exemptions_db)) 
135         {
136                 $item_tax_type_exemptions[] = $item_tax_type_exemp["tax_type_id"];
137         }
138         
139         $ret_tax_array = array();
140         
141         // if any of the taxes of the tax group are in the exemptions, then skip
142         foreach ($tax_group_items_array as $tax_group_item) 
143         { 
144                 
145                 $skip = false;                  
146                 
147                 // if it's in the exemptions, skip
148                 foreach ($item_tax_type_exemptions as $exemption) 
149                 {
150                         if (($tax_group_item['tax_type_id'] == $exemption)) 
151                         {
152                         $skip = true;
153                         break;
154                         }
155                 }
156                 
157                 if (!$skip) 
158                 {
159                         $index = $tax_group_item['tax_type_id'];
160                         $ret_tax_array[$index] = $tax_group_item;
161                 }
162         }
163         
164         return $ret_tax_array;
165 }
166 //-----------------------------------------------------------------------------------
167 // return an array of (tax_type_id, tax_type_name, sales_gl_code, purchasing_gl_code, rate, included_in_price, Value) 
168
169 function get_tax_for_items($items, $prices, $shipping_cost, $tax_group, $tax_included=null, $tax_items_array=null)
170 {
171         // first create and set an array with all the tax types of the tax group
172         if($tax_items_array!=null)
173           $ret_tax_array = $tax_items_array;
174         else
175           $ret_tax_array = get_tax_group_items_as_array($tax_group);
176
177         foreach($ret_tax_array as $k=>$t)
178                 $ret_tax_array[$k]['Net'] = 0;
179
180         // loop for all items
181         for ($i = 0; $i < count($items); $i++)
182         {
183                 $item_taxes = get_taxes_for_item($items[$i], $ret_tax_array);
184
185                 if ($item_taxes != null) 
186                 {
187                         foreach ($item_taxes as $item_tax) 
188                         {
189                                 $index = $item_tax['tax_type_id'];
190                                 if($tax_included==1) {// 2008-11-26 Joe Hunt Taxes are stored without roundings
191                                   //$ret_tax_array[$index]['Value'] += round($prices[$i] * $item_tax['rate'] 
192                                   //    / ($item_tax['rate'] + 100),  user_price_dec());
193                                   $ret_tax_array[$index]['Value'] += ($prices[$i] * $item_tax['rate'] / ($item_tax['rate'] + 100));
194                                   $ret_tax_array[$index]['Net'] += ($prices[$i] * 100 / ($item_tax['rate'] + 100));
195                                 } else {
196                                   //$ret_tax_array[$index]['Value'] += 
197                                   //    round($prices[$i] * $item_tax['rate'] / 100,  user_price_dec());
198                                   $ret_tax_array[$index]['Value'] += ($prices[$i] * $item_tax['rate'] / 100);
199                                   $ret_tax_array[$index]['Net'] += $prices[$i];
200                                 }
201                         }
202                 }
203         }
204         
205         // add the shipping taxes, only if non-zero, and only if tax group taxes shipping
206         if ($shipping_cost != 0) 
207         {
208                 $item_taxes = get_shipping_tax_as_array();
209                 if ($item_taxes != null) 
210                 {
211                         foreach ($item_taxes as $item_tax) 
212                         {
213                                 $index = $item_tax['tax_type_id'];
214                                 if(isset($ret_tax_array[$index])) {
215                                   if($tax_included==1) {// 2008-11-26 Joe Hunt Taxes are stored without roundings
216                                         //$ret_tax_array[$index]['Value'] += round($shipping_cost * $item_tax['rate'] 
217                                         //  / ($item_tax['rate'] + 100),  user_price_dec());
218                                         $ret_tax_array[$index]['Value'] += ($shipping_cost * $item_tax['rate'] / ($item_tax['rate'] + 100));
219                                     $ret_tax_array[$index]['Net'] += ($shipping_cost * 100 / ($item_tax['rate'] + 100));
220                                   } else {
221                                         //$ret_tax_array[$index]['Value'] += 
222                                         //  round($shipping_cost * $item_tax['rate'] / 100,  user_price_dec());
223                                         $ret_tax_array[$index]['Value'] += ($shipping_cost * $item_tax['rate'] / 100);
224                                     $ret_tax_array[$index]['Net'] += $shipping_cost;
225                                  }
226                                 }
227                         }
228                 }
229         }
230         
231         //print_r($ret_tax_array);
232
233         return $ret_tax_array;
234 }
235 //
236 //      Get all taxes for given tax_type_id. This can be used when 
237 //      no tax group exemptions are active (local sales).
238 //      To be used in quick entries.
239 //
240 function get_taxes_for_item_tax($tax_type_id)
241 {
242         $item_tax_type = get_item_tax_type($tax_type_id);
243         
244         // if the item is exempt from all taxes then return 0
245         if ($item_tax_type["exempt"])
246                 return null;
247                 
248         // get the exemptions for this item tax type
249         $item_tax_type_exemptions_db = get_item_tax_type_exemptions($tax_type_id);
250         
251         // read them all into an array to minimize db querying
252         $item_tax_type_exemptions = array();
253         while ($item_tax_type_exemp = db_fetch($item_tax_type_exemptions_db))
254         {
255                 $item_tax_type_exemptions[] = $item_tax_type_exemp["tax_type_id"];
256         }
257         
258         $ret_tax_array = array();
259
260         $tax_rates = get_all_tax_types_simple();
261         // if any of the taxes are in the exemptions, then skip
262         while($tax_rate = db_fetch($tax_rates)) 
263         { 
264                 
265                 $skip = false;                  
266                 
267                 // if it's in the exemptions, skip
268                 foreach ($item_tax_type_exemptions as $exemption) 
269                 {
270                         if (($tax_rate['id'] == $exemption)) 
271                         {
272                         $skip = true;
273                         break;
274                         }
275                 }
276                 
277                 if (!$skip) 
278                 {
279                         $index = $tax_rate['id'];
280                         $ret_tax_array[$index] = $tax_rate;
281                 }
282         }
283         
284         return $ret_tax_array;
285 }
286
287 function is_tax_account($account_code)
288 {
289         $sql= "SELECT id FROM ".TB_PREF."tax_types WHERE 
290                 sales_gl_code='$account_code' OR purchasing_gl_code='$account_code'";
291         $result = db_query($sql, "checking account is tax account");
292         if (db_num_rows($result) > 0) {
293                 $acct = db_fetch($result);
294                 return $acct['id'];
295         } else
296                 return false;
297 }
298
299 ?>