Commit 0f82b43c authored by Vassilis Kanellopoulos's avatar Vassilis Kanellopoulos
Browse files

school assets implemented

parent 69729892
...@@ -15,7 +15,7 @@ return [ ...@@ -15,7 +15,7 @@ return [
['/school/labs', ['school'], ['get']], ['/school/labs', ['school'], ['get']],
['/school/staff', ['school'], ['get', 'post']], ['/school/staff', ['school'], ['get', 'post']],
['/school/staff/{id:[1-9][0-9]*}', ['school'], ['delete']], ['/school/staff/{id:[1-9][0-9]*}', ['school'], ['delete']],
['/school/assets', ['school'], ['get']], ['/school/assets', ['school'], ['get', 'post', 'delete']],
], ],
], ],
], ],
......
...@@ -28,7 +28,7 @@ return function (Slim\App $app) { ...@@ -28,7 +28,7 @@ return function (Slim\App $app) {
$container['settings']['db']['user'], $container['settings']['db']['user'],
$container['settings']['db']['pass'] $container['settings']['db']['pass']
); );
RedBeanPHP\R::freeze(); RedBeanPHP\R::freeze();
$container['view'] = function ($c) { $container['view'] = function ($c) {
$settings = $c['settings']; $settings = $c['settings'];
......
...@@ -18,6 +18,9 @@ return function (Slim\App $app) { ...@@ -18,6 +18,9 @@ return function (Slim\App $app) {
}); });
$events('on', 'app.services', function ($stop, $container) { $events('on', 'app.services', function ($stop, $container) {
// actions
$container[GrEduLabs\Schools\Action\Index::class] = function ($c) { $container[GrEduLabs\Schools\Action\Index::class] = function ($c) {
return new GrEduLabs\Schools\Action\Index( return new GrEduLabs\Schools\Action\Index(
$c->get('view'), $c->get('view'),
...@@ -28,19 +31,19 @@ return function (Slim\App $app) { ...@@ -28,19 +31,19 @@ return function (Slim\App $app) {
$container[GrEduLabs\Schools\Action\Staff\ListAll::class] = function ($c) { $container[GrEduLabs\Schools\Action\Staff\ListAll::class] = function ($c) {
return new GrEduLabs\Schools\Action\Staff\ListAll( return new GrEduLabs\Schools\Action\Staff\ListAll(
$c->get('view'), $c->get('view'),
$c->get(GrEduLabs\Schools\Service\StaffService::class) $c->get(GrEduLabs\Schools\Service\StaffServiceInterface::class)
); );
}; };
$container[GrEduLabs\Schools\Action\Staff\PersistTeacher::class] = function ($c) { $container[GrEduLabs\Schools\Action\Staff\PersistTeacher::class] = function ($c) {
return new GrEduLabs\Schools\Action\Staff\PersistTeacher( return new GrEduLabs\Schools\Action\Staff\PersistTeacher(
$c->get(GrEduLabs\Schools\Service\StaffService::class) $c->get(GrEduLabs\Schools\Service\StaffServiceInterface::class)
); );
}; };
$container[GrEduLabs\Schools\Action\Staff\DeleteTeacher::class] = function ($c) { $container[GrEduLabs\Schools\Action\Staff\DeleteTeacher::class] = function ($c) {
return new GrEduLabs\Schools\Action\Staff\DeleteTeacher( return new GrEduLabs\Schools\Action\Staff\DeleteTeacher(
$c->get(GrEduLabs\Schools\Service\StaffService::class) $c->get(GrEduLabs\Schools\Service\StaffServiceInterface::class)
); );
}; };
...@@ -56,39 +59,75 @@ return function (Slim\App $app) { ...@@ -56,39 +59,75 @@ return function (Slim\App $app) {
); );
}; };
$container[GrEduLabs\Schools\Action\Assets::class] = function ($c) { $container[GrEduLabs\Schools\Action\Assets\ListAssets::class] = function ($c) {
return new GrEduLabs\Schools\Action\Assets($c->get('view')); return new GrEduLabs\Schools\Action\Assets\ListAssets(
$c->get('view'),
$c->get(GrEduLabs\Schools\Service\AssetServiceInterface::class),
$c->get(GrEduLabs\Schools\Service\SchoolAssetsInterface::class),
$c->get(GrEduLabs\Schools\Service\LabServiceInterface::class)
);
};
$container[GrEduLabs\Schools\Action\Assets\PersistAsset::class] = function ($c) {
return new GrEduLabs\Schools\Action\Assets\PersistAsset(
$c->get(GrEduLabs\Schools\Service\SchoolAssetsInterface::class)
);
};
$container[GrEduLabs\Schools\Action\Assets\DeleteAsset::class] = function ($c) {
return new GrEduLabs\Schools\Action\Assets\DeleteAsset(
$c->get(GrEduLabs\Schools\Service\SchoolAssetsInterface::class)
);
}; };
// services
$container['schoolservice'] = function ($c) { $container['schoolservice'] = function ($c) {
return new GrEduLabs\Schools\Service\SchoolService(); return $c->get(GrEduLabs\Schools\Service\SchoolServiceInterface::class);
}; };
$container[GrEduLabs\Schools\InputFilter\Teacher::class] = function ($c) { $container['staffservice'] = function ($c) {
return new GrEduLabs\Schools\InputFilter\Teacher(); return $c->get(GrEduLabs\Schools\Service\StaffServiceInterface::class);
};
$container['labservice'] = function ($c) {
return $c->get(GrEduLabs\Schools\Service\LabServiceInterface::class);
}; };
$container[GrEduLabs\Schools\Service\StaffService::class] = function ($c) { $container[GrEduLabs\Schools\Service\SchoolServiceInterface::class] = function ($c) {
return new GrEduLabs\Schools\Service\SchoolService();
};
$container[GrEduLabs\Schools\Service\StaffServiceInterface::class] = function ($c) {
return new GrEduLabs\Schools\Service\StaffService(); return new GrEduLabs\Schools\Service\StaffService();
}; };
$container[GrEduLabs\Schools\Middleware\InputFilterTeacher::class] = function ($c) { $container[GrEduLabs\Schools\Service\LabServiceInterface::class] = function ($c) {
return new GrEduLabs\Schools\Middleware\InputFilterTeacher( return new GrEduLabs\Schools\Service\LabService(
$c->get(GrEduLabs\Schools\InputFilter\Teacher::class) $c->get(GrEduLabs\Schools\Service\SchoolServiceInterface::class),
$c->get(GrEduLabs\Schools\Service\StaffServiceInterface::class)
); );
}; };
$container['labservice'] = function ($c) { $container[GrEduLabs\Schools\Service\AssetServiceInterface::class] = function ($c) {
return new GrEduLabs\Schools\Service\LabService( return new GrEduLabs\Schools\Service\AssetService();
$c->get('schoolservice'), };
$c->get('staffservice')
$container[GrEduLabs\Schools\Service\SchoolAssetsInterface::class] = function ($c) {
return $c->get(GrEduLabs\Schools\Service\AssetServiceInterface::class);
};
// middleware
$container[GrEduLabs\Schools\Middleware\InputFilterTeacher::class] = function ($c) {
return new GrEduLabs\Schools\Middleware\InputFilterTeacher(
$c->get(GrEduLabs\Schools\InputFilter\Teacher::class)
); );
}; };
$container['assetservice'] = function ($c) { $container[GrEduLabs\Schools\Middleware\InputFilterSchoolAsset::class] = function ($c) {
return new GrEduLabs\Schools\Service\AssetService( return new GrEduLabs\Schools\Middleware\InputFilterSchoolAsset(
$c->get('schoolservice'), $c->get(GrEduLabs\Schools\InputFilter\SchoolAsset::class)
$c->get('labservice')
); );
}; };
...@@ -96,13 +135,28 @@ return function (Slim\App $app) { ...@@ -96,13 +135,28 @@ return function (Slim\App $app) {
return new GrEduLabs\Schools\Middleware\FetchSchoolFromIdentity($c['authentication_service']); return new GrEduLabs\Schools\Middleware\FetchSchoolFromIdentity($c['authentication_service']);
}; };
// inputfilters
$container[GrEduLabs\Schools\InputFilter\Teacher::class] = function ($c) {
return new GrEduLabs\Schools\InputFilter\Teacher();
};
$container[GrEduLabs\Schools\InputFilter\SchoolAsset::class] = function ($c) {
return new GrEduLabs\Schools\InputFilter\SchoolAsset(
$c->get(GrEduLabs\Schools\Service\LabServiceInterface::class),
$c->get(GrEduLabs\Schools\Service\AssetServiceInterface::class)
);
};
}); });
$events('on', 'app.bootstrap', function ($stop, $app, $container) { $events('on', 'app.bootstrap', function ($stop, $app, $container) {
$container['view']->getEnvironment()->getLoader()->prependPath(__DIR__ . '/templates'); $container['view']->getEnvironment()->getLoader()->prependPath(__DIR__ . '/templates');
$app->group('/school', function () { $app->group('/school', function () {
$this->get('', GrEduLabs\Schools\Action\Index::class)->setName('school'); $this->get('', GrEduLabs\Schools\Action\Index::class)->setName('school');
$this->get('/staff', GrEduLabs\Schools\Action\Staff\ListAll::class)->setName('school.staff'); $this->get('/staff', GrEduLabs\Schools\Action\Staff\ListAll::class)->setName('school.staff');
$this->post('/staff', GrEduLabs\Schools\Action\Staff\PersistTeacher::class) $this->post('/staff', GrEduLabs\Schools\Action\Staff\PersistTeacher::class)
->add(GrEduLabs\Schools\Middleware\InputFilterTeacher::class) ->add(GrEduLabs\Schools\Middleware\InputFilterTeacher::class)
...@@ -112,7 +166,12 @@ return function (Slim\App $app) { ...@@ -112,7 +166,12 @@ return function (Slim\App $app) {
$this->get('/labs', GrEduLabs\Schools\Action\Labs::class)->setName('school.labs'); $this->get('/labs', GrEduLabs\Schools\Action\Labs::class)->setName('school.labs');
$this->post('/labs', GrEduLabs\Schools\Action\LabCreate::class)->setName('school.labcreate'); $this->post('/labs', GrEduLabs\Schools\Action\LabCreate::class)->setName('school.labcreate');
$this->get('/assets', GrEduLabs\Schools\Action\Assets::class)->setName('school.assets');
$this->get('/assets', GrEduLabs\Schools\Action\Assets\ListAssets::class)->setName('school.assets');
$this->post('/assets', GrEduLabs\Schools\Action\Assets\PersistAsset::class)
->add(GrEduLabs\Schools\Middleware\InputFilterSchoolAsset::class);
$this->delete('/assets', GrEduLabs\Schools\Action\Assets\DeleteAsset::class);
})->add(GrEduLabs\Schools\Middleware\FetchSchoolFromIdentity::class); })->add(GrEduLabs\Schools\Middleware\FetchSchoolFromIdentity::class);
}); });
}; };
...@@ -197,6 +197,69 @@ CREATE TABLE `teacher` ( ...@@ -197,6 +197,69 @@ CREATE TABLE `teacher` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ) 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 */;
--
-- Table structure for table `itemcategory`
--
DROP TABLE IF EXISTS `itemcategory`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `itemcategory` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name_UNIQUE` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `itemcategory`
--
LOCK TABLES `itemcategory` WRITE;
/*!40000 ALTER TABLE `itemcategory` DISABLE KEYS */;
INSERT INTO `itemcategory` VALUES (8,'ACCESS POINT'),(26,'LAPTOP'),(7,'MEDIA CONVERTER'),(6,'MODEM / ROUTER '),(25,'MOTHERBOARD'),(5,'PATCH PANEL'),(4,'POWERLINE PLC'),(14,'PRINTER'),(3,'RACK'),(13,'SCANNER'),(24,'SERVER'),(12,'SPLITTER'),(2,'SWITCH/ HUB'),(23,'TABLET'),(1,'VOIP ADAPTER'),(11,'WEBCAM'),(22,'WORKSTATION'),(41,'ΒΙΝΤΕΟΠΡΟΒΟΛΕΑΣ'),(40,'ΔΙΑΔΡΑΣΤΙΚΟ ΣΥΣΤΗΜΑ'),(39,'ΔΙΑΔΡΑΣΤΙΚΟΣ ΠΙΝΑΚΑΣ'),(21,'ΕΞΩΤΕΡΙΚΟ ΜΕΣΟ ΑΠΟΘΗΚΕΥΣΗΣ'),(38,'ΕΠΕΞΕΡΓΑΣΤΗΣ (CPU)'),(20,'ΗΧΕΙΑ'),(10,'ΚΑΡΤΑ WIRELESS'),(37,'ΚΑΡΤΑ ΓΡΑΦΙΚΩΝ'),(36,'ΚΑΡΤΑ ΔΙΚΤΥΟΥ'),(35,'ΚΑΡΤΑ ΗΧΟΥ'),(9,'ΚΕΡΑΙΑ WIFI'),(34,'ΚΙΝΗΤΟ ΕΡΓΑΣΤΗΡΙΟ'),(33,'ΚΟΥΤΙ ΥΠΟΛΟΓΙΣΤΗ'),(19,'ΜΙΚΡΟΦΩΝΟ MULTIMEDIA'),(32,'ΜΝΗΜΗ RAM'),(31,'ΟΔΗΓΟΙ ΟΠΤΙΚΩΝ ΜΕΣΩΝ'),(30,'ΟΘΟΝΗ'),(18,'ΠΛΗΚΤΡΟΛΟΓΙΟ'),(17,'ΠΟΝΤΙΚΙ'),(29,'ΣΚΛΗΡΟΣ ΔΙΣΚΟΣ'),(16,'ΣΤΑΘΕΡΟΠΟΙΗΤΕΣ ΤΑΣΗΣ & U.P.S'),(28,'ΣΥΣΤΗΜΑ ΤΗΛΕΔΙΑΣΚΕΨΗΣ'),(27,'ΤΡΟΦΟΔΟΤΙΚΟ'),(15,'ΨΗΦ. ΦΩΤΟΓΡΑΦΙΚΗ/ΒΙΝΤΕΟΚΑΜΕΡΑ');
/*!40000 ALTER TABLE `itemcategory` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `lab`
--
DROP TABLE IF EXISTS `lab`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `lab` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `schoolasset`
--
DROP TABLE IF EXISTS `schoolasset`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `schoolasset` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`itemcategory_id` int(11) unsigned NOT NULL,
`school_id` int(11) unsigned NOT NULL,
`qty` int(11) unsigned NOT NULL,
`lab_id` int(11) unsigned NOT NULL,
`acquisition_year` char(4) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`comments` text COLLATE utf8mb4_unicode_ci,
PRIMARY KEY (`id`),
KEY `index_foreignkey_schoolasset_itemcategory` (`itemcategory_id`),
KEY `index_foreignkey_schoolasset_school` (`school_id`),
KEY `index_foreignkey_schoolasset_lab` (`lab_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
......
(function () { (function (utils) {
'use strict'; 'use strict';
var Asset, var Asset,
Assets, Assets,
AssetView, AssetRow,
AssetsView, AssetsView,
AssetModalView, AssetView,
assetTemplate; assetTemplate;
Asset = Backbone.Model.extend({ idAttribute: 'id' }); Asset = Backbone.Model.extend({ idAttribute: 'id' });
Assets = Backbone.Collection.extend({ Assets = Backbone.Collection.extend({
model: Asset, model: Asset,
comparator: 'name', comparator: 'itemcategory',
}); });
AssetView = Backbone.View.extend({ AssetRow = Backbone.View.extend({
tagName: 'tr', tagName: 'tr',
template: (function () { template: (function () {
if (typeof assetTemplate === 'undefined') { if (typeof assetTemplate === 'undefined') {
...@@ -25,66 +25,109 @@ ...@@ -25,66 +25,109 @@
}()), }()),
initialize: function () { initialize: function () {
this.model.on('change', this.render, this); this.model.on('change', this.render, this);
this.model.on('remove', this.remove, this);
}, },
render: function () { render: function () {
var html = this.template({ asset: this.model.attributes }); this.$el.html(this.template({ asset: this.model.attributes }));
this.$el.attr('data-id', this.model.get('id')); this.$el.attr('data-id', this.model.get('id'));
this.$el.html(html);
return this; return this;
},
remove: function () {
this.$el.remove();
} }
}); });
AssetsView = Backbone.View.extend({ AssetsView = Backbone.View.extend({
el: '#school', el: '#school',
modal: null, assetView: null,
events: { events: {
'click .btn-add-asset': 'addAsset', 'click .btn-add-asset': 'addAsset',
'click tbody tr': 'editAsset' 'click tbody tr': 'editAsset'
}, },
initialize: function () { initialize: function () {
var that = this; var that = this;
this.modal = new AssetModalView(); this.assetView = new AssetView({model: this.model});
_.each(this.$el.find('tbody tr[data-asset]'), function (tr) { _.each(this.$el.find('tbody tr'), function (tr) {
var data, var data = $(tr).data('asset'),
asset; asset = new Asset(data);
tr = $(tr);
data = tr.data('asset');
asset = new Asset(data);
that.model.add(asset); that.model.add(asset);
new AssetView({ model: asset }); new AssetRow({ model: asset, el: tr });
tr.attr('data-asset', null); $(tr).attr('data-asset', null);
}); });
this.model.on('add', this.renderAsset, this); this.model.on('add', this.renderAsset, this);
}, this.model.on('remove', function () {
renderAsset: function (asset) { if (this.model.length === 0) {
this.$el.find('tbody').append(new AssetView({ this.$el.find('tbody tr.no-records').show();
model: asset }
}).render().el); }, this);
return this;
}, },
addAsset: function (evt) { addAsset: function (evt) {
var that = this;
evt.preventDefault(); evt.preventDefault();
this.modal.render(function (data) { this.assetView.render();
that.model.add(data); return this;
});
}, },
editAsset: function (evt) { editAsset: function (evt) {
var asset = this.model.get($(evt.target).closest('tr').data('id')); var assetId;
this.modal.render(function (data) { assetId = $(evt.target).closest('tr').data('id');
asset.set(data); this.assetView.render(assetId);
}, asset.attributes); return this;
},
renderAsset: function (asset) {
this.$el.find('tbody tr.no-records').hide();
this.$el.find('tbody').append(new AssetRow({
model: asset
}).render().el);
return this;
} }
}); });
AssetModalView = Backbone.View.extend({ AssetView = Backbone.View.extend({
el: '#asset-form-modal', el: '#asset-form-modal',
form: null, form: null,
asset: null,
url: null,
events: { events: {
'submit': 'submit', 'submit': 'persistAsset',
'click button.remove': 'removeAsset'
}, },
initialize: function () { initialize: function () {
var that = this;
this.form = this.$el.find('form'); this.form = this.$el.find('form');
this.url = this.form.data('url');
this.$el.on('hide.bs.modal', function () {
utils.formMessages.clear(that.form);
that.form[0].reset();
that.form.find('input[type="hidden"]').val('');
});
},
render: function (assetId) {
var assetAttributes;
if (!assetId) {
this.$el.find('.modal-footer button.remove')
.prop('disabled', true)
.addClass('hidden');
} else {
this.$el.find('.modal-footer button.remove')
.prop('disabled', false)
.removeClass('hidden');
}
this.asset = assetId && this.model.get(assetId) || null;
assetAttributes = this.asset && this.asset.attributes || {};
_.each(this.form[0].elements, function (element) {
var element = $(element),
name = element.attr('name');
if ('checkbox' === element.attr('type')) {
element.prop('checked', utils.parseInt(assetAttributes[name]));
} else {
element.val(assetAttributes[name] || '');
}
});
this.show();
return this;
}, },
show: function () { show: function () {
this.$el.modal('show'); this.$el.modal('show');
...@@ -94,43 +137,52 @@ ...@@ -94,43 +137,52 @@
this.$el.modal('hide'); this.$el.modal('hide');
return this; return this;
}, },
render: function (done, asset) { persistAsset: function (evt) {
var template, var data = utils.serializeObject(this.form),
that = this; that = this;
evt.preventDefault();
asset = asset || {}; $.ajax({
this.form[0].reset(); url: this.url,
this.form.find('input[type="hidden"]').val(''); type: 'post',
this.form.data('done', done); data: data,
_.each(this.form[0].elements, function (element) { }).done(function (response) {
var element = $(element), if (that.asset) {
name = element.attr('name'); that.asset.set(response);
} else {
if (typeof asset[name] !== undefined) { that.model.add(response);
element.val(asset[name]); }
that.hide();
}).fail(function (xhr, err) {
var messages;
if (422 === xhr.status) {
messages = JSON.parse(xhr.responseText).messages || {};
utils.formMessages.render(that.form, messages);
} else {
alert('Προέκυψε κάποιο σφάλμα');
} }
}); });
this.show();
return this;
}, },
submit: function (evt) { removeAsset: function (evt) {
var data; var that = this;
evt.preventDefault(); if (!confirm('Να διαγραφεί ο εξοπλισμός;')) {
data = _.reduce(this.form.serializeArray(), function (hash, pair) { return;
hash[pair.name] = pair.value; }
return hash; $.ajax({
}, {}); url: that.url,
evt.preventDefault(); type: 'delete',
if (!data.id) { dataType: 'json',
data.id = (100 * Math.random()).toFixed(0); data: {
id: that.asset.get('id'),
} </