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