From: Vincent Vanwaelscappel Date: Tue, 20 Apr 2021 17:53:33 +0000 (+0200) Subject: wip #4406 @7 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=46e8284cdb16c4d4db6309de927b3627c5cbf7c6;p=grandvision-ranking.git wip #4406 @7 --- diff --git a/.idea/grandvision-ranking.iml b/.idea/grandvision-ranking.iml index 1c4fdc8..b1ec454 100644 --- a/.idea/grandvision-ranking.iml +++ b/.idea/grandvision-ranking.iml @@ -119,6 +119,8 @@ + + diff --git a/.idea/laravel-plugin.xml b/.idea/laravel-plugin.xml new file mode 100644 index 0000000..5aae25d --- /dev/null +++ b/.idea/laravel-plugin.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml index c4f48f3..42cb97a 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -114,6 +114,8 @@ + + diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 615dfe1..fb9547c 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Models\FeedbackProcess; +use Cubist\Util\Files\Files; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Validation\ValidatesRequests; @@ -16,8 +17,15 @@ class Controller extends BaseController public function process() { $process = new FeedbackProcess(request()->get('_session')); - $process->process(); + $res=$process->process(); + $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($res); + $tmp = Files::tempnam().".xlsx"; + $writer->setPreCalculateFormulas(false); + $writer->save($tmp); + + $res= response()->download($tmp, 'res.xlsx', ['content-type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'])->deleteFileAfterSend(); + return $res; } public function upload() diff --git a/app/Models/FeedbackProcess.php b/app/Models/FeedbackProcess.php index 7b88d32..c8b2dc5 100644 --- a/app/Models/FeedbackProcess.php +++ b/app/Models/FeedbackProcess.php @@ -3,6 +3,12 @@ namespace App\Models; +use Cubist\Util\PHP; +use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\Reader\Xlsx; +use PhpOffice\PhpSpreadsheet\Style\Fill; +use PhpOffice\PhpSpreadsheet\Style\NumberFormat; +use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use Symfony\Component\HttpFoundation\File\UploadedFile; class FeedbackProcess @@ -123,6 +129,151 @@ class FeedbackProcess public function process() { - dd($this); + PHP::neverStop(false); + // Open feedbacks + $feedbackSheets = []; + foreach ($this->getFeedbacks() as $feedback) { + $reader = new Xlsx(); + $xlsx = $reader->load($feedback); + foreach ($xlsx->getAllSheets() as $sheet) { + if ($sheet->getSheetState() !== Worksheet::SHEETSTATE_VISIBLE) { + continue; + } + $name = $this->_getSheetName($sheet); + if (!isset($feedbackSheets[$name])) { + $feedbackSheets[$name] = []; + } + $feedbackSheets[$name][] = $sheet; + } + } + + $reader = new Xlsx(); + $template = $reader->load($this->getTemplate()); + foreach ($template->getAllSheets() as $sheet) { + if ($sheet->getSheetState() !== Worksheet::SHEETSTATE_VISIBLE) { + continue; + } + $name = $this->_getSheetName($sheet); + $this->_processSheet($sheet, $feedbackSheets[$name] ?? []); + } + // Make first sheet active + $template->setActiveSheetIndex(0); + return $template; + } + + /** + * @param $sheet Worksheet + */ + protected function _getSheetName($sheet) + { + return mb_strtolower(trim($sheet->getCellByColumnAndRow(1, 1)->getValue())); + } + + /** + * @param $templateSheet Worksheet + * @param $feedbacks Worksheet[] + * @throws \PhpOffice\PhpSpreadsheet\Exception + */ + protected function _processSheet($templateSheet, $feedbacks) + { + // Find header row + $highestRow = $templateSheet->getHighestRow(); + for ($i = 1; $i <= $highestRow; $i++) { + if ($templateSheet->getCellByColumnAndRow(1, $i)->getValue() === 'Picture References') { + $headersRow = $i; + break; + } + } + + // Add ranking column + $templateSheet->insertNewColumnBefore('O', 1); + $h = $templateSheet->getCell('O' . $headersRow); + // Style it + $h->getStyle()->getFill()->setFillType(Fill::FILL_SOLID) + ->getStartColor() + ->setARGB('5eba7d'); + // Set the caption + $h->setValue('Rank'); + + // Get data from feedbacks + + $startCol = 15; + $eanCol = 4; + $merged = []; + $feedbackId = 0; + foreach ($feedbacks as $feedback) { + $maxcol = Coordinate::columnIndexFromString($feedback->getHighestColumn()); + $maxrow = $feedback->getHighestRow(); + for ($j = $headersRow + 1; $j <= $maxrow; $j++) { + $ean = trim($feedback->getCellByColumnAndRow($eanCol, $j)->getValue()); + if (!isset($merged[$ean])) { + $merged[$ean] = []; + } + for ($i = $startCol; $i <= $maxcol; $i++) { + $v = $feedback->getCellByColumnAndRow($i, $j)->getValue(); + if (null === $v) { + continue; + } + $v = trim($v); + if (!$v) { + continue; + } + $merged[$ean][$i - $startCol] = $v; + } + } + } + $rankingData = []; + // Put feedbacks is template + foreach ($merged as $ean => $data) { + // Search line by ean + $row = null; + for ($i = $headersRow + 1; $i <= $highestRow; $i++) { + if (trim($templateSheet->getCellByColumnAndRow($eanCol, $i)->getValue()) == $ean) { + $row = $i; + break; + } + } + if (null === $row) { + continue; + } + $rankingData[$row] = []; + // Put data on that row + foreach ($data as $col => $value) { + // Set the value + $templateSheet->setCellValueByColumnAndRow($startCol + 1 + $col, $row, $value); + // Gather data to make the ranking + if ($col % 4 === 0) { + $k = count($rankingData[$row]); + $rankingData[$row][$k] = (mb_strtoupper($value) === 'YES' ? 'Y' : 'N'); + } else if ($col % 2 === 0) { + $rankingData[$row][$k] .= (mb_strtoupper($value) ?? 'C'); + } + } + } + + $coefs = [ + 'YA' => 100000, + 'YB' => 10000, + 'YC' => 1000, + 'NA' => 100, + 'NB' => 10, + 'NC' => 1]; + + $scores = []; + foreach ($rankingData as $row => $data) { + $scores[$row] = 0; + foreach ($data as $rank) { + $s = $coefs[$rank] ?? 0; + $scores[$row] += $s; + } + } + arsort($scores); + $rank = 1; + foreach ($scores as $row => $score) { + $templateSheet->setCellValueByColumnAndRow($startCol, $row, $rank); + $templateSheet->getStyleByColumnAndRow($startCol, $row)->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_NUMBER); + $rank++; + } + } } diff --git a/composer.json b/composer.json index c9a7482..c770156 100644 --- a/composer.json +++ b/composer.json @@ -2,6 +2,12 @@ "name": "cubedesigners/grandvision-ranking", "description": "description", "license": "proprietary", + "repositories": [ + { + "type": "composer", + "url": "https://composer.cubedesigners.com/" + } + ], "authors": [ { "name": "vincent", @@ -10,13 +16,14 @@ ], "require": { "php": "^7.3|^8.0", + "ext-json": "*", + "cubist/util": "dev-master", "fideloper/proxy": "^4.4", "fruitcake/laravel-cors": "^2.0", "guzzlehttp/guzzle": "^7.0.1", "laravel/framework": "^8.12", "laravel/tinker": "^2.5", - "phpoffice/phpspreadsheet": "^1.17", - "ext-json": "*" + "phpoffice/phpspreadsheet": "^1.17" }, "require-dev": { "facade/ignition": "^2.5", diff --git a/composer.lock b/composer.lock index 4bdc15c..b74d7a9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1732cf80b63526e49045d08cadf62e79", + "content-hash": "bfd96ac93a06e647207931391a023f90", "packages": [ { "name": "asm89/stack-cors", @@ -118,6 +118,85 @@ ], "time": "2021-01-20T22:51:39+00:00" }, + { + "name": "cubist/net", + "version": "dev-master", + "source": { + "type": "git", + "url": "git://git.cubedesigners.com/cubist_net.git", + "reference": "4e815d62a6f868789ecce6bdcb9f0a81ddffc64a" + }, + "dist": { + "type": "tar", + "url": "https://composer.cubedesigners.com/dist/cubist/net/cubist-net-dev-master-28d1c1.tar", + "reference": "4e815d62a6f868789ecce6bdcb9f0a81ddffc64a", + "shasum": "05f377a7717110e79d264b30738265441d4d9106" + }, + "require": { + "ext-ssh2": "*", + "php": ">=5.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cubist\\Net\\": "src" + } + }, + "license": [ + "proprietary" + ], + "authors": [ + { + "name": "Vincent Vanwaelscappel", + "email": "vincent@cubedesigners.com" + } + ], + "description": "net cubist composer package", + "time": "2020-12-03T12:49:18+00:00" + }, + { + "name": "cubist/util", + "version": "dev-master", + "source": { + "type": "git", + "url": "git://git.cubedesigners.com/cubist_util.git", + "reference": "4c5cd619a89e6679fca80ff84036f68c554426a7" + }, + "dist": { + "type": "tar", + "url": "https://composer.cubedesigners.com/dist/cubist/util/cubist-util-dev-master-906685.tar", + "reference": "4c5cd619a89e6679fca80ff84036f68c554426a7", + "shasum": "06b7f2387c140b9b0f66d86fcfb2947ccebd1886" + }, + "require": { + "cubist/net": "dev-master", + "ext-dom": "*", + "ext-iconv": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "laravel/framework": "~5.8|^6.0|^7.0|^8.0", + "php": ">=7.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cubist\\Util\\": "src" + } + }, + "license": [ + "proprietary" + ], + "authors": [ + { + "name": "Vincent Vanwaelscappel", + "email": "vincent@cubedesigners.com" + } + ], + "description": "Utilities class", + "time": "2021-04-20T13:58:22+00:00" + }, { "name": "doctrine/inflector", "version": "2.0.3", @@ -912,16 +991,16 @@ }, { "name": "laravel/framework", - "version": "v8.37.0", + "version": "v8.38.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "cf4082973abc796ec285190f0603380021f6d26f" + "reference": "26a73532c54d2c090692bf2e3e64e449669053ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/cf4082973abc796ec285190f0603380021f6d26f", - "reference": "cf4082973abc796ec285190f0603380021f6d26f", + "url": "https://api.github.com/repos/laravel/framework/zipball/26a73532c54d2c090692bf2e3e64e449669053ba", + "reference": "26a73532c54d2c090692bf2e3e64e449669053ba", "shasum": "" }, "require": { @@ -1076,7 +1155,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2021-04-13T13:49:49+00:00" + "time": "2021-04-20T13:50:21+00:00" }, { "name": "laravel/tinker", @@ -3068,16 +3147,16 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v2.2.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" + "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", - "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627", + "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627", "shasum": "" }, "require": { @@ -3086,7 +3165,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -3115,7 +3194,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/master" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0" }, "funding": [ { @@ -3131,7 +3210,7 @@ "type": "tidelift" } ], - "time": "2020-09-07T11:33:47+00:00" + "time": "2021-03-23T23:28:01+00:00" }, { "name": "symfony/error-handler", @@ -3289,16 +3368,16 @@ }, { "name": "symfony/event-dispatcher-contracts", - "version": "v2.2.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2" + "reference": "69fee1ad2332a7cbab3aca13591953da9cdb7a11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0ba7d54483095a198fa51781bc608d17e84dffa2", - "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/69fee1ad2332a7cbab3aca13591953da9cdb7a11", + "reference": "69fee1ad2332a7cbab3aca13591953da9cdb7a11", "shasum": "" }, "require": { @@ -3311,7 +3390,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -3348,7 +3427,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.2.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.4.0" }, "funding": [ { @@ -3364,7 +3443,7 @@ "type": "tidelift" } ], - "time": "2020-09-07T11:33:47+00:00" + "time": "2021-03-23T23:28:01+00:00" }, { "name": "symfony/finder", @@ -3429,16 +3508,16 @@ }, { "name": "symfony/http-client-contracts", - "version": "v2.3.1", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "41db680a15018f9c1d4b23516059633ce280ca33" + "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/41db680a15018f9c1d4b23516059633ce280ca33", - "reference": "41db680a15018f9c1d4b23516059633ce280ca33", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/7e82f6084d7cae521a75ef2cb5c9457bbda785f4", + "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4", "shasum": "" }, "require": { @@ -3449,9 +3528,8 @@ }, "type": "library", "extra": { - "branch-version": "2.3", "branch-alias": { - "dev-main": "2.3-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -3488,7 +3566,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v2.3.1" + "source": "https://github.com/symfony/http-client-contracts/tree/v2.4.0" }, "funding": [ { @@ -3504,7 +3582,7 @@ "type": "tidelift" } ], - "time": "2020-10-14T17:08:19+00:00" + "time": "2021-04-11T23:07:08+00:00" }, { "name": "symfony/http-foundation", @@ -4657,21 +4735,21 @@ }, { "name": "symfony/service-contracts", - "version": "v2.2.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" + "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", - "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", + "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/container": "^1.0" + "psr/container": "^1.1" }, "suggest": { "symfony/service-implementation": "" @@ -4679,7 +4757,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -4716,7 +4794,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/master" + "source": "https://github.com/symfony/service-contracts/tree/v2.4.0" }, "funding": [ { @@ -4732,7 +4810,7 @@ "type": "tidelift" } ], - "time": "2020-09-07T11:33:47+00:00" + "time": "2021-04-01T10:43:52+00:00" }, { "name": "symfony/string", @@ -4912,16 +4990,16 @@ }, { "name": "symfony/translation-contracts", - "version": "v2.3.0", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "e2eaa60b558f26a4b0354e1bbb25636efaaad105" + "reference": "95c812666f3e91db75385749fe219c5e494c7f95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/e2eaa60b558f26a4b0354e1bbb25636efaaad105", - "reference": "e2eaa60b558f26a4b0354e1bbb25636efaaad105", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/95c812666f3e91db75385749fe219c5e494c7f95", + "reference": "95c812666f3e91db75385749fe219c5e494c7f95", "shasum": "" }, "require": { @@ -4933,7 +5011,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -4970,7 +5048,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v2.3.0" + "source": "https://github.com/symfony/translation-contracts/tree/v2.4.0" }, "funding": [ { @@ -4986,7 +5064,7 @@ "type": "tidelift" } ], - "time": "2020-09-28T13:05:58+00:00" + "time": "2021-03-23T23:28:01+00:00" }, { "name": "symfony/var-dumper", @@ -7846,11 +7924,14 @@ ], "aliases": [], "minimum-stability": "dev", - "stability-flags": [], + "stability-flags": { + "cubist/util": 20 + }, "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^7.3|^8.0" + "php": "^7.3|^8.0", + "ext-json": "*" }, "platform-dev": [], "plugin-api-version": "2.0.0" diff --git a/resources/css/app.less b/resources/css/app.less index 7d046da..d91a599 100644 --- a/resources/css/app.less +++ b/resources/css/app.less @@ -63,4 +63,15 @@ form { } } +#wait { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + cursor: wait; + z-index: 100000; + display: none; +} + @import "dropzone.css"; diff --git a/resources/js/app.js b/resources/js/app.js index 3935e70..ea421d6 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -54,3 +54,12 @@ myDropzone = new Dropzone(dropzone2, { }, }); dropzones.push(myDropzone) + +$(function () { + $("body").append('
'); + $(document).on('click', 'input[type="submit"]', function () { + $("#wait").show(); + return true; + }); +}); + diff --git a/resources/views/welcome.blade.php b/resources/views/welcome.blade.php index 95f5f1c..b7b70d1 100644 --- a/resources/views/welcome.blade.php +++ b/resources/views/welcome.blade.php @@ -400,7 +400,7 @@

Traitement des feedbacks

-
+ @csrf