BulkUpdater work.
[order_line_extra.git] / includes / splitter.inc
index c3aff0ad894d1cba21c04e3db8d1a0e13f7b0fc2..3f03593bfd58fb8e50a984db90914d7ce5a914d0 100644 (file)
@@ -1,8 +1,12 @@
 <?php
-require_once($path_to_root.'/'.'includes/date_functions.inc');
+require_once('includes/sql_set.inc');
+
 class Split {
        public $start_date;
        public $end_date;
+       public $quantity=0;
+       public $quantity_dispatched=0;
+       
 
        function __construct($start_date, $period=null) {
                        $this->start_date = $start_date;
@@ -14,21 +18,24 @@ class Split {
                        $this->end_date = add_days($this->end_date, $days);
        }
 }
-class Splitter {
-       public $detail_ids = array() ;
+
+class Splitter extends OrderAction {
        public $start_date;
        public $end_date;
+       public $start_offset;
+       public $end_offset;
        protected $days;
-       public $quantity_max;
+       public $max_quantity;
 
        public function __construct(array $data) {
-               $this->details_id = array();
-               foreach($data['detail'] as $detail_id => $detail) {
-                       array_push($this->details_id, $detail_id);
-               }
+               parent::__construct($data);
                $this->start_date = $data['start_date'];
                $this->end_date = $data['end_date'];
+               $this->start_offset = $data['start_offset'];
+               $this->end_offset = $data['end_offset'];
                $this->days = date_diff2($this->end_date, $this->start_date, 'd');
+
+               $this->max_quantity = $data['max_quantity'];
        }
 
        protected function loadDetail($detail_id) {
@@ -40,11 +47,16 @@ class Splitter {
        }
 
        public function splitAll() {
+               $ok =  true;
                foreach($this->detail_ids as $detail_id) {
+display_warning("processing $detail_id");
                                $detail = $this->loadDetail($detail_id);
                                $splits = $this->split($detail);
-                               $this->saveSplits($detail, $splits);
+                               foreach($splits as $split) $this->alterSplit($split);
+                               $ok &= $this->saveSplits($detail, $splits);
                }
+
+               return $ok; 
        }
 
        public function days() {
@@ -59,41 +71,108 @@ class Splitter {
  * The 'splitting' split the whole quantity not only the quantity left to dispatch
  * However, fully dispatched split won't be split in real, but merged with the next one
  */
-       protected function split($row) {
+       public function split($row) {
                $splits = array();
                $quantity = $row['quantity'];
                $quantity_sent = $row['qty_sent'];
 
-               if($quantity >= $quantity_sent) return;
-               if(($quantity-$quantity_sent) % $this->max_quantity < $this->max_quantity) return;
+               /* Check if the item has been fully dispatched.
+                * If so,  there is no need to do anything.
+                */
+               if($quantity_sent >= $quantity) return $splits;
                
                // determine the number of split needed. This will give us the lenght of a split.
-               $nsplit = ceiling($initial_quantity/$this->max_quantity);
-               if($nsplit == 1) return;
+               $nsplit = ceil($quantity/$this->max_quantity);
 
                $period = $this->days/$nsplit;
 
-               array_push($splits, $split = new Split($start_date, $period));
+               array_push($splits, $split = new Split($this->start_date, $period));
+               $split->quantity_dispatched = $quantity_sent;
                $split_quantity = min($quantity, $this->max_quantity);
                while($split_quantity > 0) {
                                        $split->quantity += $split_quantity;
                                // Check if the split has been entirely dispatch or not.
-                               if($quantity_dispatched > $split->quantity) {
+                               if($split->quantity_dispatched > $split->quantity) {
                                        //extend the split
                                        $split->extend($period);
                                }
                                else {
                                        // create a new split
                                        array_push($splits, $split = new Split($split->end_date, $period));
-                                       $quantity_dispatched = 0; // we don't need to check anymore.
                                        
                                }
                                $quantity -= $split_quantity;
                                $split_quantity = min($quantity, $this->max_quantity);
                }
 
+               // We need to remove the last split if it's empty
+               if($split->quantity == 0) array_pop($splits);
                return $splits;
        }
 
+       function alterSplit($split) {
+               foreach(explode(' ', 'start end') as $att) {
+                       $date = "${att}_date";
+                       $offset = "${att}_offset";
+                       if($this->$offset === null || $this->$offset === "") {
+                               $split->$date = null;
+                       }
+                       else {
+                               $split->$date = add_days($split->$date, $this->$offset);
+                       }
+               }
+       }
+
+       public function saveSplits($detail, $splits) {
+               if(empty($splits)) return true;
+
+               $detail_id = $detail['id'];
+               $priority = $detail['priority'];
+               $priority_offset = 1;
+               $order_no = $detail['order_no'];
+               $trans_type = $detail['trans_type'];
+
+               /* We need to update the first one (as it exists already in the database)
+                * but insert the following one.
+                */
+               $first = array_shift($splits);
+               $set = new SqlSet();
+               $set->addDate($first->start_date, 'hold_until_date')
+                               ->addDate($first->end_date, 'expiry_date')
+                               ->add($first->quantity, 'quantity', false);
+       display_warning($set->toString());
+               db_query("UPDATE ".TB_PREF."sales_order_details
+                                                       SET {$set->toString()}
+                                                       WHERE id = $detail_id", "Problem splitting order details $detail_id");
+
+               // Compute common field for each split
+               $common_set  = new SqlSet();
+               $common_set->add($order_no, 'order_no', false)
+                               ->add($trans_type, 'trans_type')
+                               ->add($detail['required_date'], 'required_date')
+                               ->add($detail['comment'], 'comment')
+                               ->add($detail['stk_code'], 'stk_code')
+                               ->add($detail['description'], 'description')
+                               ->add($detail['unit_price'], 'unit_price', false)
+                               ->add($detail['discount_percent'], 'discount_percent', false);
+
+               foreach($splits as $split) {
+                       $set = new SqlSet($common_set);
+                       $set->addDate($split->start_date, 'hold_until_date')
+                               ->addDate($split->end_date, 'expiry_date')
+                               ->add($split->quantity, 'quantity', false);
+       display_warning($set->toString());
+               db_query("INSERT INTO ".TB_PREF."sales_order_details
+                                                       SET {$set->toString()}
+                                                       , priority = '$priority' + INTERVAL ${priority_offset} second"
+                                                ,"Problem spliting order details $detail_id");
+                               $priority_offset++;
+               }
+
+               return true;
+               
+
+       }
+
 }
 ?>