08b8e89806914046e52c25bdb642b90cd1bac28d
[fa-stable.git] / reporting / rep308.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_ITEMSVALREP';
13 // ----------------------------------------------------------------
14 // $ Revision:  2.0 $
15 // Creator:     Jujuk, Joe Hunt
16 // date_:       2011-05-24
17 // Title:       Stock Movements
18 // ----------------------------------------------------------------
19 $path_to_root="..";
20
21 include_once($path_to_root . "/includes/session.inc");
22 include_once($path_to_root . "/includes/date_functions.inc");
23 include_once($path_to_root . "/includes/ui/ui_input.inc");
24 include_once($path_to_root . "/includes/data_checks.inc");
25 include_once($path_to_root . "/gl/includes/gl_db.inc");
26 include_once($path_to_root . "/sales/includes/db/sales_types_db.inc");
27 include_once($path_to_root . "/inventory/includes/inventory_db.inc");
28
29 //----------------------------------------------------------------------------------------------------
30
31 inventory_movements();
32
33 function get_domestic_price($myrow, $stock_id, $qty, $old_std_cost, $old_qty)
34 {
35         if ($myrow['type'] == ST_SUPPRECEIVE || $myrow['type'] == ST_SUPPCREDIT)
36         {
37                 $price = $myrow['price'];
38                 if ($myrow['type'] == ST_SUPPRECEIVE)
39                 {
40                         // Has the supplier invoice increased the receival price?
41                         $sql = "SELECT DISTINCT act_price FROM ".TB_PREF."purch_order_details pod INNER JOIN ".TB_PREF."grn_batch grn ON pod.order_no =
42                                 grn.purch_order_no WHERE grn.id = ".$myrow['trans_no']." AND pod.item_code = '$stock_id'";
43                         $result = db_query($sql, "Could not retrieve act_price from purch_order_details");
44                         $row = db_fetch_row($result);
45                         if ($row[0] > 0 AND $row[0] <> $myrow['price'])
46                                 $price = $row[0];
47                 }
48                 if ($myrow['person_id'] > 0)
49                 {
50                         // Do we have foreign currency?
51                         $supp = get_supplier($myrow['person_id']);
52                         $currency = $supp['curr_code'];
53                         $ex_rate = get_exchange_rate_to_home_currency($currency, sql2date($myrow['tran_date']));
54                         $price /= $ex_rate;
55                 }       
56         }
57         elseif ($myrow['type'] != ST_INVADJUST) // calcutale the price from avg. price
58                 $price = ($myrow['standard_cost'] * $qty - $old_std_cost * $old_qty) / $myrow['qty'];
59         else
60                 $price = $myrow['standard_cost']; // Item Adjustments just have the real cost
61         return $price;
62 }       
63
64 function fetch_items($category=0)
65 {
66                 $sql = "SELECT stock_id, stock.description AS name,
67                                 stock.category_id,units,
68                                 cat.description
69                         FROM ".TB_PREF."stock_master stock LEFT JOIN ".TB_PREF."stock_category cat ON stock.category_id=cat.category_id
70                                 WHERE mb_flag <> 'D' AND mb_flag <> 'F'";
71                 if ($category != 0)
72                         $sql .= " AND cat.category_id = ".db_escape($category);
73                 $sql .= " ORDER BY stock.category_id, stock_id";
74
75     return db_query($sql,"No transactions were returned");
76 }
77
78 function trans_qty($stock_id, $location=null, $from_date, $to_date, $inward = true)
79 {
80         if ($from_date == null)
81                 $from_date = Today();
82
83         $from_date = date2sql($from_date);      
84
85         if ($to_date == null)
86                 $to_date = Today();
87
88         $to_date = date2sql($to_date);
89
90         $sql = "SELECT ".($inward ? '' : '-')."SUM(qty) FROM ".TB_PREF."stock_moves
91                 WHERE stock_id=".db_escape($stock_id)."
92                 AND tran_date >= '$from_date' 
93                 AND tran_date <= '$to_date' AND type <> ".ST_LOCTRANSFER;
94
95         if ($location != '')
96                 $sql .= " AND loc_code = ".db_escape($location);
97
98         if ($inward)
99                 $sql .= " AND qty > 0 ";
100         else
101                 $sql .= " AND qty < 0 ";
102
103         $result = db_query($sql, "QOH calculation failed");
104
105         $myrow = db_fetch_row($result); 
106
107         return $myrow[0];
108
109 }
110
111 function avg_unit_cost($stock_id, $location=null, $to_date)
112 {
113         if ($to_date == null)
114                 $to_date = Today();
115
116         $to_date = date2sql($to_date);
117
118         $sql = "SELECT move.*, IF(ISNULL(supplier.supplier_id), debtor.debtor_no, supplier.supplier_id) person_id
119                 FROM ".TB_PREF."stock_moves move
120                                 LEFT JOIN ".TB_PREF."supp_trans credit ON credit.trans_no=move.trans_no AND credit.type=move.type
121                                 LEFT JOIN ".TB_PREF."grn_batch grn ON grn.id=move.trans_no AND 25=move.type
122                                 LEFT JOIN ".TB_PREF."suppliers supplier ON IFNULL(grn.supplier_id, credit.supplier_id)=supplier.supplier_id
123                                 LEFT JOIN ".TB_PREF."debtor_trans cust_trans ON cust_trans.trans_no=move.trans_no AND cust_trans.type=move.type
124                                 LEFT JOIN ".TB_PREF."debtors_master debtor ON cust_trans.debtor_no=debtor.debtor_no
125                         WHERE stock_id=".db_escape($stock_id)."
126                         AND move.tran_date < '$to_date' AND standard_cost > 0.001 AND qty <> 0 AND move.type <> ".ST_LOCTRANSFER;
127
128         if ($location != '')
129                 $sql .= " AND move.loc_code = ".db_escape($location);
130         $sql .= " ORDER BY tran_date";  
131
132         $result = db_query($sql, "No standard cost transactions were returned");
133     if ($result == false)
134         return 0;
135         $qty = $old_qty = $count = $old_std_cost = $tot_cost = 0;
136         while ($row=db_fetch($result))
137         {
138                 $qty += $row['qty'];    
139
140                 $price = get_domestic_price($row, $stock_id, $qty, $old_std_cost, $old_qty);
141         
142                 $old_std_cost = $row['standard_cost'];
143                 $tot_cost += $price;
144                 $count++;
145                 $old_qty = $qty;
146         }
147         if ($count == 0)
148                 return 0;
149         return $tot_cost / $count;
150 }
151
152 //----------------------------------------------------------------------------------------------------
153
154 function trans_qty_unit_cost($stock_id, $location=null, $from_date, $to_date, $inward = true)
155 {
156         if ($from_date == null)
157                 $from_date = Today();
158
159         $from_date = date2sql($from_date);      
160
161         if ($to_date == null)
162                 $to_date = Today();
163
164         $to_date = date2sql($to_date);
165
166         $sql = "SELECT move.*, IF(ISNULL(supplier.supplier_id), debtor.debtor_no, supplier.supplier_id) person_id
167                 FROM ".TB_PREF."stock_moves move
168                                 LEFT JOIN ".TB_PREF."supp_trans credit ON credit.trans_no=move.trans_no AND credit.type=move.type
169                                 LEFT JOIN ".TB_PREF."grn_batch grn ON grn.id=move.trans_no AND 25=move.type
170                                 LEFT JOIN ".TB_PREF."suppliers supplier ON IFNULL(grn.supplier_id, credit.supplier_id)=supplier.supplier_id
171                                 LEFT JOIN ".TB_PREF."debtor_trans cust_trans ON cust_trans.trans_no=move.trans_no AND cust_trans.type=move.type
172                                 LEFT JOIN ".TB_PREF."debtors_master debtor ON cust_trans.debtor_no=debtor.debtor_no
173                 WHERE stock_id=".db_escape($stock_id)."
174                 AND move.tran_date <= '$to_date' AND standard_cost > 0.001 AND qty <> 0 AND move.type <> ".ST_LOCTRANSFER;
175
176         if ($location != '')
177                 $sql .= " AND move.loc_code = ".db_escape($location);
178
179         if ($inward)
180                 $sql .= " AND qty > 0 ";
181         else
182                 $sql .= " AND qty < 0 ";
183         $sql .= " ORDER BY tran_date";
184         $result = db_query($sql, "No standard cost transactions were returned");
185     if ($result == false)
186         return 0;
187         $qty = $count = $old_qty = $old_std_cost = $tot_cost = 0;
188         while ($row=db_fetch($result))
189         {
190                 $qty += $row['qty'];
191
192                 $price = get_domestic_price($row, $stock_id, $qty, $old_std_cost, $old_qty);
193         
194                 if (strncmp($row['tran_date'], $from_date,10) >= 0)
195                 {
196                         $tot_cost += $price;
197                         $count++;
198                 }
199                 
200                 $old_std_cost = $row['standard_cost'];
201                 $old_qty = $qty;
202         }       
203         if ($count == 0)
204                 return 0;
205         return $tot_cost / $count;
206
207 }
208
209 //----------------------------------------------------------------------------------------------------
210
211 function inventory_movements()
212 {
213     global $path_to_root;
214
215     $from_date = $_POST['PARAM_0'];
216     $to_date = $_POST['PARAM_1'];
217     $category = $_POST['PARAM_2'];
218         $location = $_POST['PARAM_3'];
219     $comments = $_POST['PARAM_4'];
220         $orientation = $_POST['PARAM_5'];
221         $destination = $_POST['PARAM_6'];
222         if ($destination)
223                 include_once($path_to_root . "/reporting/includes/excel_report.inc");
224         else
225                 include_once($path_to_root . "/reporting/includes/pdf_report.inc");
226
227         $orientation = ($orientation ? 'L' : 'P');
228         if ($category == ALL_NUMERIC)
229                 $category = 0;
230         if ($category == 0)
231                 $cat = _('All');
232         else
233                 $cat = get_category_name($category);
234
235         if ($location == '')
236                 $loc = _('All');
237         else
238                 $loc = get_location_name($location);
239
240         $cols = array(0, 60, 130, 160, 185, 215, 250, 275, 305, 340, 365, 395, 430, 455, 485, 520);
241
242         $headers = array(_('Category'), _('Description'),       _('UOM'), '', '', _('OpeningStock'), '', '',_('StockIn'), '', '', _('Delivery'), '', '', _('ClosingStock'));
243         $headers2 = array("", "", "", _("QTY"), _("Rate"), _("Value"), _("QTY"), _("Rate"), _("Value"), _("QTY"), _("Rate"), _("Value"), _("QTY"), _("Rate"), _("Value"));
244
245         $aligns = array('left', 'left', 'left', 'right', 'right', 'right', 'right','right' ,'right', 'right', 'right','right', 'right', 'right', 'right');
246
247     $params =   array(  0 => $comments,
248                                                 1 => array('text' => _('Period'), 'from' => $from_date, 'to' => $to_date),
249                                     2 => array('text' => _('Category'), 'from' => $cat, 'to' => ''),
250                                                 3 => array('text' => _('Location'), 'from' => $loc, 'to' => ''));
251
252     $rep = new FrontReport(_('Costed Inventory Movements'), "CostedInventoryMovements", user_pagesize(), 8, $orientation);
253     if ($orientation == 'L')
254         recalculate_cols($cols);
255
256     $rep->Font();
257     $rep->Info($params, $cols, $headers2, $aligns, $cols, $headers, $aligns);
258     $rep->NewPage();
259
260         $totval_open = $totval_in = $totval_out = $totval_close = 0; 
261         $result = fetch_items($category);
262
263         $dec = user_price_dec();
264         $catgor = '';
265         while ($myrow=db_fetch($result))
266         {
267                 if ($catgor != $myrow['description'])
268                 {
269                         $rep->NewLine(2);
270                         $rep->fontSize += 2;
271                         $rep->TextCol(0, 3, $myrow['category_id'] . " - " . $myrow['description']);
272                         $catgor = $myrow['description'];
273                         $rep->fontSize -= 2;
274                         $rep->NewLine();
275                 }
276                 $qoh_start = get_qoh_on_date($myrow['stock_id'], $location, add_days($from_date, -1));
277                 $qoh_end = get_qoh_on_date($myrow['stock_id'], $location, $to_date);
278                 
279                 $inward = trans_qty($myrow['stock_id'], $location, $from_date, $to_date);
280                 $outward = trans_qty($myrow['stock_id'], $location, $from_date, $to_date, false);
281                 $openCost = avg_unit_cost($myrow['stock_id'], $location, $from_date);
282                 $unitCost = avg_unit_cost($myrow['stock_id'], $location, add_days($to_date, 1));
283                 if ($qoh_start == 0 && $inward == 0 && $outward == 0 && $qoh_end == 0)
284                         continue;
285                 $rep->NewLine();
286                 $rep->TextCol(0, 1,     $myrow['stock_id']);
287                 $rep->TextCol(1, 2, $myrow['name']);
288                 $rep->TextCol(2, 3, $myrow['units']);
289                 $rep->AmountCol(3, 4, $qoh_start, get_qty_dec($myrow['stock_id']));
290                 $rep->AmountCol(4, 5, $openCost, $dec);
291                 $openCost *= $qoh_start;
292                 $totval_open += $openCost;
293                 $rep->AmountCol(5, 6, $openCost);
294                 
295                 if($inward>0){
296                         $rep->AmountCol(6, 7, $inward, get_qty_dec($myrow['stock_id']));
297                         $unitCost_in = trans_qty_unit_cost($myrow['stock_id'], $location, $from_date, $to_date);
298                         $rep->AmountCol(7, 8, $unitCost_in,$dec);
299                         $unitCost_in *= $inward;
300                         $totval_in += $unitCost_in;
301                         $rep->AmountCol(8, 9, $unitCost_in);
302                 }
303                 
304                 if($outward>0){
305                         $rep->AmountCol(9, 10, $outward, get_qty_dec($myrow['stock_id']));
306                         $unitCost_out = trans_qty_unit_cost($myrow['stock_id'], $location, $from_date, $to_date, false);
307                         $rep->AmountCol(10, 11, $unitCost_out,$dec);
308                         $unitCost_out *= $outward;
309                         $totval_out += $unitCost_out;
310                         $rep->AmountCol(11, 12, $unitCost_out);
311                 }
312                 
313                 $rep->AmountCol(12, 13, $qoh_end, get_qty_dec($myrow['stock_id']));
314                 $rep->AmountCol(13, 14, $unitCost,$dec);
315                 $unitCost *= $qoh_end;
316                 $totval_close += $unitCost;
317                 $rep->AmountCol(14, 15, $unitCost);
318                 
319                 $rep->NewLine(0, 1);
320         }
321         $rep->Line($rep->row  - 4);
322         $rep->NewLine(2);
323         $rep->TextCol(0, 1,     _("Total"));
324         $rep->AmountCol(5, 6, $totval_open);
325         $rep->AmountCol(8, 9, $totval_in);
326         $rep->AmountCol(11, 12, $totval_out);
327         $rep->AmountCol(14, 15, $totval_close);
328         $rep->Line($rep->row  - 4);
329
330     $rep->End();
331 }
332