Display different color on order detail for sold out item.
[order_line_extra.git] / includes / order_lines.inc
1 <?php
2 include_once('order_xtra_config.inc');
3 include_once('picking.inc');
4 include_once($path_to_root."/includes/ui/ui_input.inc");
5 /* This utility function remove beginning <td> and </td> from a string
6  * generated by the above *_cell function.
7  * This is usefull to use the result of the function within a pager
8  * which already include the <td>...</td>
9  * However, for function which doesn't return a string
10  * but echo, we need to capture the output of the echo first.
11  */
12 function start_extract_cell() {
13         // We need 
14         ob_start();
15 }
16
17 function end_extract_cell() {
18         $content = ob_get_contents();
19         ob_end_clean();
20         return extract_cell($content);
21 }
22
23 function extract_cell($td) {
24         if(preg_match('/\s*<td>(.*)<\/td>\s*/s', $td, $matches)) {
25                 return $matches[1];
26         }
27         else {
28                 return $td;
29         }
30 }
31
32 /* remove unchecked data so each
33  * funcion doesn't to check what's been checked or not. 
34  */
35 function filter_data(&$data) {
36         if(!isset($data['detail'])) return;
37         $new_details = array();
38         foreach(@$data['detail'] as $detail_id => $values) {
39                 if(@$values['check'] === 'on') $new_details[$detail_id]=$values;
40         }
41         $data['detail'] = $new_details;
42 }
43
44 function post_to_detail_ids() {
45         if(!isset($_POST['detail'])) return;
46         $detail_ids = array();
47         foreach($_POST['detail'] as $detail_id => $values) {
48                 array_push($detail_ids, $detail_id);
49         }
50
51         return $detail_ids;
52 }
53
54 function update_extra_order_details() {
55         if(!isset($_POST['Update']) || $_POST['Update'] != 'Update')  return;
56
57         $cart = post_to_detail_ids();
58         if($cart === null) return;
59 begin_transaction();
60         hook_db_prewrite($cart, 'order_xtra');
61         // update in database all field
62         $date_fields = array('hold_until_date', 'required_date', 'expiry_date', 'priority');
63         foreach($_POST['detail'] as $detail_id => $values) {
64                 $set = array();
65                 $comment=$values['comment'];
66           array_push($set, " comment='$comment' "); // erase comment if needed.
67                 foreach($date_fields as $date_field) {
68                         if(isset($values[$date_field])) {
69                                 $input_date = trim($values[$date_field]);
70                                 if($input_date == "")  {
71                                         // Only the priority field can be set to null.
72                                         if($date_field == 'priority') array_push($set," $date_field = NULL");
73                                 } else {
74                                         $date = date2sql($input_date);
75                                         array_push($set," $date_field='$date' ");
76                                 }
77                         }
78                 }
79
80                 if(!empty($set))  {
81                         $sql = "UPDATE ".TB_PREF."sales_order_details  SET ".implode($set,', ')."  WHERE id = $detail_id ";
82
83                         if(!db_query($sql)) {
84                                 display_error('Problem while updating order details. Try again');
85                                 cancel_transaction();
86                                 return;
87                         }
88                 }
89         }
90         hook_db_postwrite($cart, 'order_xtra');
91         commit_transaction();
92
93
94         display_notification('Order details updated');
95
96 }
97
98 function split_order_details() {
99         if(!isset($_POST['Split']) || $_POST['Split'] != 'Split')  return;
100         $splitter = new Splitter($_POST);
101         begin_transaction();
102         $cart = post_to_detail_ids();
103         if($cart === null) return;
104         hook_db_prewrite($cart, 'order_xtra');
105                 if($splitter->splitAll()) display_warning("Items have been split.");
106         hook_db_postwrite($cart, 'order_xtra');
107         commit_transaction();
108 }
109
110 function bulk_update_order_details() {
111         if(!isset($_POST['Bulk']) || $_POST['Bulk'] != 'Bulk')  return;
112         $bulk_updater = new BulkUpdater($_POST);
113         begin_transaction();
114         $cart = post_to_detail_ids();
115         if($cart === null) return;
116         hook_db_prewrite($cart, 'order_xtra');
117         $bulk_updater->update();
118         hook_db_postwrite($cart, 'order_xtra');
119         commit_transaction();
120 }
121
122
123
124 function compute_input_name($row, $field) {
125         $row_id = $row['id'];
126         return "detail[$row_id][$field]";
127 }
128
129 function view_link($dummy, $order_no)
130 {
131         return  get_customer_trans_view_str(ST_SALESORDER, $order_no);
132 }
133
134 function item_link($dummy, $stock_id)
135 {
136         return pager_link( _($stock_id),
137         "/modules/order_line_extra/item_schedule.php?stock_id=" .$stock_id);
138 }
139
140 function order_link($row)
141 {
142         return pager_link( _("Sales Order"),
143         "/sales/sales_order_entry.php?NewQuoteToSalesOrder=" .$row['order_no'], ICON_DOC);
144 }
145
146 function customer_link($row) {
147         return customer_link2($row['debtor_ref'], $row['debtor_no']);
148 }
149
150 function customer_link2($name, $id) {
151         return pager_link(_($name), "/modules/order_line_extra/order_lines_view.php?customer_id=${id}");
152
153 }
154
155 function aggregate_comment($row) {
156         $comment =  $row['order_comment'].";".$row['detail_comment'];
157         if($comment) {
158                 $comments = array_map('trim', explode(';', $comment));
159                 $comments = array_filter($comments);
160                 $first = array_shift($comments);
161                 if(count($comments) == 0)
162                         return $first;
163                 else {
164                         $tooltip = implode('<br> - ', $comments);
165                         return "$first <span class='before-tooltip'>more<span class='tooltip'>&nbsp$tooltip</span><span>";
166                 }
167         }
168         return '';
169 }
170
171 function available_quantity($row, $available) {
172         $quantity = $row['quantity'];
173         $class = '';
174         if($available== 0) $class = $row['qoh'] == 0 ? 'stockmankobg' : 'limited';
175         else if($quantity > $available)  $class = 'partial';
176         else if(OrderXtraConfig::early(sql2date($row['hold_until_date']))) $class = 'early';
177
178         return "<span class='$class'>$available<span>";
179 }
180
181 function input_date_details($row, $field_name, $date) {
182 $row_id = $row['id'];
183         $name = compute_input_name($row, $field_name);
184
185 $_POST[$name] = sql2date($date);
186
187         start_extract_cell();
188                 date_cells (null, $name, 'title', null, 0,0,1001);
189         return end_extract_cell();
190
191
192         return "
193 <input type='text' value='$date' name='$name'>
194 ";
195 }
196
197 function input_priority_date_details($row, $date) {
198         return input_date_details($row, 'priority', $date);
199 }
200
201 function input_hold_until_date_details($row, $date) {
202         return input_date_details($row, 'hold_until_date', $date);
203 }
204
205 function input_required_date_details($row, $date) {
206         return input_date_details($row, 'required_date', $date);
207 }
208
209 function input_expiry_date_details($row, $date) {
210         return input_date_details($row, 'expiry_date', $date);
211 }
212
213 function input_comment_details($row, $comment) {
214 $row_id = $row['id'];
215         return "
216 <input type='text' value='$comment' name='detail[$row_id][comment]'>
217 ";
218 }
219
220 function input_check_details($row, $dummy) {
221         $row_id = $row['id'];
222                 return "
223                 <input type='checkbox' class='check_detail' name='detail[$row_id][check]'>";
224 }
225
226 function pick_checkbox($row)
227 {
228         $id = $row['debtor_no']."_".$row['branch_code'];
229         $name = "chgpck" .$id;
230         $value = $row['quantity_to_pick'] !== null;
231
232 // save also in hidden field for testing during 'Update'
233  return checkbox(null, $name, $value, true,
234         _('Pick all possible item for this branch.'))
235         . hidden('pick['.$id.']', $value, false);
236 }
237
238 function get_order_details_extra($customer_id, $location, $item_like, $order_id) {
239         $select = "sod.id
240         , so.order_no
241         , stk_code
242         , sod.quantity - qty_sent quantity
243         , GREATEST(0, LEAST(qoh.quantity  - quantity_before, sod.quantity - qty_sent)) AS available
244         , quantity_before
245         , qoh.quantity AS qoh
246         , p.quantity AS quantity_to_pick
247         , sod.`priority`
248         , hold_until_date
249         , required_date
250         , expiry_date
251         ,comment";
252         $from =  TB_PREF."sales_order_details sod
253         JOIN ".TB_PREF."sales_orders so ON (so.order_no = sod.order_no
254                 AND so.trans_type = sod.trans_type
255                 AND so.trans_type = ".ST_SALESORDER."
256                 AND so.debtor_no = $customer_id
257         )
258         JOIN ".TB_PREF."denorm_qoh qoh ON (stock_id = stk_code AND loc_code = '$location')
259         LEFT JOIN ".TB_PREF."denorm_order_details_queue  d ON (d.id = sod.id)
260         LEFT JOIN (".pick_query().") p ON (detail_id = sod.id)
261         ";
262         $where = " sod.quantity > qty_sent
263         ";
264
265         if($item_like) {
266                         if($item_like[0]=='/')  {
267                                 $regexp = substr($item_like, 1);
268                                 $where .= " AND stk_code RLIKE '$regexp'";
269                         }
270                         else 
271                                 $where .= " AND stk_code LIKE '$item_like'";
272         }
273
274         if($order_id) {
275                 $where .= " AND so.order_no = $order_id";
276         }
277
278         return array('select' => $select, 'from' => $from, 'where' => $where);
279 }
280
281 function get_order_summary($location) {
282         $held_condition = OrderXtraConfig::sql_held_condition();
283
284         $pick = pick_query();
285
286         $sub = "SELECT debtor_no, debtor_ref, branch_code, branch_ref, stk_code
287         , min(delivery_date)
288         , sum(d.quantity) as quantity
289         , sum((d.quantity)*unit_price*(1-discount_percent/100)) as amount
290         , min(required_date)
291         , group_concat(distinct comments separator ';') as order_comment
292         , group_concat(distinct comment separator ';') as detail_comment
293         , max(quantity_before) as quantity_before
294         , sum(if($held_condition, greatest(least(d.quantity, qoh.quantity - quantity_before), 0), 0)) as quantity_held
295         , sum(if($held_condition, 0,  greatest(least(d.quantity, qoh.quantity - quantity_before), 0))) as available_quantity
296         , sum(if($held_condition, 0,  greatest(least(d.quantity, qoh.quantity - quantity_before), 0)*unit_price*(1-discount_percent/100))) as available_amount
297         , sum(p.quantity) as quantity_to_pick
298         , sum(p.quantity*unit_price) as amount_to_pick
299         FROM ".TB_PREF."sales_order_details sod
300         JOIN ".TB_PREF."sales_orders so ON (so.order_no = sod.order_no
301                 AND so.trans_type = sod.trans_type
302                 AND so.trans_type = ".ST_SALESORDER."
303         )
304         NATURAL JOIN ".TB_PREF."debtors_master
305         NATURAL JOIN ".TB_PREF."cust_branch
306         LEFT JOIN ($pick) p ON (detail_id = sod.id)
307         JOIN ".TB_PREF."denorm_order_details_queue  d ON (d.id = sod.id)
308         LEFT JOIN ".TB_PREF."denorm_qoh qoh ON (qoh.stock_id = stk_code AND loc_code = '$location')
309         WHERE sod.quantity > qty_sent AND ".ST_SALESORDER."
310         GROUP BY debtor_no, branch_code, stk_code
311         ";
312
313         //$sub = TB_PREF."order_summary_view";
314         //
315
316         $sql = array( "select" => "debtor_no, branch_code, debtor_ref, branch_ref
317         , `min(delivery_date)` as delivery_date
318         , sum(sub.quantity) as quantity
319         , sum(sub.amount) as amount
320         , sum(sub.available_quantity)
321         , sum(sub.available_amount)
322         , sum(quantity_held) as quantity_help
323         ,  min(`min(required_date)`) as required_date
324         , group_concat(distinct order_comment separator ';') as order_comment
325         , group_concat(distinct detail_comment separator ';') as detail_comment
326         , sum(quantity_to_pick) as quantity_to_pick
327         , sum(amount_to_pick) as amount_to_pick
328         ", "from" => " ($sub) sub
329                         LEFT JOIN ".TB_PREF."denorm_qoh qoh ON (stock_id = stk_code AND loc_code = '$location')
330
331         ", "group" => " debtor_no, branch_code
332         ");
333
334         return $sql;
335 }
336 ?>