Skip to content
This repository has been archived by the owner on Dec 27, 2023. It is now read-only.

Commit

Permalink
Feature(DFCom) employee dependend project time list
Browse files Browse the repository at this point in the history
  • Loading branch information
corneliusweiss committed Mar 1, 2023
1 parent 32d6e8a commit 35ce12d
Show file tree
Hide file tree
Showing 13 changed files with 139 additions and 7 deletions.
14 changes: 14 additions & 0 deletions tine20/DFCom/Controller/Device.php
Expand Up @@ -173,6 +173,8 @@ public function dispatchRecord()
foreach($lists as $list) {
/** @var DFCom_Model_DeviceList $list */
try {
// NOTE: lists starting with a lodash need special handling in domain specific handlers and are ignored here
if($list->name[0] === '_') continue;
if ($list->list_version != $deviceListController->getSyncToken($list)) {
$response->updateDeviceList($list, $device);
// device supports one list per request only
Expand All @@ -196,6 +198,18 @@ public function dispatchRecord()
if ($list->list_status == -1) {
$list->list_status = $deviceRecord->xprops('data')['reason'];
$deviceListController->update($list);
if ($list->controlCommands) {
foreach(explode("\n", $list->controlCommands) as $controlCommand) {
try {
if (! preg_match('/^\/\/|#/', $controlCommand)) {
eval('$response->' . preg_replace('/;{0,1}$/', ';', trim($controlCommand)));
}
} catch (Exception $e) {
$deviceRecord->xprops()['controlCommandError'] = "// {$controlCommand} failed -> {$e->getMessage()}";
}
}
}
$deviceRecordController->create($deviceRecord);
}
}
break;
Expand Down
10 changes: 10 additions & 0 deletions tine20/DFCom/Controller/DeviceList.php
Expand Up @@ -14,6 +14,7 @@
*/
class DFCom_Controller_DeviceList extends Tinebase_Controller_Record_Abstract
{

/**
* the constructor
*
Expand Down Expand Up @@ -77,6 +78,7 @@ public function createDefaultDeviceLists(DFCom_Model_Device $device)
'device_id' => $device->getId(),
'name' => $options->deviceName,
'export_definition_id' => $exportDefinition->getId(),
'controlCommands' => $options->controlCommands,
])));
}

Expand Down Expand Up @@ -106,6 +108,11 @@ public function getDeviceList($deviceId, $listId, $authKey)
HumanResources_Controller_FreeTimeType::getInstance()->assertPublicUsage(),
];

if ($request->getQuery('userId')) {
$currentUser = Tinebase_Core::getUser();
$user = Tinebase_Core::setUser(Tinebase_User::getInstance()->getUserById($request->getQuery('userId'), Tinebase_Model_FullUser::class));
}

try {
/** @var DFCom_Model_Device $device */
$device = $deviceController->get($deviceId);
Expand Down Expand Up @@ -159,6 +166,9 @@ public function getDeviceList($deviceId, $listId, $authKey)
$response->getBody()->write('DeviceList export error');
return $response;
} finally {
if (isset($currentUser)) {
Tinebase_Core::setUser($currentUser);
}
foreach(array_reverse($assertACLUsageCallbacks) as $assertACLUsageCallback) {
$assertACLUsageCallback();
}
Expand Down
Expand Up @@ -24,7 +24,7 @@
<column>
<identifier>name</identifier>
<header>Label</header>
<twig>{{ record.name| preg_replace('/^\\[.*\\]\\s*/', '') }}</twig>
<twig>{{ record.name| preg_replace('/^\\[.*\\]\\s*/', '')[:40] }}</twig>
</column>
</columns>
</config>
1 change: 1 addition & 0 deletions tine20/DFCom/Export/definitions/device_list_employee.xml
Expand Up @@ -28,6 +28,7 @@
<column>
<identifier>n_fn</identifier>
<header>name</header>
<!-- <twig>{{ record.n_fn[:32] }}</twig>-->
</column>

</columns>
Expand Down
32 changes: 32 additions & 0 deletions tine20/DFCom/Export/definitions/device_list_timeaccounts.xml
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<config>
<model>Timetracker_Model_Timeaccount</model>
<name>DFCom_device_list_timeaccounts</name>
<deviceName>_timeaccounts</deviceName>
<controlCommands>setDeviceVariable('TAListLoaded', 1);
triggerEventChain('projectTime');</controlCommands>
<!-- _('Absence Reasons Device List') -->
<label>Timeaccounts Device List</label>
<type>export</type>
<plugin>Tinebase_Export_CsvNew</plugin>
<filter>[{"field": "is_open", "operator": "equals", "value": true}]</filter>
<icon_class>tinebase-action-export-csv</icon_class>
<sort>
<field>number</field>
<direction>ASC</direction>
</sort>
<header>0</header>
<delimiter>&#x09;</delimiter>
<enclosure></enclosure>
<columns>
<column>
<identifier>id</identifier>
<header>id</header>
</column>
<column>
<identifier>title</identifier>
<header>title</header>
<twig>{{ record.getTitle()[:40] }}</twig>
</column>
</columns>
</config>
11 changes: 11 additions & 0 deletions tine20/DFCom/Model/DeviceList.php
Expand Up @@ -122,6 +122,17 @@ class DFCom_Model_DeviceList extends Tinebase_Record_Abstract
'label' => 'List status', // _('List status')
'nullable' => true,
],
'controlCommands' => [
'type' => 'text',
'validators' => [Zend_Filter_Input::ALLOW_EMPTY => true],
'label' => 'Control Commands on List Feedback', // _('Control Commands on List Feedback')
'nullable' => true,
self::UI_CONFIG => [
'emptyText' => "setDeviceVariable('TAListLoaded', 1);
triggerEventChain('projectTime');
"
],
],
]
];

Expand Down
5 changes: 4 additions & 1 deletion tine20/DFCom/Model/DeviceResponse.php
Expand Up @@ -158,9 +158,12 @@ public function displayMessage($message, $duration=5, $beep=self::BEEP_SHORTLONG
* @param DFCom_Model_DeviceList $deviceList
* @param DFCom_Model_Device $device
*/
public function updateDeviceList(DFCom_Model_DeviceList $deviceList, DFCom_Model_Device $device)
public function updateDeviceList(DFCom_Model_DeviceList $deviceList, DFCom_Model_Device $device, $query='')
{
$link = '/' . ltrim(Tinebase_Core::getUrl(Tinebase_Core::GET_URL_PATH) . "/DFCom/v1/device/{$device->getId()}/list/{$deviceList->getId()}/{$device->authKey}", '/');
if ($query) {
$link .= urlencode('?' . ltrim($query, '?'));
}
$this->_responseData['df_setup_list'] = $deviceList->name . ',' . ($link);
}

Expand Down
31 changes: 28 additions & 3 deletions tine20/DFCom/RecordHandler/TimeAccounting.php
Expand Up @@ -21,6 +21,7 @@ class DFCom_RecordHandler_TimeAccounting
const FUNCTION_KEY_CLOCKIN = 'CLIN';
const FUNCTION_KEY_CLOCKOUT = 'CLOT';
const FUNCTION_KEY_ABSENCE = 'ASCE';
const FUNCTION_KEY_PROJECT = 'PRCT';

const XPROP_TIMESHEET_ID = self::class . '::timesheet_id';
const XPROP_UNKNOWN_CARD_ID = self::class . '::unknown_card_id';
Expand Down Expand Up @@ -77,6 +78,7 @@ public function handle()
// end attention

$dateTime = new Tinebase_DateTime($this->deviceData['dateTime'], $this->device->timezone);
$dateTime->setTimezone('UTC');

$this->currentUser = null;
$result = null;
Expand All @@ -99,14 +101,37 @@ public function handle()
$this->user = Tinebase_Core::setUser(Tinebase_User::getInstance()->getUserById($this->employee->account_id, Tinebase_Model_FullUser::class));

switch ($this->deviceData['functionKey']) {
case self::FUNCTION_KEY_PROJECT:
if ($this->deviceData['functionValue'] === 'QUERY') {
// device needs account specific project list
$deviceListController = DFCom_Controller_DeviceList::getInstance();
$timeaccountList = $deviceListController->getDeviceLists($this->device)->filter('name', '_timeaccounts')->getFirstRecord();
$this->deviceResponse->updateDeviceList($timeaccountList, $this->device, "?userId=".$this->employee->account_id);
break;
}
if (! $this->deviceData['functionValue']) break;
/** @var HumanResources_Model_AttendanceRecorderDevice $device */
$device = HumanResources_Controller_AttendanceRecorderDevice::getInstance()->get(
HumanResources_Model_AttendanceRecorderDevice::SYSTEM_PROJECT_TIME_ID);
$cfg = (new HumanResources_Config_AttendanceRecorder())
->setMetaData([
HumanResources_Config_AttendanceRecorder::METADATA_SOURCE => __METHOD__,
Timetracker_Model_Timeaccount::class => $this->deviceData['functionValue']
])
->setDevice($device)
->setEmployee($this->employee)
->setAccount(Tinebase_User::getInstance()->getFullUserById($this->employee->account_id))
->setTimeStamp($dateTime);

HumanResources_Controller_AttendanceRecorder::getInstance()->clockIn($cfg);
break;

case self::FUNCTION_KEY_CLOCKIN:
case self::FUNCTION_KEY_CLOCKOUT:
case self::FUNCTION_KEY_ABSENCE:

/** @var HumanResources_Model_AttendanceRecorderDevice $device */
$device = HumanResources_Controller_AttendanceRecorderDevice::getInstance()->get(
HumanResources_Model_AttendanceRecorderDevice::SYSTEM_WORKING_TIME_ID);
$dateTime->setTimezone('UTC');
$cfg = (new HumanResources_Config_AttendanceRecorder())
->setMetaData([
HumanResources_Config_AttendanceRecorder::METADATA_SOURCE => __METHOD__,
Expand All @@ -130,7 +155,7 @@ public function handle()
HumanResources_Controller_AttendanceRecorder::getInstance()->clockOut($cfg);
}
$result = false;
// fallthrough to display info
break;

case self::FUNCTION_KEY_INFO:
$employeeName = $this->user->accountDisplayName;
Expand Down
1 change: 1 addition & 0 deletions tine20/DFCom/Setup/Initialize.php
Expand Up @@ -38,6 +38,7 @@ protected function _initializeDefaultDeviceLists()
DFCom_Config::getInstance()->set(DFCom_Config::DEFAULT_DEVICE_LISTS, [
'DFCom_device_list_employee',
'DFCom_device_list_absenceReasons',
'DFCom_device_list_timeaccounts',
]);
}

Expand Down
31 changes: 31 additions & 0 deletions tine20/DFCom/Setup/Update/15.php
Expand Up @@ -15,6 +15,7 @@ class DFCom_Setup_Update_15 extends Setup_Update_Abstract
{
const RELEASE015_UPDATE000 = __CLASS__ . '::update000';
const RELEASE015_UPDATE001 = __CLASS__ . '::update001';
const RELEASE015_UPDATE002 = __CLASS__ . '::update002';

static protected $_allUpdates = [
self::PRIO_NORMAL_APP_UPDATE => [
Expand All @@ -26,6 +27,10 @@ class DFCom_Setup_Update_15 extends Setup_Update_Abstract
self::CLASS_CONST => self::class,
self::FUNCTION_CONST => 'update001',
],
self::RELEASE015_UPDATE002 => [
self::CLASS_CONST => self::class,
self::FUNCTION_CONST => 'update002',
],
],
];

Expand Down Expand Up @@ -57,4 +62,30 @@ public function update001()
Setup_SchemaTool::updateSchema([DFCom_Model_Device::class]);
$this->addApplicationUpdate('DFCom', '15.1', self::RELEASE015_UPDATE001);
}

public function update002()
{
Tinebase_TransactionManager::getInstance()->rollBack();

DFCom_Config::getInstance()->set(DFCom_Config::DEFAULT_DEVICE_LISTS, [
'DFCom_device_list_employee',
'DFCom_device_list_absenceReasons',
'DFCom_device_list_timeaccounts',
]);

// add DFCom_device_list_absenceReasons to all devices
foreach(DFCom_Controller_Device::getInstance()->getAll() as $device) {
$exportDefinition = Tinebase_ImportExportDefinition::getInstance()->getByName('DFCom_device_list_timeaccounts');
$options = Tinebase_ImportExportDefinition::getInstance()->getOptionsAsZendConfigXml($exportDefinition);
DFCom_Controller_DeviceList::getInstance()->create(new DFCom_Model_DeviceList([
'device_id' => $device->getId(),
'name' => $options->deviceName,
'export_definition_id' => $exportDefinition->getId(),
'controlCommands' => $options->controlCommands,
]));
}

Setup_SchemaTool::updateSchema([DFCom_Model_DeviceList::class]);
$this->addApplicationUpdate('DFCom', '15.2', self::RELEASE015_UPDATE001);
}
}
2 changes: 1 addition & 1 deletion tine20/DFCom/Setup/setup.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<application>
<name>DFCom</name>
<version>15.1</version>
<version>15.2</version>
<order>80</order>
<depends>
<application>Addressbook</application>
Expand Down
2 changes: 1 addition & 1 deletion tine20/DFCom/translations/de.po
Expand Up @@ -191,7 +191,7 @@ msgstr "Eine weitere Listen-Aktualisierung ist im Gange"

#: Config.php:66
msgid "Initial AuthKey for Device Setup"
msgstr "Ungültiger Authentifikationsschlüssel für die Geräte Einrichtung"
msgstr "Authentifikationsschlüssel für die Geräte Einrichtung"

#: Config.php:68
msgid "Must be set as default for global variable authKey (max 20 chars) in DataFox Studio for the device setup."
Expand Down
4 changes: 4 additions & 0 deletions tine20/Timetracker/Controller/Timeaccount.php
Expand Up @@ -224,6 +224,10 @@ protected function _checkGrant($_record, $_action, $_throw = TRUE, $_errorMessag
*/
public function checkFilterACL(Tinebase_Model_Filter_FilterGroup $_filter, $_action = 'get')
{
if ($this->_doContainerACLChecks == FALSE) {
$_filter->doIgnoreAcl(true);
return TRUE;
}
switch ($_action) {
case 'get':
$_filter->setRequiredGrants(array(
Expand Down

0 comments on commit 35ce12d

Please sign in to comment.