source: contrib/ProjectManager/inc/class.datasource.inc.php @ 3594

Revision 3594, 10.7 KB checked in by afernandes, 13 years ago (diff)

Ticket #1416 - Disponibilizado o módulo ProjectManager? para a comunidade

  • Property svn:executable set to *
Line 
1<?php
2/**
3 * ProjectManager - DataSource baseclass
4 *
5 * @link http://www.egroupware.org
6 * @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
7 * @package projectmanager
8 * @copyright (c) 2005 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
9 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
10 * @version $Id: class.datasource.inc.php 22355 2006-08-26 16:30:45Z ralfbecker $
11 */
12
13/**
14 * constants for the different types of data
15 *
16 * or'ed together eg. for phpgw_pm_eletemts.pe_overwrite
17 */
18/** int percentage completion 0-100 */
19define('PM_COMPLETION',1);
20/** int seconds planned time */
21define('PM_PLANNED_TIME',2);
22/** int seconds used time */
23define('PM_USED_TIME',4);
24/** double planned budget */
25define('PM_PLANNED_BUDGET',8);
26/** double planned budget */
27define('PM_USED_BUDGET',16);
28/** int timestamp planned start-date */
29define('PM_PLANNED_START',32);
30/** int timestamp real start-date */
31define('PM_REAL_START',64);             
32/** int timestamp planned end-date */
33define('PM_PLANNED_END',128);
34/** int timestamp real end-date */
35define('PM_REAL_END',256);
36/** array with (int) user- or (string) resource-ids */
37define('PM_RESOURCES',512);
38/** string title */
39define('PM_TITLE',1024);
40/** string details */
41define('PM_DETAILS',2048);
42/** int pl_id */
43define('PM_PRICELIST_ID',4096);
44/** double price */
45define('PM_UNITPRICE',8192);
46/** double planned quantity */
47define('PM_PLANNED_QUANTITY',16384);
48/** double used quantity */
49define('PM_USED_QUANTITY',32768);
50/** all data-types or'ed together, need to be changed if new data-types get added */
51define('PM_ALL_DATA',65535);
52
53/**
54 * DataSource baseclass of the ProjectManager
55 *
56 * This is the baseclass of all DataSources, each spezific DataSource extends it and implement
57 * an own get method.
58 *
59 * The read method of this class sets (if not set by the get method) the planned start- and endtime:
60 *  - planned start from the end of a start constrain or the project start-time
61 *  - planned end from the planned time and a start-time
62 *  - real or planned start and end from each other
63 *
64 * @package projectmanager
65 * @author RalfBecker-AT-outdoor-training.de
66 * @copyright (c) 2005 by RalfBecker-AT-outdoor-training.de
67 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
68 */
69class datasource
70{
71        /**
72         * @var string $type type of the datasource, eg. name of the supported app
73         */
74        var $type;
75        /**
76         * @var bolink-object $link instance of the link-class
77         */
78        var $link;
79        /**
80         * @var object $bo bo-object of the used app
81         */
82        var $bo;
83        /**
84         * @var int $valid valid data-types of that source (or'ed PM_ constants)
85         */
86        var $valid = 0;
87        /**
88         * @var array $name2id translated names / array-keys to the numeric ids PM_*
89         */
90        var $name2id = array(
91                'pe_completion'     => PM_COMPLETION,
92                'pe_planned_time'   => PM_PLANNED_TIME,
93                'pe_used_time'      => PM_USED_TIME,
94                'pe_planned_budget' => PM_PLANNED_BUDGET,
95                'pe_used_budget'    => PM_USED_BUDGET,
96                'pe_planned_start'  => PM_PLANNED_START,
97                'pe_real_start'     => PM_REAL_START,
98                'pe_planned_end'    => PM_PLANNED_END,
99                'pe_real_end'       => PM_REAL_END,
100                'pe_title'          => PM_TITLE,
101                'pe_resources'          => PM_RESOURCES,
102                'pe_details'            => PM_DETAILS,
103                'pl_id'                         => PM_PRICELIST_ID,
104                'pe_unitprice'      => PM_UNITPRICE,
105                'pe_planned_quantity' => PM_PLANNED_QUANTITY,
106                'pe_used_quantity'  => PM_USED_QUANTITY,               
107        );
108        /**
109         * @var boprojectelements-object $bo_pe pe object to read other pe's (eg. for constraints)
110         */
111        var $bo_pe;
112
113        /**
114         * Constructor
115         *
116         * @param string $type=null type of the datasource
117         */
118        function datasource($type=null)
119        {
120                $this->type = $type;
121
122                if (!is_object($GLOBALS['phpgw']->link))
123                {
124                        $GLOBALS['phpgw']->link =& CreateObject('phpgwapi.bolink');
125                }
126                $this->link =& $GLOBALS['phpgw']->link;
127        }
128       
129        /**
130         * get an item from the underlaying app and convert applying data ia a datasource array
131         *
132         * A datasource array can contain values for the keys: completiton, {planned|used}_time, {planned|used}_budget,
133         *      {planned|real}_start, {planned|real}_end and pe_status
134         * Not set values mean they are not supported by the datasource.
135         *
136         * Reimplent this function for spezial datasource types (not read!)
137         *
138         * @param mixed $data_id id as used in the link-class for that app, or complete entry as array
139         * @return array/boolean array with the data supported by that source or false on error (eg. not found, not availible)
140         */
141        function get($data_id)
142        {
143                if (($title = $this->link->title($this->type,$data_id)))
144                {
145                        return array(
146                                'pe_title'  => $title,
147                                'pe_status' => 'ignore',        // not supported datasources are ignored, as they contain no values, eg. addressbook
148                        );
149                }
150                return false;
151        }
152       
153        /**
154         * read an item from a datasource (via the get methode) and try to set (guess) some not supported values
155         *
156         * A datasource array can contain values for the keys: completiton, {planned|used}_time, {planned|used}_budget,
157         *      {planned|real}_start, {planned|real}_end
158         * Not set values mean they are not supported by the datasource.
159         *
160         * @param mixed $data_id id as used in the link-class for that app, or complete entry as array
161         * @param array $pe_data data of the project-element or null, eg. to use the constraints
162         * @return array/boolean array with the data supported by that source or false on error (eg. not found, not availible)
163         */
164        function read($data_id,$pe_data=null)
165        {
166                $ds = $this->get($data_id);
167               
168                //echo "<p>datasource::read($data_id,$pe_data) ds="; _debug_array($ds);
169               
170                if ($ds)
171                {
172                        // setting a not set planned start from a contrains
173                        if ((!$ds['pe_planned_start'] || $ds['ignore_planned_start']) && !is_null($pe_data) && $pe_data['pe_constraints']['start'])
174                        {
175                                //echo "start-constr."; _debug_array($pe_data['pe_constraints']['start']);
176                                $start = 0;
177                                if (!is_object($this->bo_pe))
178                                {
179                                        $this->bo_pe =& CreateObject('projectmanager.boprojectelements',$pe_data['pm_id']);
180                                }
181                                foreach($pe_data['pe_constraints']['start'] as $start_pe_id)
182                                {
183                                        if ($this->bo_pe->read(array('pm_id'=>$pe_data['pm_id'],'pe_id'=>$start_pe_id)) &&
184                                                $start < $this->bo_pe->data['pe_planned_end'])
185                                        {
186                                                $start = $this->bo_pe->data['pe_planned_end'];
187                                                //echo "startdate from startconstrain with"; _debug_array($this->bo_pe->data);
188                                        }
189                                }
190                                if ($start)
191                                {
192                                        $ds['pe_planned_start'] = $this->project->date_add($start,0,$ds['pe_resources'][0]);
193                                        //echo "<p>$ds[pe_title] set planned start to ".date('D Y-m-d H:i',$ds['pe_planned_start'])."</p>\n";
194                                        unset($ds['ignore_planned_start']);
195                                }
196                        }
197                        // setting the planned start from the real-start
198                        if (!$ds['pe_planned_start'] && !$ds['ignore_planned_start'] && $ds['pe_real_start'])
199                        {
200                                $ds['pe_planned_start'] = $ds['pe_real_start'];
201                        }
202                        // setting the planned start from the projects start
203                        if ((!$ds['pe_planned_start'] || $ds['ignore_planned_start']) && $pe_data['pm_id'])
204                        {
205                                if (!is_object($this->bo_pe))
206                                {
207                                        $this->bo_pe =& CreateObject('projectmanager.boprojectelements',$pe_data['pm_id']);
208                                }
209                                if ($this->bo_pe->pm_id != $pe_data['pm_id'])
210                                {
211                                        $this->bo_pe->boprojectelements($pe_data['pm_id']);
212                                }
213                                if ($this->bo_pe->project->data['pm_planned_start'] || $this->bo_pe->project->data['pm_real_start'])
214                                {
215                                        $ds['pe_planned_start'] = $this->bo_pe->project->data['pm_planned_start'] ?
216                                                $this->bo_pe->project->data['pm_planned_start'] : $this->bo_pe->project->data['pm_real_start'];
217                                        unset($ds['ignore_planned_start']);
218                                }
219                        }
220                        // calculating the planned end-date from the planned time
221                        if ((!$ds['pe_planned_end'] || $ds['ignore_planned_end']) && $ds['pe_planned_time'])
222                        {
223                                if ($ds['pe_planned_start'] && is_object($this->project))
224                                {
225                                        $ds['pe_planned_end'] = $this->project->date_add($ds['pe_planned_start'],$ds['pe_planned_time'],$ds['pe_resources'][0]);
226                                        //echo "<p>$ds[pe_title] set planned end to ".date('D Y-m-d H:i',$ds['pe_planned_end'])."</p>\n";
227                                        unset($ds['ignore_planned_end']);
228                                }
229                        }
230                        // setting real or planned start- or end-date, from each other if not set
231                        foreach(array('start','end') as $name)
232                        {
233                                if ((!isset($ds['pe_real_'.$name]) || $ds['ignore_real_'.$name]) && isset($ds['pe_planned_'.$name]) /*&&
234                                // setting the real dates only if the completion is more then 0% (if supported by the datasource)
235                                        (!isset($ds['pe_completion']) || $ds['pe_completion'] > 0)*/)
236                                {
237                                        $ds['pe_real_'.$name] = $ds['pe_planned_'.$name];
238                                }
239                                elseif (!isset($ds['pe_planned_'.$name]) && isset($ds['pe_real_'.$name]))
240                                {
241                                        $ds['pe_planned_'.$name] = $ds['pe_real_'.$name];
242                                }
243                        }
244                        // try calculating a (second) completion from the times
245                        if (!empty($ds['pe_used_time']) && (int) $ds['pe_planned_time'] > 0)
246                        {
247                                $compl_by_time = $ds['pe_used_time'] / $ds['pe_planned_time'];
248
249                                // if no completion is given by the datasource use the calculated one
250                                if (!isset($ds['pe_completion']))
251                                {
252                                        $ds['pe_completion'] = $compl_by_time;
253                                }
254                                elseif ($compl_by_time < $ds['pe_completion'])
255                                {
256                                        $ds['warning']['completion_by_time'] = $compl_by_time;
257                                }
258                        }
259                        // try calculating a (second) completion from the budget
260                        if(!empty($ds['pe_used_budget']) && $ds['pe_planned_budget'] > 0)
261                        {
262                                $compl_by_budget = $ds['pe_used_budget'] / $ds['pe_planned_budget'];
263                       
264                                // if no completion is given by the datasource use the calculated one
265                                if (!isset($ds['pe_completion']))
266                                {
267                                        $ds['pe_completion'] = $compl_by_budget;
268                                }
269                                elseif ($compl_by_budget < $ds['pe_completion'])
270                                {
271                                        $ds['warning']['completion_by_budget'] = $compl_by_budget;
272                                }
273                        }
274                        // setting quantity from time, if not given by the ds
275                        foreach(array(
276                                'pe_planned_time' => 'pe_planned_quantity',
277                                'pe_used_time'    => 'pe_used_quantity',
278                        ) as $time => $quantity)
279                        {
280                                if (!isset($ds[$quantity]) && isset($ds[$time]))
281                                {
282                                        $ds[$quantity] = $ds[$time] / 60.0;     // time is in min, quantity in h
283                                }
284                        }
285                        // setting the budget from unitprice and quantity
286                        if (isset($ds['pe_unitprice']))
287                        {
288                                foreach(array(
289                                        'pe_planned_quantity' => 'pe_planned_budget',
290                                        'pe_used_quantity'    => 'pe_used_budget',
291                                ) as $quantity => $budget)
292                                {
293                                        if (!isset($ds[$budget]) && isset($ds[$quantity]))
294                                        {
295                                                $ds[$budget] = $ds[$quantity] * $ds['pe_unitprice'];
296                                        }
297                                }
298                        }
299                               
300                }
301                return $ds;
302        }
303       
304        /**
305         * reading the not-overwritten values from the element-data
306         *
307         * Can be used instead of read, if there's no read-access to the datasource itself
308         *
309         * @param array $data element data
310         * @return array
311         */
312        function element_values($data)
313        {
314                $values = array();
315
316                foreach($this->name2id as $name => $id)
317                {
318                        if (!($data['pe_overwrite'] & $id))
319                        {
320                                $values[$name] = $data[$name];
321                        }
322                }
323                return $values;
324        }
325}
Note: See TracBrowser for help on using the repository browser.