<?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;
$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) {
}
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() {
* 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;
+
+
+ }
+
}
?>