id) { case 'orders': $app->add_rapp_function(0, _('Order Extra'), $path_to_root.'/modules/order_line_extra/order_lines_view.php', 'SA_ORDERLINEX_EDIT'); break; case 'stock': $app->add_rapp_function(1, _('Item Schedule'), $path_to_root.'/modules/order_line_extra/item_schedule.php', 'SA_ORDERLINEX_SCHEDULE'); break; case 'system': $app->add_rapp_function(1, _('Reset Order Xtra cache'), $path_to_root.'/modules/order_line_extra/refresh_cache.php', 'SA_ORDERLINEX_REFRESH'); break; } } function install_access() { $security_sections[SS_ORDERLINEX] = _("Order Line Extra"); $security_areas['SA_ORDERLINEX_EDIT'] = array(SS_ORDERLINEX|1, _("Edit lines")); $security_areas['SA_ORDERLINEX_SCHEDULE'] = array(SS_ORDERLINEX|1, _("Item Schedule")); $security_areas['SA_ORDERLINEX_REFRESH'] = array(SS_ORDERLINEX|1, _("Reset Cache")); return array($security_areas, $security_sections); } /* This method is called on extension activation for company. */ function activate_extension($company, $check_only=true) { global $db_connections; $updates = array( 'alter_sales_order_details.sql' => array('sales_order_details','required_date'), 'alter_sales_order_details_2.sql' => array('sales_order_details','expiry_date'), 'create_denorm_order_details_queue.sql' => array('denorm_order_details_queue'), 'create_denorm_qoh.sql' => array('denorm_qoh'), 'create_order_summary_view.sql' => array('order_summary_view'), ); return $this->update_databases($company, $updates, $check_only) && update_order_detail_defaults(true) && update_queue_quantities() && update_qoh_for_item() ; } function deactivate_extension($company, $check_only=true) { global $db_connections; $updates = array( 'clean_sales_order_details.sql' => array('ugly_hack') // FIXME: just an ugly hack to clean database on deactivation ); return $this->update_databases($company, $updates, $check_only); } function get_dispatchable_quantity($line_item, $opts) { $location = array_shift($opts); $date = array_shift($opts); $qoh = array_shift($opts); $detail_id = $line_item->id; $quantity = $line_item->qty_dispatched; /* We have 2 methods to estimate the allowed quantity. * the first use the different priority to estimate what's available. * This is the same algorithm used to auto pick items. * The second rely on what's being choose to be picked up. * If an order has been selected to be picked up, only the items and the quantity picked up * needs to be available. */ /* We don't only need to check if the detail has been pick but check * that any item in the same order have or not */ $sql = "SELECT * FROM ".TB_PREF."sales_order_details sod JOIN ".TB_PREF."topick p ON (sod.id = p.detail_id) WHERE order_no IN (SELECT distinct order_no FROM ".TB_PREF."sales_order_details WHERE id = $detail_id)"; $result = db_query($sql); if(db_num_rows($result) > 0) { $result = db_query(pick_query($detail_id)); $row = db_fetch($result); if($row) { $available = $row['quantity']; if($available == 0) { return array(0, $qoh ? 'limited' : 'stockmankobg'); } else if($available < $quantity) { return array($available, 'picked'); } else { return array($quantity, 'picked'); } } else { // hasn't been picked return array(0, 'stockmankobg soldout'); } } else { return $this->get_allowed_quantity_from_priority($detail_id, $quantity, $location, $date, $qoh); } } function get_allowed_quantity_from_priority($detail_id, $quantity, $location, $date, $qoh) { if($qoh == 0) return array(0, 'stockmankobg'); $sql = "SELECT quantity_before, hold_until_date FROM ".TB_PREF."denorm_order_details_queue JOIN ".TB_PREF."sales_order_details USING (id) WHERE id = $detail_id"; $result = db_query($sql); $classes = array(); $dispatchable = $quantity; if($row=db_fetch($result)) { $quantity_before = $row['quantity_before']; $qoh = max(0, $qoh-$quantity_before); $hold_until = sql2date($row['hold_until_date']); $dispatchable = min($quantity, $qoh); if($dispatchable < $quantity) array_push($classes, 'limited'); if(OrderXtraConfig::early($hold_until, $date)) array_push($classes, 'early'); } return array($dispatchable, implode(' ', $classes)); } function db_postwrite($cart, $trans_type) { if(is_a($cart, "Cart") || is_a($cart, "purch_order")) { // It's a cart. Find all the stock_id and update the cache table foreach($cart->line_items as $line_no => $item) { $stock_id = $item->stock_id; update_queue_quantity_for_item($stock_id); update_qoh_for_item($stock_id); } } else if (isset($trans_type) && $trans_type == "order_xtra") { $stock_ids = stock_id_from_detail($cart); if($stock_ids) foreach($stock_ids as $stock_id) { update_queue_quantity_for_item($stock_id); update_qoh_for_item($stock_id); } } // update null fields of new entered orders. $types = array(ST_SALESORDER, 'order_xtra'); if(in_array($trans_type, $types)) update_order_detail_defaults(); // Clean to_pick table on dispatch if($trans_type == ST_CUSTDELIVERY) clean_pickup_for_dispatch($cart); } function db_prevoid($cart, $trans_type) { // Simple version, rebuild everything $types = array(ST_CUSTCREDIT, ST_CUSTDELIVERY, ST_INVADJUST, ST_PURCHORDER, ST_WORKORDER, ST_MANUISSUE, ST_SALESORDER, ST_SALESQUOTE, ST_MANURECEIVE); if(in_array($trans_type, $types)) { update_queue_quantities(); update_qoh_for_item(); } } } function stock_id_from_detail($detail_ids) { if(empty($detail_ids)) return null; $stock_ids = array(); $ids = implode(', ', $detail_ids); $sql = " SELECT DISTINCT stk_code FROM ".TB_PREF."sales_order_details WHERE id IN ($ids)"; $result = db_query($sql); while($row=db_fetch($result)) { array_push($stock_ids, $row['stk_code']); } return $stock_ids; } ?>