sync on demand action

parent 2daa66d0
...@@ -34,6 +34,7 @@ return [ ...@@ -34,6 +34,7 @@ return [
['/tpe_survey', ['school'], ['get', 'post']], ['/tpe_survey', ['school'], ['get', 'post']],
['/tpe_survey/total-teachers', ['school'], ['post']], ['/tpe_survey/total-teachers', ['school'], ['post']],
['/forum', ['guest', 'user'], ['get']], ['/forum', ['guest', 'user'], ['get']],
['/sch_sync/sync', ['school'], ['get']],
], ],
], ],
], ],
......
...@@ -14,6 +14,7 @@ return [ ...@@ -14,6 +14,7 @@ return [
__DIR__ . '/../../module/schools/public', __DIR__ . '/../../module/schools/public',
__DIR__ . '/../../module/application_form/public', __DIR__ . '/../../module/application_form/public',
__DIR__ . '/../../module/tpe_survey/public', __DIR__ . '/../../module/tpe_survey/public',
__DIR__ . '/../../module/sch_sync/public',
], ],
], ],
]; ];
...@@ -185,7 +185,6 @@ CREATE TABLE `lab` ( ...@@ -185,7 +185,6 @@ CREATE TABLE `lab` (
`school_id` int(11) unsigned NOT NULL, `school_id` int(11) unsigned NOT NULL,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`labtype_id` int(11) unsigned NOT NULL, `labtype_id` int(11) unsigned NOT NULL,
`is_new` tinyint(1) unsigned DEFAULT 0,
`responsible_id` int(11) unsigned DEFAULT NULL, `responsible_id` int(11) unsigned DEFAULT NULL,
`area` int(11) unsigned DEFAULT NULL, `area` int(11) unsigned DEFAULT NULL,
`attachment` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `attachment` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
...@@ -194,14 +193,17 @@ CREATE TABLE `lab` ( ...@@ -194,14 +193,17 @@ CREATE TABLE `lab` (
`has_server` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `has_server` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`use_ext_program` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `use_ext_program` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`use_in_program` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `use_in_program` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`is_new` tinyint(1) unsigned DEFAULT NULL,
`inventory_key` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `index_foreignkey_lab_school` (`school_id`), KEY `index_foreignkey_lab_school` (`school_id`),
KEY `index_foreignkey_lab_labtype` (`labtype_id`), KEY `index_foreignkey_lab_labtype` (`labtype_id`),
KEY `index_foreignkey_lab_responsible` (`responsible_id`), KEY `index_foreignkey_lab_responsible` (`responsible_id`),
CONSTRAINT `c_fk_lab_school_id` FOREIGN KEY (`school_id`) REFERENCES `school` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, KEY `index_lab_inventory_key` (`inventory_key`),
CONSTRAINT `c_fk_lab_labtype_id` FOREIGN KEY (`labtype_id`) REFERENCES `labtype` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE, CONSTRAINT `c_fk_lab_labtype_id` FOREIGN KEY (`labtype_id`) REFERENCES `labtype` (`id`) ON UPDATE CASCADE,
CONSTRAINT `c_fk_lab_responsible_id` FOREIGN KEY (`responsible_id`) REFERENCES `teacher` (`id`) ON DELETE SET NULL ON UPDATE CASCADE CONSTRAINT `c_fk_lab_responsible_id` FOREIGN KEY (`responsible_id`) REFERENCES `teacher` (`id`) ON DELETE SET NULL ON UPDATE CASCADE,
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CONSTRAINT `c_fk_lab_school_id` FOREIGN KEY (`school_id`) REFERENCES `school` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET character_set_client = @saved_cs_client */;
-- --
......
...@@ -50,24 +50,45 @@ return function (App $app) { ...@@ -50,24 +50,45 @@ return function (App $app) {
$c->get('logger') $c->get('logger')
); );
}; };
$container[CreateLabs::class] = function ($c) {
$container[\SchSync\SyncFromInventory::class] = function ($c) {
$settings = $c->get('settings'); $settings = $c->get('settings');
$categoryMap = isset($settings['inventory']['category_map']) $categoryMap = isset($settings['inventory']['category_map'])
? $settings['inventory']['category_map'] : []; ? $settings['inventory']['category_map'] : [];
return new CreateLabs( return new \SchSync\SyncFromInventory(
$c->get(LabServiceInterface::class), $c->get(LabServiceInterface::class),
$c->get(AssetServiceInterface::class), $c->get(AssetServiceInterface::class),
$c->get('SchInventory\\Service'), $c->get('SchInventory\\Service'),
$c->get(SchoolServiceInterface::class), $c->get(SchoolServiceInterface::class),
$c->get('authentication_service'),
$c->get('logger'), $c->get('logger'),
$categoryMap $categoryMap
);
};
$container[CreateLabs::class] = function ($c) {
return new CreateLabs(
$c->get(LabServiceInterface::class),
$c->get(\SchSync\SyncFromInventory::class),
$c->get('authentication_service')
);
};
$container[SchSync\Action\Sync::class] = function ($c) {
return new SchSync\Action\Sync(
$c->get(\SchSync\SyncFromInventory::class),
$c->get('authentication_service')
); );
}; };
}); });
$events('on', 'app.bootstrap', function ($app, $container) { $events('on', 'app.bootstrap', function ($app, $container) {
$app->get('/sch_sync/sync', SchSync\Action\Sync::class)->setName('sch_sync/sync');
});
$events('on', 'app.bootstrap', function ($app, $container) {
$container['view']->getEnvironment()->getLoader()->prependPath(__DIR__ . '/templates');
$container['router']->getNamedRoute('user.login.sso') $container['router']->getNamedRoute('user.login.sso')
->add(CreateUser::class) ->add(CreateUser::class)
->add(CreateSchool::class) ->add(CreateSchool::class)
......
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
(function ($, document) {
$('#inventory_sync').on('click', function (evt) {
var that = $(this),
url = that.data('href');
that.prop('disabled', true);
that.find('i').addClass('fa-spinner fa-spin');
$.ajax({
url: url,
type: 'get'
}).done(function (response) {
document.location.reload(true);
}).fail(function (xhr, err) {
alert('Προέκυψε κάποιο σφάλμα κατά την εισαγωγή. Παρακαλώ δοκιμάστε ξανά.');
that.prop('disabled', false);
that.find('i').removeClass('fa-spinner fa-spin');
});
});
} (window.jQuery, document));
\ No newline at end of file
<?php
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace SchSync\Action;
use RedBeanPHP\R;
use Slim\Http\Request;
use Slim\Http\Response;
use Zend\Authentication\AuthenticationServiceInterface;
class Sync
{
/**
*
* @var AuthenticationServiceInterface
*/
protected $authService;
/**
*
* @var callable
*/
protected $syncFromInventory;
public function __construct(
callable $syncFromInventory,
AuthenticationServiceInterface $authService
) {
$this->syncFromInventory = $syncFromInventory;
$this->authService = $authService;
}
public function __invoke(Request $req, Response $res)
{
$identity = $this->authService->getIdentity();
if (null === $identity) {
return $res;
}
$user = R::load('user', $identity->id);
if (!$user->school_id) {
return $res;
}
$school_id = $user->school_id;
$sync = $this->syncFromInventory;
$result = $sync($school_id);
if (false === $result) {
return $res->withStatus(500);
}
return $res->withJson($result);
}
}
...@@ -10,13 +10,8 @@ ...@@ -10,13 +10,8 @@
namespace SchSync\Middleware; namespace SchSync\Middleware;
use Exception;
use GrEduLabs\Schools\Service\AssetServiceInterface;
use GrEduLabs\Schools\Service\LabServiceInterface; use GrEduLabs\Schools\Service\LabServiceInterface;
use GrEduLabs\Schools\Service\SchoolServiceInterface;
use Psr\Log\LoggerInterface;
use RedBeanPHP\R; use RedBeanPHP\R;
use SchInventory\ServiceInterface as InventoryService;
use Slim\Http\Request; use Slim\Http\Request;
use Slim\Http\Response; use Slim\Http\Response;
use Zend\Authentication\AuthenticationServiceInterface; use Zend\Authentication\AuthenticationServiceInterface;
...@@ -31,55 +26,24 @@ class CreateLabs ...@@ -31,55 +26,24 @@ class CreateLabs
/** /**
* *
* @var AssetServiceInterface * @var callable
*/ */
protected $assetService; protected $syncFromInventory;
/**
*
* @var InventoryService
*/
protected $inventoryService;
/**
*
* @var SchoolServiceInterface
*/
protected $schoolService;
/** /**
* *
* @var AuthenticationServiceInterface * @var AuthenticationServiceInterface
*/ */
protected $authService; protected $authService;
/**
* @var LoggerInterface
*/
private $logger;
/**
*
* @var array
*/
private $categoryMap;
public function __construct( public function __construct(
LabServiceInterface $labService, LabServiceInterface $labService,
AssetServiceInterface $assetService, callable $syncFromInventory,
InventoryService $inventoryService, AuthenticationServiceInterface $authService
SchoolServiceInterface $schoolService,
AuthenticationServiceInterface $authService,
LoggerInterface $logger,
array $categoryMap = []
) { ) {
$this->labService = $labService; $this->labService = $labService;
$this->assetService = $assetService; $this->syncFromInventory = $syncFromInventory;
$this->inventoryService = $inventoryService; $this->authService = $authService;
$this->schoolService = $schoolService;
$this->authService = $authService;
$this->logger = $logger;
$this->categoryMap = $categoryMap;
} }
public function __invoke(Request $req, Response $res, callable $next) public function __invoke(Request $req, Response $res, callable $next)
...@@ -96,75 +60,12 @@ class CreateLabs ...@@ -96,75 +60,12 @@ class CreateLabs
} }
$school_id = $user->school_id; $school_id = $user->school_id;
$school = $this->schoolService->getSchool($school_id);
if (0 < count($this->labService->getLabsBySchoolId($school_id))) { if (0 < count($this->labService->getLabsBySchoolId($school_id))) {
return $res; return $res;
} }
try { $sync = $this->syncFromInventory;
$equipment = $this->inventoryService->getUnitEquipment($school['registry_no']); $sync($school_id);
} catch (Exception $e) {
$this->logger->error(sprintf('Problem retrieving assets from inventory for school %s', $school_id));
$this->logger->debug('Exception', [$e->getMessage(), $e->getTraceAsString()]);
return $res;
}
$labTypes = array_reduce($this->labService->getLabTypes(), function ($map, $type) {
$map[trim($type['name'])] = $type['id'];
return $map;
}, []);
$assetTypes = array_reduce($this->assetService->getAllItemCategories(), function ($map, $type) {
$map[trim($type['name'])] = $type['id'];
return $map;
}, []);
try {
$locations = array_reduce($equipment, function ($uniq, $item) use ($school_id, $labTypes, $assetTypes) {
if (!isset($uniq[$item['location.id']])) {
$locationName = $item['location.name'];
$detected = reset(array_filter(array_keys($labTypes), function ($type) use ($locationName) {
return false !== stripos($locationName, $type) ||
false !== stripos($type, $locationName);
}));
$labType = $detected ? $labTypes[$detected] : end($labTypes);
$data = [
'school_id' => (int) $school_id,
'name' => $locationName,
'labtype_id' => (int) $labType,
];
$lab = R::dispense('lab');
$lab->import($data);
$uniq[$item['location.id']] = $lab;
}
$categoryName = $item['item_template.category.name'];
$type = reset(array_filter(array_keys($this->categoryMap), function ($type) use ($categoryName) {
return $type == $categoryName;
}));
$type = ($type) ? $assetTypes[$this->categoryMap[$type]] : false;
if ($type !== false) {
if (!isset($uniq[$item['location.id']]->ownSchoolAsset[$type])) {
$asset = R::dispense('schoolasset');
$asset->school_id = (int) $school_id;
$asset->itemcategory_id = (int) $type;
$uniq[$item['location.id']]->ownSchoolAsset[$type] = $asset;
}
$uniq[$item['location.id']]->ownSchoolAsset[$type]->qty += 1;
}
return $uniq;
}, []);
R::storeAll($locations);
$this->logger->info(sprintf('Add assets from inventory for school %s', $school_id));
} catch (Exception $e) {
$this->logger->error(sprintf('Problem inserting assets for school %s in database', $school_id));
$this->logger->debug('Exception', [$e->getMessage(), $e->getTraceAsString()]);
}
return $res; return $res;
} }
......
<?php
/**
* gredu_labs.
*
* @link https://github.com/eellak/gredu_labs for the canonical source repository
*
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/)
* @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/
namespace SchSync;
use Exception;
use GrEduLabs\Schools\Service\AssetServiceInterface;
use GrEduLabs\Schools\Service\LabServiceInterface;
use GrEduLabs\Schools\Service\SchoolServiceInterface;
use Psr\Log\LoggerInterface;
use RedBeanPHP\R;
use SchInventory\ServiceInterface as InventoryService;
class SyncFromInventory
{
/**
*
* @var LabServiceInterface
*/
protected $labService;
/**
*
* @var AssetServiceInterface
*/
protected $assetService;
/**
*
* @var InventoryService
*/
protected $inventoryService;
/**
*
* @var SchoolServiceInterface
*/
protected $schoolService;
/**
* @var LoggerInterface
*/
private $logger;
/**
*
* @var array
*/
private $categoryMap;
public function __construct(
LabServiceInterface $labService,
AssetServiceInterface $assetService,
InventoryService $inventoryService,
SchoolServiceInterface $schoolService,
LoggerInterface $logger,
array $categoryMap = []
) {
$this->labService = $labService;
$this->assetService = $assetService;
$this->inventoryService = $inventoryService;
$this->schoolService = $schoolService;
$this->logger = $logger;
$this->categoryMap = $categoryMap;
}
public function __invoke($school_id)
{
$school = $this->schoolService->getSchool($school_id);
try {
$equipment = $this->inventoryService->getUnitEquipment($school['registry_no']);
} catch (Exception $e) {
$this->logger->error(sprintf('Problem retrieving assets from inventory for school %s', $school_id));
$this->logger->debug('Exception', [$e->getMessage(), $e->getTraceAsString()]);
return false;
}
$labTypes = $this->getLabTypes();
$assetTypes = $this->getAssetTypes();
try {
$locations = $this->getLocations($school_id, $equipment, $labTypes, $assetTypes);
R::storeAll($locations);
$this->logger->info(sprintf('Add assets from inventory for school %s', $school_id));
return $this->labService->getLabsBySchoolId($school_id);
} catch (Exception $e) {
$this->logger->error(sprintf('Problem inserting assets for school %s in database', $school_id));
$this->logger->debug('Exception', [$e->getMessage(), $e->getTraceAsString()]);
return false;
}
}
private function getLabTypes()
{
return array_reduce($this->labService->getLabTypes(), function ($map, $type) {
$map[trim($type['name'])] = $type['id'];
return $map;
}, []);
}
private function getAssetTypes()
{
return array_reduce($this->assetService->getAllItemCategories(), function ($map, $type) {
$map[trim($type['name'])] = $type['id'];
return $map;
}, []);
}
private function getLocations($school_id, array $equipment, array $labTypes, array $assetTypes)
{
return array_reduce($equipment, function ($uniq, $item) use ($school_id, $labTypes, $assetTypes) {
if (!isset($uniq[$item['location.id']])) {
$locationName = $item['location.name'];
$locationId = $item['location.id'];
$lab = R::findOne('lab', ' school_id = ? AND (inventory_key = ? OR name = ?)', [
$school_id,
$locationId,
$locationName,
]);
if (null !== $lab) {
return $uniq;
}
$detected = reset(array_filter(array_keys($labTypes), function ($type) use ($locationName) {
return false !== stripos($locationName, $type) ||
false !== stripos($type, $locationName);
}));
$labType = $detected ? $labTypes[$detected] : end($labTypes);
$data = [
'school_id' => (int) $school_id,
'name' => $locationName,
'labtype_id' => (int) $labType,
'inventory_key' => (int) $locationId,
];
$lab = R::dispense('lab');
$lab->import($data);
$uniq[$item['location.id']] = $lab;
}
$categoryName = $item['item_template.category.name'];
$type = reset(array_filter(array_keys($this->categoryMap), function ($type) use ($categoryName) {
return $type == $categoryName;
}));
$type = ($type) ? $assetTypes[$this->categoryMap[$type]] : false;
if ($type !== false) {
if (!isset($uniq[$item['location.id']]->ownSchoolAsset[$type])) {
$asset = R::dispense('schoolasset');
$asset->school_id = (int) $school_id;
$asset->itemcategory_id = (int) $type;
$uniq[$item['location.id']]->ownSchoolAsset[$type] = $asset;
}
$uniq[$item['location.id']]->ownSchoolAsset[$type]->qty += 1;
}
return $uniq;
}, []);
}
}
{% extends "schools/index.twig" %}
{% import "schools/form.twig" as macros %}
{% block schoolTitle %}
{{ parent() }} <small>Χώροι</small>
{% endblock %}
{% block navItems %}
<li role="presentation" class="pull-right">
<a href="#" class="btn btn-primary btn-add-lab" title="Καταχώρηση χώρου">
<i class="fa fa-plus"></i>
<span class="hidden-xs">Καταχώρηση χώρου</span>
</a>
</li>
{% endblock %}
{% block schoolContent %}
<div id="school-labs">
<p>
Σε αυτήν τη καρτέλα εμφανίζονται χώροι που χρησιμοποιούνται ήδη για
ΤΠΕ και έχουν δηλωθεί σε άλλα πληροφοριακά συστήματα του ΥΠΠΕΘ.
Επίσης, μπορείτε να καταχωρήσετε νέους χώρους από το πλήκτρο
«καταχώρηση χώρου», που θα θέλατε να χρησιμοποιήσετε για χρήση
ΤΠΕ (πχ μια διαθέσιμη αίθουσα διδασκαλίας για τη δημιουργία ενός
νέου εργαστηρίου πληροφορικής ή το εργαστήριο Τεχνολογίας το οποίο
θα θέλατε να εξοπλίσετε με ένα Η/Υ και ένα βιντεοπροβολέα ή
οποιαδήποτε άλλη αίθουσα για την οποία θα ζητήσετε εξοπλισμό).
Σε κάθε περίπτωση θα πρέπει να τεκμηριωθεί η χρήση της αίθουσας
για κάθε ένα από τα μαθήματα που θα χρησιμοποιείται συμπληρώνοντας
τα αντίστοιχα πεδία.
</p>
<p>
Σε κάθε περίπτωση θα πρέπει να δικαιολογηθεί η χρήση της αίθουσας
συμπληρώνοντας όλα τα πεδία.
</p>
<p>
<button data-href="{{ path_for('sch_sync/sync') }}" class="btn btn-primary" id="inventory_sync"><i class="fa fa-copy"></i> Ενημέρωση από το Κτηματολόγιο</button>
</p>
<div class="table-responsive">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>Ονομασία</th>
<th>Τύπος</th>
<th>Δημιουργία νέου χώρου</th>
<th>Υπεύθυνος</th>
<th>Δίκτυο</th>
<th>Server</th>
<th>Επιφάνεια (m<sup>2</sup>)</th>