Copyright notes at top op every source file
[fa-stable.git] / taxes / tax_calc.inc
1 <?php
2 /**********************************************************************
3     Copyright (C) FrontAccounting, LLC.
4         Released under the terms of the GNU Affero General Public License,
5         AGPL, as published by the Free Software Foundation, either version 
6         3 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/agpl-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         // loop for all items
178         for ($i = 0; $i < count($items); $i++)
179         {
180                 $item_taxes = get_taxes_for_item($items[$i], $ret_tax_array);
181
182                 if ($item_taxes != null) 
183                 {
184                         foreach ($item_taxes as $item_tax) 
185                         {
186                                 $index = $item_tax['tax_type_id'];
187                                 if($tax_included==1) // 2008-11-26 Joe Hunt Taxes are stored without roundings
188                                   //$ret_tax_array[$index]['Value'] += round($prices[$i] * $item_tax['rate'] 
189                                   //    / ($item_tax['rate'] + 100),  user_price_dec());
190                                   $ret_tax_array[$index]['Value'] += ($prices[$i] * $item_tax['rate'] / ($item_tax['rate'] + 100));
191                                 else
192                                   //$ret_tax_array[$index]['Value'] += 
193                                   //    round($prices[$i] * $item_tax['rate'] / 100,  user_price_dec());
194                                   $ret_tax_array[$index]['Value'] += ($prices[$i] * $item_tax['rate'] / 100);
195                         }
196                 }
197         }
198         
199         // add the shipping taxes, only if non-zero, and only if tax group taxes shipping
200         if ($shipping_cost != 0) 
201         {
202                 $item_taxes = get_shipping_tax_as_array();
203                 if ($item_taxes != null) 
204                 {
205                         foreach ($item_taxes as $item_tax) 
206                         {
207                                 $index = $item_tax['tax_type_id'];
208                                 if(isset($ret_tax_array[$index])) {
209                                   if($tax_included==1) // 2008-11-26 Joe Hunt Taxes are stored without roundings
210                                         //$ret_tax_array[$index]['Value'] += round($shipping_cost * $item_tax['rate'] 
211                                         //  / ($item_tax['rate'] + 100),  user_price_dec());
212                                         $ret_tax_array[$index]['Value'] += ($shipping_cost * $item_tax['rate'] / ($item_tax['rate'] + 100));
213                                   else
214                                         //$ret_tax_array[$index]['Value'] += 
215                                         //  round($shipping_cost * $item_tax['rate'] / 100,  user_price_dec());
216                                         $ret_tax_array[$index]['Value'] += ($shipping_cost * $item_tax['rate'] / 100);
217                                 }
218                         }
219                 }
220         }
221         
222         //print_r($ret_tax_array);
223
224         return $ret_tax_array;
225 }
226 //
227 //      Get all taxes for given tax_type_id. This can be used when 
228 //      no tax group exemptions are active (local sales).
229 //      To be used in quick entries.
230 //
231 function get_taxes_for_item_tax($tax_type_id)
232 {
233         $item_tax_type = get_item_tax_type($tax_type_id);
234         
235         // if the item is exempt from all taxes then return 0
236         if ($item_tax_type["exempt"])
237                 return null;
238                 
239         // get the exemptions for this item tax type
240         $item_tax_type_exemptions_db = get_item_tax_type_exemptions($tax_type_id);
241         
242         // read them all into an array to minimize db querying
243         $item_tax_type_exemptions = array();
244         while ($item_tax_type_exemp = db_fetch($item_tax_type_exemptions_db))
245         {
246                 $item_tax_type_exemptions[] = $item_tax_type_exemp["tax_type_id"];
247         }
248         
249         $ret_tax_array = array();
250
251         $tax_rates = get_all_tax_types_simple();
252         // if any of the taxes are in the exemptions, then skip
253         while($tax_rate = db_fetch($tax_rates)) 
254         { 
255                 
256                 $skip = false;                  
257                 
258                 // if it's in the exemptions, skip
259                 foreach ($item_tax_type_exemptions as $exemption) 
260                 {
261                         if (($tax_rate['id'] == $exemption)) 
262                         {
263                         $skip = true;
264                         break;
265                         }
266                 }
267                 
268                 if (!$skip) 
269                 {
270                         $index = $tax_rate['id'];
271                         $ret_tax_array[$index] = $tax_rate;
272                 }
273         }
274         
275         return $ret_tax_array;
276 }
277
278 function is_tax_account($account_code)
279 {
280         $sql= "SELECT id FROM ".TB_PREF."tax_types WHERE 
281                 sales_gl_code='$account_code' OR purchasing_gl_code='$account_code'";
282         $result = db_query($sql, "checking account is tax account");
283         if (db_num_rows($result) > 0) {
284                 $acct = db_fetch($result);
285                 return $acct['id'];
286         } else
287                 return false;
288 }
289
290 ?>