2 require_once($path_to_root.'/'.'includes/date_functions.inc');
5 function __construct($set=null) {
6 $this->pairs = $set ? array_merge($set->pairs) : array();
9 function add($value, $field, $quote=true) {
11 array_push($this->pairs, $quote ? "$field = '$value'" : "$field = $value");
17 function addDate($date, $field) {
18 return $this->add(date2sql($date), $field);
22 return implode(', ', $this->pairs);
30 public $quantity_dispatched=0;
33 function __construct($start_date, $period=null) {
34 $this->start_date = $start_date;
35 $this->end_date = $start_date;
36 if($period) $this->extend($period);
39 function extend($days) {
40 $this->end_date = add_days($this->end_date, $days);
45 public $detail_ids = array() ;
51 public function __construct(array $data) {
52 $this->detail_ids = array();
53 foreach($data['detail'] as $detail_id => $detail) {
54 array_push($this->detail_ids, $detail_id);
56 $this->start_date = $data['start_date'];
57 $this->end_date = $data['end_date'];
58 $this->days = date_diff2($this->end_date, $this->start_date, 'd');
60 $this->max_quantity = $data['max_quantity'];
63 protected function loadDetail($detail_id) {
65 FROM ".TB_PREF."sales_order_details
66 WHERE id = $detail_id";
67 $result = db_query($sql);
68 return db_fetch($result);
71 public function splitAll() {
73 foreach($this->detail_ids as $detail_id) {
74 display_warning("processing $detail_id");
75 $detail = $this->loadDetail($detail_id);
76 $splits = $this->split($detail);
77 $ok &= $this->saveSplits($detail, $splits);
83 public function days() {
89 /* This function splits on order detail in bits of a specified size.
90 * Each split starting at the end time of the previous one.
91 * the first split starts at the start_date and ends at the end_date.
92 * The 'splitting' split the whole quantity not only the quantity left to dispatch
93 * However, fully dispatched split won't be split in real, but merged with the next one
95 public function split($row) {
97 $quantity = $row['quantity'];
98 $quantity_sent = $row['qty_sent'];
100 /* Check if the item has been fully dispatched.
101 * If so, there is no need to do anything.
103 if($quantity_sent >= $quantity) return $splits;
105 // determine the number of split needed. This will give us the lenght of a split.
106 $nsplit = ceil($quantity/$this->max_quantity);
108 $period = $this->days/$nsplit;
110 array_push($splits, $split = new Split($this->start_date, $period));
111 $split->quantity_dispatched = $quantity_sent;
112 $split_quantity = min($quantity, $this->max_quantity);
113 while($split_quantity > 0) {
114 $split->quantity += $split_quantity;
115 // Check if the split has been entirely dispatch or not.
116 if($split->quantity_dispatched > $split->quantity) {
118 $split->extend($period);
121 // create a new split
122 array_push($splits, $split = new Split($split->end_date, $period));
125 $quantity -= $split_quantity;
126 $split_quantity = min($quantity, $this->max_quantity);
129 // We need to remove the last split if it's empty
130 if($split->quantity == 0) array_pop($splits);
134 public function saveSplits($detail, $splits) {
135 if(empty($splits)) return true;
137 $detail_id = $detail['id'];
138 $priority = $detail['priority'];
139 $order_no = $detail['order_no'];
140 $trans_type = $detail['trans_type'];
142 /* We need to update the first one (as it exists already in the database)
143 * but insert the following one.
145 $first = array_shift($splits);
147 $set->addDate($first->start_date, 'hold_until_date')
148 ->addDate($first->end_date, 'expiry_date')
149 ->add($first->quantity, 'quantity', false)
150 ->add($priority, 'priority');
151 display_warning($set->toString());
152 db_query("UPDATE ".TB_PREF."sales_order_details
153 SET {$set->toString()}
154 WHERE id = $detail_id", "Problem splitting order details $detail_id");
156 // Compute common field for each split
157 $common_set = new SqlSet();
158 $common_set->add($order_no, 'order_no', false)
159 ->add($priority, 'priority')
160 ->add($trans_type, 'trans_type')
161 ->add($detail['required_date'], 'required_date')
162 ->add($detail['comment'], 'comment')
163 ->add($detail['stk_code'], 'stk_code')
164 ->add($detail['description'], 'description')
165 ->add($detail['unit_price'], 'unit_price', false)
166 ->add($detail['discount_percent'], 'discount_percent', false);
168 foreach($splits as $split) {
169 $set = new SqlSet($common_set);
170 $set->addDate($split->start_date, 'hold_until_date')
171 ->addDate($split->end_date, 'expiry_date')
172 ->add($split->quantity, 'quantity', false);
173 display_warning($set->toString());
174 db_query("INSERT INTO ".TB_PREF."sales_order_details
175 SET {$set->toString()}"
176 ,"Problem spliting order details $detail_id");