Splitter Test written. Doesn't pass.
[order_line_extra.git] / includes / splitter.inc
1 <?php
2 require_once($path_to_root.'/'.'includes/date_functions.inc');
3 class Split {
4         public $start_date;
5         public $end_date;
6         public $quantity=0;
7         public $quantity_dispatched=0;
8         
9
10         function __construct($start_date, $period=null) {
11                         $this->start_date = $start_date;
12                         $this->end_date = $start_date;
13                         if($period) $this->extend($period);
14         }
15
16         function extend($days) {
17                         $this->end_date = add_days($this->end_date, $days);
18         }
19 }
20
21 class Splitter {
22         public $detail_ids = array() ;
23         public $start_date;
24         public $end_date;
25         protected $days;
26         public $max_quantity;
27
28         public function __construct(array $data) {
29                 $this->details_id = array();
30                 foreach($data['detail'] as $detail_id => $detail) {
31                         array_push($this->details_id, $detail_id);
32                 }
33                 $this->start_date = $data['start_date'];
34                 $this->end_date = $data['end_date'];
35                 $this->days = date_diff2($this->end_date, $this->start_date, 'd');
36
37                 $this->max_quantity = $data['max_quantity'];
38         }
39
40         protected function loadDetail($detail_id) {
41                 $sql = "SELECT *
42                                                 FROM ".TB_PREF."sales_order_details
43                                                 WHERE id = $detail_id";
44                 $result = db_query($sql);
45                 return db_fetch($result);
46         }
47
48         public function splitAll() {
49                 foreach($this->detail_ids as $detail_id) {
50                                 $detail = $this->loadDetail($detail_id);
51                                 $splits = $this->split($detail);
52                                 $this->saveSplits($detail, $splits);
53                 }
54         }
55
56         public function days() {
57                 return $this->days;
58         }
59
60
61         
62         /* This function splits on order detail in bits of a specified size.
63  * Each split  starting at the end time of the previous one.
64  * the first split starts at the start_date and ends at the end_date.
65  * The 'splitting' split the whole quantity not only the quantity left to dispatch
66  * However, fully dispatched split won't be split in real, but merged with the next one
67  */
68         public function split($row) {
69                 $splits = array();
70                 $quantity = $row['quantity'];
71                 $quantity_sent = $row['qty_sent'];
72
73                 if($quantity >= $quantity_sent) return $splits;
74                 if(($quantity-$quantity_sent) % $this->max_quantity < $this->max_quantity) return;
75                 
76                 // determine the number of split needed. This will give us the lenght of a split.
77                 $nsplit = ceiling($initial_quantity/$this->max_quantity);
78                 if($nsplit == 1) return $splits;
79
80                 $period = $this->days/$nsplit;
81
82                 array_push($splits, $split = new Split($start_date, $period));
83                 $split->quantity_dispatched = $quantity_dispatched;
84                 $split_quantity = min($quantity, $this->max_quantity);
85                 while($split_quantity > 0) {
86                                         $split->quantity += $split_quantity;
87                                 // Check if the split has been entirely dispatch or not.
88                                 if($split->$quantity_dispatched > $split->quantity) {
89                                         //extend the split
90                                         $split->extend($period);
91                                 }
92                                 else {
93                                         // create a new split
94                                         array_push($splits, $split = new Split($split->end_date, $period));
95                                         
96                                 }
97                                 $quantity -= $split_quantity;
98                                 $split_quantity = min($quantity, $this->max_quantity);
99                 }
100
101                 return $splits;
102         }
103
104 }
105 ?>