0009768: Use ModelConfig for Timetracker models
[tine20] / tine20 / Timetracker / Setup / DemoData.php
1 <?php
2 /**
3  * Tine 2.0
4  *
5  * @package     Timetracker
6  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
7  * @author      Alexander Stintzing <a.stintzing@metaways.de>
8  * @copyright   Copyright (c) 2013 Metaways Infosystems GmbH (http://www.metaways.de)
9  *
10  */
11
12 /**
13  * class for Timetracker initialization
14  *
15  * @package     Setup
16  */
17 class Timetracker_Setup_DemoData extends Tinebase_Setup_DemoData_Abstract
18 {
19     /**
20      * required apps
21      * 
22      * @var array
23      */
24     protected static $_requiredApplications = array('Admin', 'Sales', 'HumanResources');
25     
26     /**
27      * holds the instance of the singleton
28      *
29      * @var Timetracker_Setup_DemoData
30      */
31     private static $_instance = NULL;
32     
33     /**
34      * the application name to work on
35      * 
36      * @var string
37      */
38     protected $_appName = 'Timetracker';
39     
40     /**
41      * @var Timetracker_Controller_Timeaccount
42      */
43     protected $_taController;
44     
45     /**
46      * 
47      * @var Tinebase_DateTime
48      */
49     protected $_startDate;
50     
51     /**
52      * @var Timetracker_Controller_Timesheet
53      */
54     protected $_tsController;
55     
56     /**
57      * @var Tinebase_DateTime
58      */
59     protected $_clearedDate;
60     
61     /**
62      * RecordSet with all employees
63      *
64      * @var Tinebase_Record_RecordSet
65      */
66     protected $_employees;
67     
68     /**
69      * @var HumanResources_Controller_Employee
70      */
71     protected $_empController;
72     
73     /**
74      * array of RecordSets with all timetracker.timeaccounts
75      *
76      * @var Tinebase_Record_RecordSet
77      */
78     protected $_timeAccounts;
79     
80     /**
81      * array of RecordSets with all contracts having the development costcenter assigned
82      *
83      * @var Tinebase_Record_RecordSet
84      */
85     protected $_contractsDevelopment;
86
87     /**
88      * array of RecordSets with all contracts having the marketing costcenter assigned
89      *
90      * @var Tinebase_Record_RecordSet
91      */
92     protected $_contractsMarketing;
93     
94     /**
95      * cc controller
96      * 
97      * @var Sales_Controller_CostCenter
98      */
99     protected $_ccController;
100     
101     /**
102      * The contract controller
103      * 
104      * @var Sales_Controller_Contract
105      */
106     protected $_contractController = NULL;
107     
108     /**
109      * models to work on
110      * 
111      * @var array
112      */
113     protected $_models = array('timeaccount', 'timesheet');
114     
115     /**
116      * the constructor
117      *
118      */
119     private function __construct()
120     {
121     }
122
123     /**
124      * the singleton pattern
125      *
126      * @return Timetracker_Setup_DemoData
127      */
128     public static function getInstance()
129     {
130         if (self::$_instance === NULL) {
131             self::$_instance = new self();
132         }
133         
134         return self::$_instance;
135     }
136
137     /**
138      * unsets the instance to save memory, be aware that hasBeenRun still needs to work after unsetting!
139      *
140      */
141     public function unsetInstance()
142     {
143         if (self::$_instance !== NULL) {
144             self::$_instance = null;
145         }
146     }
147
148     /**
149      * this is required for other applications needing demo data of this application
150      * if this returns true, this demodata has been run already
151      * 
152      * @return boolean
153      */
154     public static function hasBeenRun()
155     {
156         $c = Timetracker_Controller_Timeaccount::getInstance();
157         
158         $f = new Timetracker_Model_TimeaccountFilter(array(
159             array('field' => 'description', 'operator' => 'equals', 'value' => 'Created By Tine 2.0 DemoData'),
160         ), 'AND');
161         
162         return ($c->search($f)->count() > 9) ? true : false;
163     }
164     
165     /**
166      * @see Tinebase_Setup_DemoData_Abstract
167      * 
168      */
169     protected function _beforeCreate()
170     {
171         $this->_ccController  = Sales_Controller_CostCenter::getInstance();
172         $this->_taController  = Timetracker_Controller_Timeaccount::getInstance();
173         $this->_taController->sendNotifications(FALSE);
174         $this->_tsController  = Timetracker_Controller_Timesheet::getInstance();
175         $this->_tsController->sendNotifications(FALSE);
176         $this->_tsController->doContainerACLChecks(false);
177         
178         $this->_contractController    = Sales_Controller_Contract::getInstance();
179         $contracts = $this->_contractController->getAll();
180         $developmentString = self::$_de ? 'Entwicklung' : 'Development';
181         
182         $this->_contractsDevelopment = $contracts->filter('title', '/.' . $developmentString . '/', TRUE);
183         $this->_contractsMarketing = $contracts->filter('title', '/.Marketing/', TRUE);
184         
185         $this->_loadCostCentersAndDivisions();
186         
187         if (Tinebase_Application::getInstance()->isInstalled('HumanResources')) {
188             $this->_empController = HumanResources_Controller_Employee::getInstance();
189             $filter = new HumanResources_Model_EmployeeFilter(array());
190             $this->_employees = $this->_empController->search($filter);
191         }
192         
193         // set start date to start date of june 1st before last year
194         $date = Tinebase_DateTime::now();
195         $this->_startDate = $date->subMonth(3)->setTime(8,0,0);
196
197         // set clearedDate almost a month after
198         $this->_clearedDate = clone $this->_startDate;
199         $this->_clearedDate->addMonth(1)->subDay(2);
200     }
201     
202     /**
203      * creates shared tas
204      */
205     protected function _createSharedTimeaccounts()
206     {
207         // create 2 timeaccounts for each cc
208         $taNumber = 1;
209         
210         $userGroup = Tinebase_Group::getInstance()->getGroupByName('Users');
211         $developmentString = self::$_de ? 'Entwicklung' : 'Development';
212         if (! $userGroup) {
213             die('Could not find userGroup "Users", stopping.');
214         }
215         
216         $grants = array(array(
217             'account_id' => $userGroup->getId(),
218             'account_type' => 'group',
219             'bookOwnGrant' => TRUE,
220             'viewAllGrant' => TRUE,
221             'bookAllGrant' => TRUE,
222             // TODO: this shouldn't be neccessary, but is. why?:
223             'manageBillableGrant' => TRUE,
224             'exportGrant' => TRUE,
225             'adminGrant' => TRUE
226         ));
227         
228         $contractsIndex = 0;
229         
230         foreach($this->_costCenters as $costcenter) {
231             
232             $this->_timeAccounts[$costcenter->getId()] = new Tinebase_Record_RecordSet('Timetracker_Model_Timeaccount');
233             $i=0;
234             
235             while ($i < 2) {
236                 $i++;
237                 
238                 $ta = new Timetracker_Model_Timeaccount(array(
239                     'number'      => $taNumber,
240                     'title'       => Tinebase_Record_Abstract::generateUID(3),
241                     'grants'      => $grants,
242                     'status'      => 'billed',
243                     'cleared_at'  => $this->_clearedDate,
244                     'budget'      => NULL,
245                     'description' => 'Created By Tine 2.0 DEMO DATA'
246                 ));
247                 
248                 if (($costcenter->remark == 'Marketing') || ($costcenter->remark == $developmentString)) {
249                     $contract = $costcenter->remark == 'Marketing' ? $this->_contractsMarketing->getByIndex(rand(0, ($this->_contractsMarketing->count() -1))) : $this->_contractsDevelopment->getByIndex(rand(0, ($this->_contractsDevelopment->count() -1)));
250                     
251                     $ta->budget = $costcenter->remark == 'Marketing' ? 100 : NULL;
252                     $ta->relations = array(
253                         array(
254                             'own_model'              => 'Timetracker_Model_Timeaccount',
255                             'own_backend'            => 'SQL',
256                             'own_id'                 => NULL,
257                             'related_degree'         => Tinebase_Model_Relation::DEGREE_SIBLING,
258                             'related_model'          => 'Sales_Model_CostCenter',
259                             'related_backend'        => Tasks_Backend_Factory::SQL,
260                             'related_id'             => $costcenter->getId(),
261                             'type'                   => 'COST_CENTER'
262                         ),
263                         array(
264                             'own_model'              => 'Timetracker_Model_Timeaccount',
265                             'own_backend'            => 'SQL',
266                             'own_id'                 => NULL,
267                             'related_degree'         => Tinebase_Model_Relation::DEGREE_SIBLING,
268                             'related_model'          => 'Sales_Model_Contract',
269                             'related_backend'        => Tasks_Backend_Factory::SQL,
270                             'related_id'             => $contract->getId(),
271                             'type'                   => 'TIME_ACCOUNT'
272                         ));
273                     $ta->title = (self::$_de ? 'Zeitkonto mit ' : 'Timeaccount for ') . $contract->getTitle();
274                 } else {
275                     $ta->title = (self::$_de ? 'Zeitkonto mit KST ' : 'Timeaccount for CC ') . $costcenter->getTitle();
276                     $ta->relations = array(
277                         array(
278                             'own_model'              => 'Timetracker_Model_Timeaccount',
279                             'own_backend'            => 'SQL',
280                             'own_id'                 => NULL,
281                             'related_degree'         => Tinebase_Model_Relation::DEGREE_SIBLING,
282                             'related_model'          => 'Sales_Model_CostCenter',
283                             'related_backend'        => Tasks_Backend_Factory::SQL,
284                             'related_id'             => $costcenter->getId(),
285                             'type'                   => 'COST_CENTER'
286                         )
287                     );
288                 }
289                 
290                 $this->_timeAccounts[$costcenter->getId()]->addRecord($this->_taController->create($ta));
291                 
292                 $taNumber++;
293             }
294         }
295     }
296     
297     /**
298      * creates and persists a timesheet
299      * 
300      * @param array $data
301      * @return Tinebase_Record_Interface
302      */
303     protected function _createTimesheet($data)
304     {
305         $ts = new Timetracker_Model_Timesheet($data);
306         return $this->_tsController->create($ts);
307     }
308     
309     /**
310      * returns the cost center for the current account
311      *
312      * @return HumanResources_Model_CostCenter|Sales_Model_CostCenter
313      */
314     protected function _getCurrentUsersCostCenter()
315     {
316         $employee = $this->_getCurrentUsersEmployee();
317         $salesCC = HumanResources_Controller_CostCenter::getInstance()->getValidCostCenter($employee->getId(), NULL, TRUE);
318         return $salesCC;
319     }
320     
321     /**
322      * returns the employee for the current account
323      */
324     protected function _getCurrentUsersEmployee()
325     {
326         return $this->_employees->filter('account_id', Tinebase_Core::getUser()->accountId)->getFirstRecord();
327     }
328     
329     /**
330      * creates timesheets
331      */
332     protected function _createTimesheets()
333     {
334         if (Tinebase_Application::getInstance()->isInstalled('HumanResources')) {
335             $cc = $this->_getCurrentUsersCostCenter();
336         } else {
337             $cc = $this->_costCenters->filter('remark', 'Management')->getFirstRecord();
338         }
339         
340         
341         $ownTimeAccountRecordSet = $this->_timeAccounts[$cc->getId()]->sort('number');
342         $userId = Tinebase_Core::getUser()->accountId;
343         
344         $startDate = clone $this->_startDate;
345         $endDate   = clone $startDate;
346         $endDate->addMonth(3);
347         
348         $mkccId = $this->_marketingCostCenter->getId();
349         $deccId = $this->_developmentCostCenter->getId();
350         
351         $allMkccTimeAccountRecordSet = $this->_timeAccounts[$mkccId]->sort('number');
352         $allDeccTimeAccountRecordSet = $this->_timeAccounts[$deccId]->sort('number');
353         
354         $afterCleared = FALSE;
355         $stopIndex = 8;
356         
357         while ($startDate < $endDate) {
358             $wd = (int) $startDate->format('w');
359             
360             // create timesheets from tue -> fri, always a timeaccount of the users costcenter
361             if (($wd < 6) && ($wd > 2)) {
362                 // 8 hrs
363                 $ta = $ownTimeAccountRecordSet->getByIndex(rand(0, ($ownTimeAccountRecordSet->count() - 1)));
364                 $ts = $this->_createTimesheet(array(
365                     'account_id'     => $userId,
366                     'timeaccount_id' => $ta->getId(),
367                     'is_billable'    => false,
368                     'start_date'     => $startDate,
369                     'duration'       => 480,
370                     'description'    => static::$_de ? 'DemoData eigenes Zeitkonto' : 'DemoData own timeaccount',
371                     'is_cleared'     => (($ta->status == 'billed') ? true : false),
372                  ));
373             } else {
374                 
375                 // create timesheets on monday and tuesday
376                 $ta = $allMkccTimeAccountRecordSet->getByIndex(rand(0, ($allMkccTimeAccountRecordSet->count() - 1)));
377                 // 4 hrs for a marketing costcenter timeaccount
378                 $ts = $this->_createTimesheet(array(
379                     'account_id'     => $userId,
380                     'timeaccount_id' => $ta->getId(),
381                     'is_billable'    => false,
382                     'start_date'     => $startDate,
383                     'duration'       => 240,
384                     'description'    => static::$_de ? ('DemoData auf KST ' . $cc->number) : ('DemoData on costcenter ' . $cc->number),
385                     'is_cleared'     => (($ta->status == 'billed') ? true : false),
386                 ));
387                 
388                 $sd = clone $startDate;
389                 $sd->addMinute(300);
390                 $ta = $allDeccTimeAccountRecordSet->getByIndex(rand(0, ($allDeccTimeAccountRecordSet->count() - 1)));
391                 
392                 // 4 hrs for a development costcenter timeaccount
393                 $ts = $this->_createTimesheet(array(
394                     'account_id'     => $userId,
395                     'timeaccount_id' => $ta->getId(),
396                     'is_billable'    => false,
397                     'start_date'     => $sd,
398                     'duration'       => 240,
399                     'description'    => static::$_de ? ('DemoData auf KST ' . $cc->number) : ('DemoData on costcenter ' . $cc->number),
400                     'is_cleared'     => (($ta->status == 'billed') ? true : false),
401                 ));
402             }
403         
404             $startDate->addDay(1);
405         }
406     }
407     
408     /**
409      * @see parent
410      */
411     protected function _createTimesheetsForPwulf()
412     {
413         $this->_createTimesheets();
414     }
415
416     /**
417      * @see parent
418      */
419     protected function _createTimesheetsForRwright()
420     {
421         $this->_createTimesheets();
422     }
423
424     /**
425      * @see parent
426      */
427     protected function _createTimesheetsForSclever()
428     {
429         $this->_createTimesheets();
430     }
431     
432     /**
433      * @see parent
434      */
435     protected function _createTimesheetsForJmcblack()
436     {
437         $this->_createTimesheets();
438     }
439     
440     /**
441      * @see parent
442      */
443     protected function _createTimesheetsForJsmith()
444     {
445         $this->_createTimesheets();
446     }
447 }