Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Run {
- function run(){
- $databook = DataBook::load('book1.xlsx');
- $orders = $databook->orders;
- $workCenters = $databook->workCenters;
- $countOperations = $databook->countOperations;
- $countPeriods = $databook->countPeriods;
- $loadPercentage = $databook->loadPercentage;
- $initialTable = array(
- 'ordersTable' => $this->renderPartial('_orders', array(
- 'orders' => $orders,
- 'countOperations' => $countOperations,
- 'releaseCode' => false,
- 'tableId' => 'initialOrders'
- ), true),
- 'workCentersTable' => $this->renderPartial('_workCenters', array(
- 'workCenters' => $workCenters,
- 'countPeriods' => $countPeriods,
- 'tableId' => 'initialWorkCenters'
- ), true),
- );
- $pool = new Pool();
- $pool->init($workCenters);
- $periods = array();
- $stop = false;
- $totalCountPeriods = 0;
- Order::initAllLoadPercentage($orders, $loadPercentage);
- while (!$stop) {
- $totalCountPeriods++;
- //Start working
- $loadLimits = $databook->getLoadLimitsAtPeriod($totalCountPeriods - 1);
- $capacityLimits = $databook->getCapacityLimitsAtPeriod($totalCountPeriods - 1, true);
- Order::reinitTaskStatus($orders);
- $snapshot = '';
- $pool->checkRelease($orders, $loadLimits, $capacityLimits, $totalCountPeriods);
- $periods[] = array(
- 'orderTable' => $this->renderPartial('_orders', array(
- 'orders' => $orders,
- 'countOperations' => $countOperations,
- 'releaseCode' => true,
- 'tableId' => 'period' . $totalCountPeriods,
- ), true),
- 'poolTable' => $this->renderPartial('_pool', array(
- 'pool' => $pool,
- 'tableId' => 'pool' . $totalCountPeriods,
- 'loadLimits' => $databook->getLoadLimitsAtPeriod($totalCountPeriods - 1),
- 'capacityLimits' => $databook->getCapacityLimitsAtPeriod($totalCountPeriods - 1),
- ), true),
- );
- $pool->pullDownTasks($orders, $loadLimits, $capacityLimits, $totalCountPeriods);
- $stop = $totalCountPeriods == 3;
- $capacityLimits = $databook->getCapacityLimitsAtPeriod($totalCountPeriods - 1, false);
- $pool->forwardTimeLine($capacityLimits);
- //echo "$totalCountPeriods <<< =====================================\n";
- //print_r($orders);
- $pool->releaseAvailableFirsTask($orders, $loadPercentage);
- }
- //
- $this->render('run', array(
- 'initialTables' => $initialTable,
- 'periods' => $periods,
- 'countOperations' => $countOperations,
- 'countPeriods' => $countPeriods,
- 'totalCountPeriods' => $totalCountPeriods,
- ));
- }
- }
- class Order {
- const RELEASE_CODE_NOT_RELEASE = 'X';
- const RELEASE_CODE_RELEASE = 'R';
- const RELEASE_CODE_OPEN = 'O';
- public $name;
- public $plannedStartDate;
- public $tasks;
- public $releaseCode;
- public function getTask($idx) {
- return (isset($this->tasks[$idx])) ? $this->tasks[$idx] : NULL;
- }
- public function getTaskByWCName($name) {
- foreach ($this->tasks as &$task) {
- if ($task->workCenter == $name) {
- return $task;
- }
- }
- return NULL;
- }
- public function attributeNames() {
- return array();
- }
- public function popFront() {
- array_shift($this->tasks);
- }
- public static function flatten($orders, $countOperations) {
- $array = array();
- foreach ($orders as $order) {
- $arorder = array();
- $arorder['name'] = $order->name;
- $arorder['plannedStartDate'] = $order->plannedStartDate;
- for ($i = 0; $i < $countOperations; $i++) {
- if (($task = $order->getTask($i)) !== NULL) {
- $arorder['tasks'][] = array(
- 'hours' => $task->hours,
- 'workCenter' => $task->workCenter,
- );
- } else {
- $arorder['tasks'][] = array(
- 'hours' => '',
- 'workCenter' => '',
- );
- }
- }
- $array[] = $arorder;
- }
- return $array;
- }
- public function initLoadPercentage($loadPercentage) {
- foreach ($this->tasks as $i => &$task) {
- $ii = (($i + 1) * 2) + 1;
- $task->hours = $task->hours * pow((100 / $loadPercentage), (($ii + 1) / 2) - 2);
- }
- }
- public function isEmpty() {
- return count($this->tasks) == 0;
- }
- public function getCssClass() {
- if (isset($this->releaseCode)) {
- switch ($this->releaseCode) {
- case self::RELEASE_CODE_RELEASE:
- return 'release';
- case self::RELEASE_CODE_NOT_RELEASE:
- return 'not_release';
- case self::RELEASE_CODE_OPEN:
- return 'open';
- default:
- return '';
- }
- } else {
- return '';
- }
- }
- public static function initAllLoadPercentage(&$orders, $loadPercentage) {
- foreach ($orders as &$order) {
- $order->initLoadPercentage($loadPercentage);
- }
- }
- public static function sortByDate(&$orders) {
- uasort($orders, function($a, $b) {
- return (($a->plannedStartDate == $b->plannedStartDate) ? 0 : (($a->plannedStartDate > $b->plannedStartDate) ? +1 : -1));
- });
- }
- public static function reinitTaskStatus(&$orders) {
- foreach ($orders as &$order) {
- foreach ($order->tasks as &$task) {
- $task->status = NULL;
- }
- }
- }
- }
- class Pool {
- public $workCenters = array();
- public function init($workCenters) {
- $this->workCenters = array();
- foreach ($workCenters as $workCenter) {
- $ws = new PoolWorkCenter();
- $ws->name = $workCenter->name;
- //adding leftover
- $leftOver = new PoolTask($workCenter->name, 0, $workCenter->leftOver);
- $leftOver->type = PoolTask::TYPE_LEFTOVER;
- $ws->putTask($leftOver);
- $this->workCenters[] = $ws;
- }
- }
- public function getWorkCenterByName($name) {
- foreach ($this->workCenters as &$workcenter) {
- if ($workcenter->name == $name) {
- return $workcenter;
- }
- }
- }
- public function getTaskByTID($tId) {
- foreach ($this->workCenters as &$workcenter) {
- foreach ($workcenter->tasks as &$p) {
- if ($p->tId == $tId) {
- return $p;
- }
- }
- }
- return NULL;
- }
- public function getMaximumTaskCount() {
- $max = 0;
- foreach ($this->workCenters as $ws) {
- $max = ($max < $ws->getTaskCount()) ? $ws->getTaskCount() : $max;
- }
- return $max;
- }
- public function getWorkCenterCount() {
- return count($this->workCenters);
- }
- public function forwardTimeLine($arCapacity) {
- foreach ($this->workCenters as $i => $ws) {
- $time = isset($arCapacity[$i]) ? $arCapacity[$i] : 0;
- $ws->forwardTimeLine($time);
- }
- }
- public function checkRelease(&$orders, $loadLimits, $capacityLimits, $period) {
- $loads = array();
- $loads2 = array();
- $loads3 = array();
- foreach ($this->workCenters as $m => $pws) {
- $loads[$m] = $pws->getEndTime();
- $loads2[$pws->name] = $pws->getLoad();
- $loads3[$pws->name] = $pws->getLoad();
- }
- foreach ($orders as $k => &$order) {
- if (!$order->isEmpty() && ($order->releaseCode == Order::RELEASE_CODE_RELEASE || $order->releaseCode == Order::RELEASE_CODE_OPEN)) {
- $order->releaseCode = Order::RELEASE_CODE_OPEN;
- continue;
- }
- $flag = true;
- //echo $order->name . ' ';
- foreach ($this->workCenters as $m => $pws) {
- $ptask = $order->getTaskByWCName($pws->name);
- if ($ptask != NULL) {
- $load = $loads[$m];
- //echo $ptask->hours . ' ' . $load . ' ' . $loadLimits[$m] . " -- ";
- $flag = $flag && ($load < $loadLimits[$m]);
- } else {
- $load = $loads[$m];
- //echo 0 . ' ' . $load . ' ' . $loadLimits[$m] . " -- ";
- }
- }
- //echo $flag . ' -- ';
- //echo "\n";
- foreach ($this->workCenters as $m => $pws) {
- if ($flag) {
- $otask = $order->getTaskByWCName($pws->name);
- if ($otask != NULL) {
- $newTask = new PoolTask($pws->name, $loads[$m], $otask->hours, $order->name);
- $newTask->tId = $otask->tId;
- $pws->putTask($newTask);
- $loads[$m] = $loads[$m] + $otask->hours;
- } else {
- $loads[$m] = $loads[$m] + 0;
- }
- $order->releaseCode = Order::RELEASE_CODE_RELEASE;
- } else {
- $order->releaseCode = Order::RELEASE_CODE_NOT_RELEASE;
- }
- }
- }
- $idx = 0;
- foreach ($orders as &$order) {
- if ($order->releaseCode == Order::RELEASE_CODE_RELEASE || $order->releaseCode == Order::RELEASE_CODE_OPEN) {
- $task = $order->getTask(0);
- if ($task != NULL) {
- //echo $task->workCenter . ") " . $loads2[$task->workCenter] . ' ' . $task->hours . ' ' . $capacityLimits[$task->workCenter] . "\n";
- if ($loads2[$task->workCenter] < $capacityLimits[$task->workCenter]) {
- $task->status = Task::STATUS_PHYSICALLY_AVAILABLE;
- if ($loads3[$task->workCenter] < $capacityLimits[$task->workCenter]) {
- $task->status = Task::STATUS_WORKABLE;
- $loads3[$task->workCenter] += $task->hours;
- }
- }
- }
- }
- }
- //$this->pullDownTasks($orders, $loadLimits, $capacityLimits, $period);
- }
- public function evaluate(&$orders, $loadLimits, $capacityLimits, $period) {
- //evaluate
- }
- public function pullDownTasks(&$orders, $loadLimits, $capacityLimits, $period) {
- foreach ($orders as &$order) {
- foreach ($order->tasks as $task) {
- if ($task->status == TASK::STATUS_WORKABLE) {
- $pws = $this->getWorkCenterByName($task->workCenter);
- $pws->pullDownTask($task);
- }
- }
- }
- }
- public function releaseAvailableFirsTask(&$orders, $loadPercentage) {
- $tIds = array();
- foreach ($orders as &$order) {
- $idx = 0;
- $task = $order->getTask($idx);
- if (isset($task) && $task->status == Task::STATUS_WORKABLE) {
- $ptask = $this->getTaskByTID($task->tId);
- if (isset($ptask) && $ptask->end <= 0) {
- array_shift($order->tasks);
- foreach ($order->tasks as $i => &$tt) {
- $ii = (($i + 1) * 2) + 1;
- $tt->hours = $tt->hours * pow(($loadPercentage / 100), (($ii + 1) / 2) - 1);
- $ii = (($i + 1) * 2) + 1;
- $tt->hours = $tt->hours * pow((100 / $loadPercentage), (($ii + 1) / 2) - 2);
- $tIds[] = array(
- 'id' => $tt->tId,
- 'newHours' => $tt->hours,
- );
- }
- }
- }
- }
- $this->resyncTasks($tIds);
- }
- public function resyncTasks($tIds) {
- foreach ($tIds as $tId) {
- $ptask = $this->getTaskByTID($tId['id']);
- if ($ptask != NULL) {
- $ptask->hours = $tId['newHours'];
- }
- }
- $this->fixTimeLine();
- }
- public function fixTimeLine() {
- foreach ($this->workCenters as &$ws) {
- $ws->fixTaskTimeline();
- }
- }
- }
- class PoolTask {
- const TYPE_TASK = 0;
- const TYPE_LEFTOVER = 1;
- const TYPE_IDLE = 2;
- public $orderName = NULL;
- public $hours = '';
- public $workCenterName = '';
- public $start = 0;
- public $end = 0;
- public $type = self::TYPE_TASK;
- public $tId;
- public function __construct($workCenterName, $start, $hours, $orderName = NULL) {
- $this->workCenterName = $workCenterName;
- $this->start = $start;
- $this->hours = $hours;
- $this->end = $this->start + $hours;
- $this->orderName = $orderName;
- }
- }
- class PoolWorkCenter {
- public $name;
- public $tasks = array();
- public function putTask($task) {
- $this->tasks[] = $task;
- }
- public function getTask($idx) {
- return (isset($this->tasks[$idx])) ? $this->tasks[$idx] : NULL;
- }
- public function hasTaskAt($idx) {
- return (isset($this->tasks[$idx]));
- }
- public function getTaskCount() {
- return count($this->tasks);
- }
- public function getEndTime() {
- $endTask = $this->tasks[count($this->tasks) - 1];
- return $endTask->end;
- }
- public function getLoad() {
- $stop = false;
- $i = 0;
- while (!$stop) {
- $retval = $this->tasks[$i]->end;
- if ($retval > 0) {
- $stop = true;
- } else {
- $i++;
- }
- }
- return $retval;
- }
- public function forwardTimeLine($time) {
- foreach ($this->tasks as $task) {
- $task->start -= $time;
- $task->end -= $time;
- }
- }
- public function pullDownTask($task) {
- $tId = $task->tId;
- $idx = 0;
- for ($i = 0; $i < count($this->tasks); $i++) {
- $ttask = $this->tasks[$i];
- if ($ttask->tId == $tId) {
- $idx = $i;
- break;
- }
- }
- while ($idx > 0 && $this->getTask($idx - 1)->start > 0) {
- $temp = $this->tasks[$idx - 1];
- $this->tasks[$idx - 1] = $this->tasks[$idx];
- $this->tasks[$idx] = $temp;
- $idx--;
- }
- //fixing
- $this->fixTaskTimeline();
- }
- public function fixTaskTimeline() {
- $ttask = $this->tasks[0];
- $ttask->end = $ttask->start + $ttask->hours;
- for ($i = 1; $i < count($this->tasks); $i++) {
- $curtask = $this->tasks[$i];
- $lasttask = $this->tasks[$i - 1];
- $curtask->start = $lasttask->end;
- $curtask->end = $curtask->start + $curtask->hours;
- }
- }
- }
- class Task {
- const STATUS_PHYSICALLY_AVAILABLE = 'P';
- const STATUS_WORKABLE = 'W';
- public $hours;
- public $workCenter;
- public $tId;
- public $status = NULL;
- public static $count;
- public function __construct() {
- $this->tId = ++self::$count;
- }
- public function getCssClass() {
- if ($this->status != NULL) {
- switch ($this->status) {
- case self::STATUS_PHYSICALLY_AVAILABLE:
- return 'tp';
- case self::STATUS_WORKABLE:
- return 'tw';
- }
- }
- }
- }
- class WorkCenter {
- public $name;
- public $leftOver;
- public $periods;
- public function getPeriod($idx) {
- return (isset($this->periods[$idx])) ? $this->periods[$idx] : NULL;
- }
- public function getCapacityLimitAtPeriod($idx) {
- return isset($this->periods[$idx]) ? $this->getPeriod($idx)->capacityLimit : 0;
- }
- public function getLoadLimitAtPeriod($idx) {
- return isset($this->periods[$idx]) ? $this->getPeriod($idx)->loadLimit : 0;
- }
- }
- class WorkCenterPeriod {
- public $capacityLimit;
- public $loadLimit;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement