Switch to new access levels system
[fa-stable.git] / admin / fiscalyears.php
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 $page_security = 'SA_FISCALYEARS';
13 $path_to_root = "..";
14 include_once($path_to_root . "/includes/session.inc");
15
16 include_once($path_to_root . "/includes/date_functions.inc");
17 include_once($path_to_root . "/admin/db/company_db.inc");
18 include_once($path_to_root . "/includes/ui.inc");
19 include_once($path_to_root . "/sales/includes/db/cust_trans_db.inc");
20 include_once($path_to_root . "/admin/db/maintenance_db.inc");
21 $js = "";
22 if ($use_date_picker)
23         $js .= get_js_date_picker();
24 page(_("Fiscal Years"), false, false, "", $js);
25
26 simple_page_mode(true);
27 //---------------------------------------------------------------------------------------------
28
29 function is_date_in_fiscalyears($date)
30 {
31         $date = date2sql($date);
32         $sql = "SELECT * FROM ".TB_PREF."fiscal_year WHERE '$date' >= begin AND '$date' <= end";
33
34         $result = db_query($sql, "could not get all fiscal years");
35         return db_fetch($result) !== false;
36 }
37
38 function is_bad_begin_date($date)
39 {
40         $bdate = date2sql($date);
41         $sql = "SELECT MAX(end) FROM ".TB_PREF."fiscal_year WHERE begin < '$bdate'";
42
43         $result = db_query($sql, "could not retrieve last fiscal years");
44         $row = db_fetch_row($result);
45         if ($row[0] === null)
46                 return false;
47         $max = add_days(sql2date($row[0]), 1);
48         return ($max !== $date);
49 }
50
51 function check_years_before($date, $closed=false)
52 {
53         $date = date2sql($date);
54         $sql = "SELECT COUNT(*) FROM ".TB_PREF."fiscal_year WHERE begin < '$date'";
55         if (!$closed)
56                 $sql .= " AND closed=0";
57
58         $result = db_query($sql, "could not check fiscal years before");
59         $row = db_fetch_row($result);
60         return ($row[0] > 0);
61 }
62
63 function check_data()
64 {
65         if (!is_date($_POST['from_date']) || is_date_in_fiscalyears($_POST['from_date']) || is_bad_begin_date($_POST['from_date']))
66         {
67                 display_error( _("Invalid BEGIN date in fiscal year."));
68                 set_focus('from_date');
69                 return false;
70         }
71         if (!is_date($_POST['to_date']) || is_date_in_fiscalyears($_POST['to_date']))
72         {
73                 display_error( _("Invalid END date in fiscal year."));
74                 set_focus('to_date');
75                 return false;
76         }
77         if (date1_greater_date2($_POST['from_date'], $_POST['to_date']))
78         {
79                 display_error( _("BEGIN date bigger than END date."));
80                 set_focus('from_date');
81                 return false;
82         }
83         return true;
84 }
85 //---------------------------------------------------------------------------------------------
86 function close_year($year)
87 {
88         $myrow = get_fiscalyear($year);
89         $to = $myrow['end'];
90         // retrieve total balances from balance sheet accounts
91     $sql = "SELECT SUM(amount) FROM ".TB_PREF."gl_trans INNER JOIN ".TB_PREF."chart_master ON account=account_code
92         INNER JOIN ".TB_PREF."chart_types ON account_type=id INNER JOIN ".TB_PREF."chart_class ON class_id=cid 
93                 WHERE ctype>=".CL_ASSETS." AND ctype <=".CL_EQUITY." AND tran_date <= '$to'";
94         $result = db_query($sql, "The total balance could not be calculated");
95
96         $row = db_fetch_row($result);
97         $balance = round2($row[0], user_price_dec());
98
99         begin_transaction();
100         $to = sql2date($to);
101
102         if ($balance != 0.0)
103         {
104                 $co = get_company_prefs();
105
106                 $trans_type = systypes::journal_entry();
107                 $trans_id = get_next_trans_no($trans_type);
108
109                 add_gl_trans($trans_type, $trans_id, $to, $co['retained_earnings_act'],
110                         0, 0, _("Closing Year"), -$balance);
111                 add_gl_trans($trans_type, $trans_id, $to, $co['profit_loss_year_act'],
112                         0, 0, _("Closing Year"), $balance);
113
114         }       
115                 close_transactions($to);
116                 commit_transaction();
117 }
118
119 function open_year($year)
120 {
121         $myrow = get_fiscalyear($year);
122         $from = sql2date($myrow['begin']);
123
124         begin_transaction();
125         open_transactions($from);
126         commit_transaction();
127 }
128
129 function handle_submit()
130 {
131         global $selected_id, $Mode;
132
133         if ($selected_id != -1)
134         {
135                 if ($_POST['closed'] == 1)
136                 {
137                         if (check_years_before($_POST['from_date'], false))
138                         {
139                                 display_error( _("Cannot CLOSE this year because there are open fiscal years before"));
140                                 set_focus('closed');
141                                 return false;
142                         }       
143                         close_year($selected_id);
144                 }       
145                 else
146                         open_year($selected_id);
147                 update_fiscalyear($selected_id, $_POST['closed']);
148                 display_notification(_('Selected fiscal year has been updated'));
149         }
150         else
151         {
152                 if (!check_data())
153                         return false;
154                 add_fiscalyear($_POST['from_date'], $_POST['to_date'], $_POST['closed']);
155                 display_notification(_('New fiscal year has been added'));
156         }
157         $Mode = 'RESET';
158 }
159
160 //---------------------------------------------------------------------------------------------
161
162 function check_can_delete($selected_id)
163 {
164         $myrow = get_fiscalyear($selected_id);
165         // PREVENT DELETES IF DEPENDENT RECORDS IN gl_trans
166         if (check_years_before(sql2date($myrow['begin']), true))
167         {
168                 display_error(_("Cannot delete this fiscal year because thera are fiscal years before."));
169                 return false;
170         }
171         if ($myrow['closed'] == 0)
172         {
173                 display_error(_("Cannot delete this fiscal year because the fiscal year is not closed."));
174                 return false;
175         }
176         return true;
177 }
178
179 //---------------------------------------------------------------------------------------------
180 function delete_attachments_and_comments($type_no, $trans_no)
181 {
182         global $comp_path;
183         
184         $sql = "SELECT * FROM ".TB_PREF."attachments WHERE type_no = $type_no AND trans_no = $trans_no";
185         $result = db_query($sql, "Could not retrieve attachments");
186         while ($row = db_fetch($result))
187         {
188                 $dir =  $comp_path."/".user_company(). "/attachments";
189                 if (file_exists($dir."/".$row['unique_name']))
190                         unlink($dir."/".$row['unique_name']);
191                 $sql = "DELETE FROM ".TB_PREF."attachments WHERE  type_no = $type_no AND trans_no = $trans_no";
192                 db_query($sql, "Could not delete attachment");
193         }       
194         $sql = "DELETE FROM ".TB_PREF."comments WHERE  type = $type_no AND id = $trans_no";
195         db_query($sql, "Could not delete comments");
196 }       
197
198 function delete_this_fiscalyear($selected_id)
199 {
200         global $db_connections;
201         
202         db_backup($db_connections[$_SESSION["wa_current_user"]->company], 'Security backup before Fiscal Year Removal');
203         begin_transaction();
204         $ref = _("Open Balance");
205         $myrow = get_fiscalyear($selected_id);
206         $to = $myrow['end'];
207         $sql = "SELECT order_no FROM ".TB_PREF."sales_orders WHERE ord_date <= '$to' AND type <> 1"; // don't take the templates
208         $result = db_query($sql, "Could not retrieve sales orders");
209         while ($row = db_fetch($result))
210         {
211                 $sql = "SELECT SUM(qty_sent), SUM(quantity) FROM ".TB_PREF."sales_order_details WHERE order_no = {$row['order_no']}";
212                 $res = db_query($sql, "Could not retrieve sales order details");
213                 $row2 = db_fetch_row($res);
214                 if ($row2[0] == $row2[1])
215                 {
216                         $sql = "DELETE FROM ".TB_PREF."sales_order_details WHERE order_no = {$row['order_no']}";
217                         db_query($sql, "Could not delete sales order details");
218                         $sql = "DELETE FROM ".TB_PREF."sales_orders WHERE order_no = {$row['order_no']}";
219                         db_query($sql, "Could not delete sales order");
220                         delete_attachments_and_comments(systypes::sales_order(), $row['order_no']);
221                 }
222         }
223         $sql = "SELECT order_no FROM ".TB_PREF."purch_orders WHERE ord_date <= '$to'";
224         $result = db_query($sql, "Could not retrieve purchase orders");
225         while ($row = db_fetch($result))
226         {
227                 $sql = "SELECT SUM(quantity_ordered), SUM(quantity_received) FROM ".TB_PREF."purch_order_details WHERE order_no = {$row['order_no']}";
228                 $res = db_query($sql, "Could not retrieve purchase order details");
229                 $row2 = db_fetch_row($res);
230                 if ($row2[0] == $row2[1])
231                 {
232                         $sql = "DELETE FROM ".TB_PREF."purch_order_details WHERE order_no = {$row['order_no']}";
233                         db_query($sql, "Could not delete purchase order details");
234                         $sql = "DELETE FROM ".TB_PREF."purch_orders WHERE order_no = {$row['order_no']}";
235                         db_query($sql, "Could not delete purchase order");
236                         delete_attachments_and_comments(systypes::po(), $row['order_no']);
237                 }
238         }
239         $sql = "SELECT id FROM ".TB_PREF."grn_batch WHERE delivery_date <= '$to'";
240         $result = db_query($sql, "Could not retrieve grn batch");
241         while ($row = db_fetch($result))
242         {
243                 $sql = "DELETE FROM ".TB_PREF."grn_items WHERE grn_batch_id = {$row['id']}";
244                 db_query($sql, "Could not delete grn items");
245                 $sql = "DELETE FROM ".TB_PREF."grn_batch WHERE id = {$row['id']}";
246                 db_query($sql, "Could not delete grn batch");
247                 delete_attachments_and_comments(25, $row['id']);
248         }
249         $sql = "SELECT trans_no, type FROM ".TB_PREF."debtor_trans WHERE tran_date <= '$to' AND 
250                 (ov_amount + ov_gst + ov_freight + ov_freight_tax + ov_discount) = alloc";
251         $result = db_query($sql, "Could not retrieve debtor trans");
252         while ($row = db_fetch($result))
253         {
254                 if ($row['type'] == 10)
255                 {
256                         $deliveries = get_parent_trans(10,$row['trans_no']);
257                         foreach ($deliveries as $delivery)
258                         {
259                                 $sql = "DELETE FROM ".TB_PREF."debtor_trans_details WHERE debtor_trans_no = $delivery AND debtor_trans_type = 13";
260                                 db_query($sql, "Could not delete debtor trans details");
261                                 $sql = "DELETE FROM ".TB_PREF."debtor_trans WHERE trans_no = $delivery AND type = 13";
262                                 db_query($sql, "Could not delete debtor trans");
263                         }               
264                 }       
265                 $sql = "DELETE FROM ".TB_PREF."cust_allocations WHERE trans_no_from = {$row['trans_no']} AND type_no_from = {$row['type']}";
266                 db_query($sql, "Could not delete cust allocations");
267                 $sql = "DELETE FROM ".TB_PREF."debtor_trans_details WHERE debtor_trans_no = {$row['trans_no']} AND debtor_trans_type = {$row['type']}";
268                 db_query($sql, "Could not delete debtor trans details");
269                 $sql = "DELETE FROM ".TB_PREF."debtor_trans WHERE trans_no = {$row['trans_no']} AND type = {$row['type']}";
270                 db_query($sql, "Could not delete debtor trans");
271                 delete_attachments_and_comments($row['type'], $row['trans_no']);
272         }
273         $sql = "SELECT trans_no, type FROM ".TB_PREF."supp_trans WHERE tran_date <= '$to' AND 
274                 ABS(ov_amount + ov_gst + ov_discount) = alloc";
275         $result = db_query($sql, "Could not retrieve supp trans");
276         while ($row = db_fetch($result))
277         {
278                 $sql = "DELETE FROM ".TB_PREF."supp_allocations WHERE trans_no_from = {$row['trans_no']} AND type_no_from = {$row['type']}";
279                 db_query($sql, "Could not delete supp allocations");
280                 $sql = "DELETE FROM ".TB_PREF."supp_invoice_items WHERE supp_trans_no = {$row['trans_no']} AND supp_trans_type = {$row['type']}";
281                 db_query($sql, "Could not delete supp invoice items");
282                 $sql = "DELETE FROM ".TB_PREF."supp_trans WHERE trans_no = {$row['trans_no']} AND type = {$row['type']}";
283                 db_query($sql, "Could not delete supp trans");
284                 delete_attachments_and_comments($row['type'], $row['trans_no']);
285         }
286         $sql = "SELECT id FROM ".TB_PREF."workorders WHERE released_date <= '$to' AND closed=1";
287         $result = db_query($sql, "Could not retrieve supp trans");
288         while ($row = db_fetch($result))
289         {
290                 $sql = "SELECT issue_no FROM ".TB_PREF."wo_issues WHERE workorder_id = {$row['id']}"; 
291                 $res = db_query($sql, "Could not retrieve wo issues");
292                 while ($row2 = db_fetch_row($res))
293                 {
294                         $sql = "DELETE FROM ".TB_PREF."wo_issue_items WHERE issue_id = {$row2[0]}";
295                         db_query($sql, "Could not delete wo issue items");
296                 }       
297                 delete_attachments_and_comments(28, $row['id']);
298                 $sql = "DELETE FROM ".TB_PREF."wo_issues WHERE workorder_id = {$row['id']}";
299                 db_query($sql, "Could not delete wo issues");
300                 $sql = "DELETE FROM ".TB_PREF."wo_manufacture WHERE workorder_id = {$row['id']}";
301                 db_query($sql, "Could not delete wo manufacture");
302                 $sql = "DELETE FROM ".TB_PREF."wo_requirements WHERE workorder_id = {$row['id']}";
303                 db_query($sql, "Could not delete wo requirements");
304                 $sql = "DELETE FROM ".TB_PREF."workorders WHERE id = {$row['id']}";
305                 db_query($sql, "Could not delete workorders");
306                 delete_attachments_and_comments(26, $row['id']);
307         }
308         $sql = "SELECT loc_code, stock_id, SUM(qty) AS qty, SUM(qty*standard_cost) AS std_cost FROM ".TB_PREF."stock_moves WHERE tran_date <= '$to' GROUP by 
309                 loc_code, stock_id";
310         $result = db_query($sql, "Could not retrieve supp trans");
311         while ($row = db_fetch($result))
312         {
313                 $sql = "DELETE FROM ".TB_PREF."stock_moves WHERE tran_date <= '$to' AND loc_code = '{$row['loc_code']}' AND stock_id = '{$row['stock_id']}'";
314                 db_query($sql, "Could not delete stock moves");
315                 $qty = $row['qty'];
316                 $std_cost = ($qty == 0 ? 0 : round2($row['std_cost'] / $qty, user_price_dec()));
317                 $sql = "INSERT INTO ".TB_PREF."stock_moves (stock_id, loc_code, tran_date, reference, qty, standard_cost) VALUES
318                         ('{$row['stock_id']}', '{$row['loc_code']}', '$to', '$ref', $qty, $std_cost)";   
319                 db_query($sql, "Could not insert stock move");
320         }               
321         $sql = "DELETE FROM ".TB_PREF."voided WHERE date_ <= '$to'";
322         db_query($sql, "Could not delete voided items");
323         $sql = "DELETE FROM ".TB_PREF."trans_tax_details WHERE tran_date <= '$to'";
324         db_query($sql, "Could not delete trans tax details");
325         $sql = "DELETE FROM ".TB_PREF."exchange_rates WHERE date_ <= '$to'";
326         db_query($sql, "Could not delete exchange rates");
327         $sql = "DELETE FROM ".TB_PREF."budget_trans WHERE tran_date <= '$to'";
328         db_query($sql, "Could not delete exchange rates");
329         $sql = "SELECT account, SUM(amount) AS amount FROM ".TB_PREF."gl_trans WHERE tran_date <= '$to' GROUP by account";
330         $result = db_query($sql, "Could not retrieve gl trans");
331         while ($row = db_fetch($result))
332         {
333                 $sql = "DELETE FROM ".TB_PREF."gl_trans WHERE tran_date <= '$to' AND account = '{$row['account']}'";
334                 db_query($sql, "Could not delete gl trans");
335                 if (is_account_balancesheet($row['account']))
336                 {
337                         $trans_no = get_next_trans_no(0);
338                         if (is_bank_account($row['account']))
339                         {
340                                 $sql = "SELECT SUM(amount) FROM ".TB_PREF."bank_trans WHERE trans_date <= '$to' AND bank_act = '{$row['account']}'";
341                                 $res = db_query($sql, "Could not retrieve bank trans");
342                                 $row2 = db_fetch_row($res);
343                                 $sql = "DELETE FROM ".TB_PREF."bank_trans WHERE trans_date <= '$to' AND bank_act = '{$row['account']}'";
344                                 db_query($sql, "Could not delete bank trans");
345                                 $sql = "INSERT INTO ".TB_PREF."bank_trans (type, trans_no, trans_date, bank_act, ref, amount) VALUES
346                                         (0, $trans_no, '$to', '{$row['account']}', '$ref', {$row2[0]})";
347                                 db_query($sql, "Could not insert bank trans");
348                         }       
349                         $sql = "INSERT INTO ".TB_PREF."gl_trans (type, type_no, tran_date, account, memo_, amount) VALUES
350                                 (0, $trans_no, '$to', '{$row['account']}', '$ref', {$row['amount']})";
351                         db_query($sql, "Could not insert gl trans");
352                 }
353         }
354         delete_fiscalyear($selected_id);
355         commit_transaction();   
356 }
357
358 function handle_delete()
359 {
360         global $selected_id, $Mode;
361
362         if (check_can_delete($selected_id)) {
363         //only delete if used in neither customer or supplier, comp prefs, bank trans accounts
364                 delete_this_fiscalyear($selected_id);
365                 display_notification(_('Selected fiscal year has been deleted'));
366         }
367         $Mode = 'RESET';
368 }
369
370 //---------------------------------------------------------------------------------------------
371
372 function display_fiscalyears()
373 {
374         global $table_style;
375
376         $company_year = get_company_pref('f_year');
377
378         $result = get_all_fiscalyears();
379         start_form();
380         display_note(_("Warning: During fiscal year removal all transactions 
381                 are removed and converted into relevant balances. This process is irreversible!"), 
382                 0, 0, "class='currentfg'");
383         start_table($table_style);
384
385         $th = array(_("Fiscal Year Begin"), _("Fiscal Year End"), _("Closed"), "", "");
386         table_header($th);
387
388         $k=0;
389         while ($myrow=db_fetch($result))
390         {
391         if ($myrow['id'] == $company_year)
392         {
393                 start_row("class='stockmankobg'");
394         }
395         else
396                 alt_table_row_color($k);
397
398                 $from = sql2date($myrow["begin"]);
399                 $to = sql2date($myrow["end"]);
400                 if ($myrow["closed"] == 0)
401                 {
402                         $closed_text = _("No");
403                 }
404                 else
405                 {
406                         $closed_text = _("Yes");
407                 }
408                 label_cell($from);
409                 label_cell($to);
410                 label_cell($closed_text);
411                 edit_button_cell("Edit".$myrow['id'], _("Edit"));
412                 if ($myrow["id"] != $company_year) {
413                         delete_button_cell("Delete".$myrow['id'], _("Delete"));
414                         submit_js_confirm("Delete".$myrow['id'],
415                                 sprintf(_("Are you sure you want to remove fiscal year
416                                 '%s'-'%s'? All transactions are removed and converted into relevant
417                                 balances. Do you want to continue ?"), $from, $to));
418                 } else
419                         label_cell('');
420                 end_row();
421         }
422
423         end_table();
424         end_form();
425         display_note(_("The marked fiscal year is the current fiscal year which cannot be deleted."), 0, 0, "class='currentfg'");
426 }
427
428 //---------------------------------------------------------------------------------------------
429
430 function display_fiscalyear_edit($selected_id)
431 {
432         global $table_style2, $Mode;
433
434         start_form();
435         start_table($table_style2);
436
437         if ($selected_id != -1)
438         {
439                 if($Mode =='Edit')
440                 {
441                         $myrow = get_fiscalyear($selected_id);
442
443                         $_POST['from_date'] = sql2date($myrow["begin"]);
444                         $_POST['to_date']  = sql2date($myrow["end"]);
445                         $_POST['closed']  = $myrow["closed"];
446                 }
447                 hidden('from_date');
448                 hidden('to_date');
449                 label_row(_("Fiscal Year Begin:"), $_POST['from_date']);
450                 label_row(_("Fiscal Year End:"), $_POST['to_date']);
451         }
452         else
453         {
454                 date_row(_("Fiscal Year Begin:"), 'from_date', '', null, 0, 0, 1001);
455                 date_row(_("Fiscal Year End:"), 'to_date', '', null, 0, 0, 1001);
456         }
457         hidden('selected_id', $selected_id);
458
459         yesno_list_row(_("Is Closed:"), 'closed', null, "", "", false);
460
461         end_table(1);
462
463         submit_add_or_update_center($selected_id == -1, '', 'both');
464
465         end_form();
466 }
467
468 //---------------------------------------------------------------------------------------------
469
470 if ($Mode=='ADD_ITEM' || $Mode=='UPDATE_ITEM')
471 {
472         handle_submit();
473 }
474
475 //---------------------------------------------------------------------------------------------
476
477 if ($Mode == 'Delete')
478 {
479         global $selected_id;
480         handle_delete($selected_id);
481 }
482
483 if ($Mode == 'RESET')
484 {
485         $selected_id = -1;
486 }
487 //---------------------------------------------------------------------------------------------
488
489 display_fiscalyears();
490
491 echo '<br>';
492
493 display_fiscalyear_edit($selected_id);
494
495 //---------------------------------------------------------------------------------------------
496
497 end_page();
498
499 ?>