Added POS and cash sale support.
[fa-stable.git] / sales / includes / db / sales_order_db.inc
1 <?php
2
3 //----------------------------------------------------------------------------------------
4 function get_demand_qty($stockid, $location)
5 {
6         $sql = "SELECT SUM(".TB_PREF."sales_order_details.quantity - ".TB_PREF."sales_order_details.qty_sent) AS QtyDemand
7                                 FROM ".TB_PREF."sales_order_details,
8                                         ".TB_PREF."sales_orders
9                                 WHERE ".TB_PREF."sales_order_details.order_no=".TB_PREF."sales_orders.order_no AND
10                                         ".TB_PREF."sales_orders.from_stk_loc ='$location' AND
11                                         ".TB_PREF."sales_order_details.stk_code = '$stockid'";
12
13         $TransResult = db_query($sql,"No transactions were returned");
14         $DemandRow = db_fetch($TransResult);
15         return $DemandRow['QtyDemand'];
16 }
17
18 function get_demand_asm_qty($stockid, $location)
19 {
20         $sql = "SELECT SUM((".TB_PREF."sales_order_details.quantity-".TB_PREF."sales_order_details.qty_sent)*".TB_PREF."bom.quantity)
21                                 AS Dem
22                                 FROM ".TB_PREF."sales_order_details,
23                                                 ".TB_PREF."sales_orders,
24                                                 ".TB_PREF."bom,
25                                                 ".TB_PREF."stock_master
26                                 WHERE ".TB_PREF."sales_order_details.stk_code=".TB_PREF."bom.parent AND
27                                 ".TB_PREF."sales_orders.order_no = ".TB_PREF."sales_order_details.order_no AND
28                                 ".TB_PREF."sales_orders.from_stk_loc='$location' AND
29                                 ".TB_PREF."sales_order_details.quantity-".TB_PREF."sales_order_details.qty_sent > 0 AND
30                                 ".TB_PREF."bom.component='$stockid' AND
31                                 ".TB_PREF."stock_master.stock_id=".TB_PREF."bom.parent AND
32                                 ".TB_PREF."stock_master.mb_flag='A'";
33
34         $TransResult = db_query($sql,"No transactions were returned");
35         if (db_num_rows($TransResult)==1)
36         {
37                 $DemandRow = db_fetch_row($TransResult);
38                 $DemandQty = $DemandRow[0];
39         }
40         else
41                 $DemandQty = 0.0;
42
43         return $DemandQty;
44 }
45
46 function add_sales_order(&$order)
47 {
48         global $loc_notification, $path_to_root;
49
50         begin_transaction();
51
52         $del_date = date2sql($order->due_date);
53         $order_type = 0; // this is default on new order
54         $sql = "INSERT INTO ".TB_PREF."sales_orders (type, debtor_no, branch_code, customer_ref, comments, ord_date,
55                 order_type, ship_via, deliver_to, delivery_address, contact_phone,
56                 contact_email, freight_cost, from_stk_loc, delivery_date)
57                 VALUES (" .db_escape($order_type) . "," . db_escape($order->customer_id) .
58                  ", " . db_escape($order->Branch) . ", ".
59                         db_escape($order->cust_ref) .",". 
60                         db_escape($order->Comments) .",'" . 
61                         date2sql($order->document_date) . "', " .
62                         db_escape($order->sales_type) . ", " .
63                         db_escape($order->ship_via)."," . 
64                         db_escape($order->deliver_to) . "," .
65                         db_escape($order->delivery_address) . ", " .
66                         db_escape($order->phone) . ", " . 
67                         db_escape($order->email) . ", " .
68                         db_escape($order->freight_cost) .", " . 
69                         db_escape($order->Location) .", " .
70                         db_escape($del_date) . ")";
71
72         db_query($sql, "order Cannot be Added");
73
74         $order_no = db_insert_id();
75         $order->trans_no = array($order_no=>0);
76
77         if ($loc_notification == 1)
78         {
79                 include_once($path_to_root . "/inventory/includes/inventory_db.inc");
80                 $st_ids = array();
81                 $st_names = array();
82                 $st_num = array();
83                 $st_reorder = array();
84         }
85         foreach ($order->line_items as $line)
86         {
87                 if ($loc_notification == 1 && is_inventory_item($line->stock_id))
88                 {
89                         $sql = "SELECT ".TB_PREF."loc_stock.*, ".TB_PREF."locations.location_name, ".TB_PREF."locations.email
90                                 FROM ".TB_PREF."loc_stock, ".TB_PREF."locations
91                                 WHERE ".TB_PREF."loc_stock.loc_code=".TB_PREF."locations.loc_code
92                                 AND ".TB_PREF."loc_stock.stock_id = '" . $line->stock_id . "'
93                                 AND ".TB_PREF."loc_stock.loc_code = '" . $order->Location . "'";
94                         $res = db_query($sql,"a location could not be retreived");
95                         $loc = db_fetch($res);
96                         if ($loc['email'] != "")
97                         {
98                                 $qoh = get_qoh_on_date($line->stock_id, $order->Location);
99                                 $qoh -= get_demand_qty($line->stock_id, $order->Location);
100                                 $qoh -= get_demand_asm_qty($line->stock_id, $order->Location);
101                                 $qoh -= $line->quantity;
102                                 if ($qoh < $loc['reorder_level'])
103                                 {
104                                         $st_ids[] = $line->stock_id;
105                                         $st_names[] = $line->item_description;
106                                         $st_num[] = $qoh - $loc['reorder_level'];
107                                         $st_reorder[] = $loc['reorder_level'];
108                                 }
109                         }
110                 }
111
112                 $sql = "INSERT INTO ".TB_PREF."sales_order_details (order_no, stk_code, description, unit_price, quantity, discount_percent) VALUES (";
113                 $sql .= $order_no .
114                                 ",".db_escape($line->stock_id).", "
115                                 .db_escape($line->item_description).", $line->price,
116                                 $line->quantity,
117                                 $line->discount_percent)";
118                 db_query($sql, "order Details Cannot be Added");
119
120         } /* inserted line items into sales order details */
121
122         commit_transaction();
123
124         if ($loc_notification == 1 && count($st_ids) > 0)
125         {
126                 require_once($path_to_root . "/reporting/includes/class.mail.inc");
127                 $company = get_company_prefs();
128                 $mail = new email($company['coy_name'], $company['email']);
129                 $from = $company['coy_name'] . " <" . $company['email'] . ">";
130                 $to = $loc['location_name'] . " <" . $loc['email'] . ">";
131                 $subject = _("Stocks below Re-Order Level at " . $loc['location_name']);
132                 $msg = "\n";
133                 for ($i = 0; $i < count($st_ids); $i++)
134                         $msg .= $st_ids[$i] . " " . $st_names[$i] . ", " . _("Re-Order Level") . ": " . $st_reorder[$i] . ", " . _("Below") . ": " . $st_num[$i] . "\n";
135                 $msg .= "\n" . _("Please reorder") . "\n\n";
136                 $msg .= $company['coy_name'];
137                 $mail->to($to);
138                 $mail->subject($subject);
139                 $mail->text($msg);
140                 $ret = $mail->send();
141         }
142         return $order_no;
143 }
144
145 //----------------------------------------------------------------------------------------
146
147 function delete_sales_order($order_no)
148 {
149         begin_transaction();
150
151         $sql = "DELETE FROM ".TB_PREF."sales_orders WHERE order_no=" . $order_no;
152         db_query($sql, "order Header Delete");
153
154         $sql = "DELETE FROM ".TB_PREF."sales_order_details WHERE order_no =" . $order_no;
155         db_query($sql, "order Detail Delete");
156
157         commit_transaction();
158 }
159
160 //----------------------------------------------------------------------------------------
161 // Mark changes in sales_order_details
162 //
163 function update_sales_order_version($order)
164 {
165   foreach ($order as $so_num => $so_ver) {
166   $sql= 'UPDATE '.TB_PREF.'sales_orders SET version=version+1 WHERE order_no='. $so_num.
167         ' AND version='.$so_ver;
168   db_query($sql, 'Concurrent editing conflict while sales order update');
169   }
170 }
171
172 //----------------------------------------------------------------------------------------
173
174 function update_sales_order($order)
175 {
176         global $loc_notification, $path_to_root;
177
178         $del_date = date2sql($order->due_date);
179         $ord_date = date2sql($order->document_date);
180         $order_no =  key($order->trans_no);
181         $version= current($order->trans_no);
182
183         begin_transaction();
184
185         $sql = "UPDATE ".TB_PREF."sales_orders SET type =".$order->so_type." ,
186                 debtor_no = " . db_escape($order->customer_id) . ",
187                 branch_code = " . db_escape($order->Branch) . ",
188                 customer_ref = ". db_escape($order->cust_ref) .",
189                 comments = ". db_escape($order->Comments) .",
190                 ord_date = " . db_escape($ord_date) . ",
191                 order_type = " .db_escape($order->sales_type) . ",
192                 ship_via = " . db_escape($order->ship_via) .",
193                 deliver_to = " . db_escape($order->deliver_to) . ",
194                 delivery_address = " . db_escape($order->delivery_address) . ",
195                 contact_phone = " .db_escape($order->phone) . ",
196                 contact_email = " .db_escape($order->email) . ",
197                 freight_cost = " .db_escape($order->freight_cost) .",
198                 from_stk_loc = " .db_escape($order->Location) .",
199                 delivery_date = " .db_escape($del_date). ",
200                 version = ".($version+1)."
201          WHERE order_no=" . $order_no ."
202          AND version=".$version;
203         db_query($sql, "order Cannot be Updated, this can be concurrent edition conflict");
204
205         $sql = "DELETE FROM ".TB_PREF."sales_order_details WHERE order_no =" . $order_no;
206
207         db_query($sql, "Old order Cannot be Deleted");
208
209         if ($loc_notification == 1)
210         {
211                 include_once($path_to_root . "/inventory/includes/inventory_db.inc");
212                 $st_ids = array();
213                 $st_names = array();
214                 $st_num = array();
215                 $st_reorder = array();
216         }
217         foreach ($order->line_items as $line)
218         {
219                 if ($loc_notification == 1 && is_inventory_item($line->stock_id))
220                 {
221                         $sql = "SELECT ".TB_PREF."loc_stock.*, "
222                                   .TB_PREF."locations.location_name, "
223                                   .TB_PREF."locations.email
224                                 FROM ".TB_PREF."loc_stock, "
225                                   .TB_PREF."locations
226                                 WHERE ".TB_PREF."loc_stock.loc_code=".TB_PREF."locations.loc_code
227                                  AND ".TB_PREF."loc_stock.stock_id = '" . $line->stock_id . "'
228                                  AND ".TB_PREF."loc_stock.loc_code = '" . $order->Location . "'";
229                         $res = db_query($sql,"a location could not be retreived");
230                         $loc = db_fetch($res);
231                         if ($loc['email'] != "")
232                         {
233                                 $qoh = get_qoh_on_date($line->stock_id, $order->Location);
234                                 $qoh -= get_demand_qty($line->stock_id, $order->Location);
235                                 $qoh -= get_demand_asm_qty($line->stock_id, $order->Location);
236                                 $qoh -= $line->quantity;
237                                 if ($qoh < $loc['reorder_level'])
238                                 {
239                                         $st_ids[] = $line->stock_id;
240                                         $st_names[] = $line->item_description;
241                                         $st_num[] = $qoh - $loc['reorder_level'];
242                                         $st_reorder[] = $loc['reorder_level'];
243                                 }
244                         }
245                 }
246                 $sql = "INSERT INTO ".TB_PREF."sales_order_details
247                  (order_no, stk_code,  description, unit_price, quantity,
248                   discount_percent, qty_sent)
249                  VALUES (";
250                 $sql .= $order_no . ","
251                   .db_escape($line->stock_id) . ","
252                   .db_escape($line->item_description) . ", "
253                   .db_escape($line->price) . ", "
254                   .db_escape($line->quantity) . ", "
255                   .db_escape($line->discount_percent) . ", "
256                   .db_escape($line->qty_done) ." )";
257
258                 db_query($sql, "Old order Cannot be Inserted");
259
260         } /* inserted line items into sales order details */
261
262         commit_transaction();
263         if ($loc_notification == 1 && count($st_ids) > 0)
264         {
265                 require_once($path_to_root . "/reporting/includes/class.mail.inc");
266                 $company = get_company_prefs();
267                 $mail = new email($company['coy_name'], $company['email']);
268                 $from = $company['coy_name'] . " <" . $company['email'] . ">";
269                 $to = $loc['location_name'] . " <" . $loc['email'] . ">";
270                 $subject = _("Stocks below Re-Order Level at " . $loc['location_name']);
271                 $msg = "\n";
272                 for ($i = 0; $i < count($st_ids); $i++)
273                         $msg .= $st_ids[$i] . " " . $st_names[$i] . ", "
274                           . _("Re-Order Level") . ": " . $st_reorder[$i] . ", "
275                           . _("Below") . ": " . $st_num[$i] . "\n";
276                 $msg .= "\n" . _("Please reorder") . "\n\n";
277                 $msg .= $company['coy_name'];
278                 $mail->to($to);
279                 $mail->subject($subject);
280                 $mail->text($msg);
281                 $ret = $mail->send();
282         }
283 }
284
285 //----------------------------------------------------------------------------------------
286
287 function get_sales_order_header($order_no)
288 {
289         $sql = "SELECT ".TB_PREF."sales_orders.*, "
290           .TB_PREF."debtors_master.name, "
291           .TB_PREF."debtors_master.curr_code, "
292           .TB_PREF."locations.location_name, "
293           .TB_PREF."debtors_master.payment_terms, "
294           .TB_PREF."debtors_master.discount, "
295           .TB_PREF."sales_types.sales_type, "
296           .TB_PREF."sales_types.id AS sales_type_id, "
297           .TB_PREF."sales_types.tax_included, "
298           .TB_PREF."shippers.shipper_name, "
299           .TB_PREF."tax_groups.name AS tax_group_name , "
300           .TB_PREF."tax_groups.id AS tax_group_id
301         FROM ".TB_PREF."sales_orders, "
302           .TB_PREF."debtors_master, "
303           .TB_PREF."sales_types, "
304           .TB_PREF."tax_groups, "
305           .TB_PREF."cust_branch, "
306           .TB_PREF."locations, "
307           .TB_PREF."shippers
308         WHERE ".TB_PREF."sales_orders.order_type=".TB_PREF."sales_types.id
309                 AND ".TB_PREF."cust_branch.branch_code = ".TB_PREF."sales_orders.branch_code
310                 AND ".TB_PREF."cust_branch.tax_group_id = ".TB_PREF."tax_groups.id
311                 AND ".TB_PREF."sales_orders.debtor_no = ".TB_PREF."debtors_master.debtor_no
312                 AND ".TB_PREF."locations.loc_code = ".TB_PREF."sales_orders.from_stk_loc
313                 AND ".TB_PREF."shippers.shipper_id = ".TB_PREF."sales_orders.ship_via
314                 AND ".TB_PREF."sales_orders.order_no = " . $order_no ;
315         $result = db_query($sql, "order Retreival");
316
317         $num = db_num_rows($result);
318         if ($num > 1)
319         {
320                 display_db_error("FATAL : sales order query returned a duplicate - " . db_num_rows($result), $sql, true);
321         }
322         else if ($num == 1)
323         {
324                 return db_fetch($result);
325         }
326         else
327                 display_db_error("FATAL : sales order return nothing - " . db_num_rows($result), $sql, true);
328
329 }
330
331 //----------------------------------------------------------------------------------------
332
333 function get_sales_order_details($order_no) {
334         $sql = "SELECT id, stk_code, unit_price, "
335                 .TB_PREF."sales_order_details.description,"
336                 .TB_PREF."sales_order_details.quantity,
337                   discount_percent,
338                   qty_sent as qty_done, "
339                 .TB_PREF."stock_master.units,
340                 ".TB_PREF."stock_master.material_cost + "
341                         .TB_PREF."stock_master.labour_cost + "
342                         .TB_PREF."stock_master.overhead_cost AS standard_cost
343         FROM ".TB_PREF."sales_order_details, ".TB_PREF."stock_master
344         WHERE ".TB_PREF."sales_order_details.stk_code = ".TB_PREF."stock_master.stock_id
345         AND order_no =" . $order_no . " ORDER BY id";
346
347         return db_query($sql, "Retreive order Line Items");
348 }
349 //----------------------------------------------------------------------------------------
350
351 function read_sales_order($order_no, &$order)
352 {
353         $myrow = get_sales_order_header($order_no);
354
355         $order->trans_type = 30;
356         $order->so_type =  $myrow["type"];
357         $order->trans_no = array($order_no=> $myrow["version"]);
358
359         $order->set_customer($myrow["debtor_no"], $myrow["name"],
360           $myrow["curr_code"], $myrow["discount"]);
361
362         $order->set_branch($myrow["branch_code"], $myrow["tax_group_id"],
363           $myrow["tax_group_name"], $myrow["contact_phone"], $myrow["contact_email"]);
364
365         $order->set_sales_type($myrow["sales_type_id"], $myrow["sales_type"], 
366             $myrow["tax_included"], 0); // no default price calculations on edit
367
368         $order->set_location($myrow["from_stk_loc"], $myrow["location_name"]);
369
370         $order->set_delivery($myrow["ship_via"], $myrow["deliver_to"],
371           $myrow["delivery_address"], $myrow["freight_cost"]);
372
373         $order->cust_ref = $myrow["customer_ref"];
374         $order->sales_type =$myrow["order_type"];
375         $order->Comments = $myrow["comments"];
376         $order->due_date = sql2date($myrow["delivery_date"]);
377         $order->document_date = sql2date($myrow["ord_date"]);
378
379         $result = get_sales_order_details($order_no);
380         if (db_num_rows($result) > 0)
381         {
382                 $line_no=0;
383                 while ($myrow = db_fetch($result))
384                 {
385                         $order->add_to_cart($line_no,$myrow["stk_code"],$myrow["quantity"],
386                                 $myrow["unit_price"], $myrow["discount_percent"],
387                                 $myrow["qty_done"], $myrow["standard_cost"], $myrow["description"], $myrow["id"] );
388                 $line_no++;
389                 }
390         }
391
392         return true;
393 }
394
395 //----------------------------------------------------------------------------------------
396
397 function sales_order_has_deliveries($order_no)
398 {
399         $sql = "SELECT SUM(qty_sent) FROM ".TB_PREF.
400         "sales_order_details WHERE order_no=$order_no";
401
402         $result = db_query($sql, "could not query for sales order usage");
403
404         $row = db_fetch_row($result);
405
406         return ($row[0] > 0);
407 }
408
409 //----------------------------------------------------------------------------------------
410
411 function close_sales_order($order_no)
412 {
413         // set the quantity of each item to the already sent quantity. this will mark item as closed.
414         $sql = "UPDATE ".TB_PREF."sales_order_details
415                 SET quantity = qty_sent,
416                         type = 0,
417                         WHERE order_no = $order_no";
418
419         db_query($sql, "The sales order detail record could not be updated");
420 }
421
422 //---------------------------------------------------------------------------------------------------------------
423
424 function get_invoice_duedate($debtorno, $invdate)
425 {
426         if (!is_date($invdate))
427         {
428                 return Today();
429         }
430         $sql = "SELECT ".TB_PREF."debtors_master.debtor_no, ".TB_PREF."debtors_master.payment_terms, ".TB_PREF."payment_terms.* FROM ".TB_PREF."debtors_master,
431                 ".TB_PREF."payment_terms WHERE ".TB_PREF."debtors_master.payment_terms = ".TB_PREF."payment_terms.terms_indicator AND
432                 ".TB_PREF."debtors_master.debtor_no = '$debtorno'";
433
434         $result = db_query($sql,"The customer details could not be retrieved");
435         $myrow = db_fetch($result);
436
437         if (db_num_rows($result) == 0)
438                 return $invdate;
439         if ($myrow['day_in_following_month'] > 0)
440                 $duedate = add_days(end_month($invdate), $myrow['day_in_following_month']);
441         else
442                 $duedate = add_days($invdate, $myrow['days_before_due']);
443         return $duedate;
444 }
445
446 function get_customer_to_order($customer_id) {
447
448         // Now check to ensure this account is not on hold */
449         $sql = "SELECT ".TB_PREF."debtors_master.name, "
450                   .TB_PREF."debtors_master.address, "
451                   .TB_PREF."credit_status.dissallow_invoices, "
452                   .TB_PREF."debtors_master.sales_type AS salestype, "
453                   .TB_PREF."sales_types.sales_type, "
454                   .TB_PREF."sales_types.tax_included, "
455                   .TB_PREF."sales_types.factor, "
456                   .TB_PREF."debtors_master.curr_code, "
457                   .TB_PREF."debtors_master.discount,"
458                   .TB_PREF."debtors_master.pymt_discount
459                 FROM ".TB_PREF."debtors_master, "
460                   .TB_PREF."credit_status, "
461                   .TB_PREF."sales_types
462                 WHERE ".TB_PREF."debtors_master.sales_type="
463                   .TB_PREF."sales_types.id
464                 AND ".TB_PREF."debtors_master.credit_status=".TB_PREF."credit_status.id
465                 AND ".TB_PREF."debtors_master.debtor_no = '" . $customer_id . "'";
466
467         $result =db_query($sql,"Customer Record Retreive");
468         return  db_fetch($result);
469 }
470
471 function get_branch_to_order($customer_id, $branch_id) {
472
473         // the branch was also selected from the customer selection so default the delivery details from the customer branches table cust_branch. The order process will ask for branch details later anyway
474                 $sql = "SELECT ".TB_PREF."cust_branch.br_name, "
475                         .TB_PREF."cust_branch.br_address, "
476                         .TB_PREF."cust_branch.br_post_address, "
477                         .TB_PREF."cust_branch.phone, "
478                         .TB_PREF."cust_branch.email,
479                           default_location, location_name, default_ship_via, "
480                         .TB_PREF."tax_groups.name AS tax_group_name, "
481                         .TB_PREF."tax_groups.id AS tax_group_id
482                         FROM ".TB_PREF."cust_branch, "
483                           .TB_PREF."tax_groups, "
484                           .TB_PREF."locations
485                         WHERE ".TB_PREF."cust_branch.tax_group_id = ".TB_PREF."tax_groups.id
486                                 AND ".TB_PREF."locations.loc_code=default_location
487                                 AND ".TB_PREF."cust_branch.branch_code='" . $branch_id . "'
488                                 AND ".TB_PREF."cust_branch.debtor_no = '" . $customer_id . "'";
489
490             return db_query($sql,"Customer Branch Record Retreive");
491 }
492 ?>