DB schema updated, code restructured, full exception and empty posts handling,...

DB schema updated, code restructured, full exception and empty posts handling, added download script and new route, various fixes
parent ebb0fd83
...@@ -35,6 +35,7 @@ return [ ...@@ -35,6 +35,7 @@ return [
['/receive-equip', ['school'], ['get', 'post']], ['/receive-equip', ['school'], ['get', 'post']],
['/receive-equip/submit-success', ['school'], ['get']], ['/receive-equip/submit-success', ['school'], ['get']],
['/receive-equip/report', ['school'], ['get']], ['/receive-equip/report', ['school'], ['get']],
['/receive-equip/receive-doc/{fn}', ['school'], ['get']],
['/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']],
...@@ -42,6 +43,7 @@ return [ ...@@ -42,6 +43,7 @@ return [
['/in_numbers', ['guest', 'user'], ['get']], ['/in_numbers', ['guest', 'user'], ['get']],
['/export/csv/edulabs_{type}.csv', ['guest', 'user'], ['get']], ['/export/csv/edulabs_{type}.csv', ['guest', 'user'], ['get']],
['/open-data', ['guest', 'user'], ['get']], ['/open-data', ['guest', 'user'], ['get']],
['/receive-equip/undo-submit/{applicationform_id}', ['school'], ['get']], // only for tests. Must be removed
], ],
], ],
], ],
......
<?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
*/
return [
'receive_equip' => [
'file_upload_path' => __DIR__ . '/../../data/uploads', // path to save file
'file_upload_max_size' => 3145728, // Maximum number of bytes allowed(default 3MB)
'file_upload_types_permitted' => ['jpg', 'jpeg', 'pdf', 'png'], // Array of allowed extensions
],
];
...@@ -24,6 +24,7 @@ CREATE TABLE `applicationform` ( ...@@ -24,6 +24,7 @@ CREATE TABLE `applicationform` (
`submitted_by` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `submitted_by` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`received_ts` timestamp NULL, `received_ts` timestamp NULL,
`received_by` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `received_by` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`received_document` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT '',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `index_foreignkey_applicationform_school` (`school_id`), KEY `index_foreignkey_applicationform_school` (`school_id`),
CONSTRAINT `c_fk_applicationform_school_id` FOREIGN KEY (`school_id`) REFERENCES `school` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE CONSTRAINT `c_fk_applicationform_school_id` FOREIGN KEY (`school_id`) REFERENCES `school` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE
......
...@@ -24,6 +24,7 @@ CREATE TABLE `applicationform` ( ...@@ -24,6 +24,7 @@ CREATE TABLE `applicationform` (
`submitted_by` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL, `submitted_by` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`received_ts` timestamp NULL, `received_ts` timestamp NULL,
`received_by` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `received_by` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`received_document` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT '',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `index_foreignkey_applicationform_school` (`school_id`), KEY `index_foreignkey_applicationform_school` (`school_id`),
CONSTRAINT `c_fk_applicationform_school_id` FOREIGN KEY (`school_id`) REFERENCES `school` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE CONSTRAINT `c_fk_applicationform_school_id` FOREIGN KEY (`school_id`) REFERENCES `school` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE
......
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
* @copyright Copyright (c) 2008-2015 Greek Free/Open Source Software Society (https://gfoss.ellak.gr/) * @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 * @license GNU GPLv3 http://www.gnu.org/licenses/gpl-3.0-standalone.html
*/ */
use Slim\Http\Request;
use Slim\Http\Response;
use RedBeanPHP\R;
return function (Slim\App $app) { return function (Slim\App $app) {
$container = $app->getContainer(); $container = $app->getContainer();
...@@ -17,7 +20,6 @@ return function (Slim\App $app) { ...@@ -17,7 +20,6 @@ return function (Slim\App $app) {
}); });
$events('on', 'app.services', function ($container) { $events('on', 'app.services', function ($container) {
$container[GrEduLabs\ReceiveEquip\Service\ReceiveEquipServiceInterface::class] = function ($c) { $container[GrEduLabs\ReceiveEquip\Service\ReceiveEquipServiceInterface::class] = function ($c) {
return new GrEduLabs\ReceiveEquip\Service\ReceiveEquipService($c['logger']); return new GrEduLabs\ReceiveEquip\Service\ReceiveEquipService($c['logger']);
}; };
...@@ -43,13 +45,13 @@ return function (Slim\App $app) { ...@@ -43,13 +45,13 @@ return function (Slim\App $app) {
$container[GrEduLabs\ReceiveEquip\Action\ReceiveEquip::class] = function ($c) { $container[GrEduLabs\ReceiveEquip\Action\ReceiveEquip::class] = function ($c) {
$settings = $c->get('settings'); $settings = $c->get('settings');
return new GrEduLabs\ReceiveEquip\Action\ReceiveEquip( return new GrEduLabs\ReceiveEquip\Action\ReceiveEquip(
$c->get('view'), $c->get('view'),
$c->get(GrEduLabs\ReceiveEquip\Service\ReceiveEquipServiceInterface::class), $c->get(GrEduLabs\ReceiveEquip\Service\ReceiveEquipServiceInterface::class),
$c->get(GrEduLabs\ReceiveEquip\InputFilter\ReceiveEquip::class), $c->get(GrEduLabs\ReceiveEquip\InputFilter\ReceiveEquip::class),
$c->get('authentication_service'), $c->get('authentication_service'),
$c->get('router')->pathFor('receive_equip.submit_success'), $c->get('router')->pathFor('receive_equip.submit_success'),
$c['flash'],
$c $c
); );
}; };
...@@ -74,15 +76,18 @@ return function (Slim\App $app) { ...@@ -74,15 +76,18 @@ return function (Slim\App $app) {
$c->get(GrEduLabs\ReceiveEquip\Service\ReceiveEquipServiceInterface::class) $c->get(GrEduLabs\ReceiveEquip\Service\ReceiveEquipServiceInterface::class)
); );
}; };
});
$container[GrEduLabs\ReceiveEquip\Middleware\SchoolReceiveEquip::class] = function ($c) { $events('on', 'app.services', function ($container) {
return new GrEduLabs\ReceiveEquip\Middleware\SchoolReceiveEquip( $container[GrEduLabs\ReceiveEquip\Middleware\HandleEmptyPosts::class] = function ($c) {
return new GrEduLabs\ReceiveEquip\Middleware\HandleEmptyPosts(
$c->get('view'), $c->get('view'),
$c->get(GrEduLabs\ReceiveEquip\Service\ReceiveEquipServiceInterface::class), $c->get(GrEduLabs\ReceiveEquip\Service\ReceiveEquipServiceInterface::class),
$c['flash'],
$c $c
); );
}; };
}); }, -100000);
$events('on', 'app.bootstrap', function ($app, $container) { $events('on', 'app.bootstrap', function ($app, $container) {
$container['view']->getEnvironment()->getLoader()->prependPath(__DIR__ . '/templates'); $container['view']->getEnvironment()->getLoader()->prependPath(__DIR__ . '/templates');
...@@ -91,11 +96,46 @@ return function (Slim\App $app) { ...@@ -91,11 +96,46 @@ return function (Slim\App $app) {
$this->map(['get', 'post'], '', GrEduLabs\ReceiveEquip\Action\ReceiveEquip::class) $this->map(['get', 'post'], '', GrEduLabs\ReceiveEquip\Action\ReceiveEquip::class)
->add(GrEduLabs\Application\Middleware\AddCsrfToView::class) ->add(GrEduLabs\Application\Middleware\AddCsrfToView::class)
->add('csrf') ->add('csrf')
->add(GrEduLabs\ReceiveEquip\Middleware\HandleEmptyPosts::class)
->setName('receive_equip'); ->setName('receive_equip');
$this->get('/submit-success', GrEduLabs\ReceiveEquip\Action\SubmitSuccess::class) $this->get('/submit-success', GrEduLabs\ReceiveEquip\Action\SubmitSuccess::class)
->setName('receive_equip.submit_success'); ->setName('receive_equip.submit_success');
$this->get('/report', GrEduLabs\ReceiveEquip\Action\ReceiveEquipPdf::class) $this->get('/report', GrEduLabs\ReceiveEquip\Action\ReceiveEquipPdf::class)
->setName('receive_equip.report'); ->setName('receive_equip.report');
})->add(GrEduLabs\Schools\Middleware\FetchSchoolFromIdentity::class); })->add(GrEduLabs\Schools\Middleware\FetchSchoolFromIdentity::class);
$app->get('/receive-equip/receive-doc/{fn}', function (Request $req, Response $res) use ($container) {
$route = $req->getAttribute('route');
$fn = $route->getArgument('fn');
/* $container["logger"]->info(sprintf('filename = %s url=%s', $fn, path_for('receive_equip.receive_doc', [
'fn' => form.values.received_document,])
)); */
$file = $container['settings']['receive_equip']['file_upload_path'] . "/" . $fn;
$response = $res->withHeader('Content-Description', 'File Transfer')
->withHeader('Content-Type', 'application/octet-stream')
->withHeader('Content-Disposition', 'attachment;filename="' . basename($file) . '"')
->withHeader('Expires', '0')
->withHeader('Cache-Control', 'must-revalidate')
->withHeader('Content-Length', filesize($file));
readfile($file);
return $response;
})->setName('receive_equip.receive_doc');
/******************* only for tests ***************************/
$app->get('/receive-equip/undo-submit/{applicationform_id}', function (Request $req, Response $res) use ($container) {
$route = $req->getAttribute('route');
$applicationform_id = $route->getArgument('applicationform_id');
$sql = 'update `applicationform` set `approved`=1, `received_ts`=null where `id`=' . $applicationform_id;
R::exec($sql);
return $res->withRedirect("/receive-equip");
})->setName('receive_equip.undosubmit');
/****************** /only for tests ***************************/
}); });
}; };
...@@ -15,6 +15,7 @@ use Zend\Filter; ...@@ -15,6 +15,7 @@ use Zend\Filter;
use Zend\InputFilter\CollectionInputFilter; use Zend\InputFilter\CollectionInputFilter;
use Zend\InputFilter\Input; use Zend\InputFilter\Input;
use Zend\InputFilter\InputFilter; use Zend\InputFilter\InputFilter;
use Zend\InputFilter\FileInput;
use Zend\Validator; use Zend\Validator;
class ReceiveEquip extends InputFilter class ReceiveEquip extends InputFilter
...@@ -30,7 +31,7 @@ class ReceiveEquip extends InputFilter ...@@ -30,7 +31,7 @@ class ReceiveEquip extends InputFilter
->attach(new Filter\ToInt()); ->attach(new Filter\ToInt());
$id->getValidatorChain() $id->getValidatorChain()
->attach(new Validator\NotEmpty()); ->attach(new Validator\NotEmpty());
$schoolId = new Input('school_id'); $schoolId = new Input('school_id');
$schoolId->setRequired(true) $schoolId->setRequired(true)
->getFilterChain() ->getFilterChain()
...@@ -46,9 +47,14 @@ class ReceiveEquip extends InputFilter ...@@ -46,9 +47,14 @@ class ReceiveEquip extends InputFilter
'useDomainCheck' => false, 'useDomainCheck' => false,
])); ]));
/* $received_document = new FileInput('received_document');
$received_document->getValidatorChain()
->attach(new Validator\File\UploadFile()); */
$this->add($id) $this->add($id)
->add($schoolId) ->add($schoolId)
->add($submittedBy) ->add($submittedBy)
// ->add($received_document)
->add($itemsInputFilter, 'items'); ->add($itemsInputFilter, 'items');
} }
} }
...@@ -17,7 +17,7 @@ use Slim\Http\Response; ...@@ -17,7 +17,7 @@ use Slim\Http\Response;
use Slim\Views\Twig; use Slim\Views\Twig;
class SchoolReceiveEquip class HandleEmptyPosts
{ {
/** /**
* *
...@@ -32,10 +32,18 @@ class SchoolReceiveEquip ...@@ -32,10 +32,18 @@ class SchoolReceiveEquip
*/ */
protected $receiveEquipService; protected $receiveEquipService;
public function __construct(Twig $view, ReceiveEquipServiceInterface $receiveEquipService, $container) /**
*
* @var flash messages
*/
protected $flash;
public function __construct(Twig $view, ReceiveEquipServiceInterface $receiveEquipService, $flash, $container)
{ {
$this->view = $view; $this->view = $view;
$this->receiveEquipService = $receiveEquipService; $this->receiveEquipService = $receiveEquipService;
$this->flash = $flash;
$this->container = $container; $this->container = $container;
} }
...@@ -43,28 +51,17 @@ class SchoolReceiveEquip ...@@ -43,28 +51,17 @@ class SchoolReceiveEquip
{ {
$school = $req->getAttribute('school'); $school = $req->getAttribute('school');
$receiveEquip = $this->receiveEquipService->findSchoolReceiveEquip($school->id); if(empty($_FILES) && empty($_POST) && isset($_SERVER['REQUEST_METHOD']) && strtolower($_SERVER['REQUEST_METHOD']) == 'post'){ //catch file overload error...
if ($receiveEquip) { $postMax = ini_get('post_max_size'); //grab the size limits...
$receiveEquip['items'] = array_reduce($receiveEquip['items'], function ($aggr, $item) { $this->flash->addMessage('danger', "Αποστείλατε αρχείο με μέγεθος ανώτερο του επιτρεπτού");
$category = $item['itemcategory_id']; $this->container["logger"]->info(sprintf(
if (!isset($aggr[$category])) { 'post max size exceeded'
$aggr[$category] = [ ));
'category' => $item['itemcategory'], return $res->withRedirect($req->getUri());
'count' => 0, }
'countAcquired' => 0, else {
'available' => 'LATEST' return $next($req, $res);
];
}
$aggr[$category]['count'] += $item['qty'];
$aggr[$category]['countAcquired'] += $item['qtyacquired'];
return $aggr;
}, []);
} }
$this->view['receiveEquip'] = $receiveEquip;
return $next($req, $res);
} }
} }
...@@ -76,6 +76,7 @@ public function __construct($logger) { ...@@ -76,6 +76,7 @@ public function __construct($logger) {
$receiveEquip['items'] = array_map(function ($itemBean) { $receiveEquip['items'] = array_map(function ($itemBean) {
return array_merge($itemBean->export(), [ return array_merge($itemBean->export(), [
'itemcategory' => $itemBean->itemcategory->name, 'itemcategory' => $itemBean->itemcategory->name,
'lab' => $itemBean->lab->name,
'version' => $itemBean->itemcategory->groupflag, 'version' => $itemBean->itemcategory->groupflag,
]); ]);
}, $bean->ownApplicationformitemList); }, $bean->ownApplicationformitemList);
......
<h1 class="no-print"> <h1 class="no-print alert alert-success">
{% block title %} {% block title %}
Επιτυχής Καταχώρηση <small>φόρμας παραλαβής νέου εξοπλισμού</small> Επιτυχής Καταχώρηση <small>φόρμας παραλαβής νέου εξοπλισμού</small>
{% endblock %} {% endblock %}
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
<thead> <thead>
<tr> <tr>
<th>Τύπος</th> <th>Τύπος</th>
<th>Χώρος</th>
<th>Πλήθος αιτηθέντων</th> <th>Πλήθος αιτηθέντων</th>
<th>Πλήθος παραληφθέντων</th> <th>Πλήθος παραληφθέντων</th>
</tr> </tr>
...@@ -40,6 +41,7 @@ ...@@ -40,6 +41,7 @@
{% for item in receiveEquip.items %} {% for item in receiveEquip.items %}
<tr> <tr>
<td>{{ item.itemcategory }}</td> <td>{{ item.itemcategory }}</td>
<td>{{ item.lab }}</td>
<td>{{ item.qty }}</td> <td>{{ item.qty }}</td>
<td>{{ item.qtyreceived }}</td> <td>{{ item.qtyreceived }}</td>
</tr> </tr>
......
...@@ -4,7 +4,11 @@ ...@@ -4,7 +4,11 @@
<div id="receive-equip-success"> <div id="receive-equip-success">
{% include 'receive_equip/result.twig' %} {% include 'receive_equip/result.twig' %}
<div class="row no-print"> <div class="row no-print">
<div class="col-xs-12 text-center"> <div class="col-xs-6 text-center">
<a href="{{path_for('receive_equip.receive_doc', {'fn':receiveEquip.received_document})}}"
class="btn btn-lg btn-primary btn-print"><span class="glyphicon glyphicon-download" aria-hidden="true"></span>&nbsp;Δελτίο Παραλαβής</a>
</div>
<div class="col-xs-6 text-center">
<a href="{{ path_for('receive_equip.report') }}" class="btn btn-lg btn-primary btn-print">Εκτύπωση</a> <a href="{{ path_for('receive_equip.report') }}" class="btn btn-lg btn-primary btn-print">Εκτύπωση</a>
</div> </div>
</div> </div>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment