diff --git a/composer.lock b/composer.lock index 08ee90e0..ca8a10a1 100644 --- a/composer.lock +++ b/composer.lock @@ -367,20 +367,21 @@ }, { "name": "doctrine/annotations", - "version": "v1.8.0", + "version": "1.10.2", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "904dca4eb10715b92569fbcd79e201d5c349b6bc" + "reference": "b9d758e831c70751155c698c2f7df4665314a1cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/904dca4eb10715b92569fbcd79e201d5c349b6bc", - "reference": "904dca4eb10715b92569fbcd79e201d5c349b6bc", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/b9d758e831c70751155c698c2f7df4665314a1cb", + "reference": "b9d758e831c70751155c698c2f7df4665314a1cb", "shasum": "" }, "require": { "doctrine/lexer": "1.*", + "ext-tokenizer": "*", "php": "^7.1" }, "require-dev": { @@ -390,7 +391,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7.x-dev" + "dev-master": "1.9.x-dev" } }, "autoload": { @@ -431,7 +432,7 @@ "docblock", "parser" ], - "time": "2019-10-01T18:55:10+00:00" + "time": "2020-04-20T09:18:32+00:00" }, { "name": "doctrine/cache", @@ -587,16 +588,16 @@ }, { "name": "doctrine/common", - "version": "2.12.0", + "version": "2.13.0", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "2053eafdf60c2172ee1373d1b9289ba1db7f1fc6" + "reference": "308728eae8d90412d850c155d40b1cfbede549da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/2053eafdf60c2172ee1373d1b9289ba1db7f1fc6", - "reference": "2053eafdf60c2172ee1373d1b9289ba1db7f1fc6", + "url": "https://api.github.com/repos/doctrine/common/zipball/308728eae8d90412d850c155d40b1cfbede549da", + "reference": "308728eae8d90412d850c155d40b1cfbede549da", "shasum": "" }, "require": { @@ -606,7 +607,7 @@ "doctrine/event-manager": "^1.0", "doctrine/inflector": "^1.0", "doctrine/lexer": "^1.0", - "doctrine/persistence": "^1.1", + "doctrine/persistence": "^1.3.3", "doctrine/reflection": "^1.0", "php": "^7.1" }, @@ -666,20 +667,20 @@ "doctrine", "php" ], - "time": "2020-01-10T15:49:25+00:00" + "time": "2020-05-15T05:51:54+00:00" }, { "name": "doctrine/dbal", - "version": "v2.10.1", + "version": "2.10.2", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8" + "reference": "aab745e7b6b2de3b47019da81e7225e14dcfdac8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8", - "reference": "c2b8e6e82732a64ecde1cddf9e1e06cb8556e3d8", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/aab745e7b6b2de3b47019da81e7225e14dcfdac8", + "reference": "aab745e7b6b2de3b47019da81e7225e14dcfdac8", "shasum": "" }, "require": { @@ -691,9 +692,11 @@ "require-dev": { "doctrine/coding-standard": "^6.0", "jetbrains/phpstorm-stubs": "^2019.1", - "phpstan/phpstan": "^0.11.3", + "nikic/php-parser": "^4.4", + "phpstan/phpstan": "^0.12", "phpunit/phpunit": "^8.4.1", - "symfony/console": "^2.0.5|^3.0|^4.0|^5.0" + "symfony/console": "^2.0.5|^3.0|^4.0|^5.0", + "vimeo/psalm": "^3.11" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -758,20 +761,20 @@ "sqlserver", "sqlsrv" ], - "time": "2020-01-04T12:56:21+00:00" + "time": "2020-04-20T17:19:26+00:00" }, { "name": "doctrine/doctrine-bundle", - "version": "2.0.7", + "version": "2.0.8", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "6926771140ee87a823c3b2c72602de9dda4490d3" + "reference": "b0e0deb6e700438401ede433a15a6372d2285202" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/6926771140ee87a823c3b2c72602de9dda4490d3", - "reference": "6926771140ee87a823c3b2c72602de9dda4490d3", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/b0e0deb6e700438401ede433a15a6372d2285202", + "reference": "b0e0deb6e700438401ede433a15a6372d2285202", "shasum": "" }, "require": { @@ -850,7 +853,7 @@ "orm", "persistence" ], - "time": "2020-01-18T11:56:15+00:00" + "time": "2020-04-23T10:52:09+00:00" }, { "name": "doctrine/doctrine-cache-bundle", @@ -1089,33 +1092,38 @@ }, { "name": "doctrine/inflector", - "version": "1.3.1", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "ec3a55242203ffa6a4b27c58176da97ff0a7aec1" + "reference": "4111f6853aea6f28b2b1dcfdde83d12dd3d5e6e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/ec3a55242203ffa6a4b27c58176da97ff0a7aec1", - "reference": "ec3a55242203ffa6a4b27c58176da97ff0a7aec1", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/4111f6853aea6f28b2b1dcfdde83d12dd3d5e6e3", + "reference": "4111f6853aea6f28b2b1dcfdde83d12dd3d5e6e3", "shasum": "" }, "require": { - "php": "^7.1" + "php": "^7.2" }, "require-dev": { - "phpunit/phpunit": "^6.2" + "doctrine/coding-standard": "^7.0", + "phpstan/phpstan": "^0.11", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-strict-rules": "^0.11", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { "psr-4": { - "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector" + "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector", + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" } }, "notification-url": "https://packagist.org/downloads/", @@ -1144,15 +1152,21 @@ "email": "schmittjoh@gmail.com" } ], - "description": "Common String Manipulations with regard to casing and singular/plural rules.", - "homepage": "http://www.doctrine-project.org", + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", "keywords": [ "inflection", - "pluralize", - "singularize", - "string" + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" ], - "time": "2019-10-30T19:59:35+00:00" + "time": "2020-05-09T15:09:09+00:00" }, { "name": "doctrine/instantiator", @@ -1356,16 +1370,16 @@ }, { "name": "doctrine/orm", - "version": "v2.7.0", + "version": "v2.7.2", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "4d763ca4c925f647b248b9fa01b5f47aa3685d62" + "reference": "dafe298ce5d0b995ebe1746670704c0a35868a6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/4d763ca4c925f647b248b9fa01b5f47aa3685d62", - "reference": "4d763ca4c925f647b248b9fa01b5f47aa3685d62", + "url": "https://api.github.com/repos/doctrine/orm/zipball/dafe298ce5d0b995ebe1746670704c0a35868a6a", + "reference": "dafe298ce5d0b995ebe1746670704c0a35868a6a", "shasum": "" }, "require": { @@ -1378,6 +1392,7 @@ "doctrine/instantiator": "^1.3", "doctrine/persistence": "^1.2", "ext-pdo": "*", + "ocramius/package-versions": "^1.2", "php": "^7.1", "symfony/console": "^3.0|^4.0|^5.0" }, @@ -1435,20 +1450,20 @@ "database", "orm" ], - "time": "2019-11-19T08:38:05+00:00" + "time": "2020-03-19T06:41:02+00:00" }, { "name": "doctrine/persistence", - "version": "1.3.6", + "version": "1.3.7", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "5dd3ac5eebef2d0b074daa4440bb18f93132dee4" + "reference": "0af483f91bada1c9ded6c2cfd26ab7d5ab2094e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/5dd3ac5eebef2d0b074daa4440bb18f93132dee4", - "reference": "5dd3ac5eebef2d0b074daa4440bb18f93132dee4", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/0af483f91bada1c9ded6c2cfd26ab7d5ab2094e0", + "reference": "0af483f91bada1c9ded6c2cfd26ab7d5ab2094e0", "shasum": "" }, "require": { @@ -1456,7 +1471,7 @@ "doctrine/cache": "^1.0", "doctrine/collections": "^1.0", "doctrine/event-manager": "^1.0", - "doctrine/reflection": "^1.1", + "doctrine/reflection": "^1.2", "php": "^7.1" }, "conflict": { @@ -1518,20 +1533,20 @@ "orm", "persistence" ], - "time": "2020-01-16T22:06:23+00:00" + "time": "2020-03-21T15:13:52+00:00" }, { "name": "doctrine/reflection", - "version": "v1.1.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/doctrine/reflection.git", - "reference": "bc420ead87fdfe08c03ecc3549db603a45b06d4c" + "reference": "55e71912dfcd824b2fdd16f2d9afe15684cfce79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/reflection/zipball/bc420ead87fdfe08c03ecc3549db603a45b06d4c", - "reference": "bc420ead87fdfe08c03ecc3549db603a45b06d4c", + "url": "https://api.github.com/repos/doctrine/reflection/zipball/55e71912dfcd824b2fdd16f2d9afe15684cfce79", + "reference": "55e71912dfcd824b2fdd16f2d9afe15684cfce79", "shasum": "" }, "require": { @@ -1552,7 +1567,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -1596,7 +1611,7 @@ "reflection", "static" ], - "time": "2020-01-08T19:53:19+00:00" + "time": "2020-03-27T11:06:43+00:00" }, { "name": "edwinhoksberg/php-fcm", @@ -2255,16 +2270,16 @@ }, { "name": "psr/log", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801" + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801", - "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801", + "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", "shasum": "" }, "require": { @@ -2298,7 +2313,7 @@ "psr", "psr-3" ], - "time": "2019-11-01T11:05:21+00:00" + "time": "2020-03-23T09:12:05+00:00" }, { "name": "ralouphie/getallheaders", @@ -2515,16 +2530,16 @@ }, { "name": "symfony/cache", - "version": "v5.0.4", + "version": "v5.0.8", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "4572116c640a6bc9fc0047180fe7f9362e5923fc" + "reference": "0c5f5b1882dc82b255a4bdead4ed3c7738cddc04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/4572116c640a6bc9fc0047180fe7f9362e5923fc", - "reference": "4572116c640a6bc9fc0047180fe7f9362e5923fc", + "url": "https://api.github.com/repos/symfony/cache/zipball/0c5f5b1882dc82b255a4bdead4ed3c7738cddc04", + "reference": "0c5f5b1882dc82b255a4bdead4ed3c7738cddc04", "shasum": "" }, "require": { @@ -2590,7 +2605,7 @@ "caching", "psr6" ], - "time": "2020-01-31T09:13:47+00:00" + "time": "2020-04-28T17:58:55+00:00" }, { "name": "symfony/cache-contracts", @@ -2652,16 +2667,16 @@ }, { "name": "symfony/config", - "version": "v5.0.4", + "version": "v5.0.8", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "7640c6704f56bf64045066bc5d93fd9d664baa63" + "reference": "db1674e1a261148429f123871f30d211992294e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/7640c6704f56bf64045066bc5d93fd9d664baa63", - "reference": "7640c6704f56bf64045066bc5d93fd9d664baa63", + "url": "https://api.github.com/repos/symfony/config/zipball/db1674e1a261148429f123871f30d211992294e7", + "reference": "db1674e1a261148429f123871f30d211992294e7", "shasum": "" }, "require": { @@ -2712,7 +2727,7 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2020-01-04T14:08:26+00:00" + "time": "2020-04-15T15:59:10+00:00" }, { "name": "symfony/console", @@ -2848,16 +2863,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v5.0.4", + "version": "v5.0.8", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "86338f459313525dd95f5a012f8a9ea118002f94" + "reference": "92d8b3bd896a87cdd8aba0a3dd041bc072e8cfba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/86338f459313525dd95f5a012f8a9ea118002f94", - "reference": "86338f459313525dd95f5a012f8a9ea118002f94", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/92d8b3bd896a87cdd8aba0a3dd041bc072e8cfba", + "reference": "92d8b3bd896a87cdd8aba0a3dd041bc072e8cfba", "shasum": "" }, "require": { @@ -2917,20 +2932,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2020-01-31T09:49:43+00:00" + "time": "2020-04-28T17:58:55+00:00" }, { "name": "symfony/doctrine-bridge", - "version": "v4.4.4", + "version": "v4.4.8", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "b8d43116f0e5abef4b7abcbeec81c3b9328ca7b7" + "reference": "642cb1000331b8dc5568587f60aeb299070f9a55" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/b8d43116f0e5abef4b7abcbeec81c3b9328ca7b7", - "reference": "b8d43116f0e5abef4b7abcbeec81c3b9328ca7b7", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/642cb1000331b8dc5568587f60aeb299070f9a55", + "reference": "642cb1000331b8dc5568587f60aeb299070f9a55", "shasum": "" }, "require": { @@ -3011,7 +3026,7 @@ ], "description": "Symfony Doctrine Bridge", "homepage": "https://symfony.com", - "time": "2020-01-23T10:56:47+00:00" + "time": "2020-04-12T16:45:36+00:00" }, { "name": "symfony/error-handler", @@ -3838,16 +3853,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.13.1", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3" + "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f8f0b461be3385e56d6de3dbb5a0df24c0c275e3", - "reference": "f8f0b461be3385e56d6de3dbb5a0df24c0c275e3", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e94c8b1bbe2bc77507a1056cdb06451c75b427f9", + "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9", "shasum": "" }, "require": { @@ -3859,7 +3874,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.13-dev" + "dev-master": "1.17-dev" } }, "autoload": { @@ -3892,7 +3907,7 @@ "polyfill", "portable" ], - "time": "2019-11-27T13:56:44+00:00" + "time": "2020-05-12T16:14:59+00:00" }, { "name": "symfony/polyfill-intl-idn", @@ -3958,16 +3973,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.13.1", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f" + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7b4aab9743c30be783b73de055d24a39cf4b954f", - "reference": "7b4aab9743c30be783b73de055d24a39cf4b954f", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c", + "reference": "fa79b11539418b02fc5e1897267673ba2c19419c", "shasum": "" }, "require": { @@ -3979,7 +3994,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.13-dev" + "dev-master": "1.17-dev" } }, "autoload": { @@ -4013,7 +4028,7 @@ "portable", "shim" ], - "time": "2019-11-27T14:18:11+00:00" + "time": "2020-05-12T16:47:27+00:00" }, { "name": "symfony/polyfill-php72", @@ -5222,16 +5237,16 @@ }, { "name": "symfony/var-exporter", - "version": "v5.0.4", + "version": "v5.0.8", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "960f9ac0fdbd642461ed29d7717aeb2a94d428b9" + "reference": "5d18811da9e1ae2bb86b0a97fb2d784e27ffd59f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/960f9ac0fdbd642461ed29d7717aeb2a94d428b9", - "reference": "960f9ac0fdbd642461ed29d7717aeb2a94d428b9", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/5d18811da9e1ae2bb86b0a97fb2d784e27ffd59f", + "reference": "5d18811da9e1ae2bb86b0a97fb2d784e27ffd59f", "shasum": "" }, "require": { @@ -5278,7 +5293,7 @@ "instantiate", "serialize" ], - "time": "2020-01-04T14:08:26+00:00" + "time": "2020-04-15T15:59:10+00:00" }, { "name": "symfony/web-profiler-bundle", diff --git a/config/acl.yaml b/config/acl.yaml index 9d9fba7c..abd73118 100644 --- a/config/acl.yaml +++ b/config/acl.yaml @@ -420,3 +420,12 @@ access_keys: label: Update - id: static_content.delete label: Delete + + - id: analytics + label: Analytics + acls: + - id: analytics.menu + label: Menu + - id: analytics.forecast + label: Forecasting + diff --git a/config/menu.yaml b/config/menu.yaml index f04dd4f9..246eda01 100644 --- a/config/menu.yaml +++ b/config/menu.yaml @@ -185,3 +185,12 @@ main_menu: acl: review.list label: Reviews parent: partner + + - id: analytics + acl: analytics.menu + label: Analytics + icon: flaticon-graphic + - id: analytics_forecast_form + acl: analytics.forecast + label: Forecasting + parent: analytics diff --git a/config/routes/analytics.yaml b/config/routes/analytics.yaml new file mode 100644 index 00000000..65314662 --- /dev/null +++ b/config/routes/analytics.yaml @@ -0,0 +1,11 @@ +# analytics + +analytics_forecast_form: + path: /analytics/forecast + controller: App\Controller\AnalyticsController::forecastForm + methods: [GET] + +analytics_forecast_submit: + path: /analytics/forecast + controller: App\Controller\AnalyticsController::forecastSubmit + methods: [POST] diff --git a/src/Controller/AnalyticsController.php b/src/Controller/AnalyticsController.php new file mode 100644 index 00000000..8dfbddde --- /dev/null +++ b/src/Controller/AnalyticsController.php @@ -0,0 +1,253 @@ +getRepository(Hub::class)->findAll(); + + $hub_list = []; + foreach ($all_hubs as $hub) + { + $hub_list[$hub->getID()] = $hub->getName() . ' - ' . $hub->getBranch(); + } + + $params = [ + 'hub_list' => $hub_list, + 'default_hubs' => $hub_ids, + ]; + + return $this->render('analytics/forecast_form.html.twig', $params); + } + + + /** + * @Menu(selected="analytics_forecast") + * @IsGranted("analytics.forecast") + */ + public function forecastSubmit(EntityManagerInterface $em, Request $req) + { + $hub_list = $req->request->get('hub_ids', []); + $distances = $req->request->get('distances', []); + $today = DateTime::createFromFormat('d M Y', $req->request->get('date')); + error_log(print_r($hub_list, true)); + + // $hub_list = [ 6, 4, 36, 7, 8, 126, 127, 18, 12, 9, 60, 10, 21, 135 ]; + + $hub_data = []; + $hub_coverage = []; + foreach ($hub_list as $key => $hub_id) + { + $hub = $em->getRepository(Hub::class)->find($hub_id); + $coords = $hub->getCoordinates(); + + $dist = $distances[$key]; + $hub_data[$hub_id] = $this->generateHubData($em, $hub, $dist, $today); + + $hub_coverage[] = [ + 'longitude' => $coords->getLongitude(), + 'latitude' => $coords->getLatitude(), + 'distance' => $dist, + ]; + } + + $params = [ + 'date' => $today, + 'hub_list' => $hub_data, + 'hub_coverage' => $hub_coverage, + ]; + + return $this->render('analytics/forecast_submit.html.twig', $params); + } + + protected function generateHubData($em, $hub, $distance_limit, DateTime $today) + { + $date_start = DateTime::createFromFormat('Y-m-d H:i:s', '2018-01-01 00:00:00'); + $date_end = new DateTime(); + + // get hub to analyze + // $hub = $em->getRepository(Hub::class)->find($hub_id); + $conn = $em->getConnection(); + + // get job order data + $jos = $this->generateJobOrderData($conn, $hub, $distance_limit); + + // initialize counters + $c_weekday = []; + $c_day = []; + + // counter to check instances of hourly weekdays, so we can get average + $c_week_count = []; + + // loop through job orders + foreach ($jos as $jo) + { + $date = DateTime::createFromFormat('Y-m-d H:i:s', $jo['date_schedule']); + $year = $date->format('Y'); + $month = $date->format('m'); + $day = $date->format('d'); + $weekday = $date->format('l'); + $hour = $date->format('H'); + $week = $date->format('W'); + + // year day + if (!isset($c_day[$year][$month][$day])) + $c_day[$year][$month][$day] = 0; + $c_day[$year][$month][$day]++; + + // weekday + if (!isset($c_weekday[$year][$month][$weekday][$hour])) + { + $c_weekday[$year][$month][$weekday][$hour]['total'] = 0; + $c_weekday[$year][$month][$weekday][$hour]['count'] = 0; + } + + $c_weekday[$year][$month][$weekday][$hour]['total']++; + + if (!isset($c_week_count[$year][$month][$week][$weekday][$hour])) + { + // error_log('week detected - ' . $week); + $c_week_count[$year][$month][$week][$weekday][$hour] = 1; + $c_weekday[$year][$month][$weekday][$hour]['count']++; + } + } + + // error_log(print_r($c_weekday, true)); + + $chart_year = $this->generateYearData($date_start, $date_end, $c_day); + $chart_weekday = $this->generateWeekdayData($c_weekday, $today); + + // error_log(print_r($chart_weekday, true)); + + $params = [ + 'id' => $hub->getID(), + 'label' => $hub->getName(), + 'data_year' => $chart_year, + 'data_weekday' => $chart_weekday, + ]; + + return $params; + } + + protected function generateJobOrderData($conn, $hub, $distance_limit) + { + $hub_coord = $hub->getCoordinates(); + + // create query + // formula to convert to km is 111195 * st_distance + $sql = "select id, round(st_distance(coordinates, Point(:lng, :lat)) * 111195) as dist, date_schedule from job_order where st_distance(coordinates, Point(:lng, :lat)) * 111195 <= :distance_limit and status <> 'cancelled' order by date_schedule asc"; + $stmt = $conn->prepare($sql); + $stmt->bindValue('lng', $hub_coord->getLongitude()); + $stmt->bindValue('lat', $hub_coord->getLatitude()); + $stmt->bindValue('distance_limit', $distance_limit); + // $stmt->bindValue('date_start', $date_start->format('Y-m-d H:i:s')); + // $stmt->bindValue('date_end', $date_end->format('Y-m-d H:i:s')); + $stmt->execute(); + $jos = $stmt->fetchAll(); + + error_log(count($jos)); + + return $jos; + } + + protected function generateYearData($date_start, $date_end, $c_day) + { + $res_year = []; + $date_loop = clone $date_start; + for (; $date_loop <= $date_end; $date_loop->add(new DateInterval('P1D'))) + { + $year = $date_loop->format('Y'); + $month = $date_loop->format('m'); + $day = $date_loop->format('d'); + $year_field = 'y' . $date_loop->format('Y'); + $id = $date_loop->format('m-d'); + + // NOTE: toss aside feb 29 + // TODO: handle april 29 + if ($id == '02-29') + continue; + + if (!isset($res_year[$id][$year_field])) + { + $res_year[$id]['date'] = $date_loop->format('M j'); + $res_year[$id][$year_field] = 0; + } + + if (isset($c_day[$year][$month][$day])) + $res_year[$id][$year_field] = $c_day[$year][$month][$day]; + } + + // error_log(print_r($res_year, true)); + + $chart_year = []; + foreach ($res_year as $day => $day_data) + $chart_year[] = $day_data; + + return $chart_year; + } + + protected function generateWeekdayData($all_weekday_data, $today) + { + $data = []; + + // build hours + $hours = []; + for ($i = 0; $i < 24; $i++) + $hours[] = sprintf('%02d', $i); + + $month = $today->format('m'); + $weekday = $today->format('l'); + + $year_data = []; + foreach ($all_weekday_data as $year => $year_data) + { + // go through the hours + foreach ($hours as $hour) + { + $id = $hour + 0; + if (!isset($data[$id])) + $data[$id] = [ + 'hour' => $hour, + ]; + + // get hour data + if (isset($year_data[$month][$weekday][$hour])) + { + $year_id = 'y' . $year; + + $data[$id][$year_id] = $year_data[$month][$weekday][$hour]['total']; + $data[$id][$year_id . '_count'] = $year_data[$month][$weekday][$hour]['count']; + $data[$id][$year_id . '_average'] = ceil($year_data[$month][$weekday][$hour]['total'] / $year_data[$month][$weekday][$hour]['count']); + } + } + } + + return $data; + } +} diff --git a/templates/analytics/forecast_form.html.twig b/templates/analytics/forecast_form.html.twig new file mode 100644 index 00000000..5dd51e7f --- /dev/null +++ b/templates/analytics/forecast_form.html.twig @@ -0,0 +1,96 @@ +{% extends 'base.html.twig' %} + +{% block body %} + +
+
+
+

Analytics - Forecasting

+
+
+
+ +
+ +
+
+
+
+
+
+ + + +

+ Forecasting Variables +

+
+
+
+
+ +
+
+
+ +
+ + + + +
+ +
+
+ + {% for hub_id in default_hubs %} +
+
+ + +
+
+ + +
+
+ {% endfor %} +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+{% endblock %} + + +{% block scripts %} + + +{% endblock %} diff --git a/templates/analytics/forecast_submit.html.twig b/templates/analytics/forecast_submit.html.twig new file mode 100644 index 00000000..3951a231 --- /dev/null +++ b/templates/analytics/forecast_submit.html.twig @@ -0,0 +1,138 @@ +{% extends 'base.html.twig' %} + +{% block stylesheets %} + +{% endblock %} + +{% block body %} + +
+
+
+

Analytics Forecasting - {{ date | date('M - l') }}

+
+
+
+ +
+ +
+
+ + {% for hub in hub_list %} +
+
+
+
+
+
+

+ {{ hub.label }} +

+
+
+
+ +
+
+ +
+
+
+
+
+ {% endfor %} +
+{% endblock %} + +{% block scripts %} + + + + + +{% endblock %}