Resolve "Entity logging service / bundle" #1208
23 changed files with 821 additions and 93 deletions
|
|
@ -14,9 +14,15 @@ APP_SECRET=b344cd6cd151ae1d61403ed55806c5ce
|
||||||
# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
|
# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
|
||||||
# Configure your db driver and server_version in config/packages/doctrine.yaml
|
# Configure your db driver and server_version in config/packages/doctrine.yaml
|
||||||
DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name
|
DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name
|
||||||
|
LOGGING_DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_logging
|
||||||
###< doctrine/doctrine-bundle ###
|
###< doctrine/doctrine-bundle ###
|
||||||
GMAPS_API_KEY=insert_gmapsapikey_here
|
GMAPS_API_KEY=insert_gmapsapikey_here
|
||||||
|
|
||||||
|
# influxdb
|
||||||
|
INFLUXDB_HOST=127.0.0.1
|
||||||
|
INFLUXDB_PORT=8086
|
||||||
|
INFLUXDB_DB=logging_db
|
||||||
|
|
||||||
# rising tide sms gateway
|
# rising tide sms gateway
|
||||||
RT_USER=rt_user
|
RT_USER=rt_user
|
||||||
RT_PASS=rt_pass
|
RT_PASS=rt_pass
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
"data-dog/audit-bundle": "^0.1.10",
|
"data-dog/audit-bundle": "^0.1.10",
|
||||||
"edwinhoksberg/php-fcm": "^1.0",
|
"edwinhoksberg/php-fcm": "^1.0",
|
||||||
"guzzlehttp/guzzle": "^6.3",
|
"guzzlehttp/guzzle": "^6.3",
|
||||||
|
"influxdb/influxdb-php": "^1.15",
|
||||||
"predis/predis": "^1.1",
|
"predis/predis": "^1.1",
|
||||||
"sensio/framework-extra-bundle": "^5.1",
|
"sensio/framework-extra-bundle": "^5.1",
|
||||||
"setasign/fpdf": "^1.8",
|
"setasign/fpdf": "^1.8",
|
||||||
|
|
|
||||||
65
composer.lock
generated
65
composer.lock
generated
|
|
@ -1,10 +1,10 @@
|
||||||
{
|
{
|
||||||
"_readme": [
|
"_readme": [
|
||||||
"This file locks the dependencies of your project to a known state",
|
"This file locks the dependencies of your project to a known state",
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "b101ecfbc1f6f2270f0e8ad326035b7e",
|
"content-hash": "cbde0e7f1fa49277c6196a3c677c3a51",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "catalyst/auth-bundle",
|
"name": "catalyst/auth-bundle",
|
||||||
|
|
@ -1836,6 +1836,67 @@
|
||||||
],
|
],
|
||||||
"time": "2019-07-01T23:21:34+00:00"
|
"time": "2019-07-01T23:21:34+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "influxdb/influxdb-php",
|
||||||
|
"version": "1.15.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/influxdata/influxdb-php.git",
|
||||||
|
"reference": "bf3415f81962e1ab8c939bc1a08a85f500bead35"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/influxdata/influxdb-php/zipball/bf3415f81962e1ab8c939bc1a08a85f500bead35",
|
||||||
|
"reference": "bf3415f81962e1ab8c939bc1a08a85f500bead35",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"guzzlehttp/guzzle": "^6.0",
|
||||||
|
"php": "^5.5 || ^7.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^5.7"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"ext-curl": "Curl extension, needed for Curl driver",
|
||||||
|
"stefanotorresi/influxdb-php-async": "An asyncronous client for InfluxDB, implemented via ReactPHP."
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"InfluxDB\\": "src/InfluxDB"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Gianluca Arbezzano",
|
||||||
|
"email": "gianarb92@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Daniel Martinez",
|
||||||
|
"email": "danimartcas@hotmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Stephen Hoogendijk",
|
||||||
|
"email": "stephen@tca0.nl"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "InfluxDB client library for PHP",
|
||||||
|
"keywords": [
|
||||||
|
"client",
|
||||||
|
"influxdata",
|
||||||
|
"influxdb",
|
||||||
|
"influxdb class",
|
||||||
|
"influxdb client",
|
||||||
|
"influxdb library",
|
||||||
|
"time series"
|
||||||
|
],
|
||||||
|
"time": "2019-05-30T00:15:14+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "jdorn/sql-formatter",
|
"name": "jdorn/sql-formatter",
|
||||||
"version": "v1.2.17",
|
"version": "v1.2.17",
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,10 @@ access_keys:
|
||||||
label: Super Admin Role
|
label: Super Admin Role
|
||||||
- id: user.profile
|
- id: user.profile
|
||||||
label: User Profile
|
label: User Profile
|
||||||
|
- id: user.logs
|
||||||
|
label: User Logs
|
||||||
|
- id: user.change.history
|
||||||
|
label: User Change History
|
||||||
- id: role
|
- id: role
|
||||||
label: Role Access
|
label: Role Access
|
||||||
acls:
|
acls:
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ parameters:
|
||||||
app_access_key: 'access_keys'
|
app_access_key: 'access_keys'
|
||||||
cvu_brand_id: "%env(CVU_BRAND_ID)%"
|
cvu_brand_id: "%env(CVU_BRAND_ID)%"
|
||||||
country_code: "%env(COUNTRY_CODE)%"
|
country_code: "%env(COUNTRY_CODE)%"
|
||||||
|
log_db: "%env(INFLUXDB_DB)%"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# default configuration for services in *this* file
|
# default configuration for services in *this* file
|
||||||
|
|
@ -202,6 +203,12 @@ services:
|
||||||
#App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Bing"
|
#App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Bing"
|
||||||
App\Service\GISManagerInterface: "@App\\Service\\GISManager\\OpenStreet"
|
App\Service\GISManagerInterface: "@App\\Service\\GISManager\\OpenStreet"
|
||||||
#App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Google"
|
#App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Google"
|
||||||
|
|
||||||
|
# influxdb
|
||||||
|
InfluxDB\Client:
|
||||||
|
arguments: ['%env(INFLUXDB_HOST)%', '%env(INFLUXDB_PORT)%']
|
||||||
|
InfluxDB\Database:
|
||||||
|
arguments: ['%env(INFLUXDB_DB)%', "@InfluxDB\\Client"]
|
||||||
|
|
||||||
App\EventListener\JobOrderActiveCacheListener:
|
App\EventListener\JobOrderActiveCacheListener:
|
||||||
arguments:
|
arguments:
|
||||||
|
|
@ -229,6 +236,28 @@ services:
|
||||||
$loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%"
|
$loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%"
|
||||||
$status_key: "%env(STATUS_RIDER_KEY)%"
|
$status_key: "%env(STATUS_RIDER_KEY)%"
|
||||||
|
|
||||||
|
App\EventListener\JobOrderStatusListener:
|
||||||
|
arguments:
|
||||||
|
$wh: "@App\\Service\\WarrantyHandler"
|
||||||
|
tags:
|
||||||
|
- name: 'doctrine.orm.entity_listener'
|
||||||
|
event: 'postUpdate'
|
||||||
|
entity: 'App\Entity\JobOrder'
|
||||||
|
- name: 'doctrine.orm.entity_listener'
|
||||||
|
event: 'postPersist'
|
||||||
|
entity: 'App\Entity\JobOrder'
|
||||||
|
|
||||||
|
App\EventListener\EntityListener:
|
||||||
|
arguments:
|
||||||
|
$token_storage: "@security.token_storage"
|
||||||
|
$log_db: "@InfluxDB\\Database"
|
||||||
|
$entities: ['App\Entity\User', 'App\Entity\Role', 'App\Entity\Partner']
|
||||||
|
tags:
|
||||||
|
- name: 'doctrine.event_listener'
|
||||||
|
event: 'onFlush'
|
||||||
|
- name: 'doctrine.event_listener'
|
||||||
|
event: 'postPersist'
|
||||||
|
|
||||||
# API logging
|
# API logging
|
||||||
App\EventSubscriber\LogSubscriber:
|
App\EventSubscriber\LogSubscriber:
|
||||||
arguments:
|
arguments:
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ doctrine:
|
||||||
point: CrEOF\Spatial\DBAL\Types\Geometry\PointType
|
point: CrEOF\Spatial\DBAL\Types\Geometry\PointType
|
||||||
polygon: CrEOF\Spatial\DBAL\Types\Geometry\PolygonType
|
polygon: CrEOF\Spatial\DBAL\Types\Geometry\PolygonType
|
||||||
linestring: CrEOF\Spatial\DBAL\Types\Geometry\LineStringType
|
linestring: CrEOF\Spatial\DBAL\Types\Geometry\LineStringType
|
||||||
multipolygon: CrEOF\Spatial\DBAL\Types\Geometry\MultiPolygonType
|
|
||||||
orm:
|
orm:
|
||||||
auto_generate_proxy_classes: '%kernel.debug%'
|
auto_generate_proxy_classes: '%kernel.debug%'
|
||||||
naming_strategy: doctrine.orm.naming_strategy.underscore
|
naming_strategy: doctrine.orm.naming_strategy.underscore
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ parameters:
|
||||||
app_access_key: 'access_keys'
|
app_access_key: 'access_keys'
|
||||||
cvu_brand_id: "%env(CVU_BRAND_ID)%"
|
cvu_brand_id: "%env(CVU_BRAND_ID)%"
|
||||||
country_code: "%env(COUNTRY_CODE)%"
|
country_code: "%env(COUNTRY_CODE)%"
|
||||||
|
log_db: "%env(INFLUXDB_DB)%"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# default configuration for services in *this* file
|
# default configuration for services in *this* file
|
||||||
|
|
@ -201,7 +202,13 @@ services:
|
||||||
#App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Bing"
|
#App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Bing"
|
||||||
App\Service\GISManagerInterface: "@App\\Service\\GISManager\\OpenStreet"
|
App\Service\GISManagerInterface: "@App\\Service\\GISManager\\OpenStreet"
|
||||||
#App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Google"
|
#App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Google"
|
||||||
|
|
||||||
|
# influxdb
|
||||||
|
InfluxDB\Client:
|
||||||
|
arguments: ['%env(INFLUXDB_HOST)%', '%env(INFLUXDB_PORT)%']
|
||||||
|
InfluxDB\Database:
|
||||||
|
arguments: ['%env(INFLUXDB_DB)%', "@InfluxDB\\Client"]
|
||||||
|
|
||||||
App\EventListener\JobOrderActiveCacheListener:
|
App\EventListener\JobOrderActiveCacheListener:
|
||||||
arguments:
|
arguments:
|
||||||
$jo_cache: "@App\\Service\\JobOrderCache"
|
$jo_cache: "@App\\Service\\JobOrderCache"
|
||||||
|
|
@ -228,6 +235,28 @@ services:
|
||||||
$loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%"
|
$loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%"
|
||||||
$status_key: "%env(STATUS_RIDER_KEY)%"
|
$status_key: "%env(STATUS_RIDER_KEY)%"
|
||||||
|
|
||||||
|
App\EventListener\JobOrderStatusListener:
|
||||||
|
arguments:
|
||||||
|
$wh: "@App\\Service\\WarrantyHandler"
|
||||||
|
tags:
|
||||||
|
- name: 'doctrine.orm.entity_listener'
|
||||||
|
event: 'postUpdate'
|
||||||
|
entity: 'App\Entity\JobOrder'
|
||||||
|
- name: 'doctrine.orm.entity_listener'
|
||||||
|
event: 'postPersist'
|
||||||
|
entity: 'App\Entity\JobOrder'
|
||||||
|
|
||||||
|
App\EventListener\EntityListener:
|
||||||
|
arguments:
|
||||||
|
$token_storage: "@security.token_storage"
|
||||||
|
$log_db: "@InfluxDB\\Database"
|
||||||
|
$entities: ['App\Entity\User', 'App\Entity\Role', 'App\Entity\Partner']
|
||||||
|
tags:
|
||||||
|
- name: 'doctrine.event_listener'
|
||||||
|
event: 'onFlush'
|
||||||
|
- name: 'doctrine.event_listener'
|
||||||
|
event: 'postPersist'
|
||||||
|
|
||||||
# inventory manager
|
# inventory manager
|
||||||
App\Service\InventoryManager:
|
App\Service\InventoryManager:
|
||||||
arguments:
|
arguments:
|
||||||
|
|
|
||||||
|
|
@ -41,3 +41,23 @@ user_profile_submit:
|
||||||
path: /profile
|
path: /profile
|
||||||
controller: App\Controller\UserController::profileSubmit
|
controller: App\Controller\UserController::profileSubmit
|
||||||
methods: [POST]
|
methods: [POST]
|
||||||
|
|
||||||
|
user_view_logs_form:
|
||||||
|
path: /users/{id}/logs
|
||||||
|
controller: App\Controller\UserController::viewLogsForm
|
||||||
|
methods: [GET]
|
||||||
|
|
||||||
|
user_view_logs:
|
||||||
|
path: /user/{id}/logs
|
||||||
|
controller: App\Controller\UserController::getAuditLogs
|
||||||
|
methods: [POST]
|
||||||
|
|
||||||
|
user_view_change_history_form:
|
||||||
|
path: /users/{id}/change-history
|
||||||
|
controller: App\Controller\UserController::viewChangeHistoryForm
|
||||||
|
methods: [GET]
|
||||||
|
|
||||||
|
user_view_change_history:
|
||||||
|
path: /user/{id}/change-history
|
||||||
|
controller: App\Controller\UserController::getChangeHistory
|
||||||
|
methods: [POST]
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ parameters:
|
||||||
app_access_key: 'access_keys'
|
app_access_key: 'access_keys'
|
||||||
cvu_brand_id: "%env(CVU_BRAND_ID)%"
|
cvu_brand_id: "%env(CVU_BRAND_ID)%"
|
||||||
country_code: "%env(COUNTRY_CODE)%"
|
country_code: "%env(COUNTRY_CODE)%"
|
||||||
|
log_db: "%env(INFLUXDB_DB)%"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# default configuration for services in *this* file
|
# default configuration for services in *this* file
|
||||||
|
|
@ -21,7 +22,7 @@ services:
|
||||||
public: false # Allows optimizing the container by removing unused services; this also means
|
public: false # Allows optimizing the container by removing unused services; this also means
|
||||||
# fetching services directly from the container via $container->get() won't work.
|
# fetching services directly from the container via $container->get() won't work.
|
||||||
# The best practice is to be explicit about your dependencies anyway.
|
# The best practice is to be explicit about your dependencies anyway.
|
||||||
|
|
||||||
# makes classes in src/ available to be used as services
|
# makes classes in src/ available to be used as services
|
||||||
# this creates a service per class whose id is the fully-qualified class name
|
# this creates a service per class whose id is the fully-qualified class name
|
||||||
App\:
|
App\:
|
||||||
|
|
@ -201,6 +202,12 @@ services:
|
||||||
#App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Bing"
|
#App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Bing"
|
||||||
App\Service\GISManagerInterface: "@App\\Service\\GISManager\\OpenStreet"
|
App\Service\GISManagerInterface: "@App\\Service\\GISManager\\OpenStreet"
|
||||||
#App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Google"
|
#App\Service\GISManagerInterface: "@App\\Service\\GISManager\\Google"
|
||||||
|
|
||||||
|
# influxdb
|
||||||
|
InfluxDB\Client:
|
||||||
|
arguments: ['%env(INFLUXDB_HOST)%', '%env(INFLUXDB_PORT)%']
|
||||||
|
InfluxDB\Database:
|
||||||
|
arguments: ['%env(INFLUXDB_DB)%', "@InfluxDB\\Client"]
|
||||||
|
|
||||||
App\EventListener\JobOrderActiveCacheListener:
|
App\EventListener\JobOrderActiveCacheListener:
|
||||||
arguments:
|
arguments:
|
||||||
|
|
@ -228,6 +235,28 @@ services:
|
||||||
$loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%"
|
$loc_key: "%env(LOCATION_RIDER_ACTIVE_KEY)%"
|
||||||
$status_key: "%env(STATUS_RIDER_KEY)%"
|
$status_key: "%env(STATUS_RIDER_KEY)%"
|
||||||
|
|
||||||
|
App\EventListener\JobOrderStatusListener:
|
||||||
|
arguments:
|
||||||
|
$wh: "@App\\Service\\WarrantyHandler"
|
||||||
|
tags:
|
||||||
|
- name: 'doctrine.orm.entity_listener'
|
||||||
|
event: 'postUpdate'
|
||||||
|
entity: 'App\Entity\JobOrder'
|
||||||
|
- name: 'doctrine.orm.entity_listener'
|
||||||
|
event: 'postPersist'
|
||||||
|
entity: 'App\Entity\JobOrder'
|
||||||
|
|
||||||
|
App\EventListener\EntityListener:
|
||||||
|
arguments:
|
||||||
|
$token_storage: "@security.token_storage"
|
||||||
|
$log_db: "@InfluxDB\\Database"
|
||||||
|
$entities: ['App\Entity\User', 'App\Entity\Role', 'App\Entity\Partner']
|
||||||
|
tags:
|
||||||
|
- name: 'doctrine.event_listener'
|
||||||
|
event: 'onFlush'
|
||||||
|
- name: 'doctrine.event_listener'
|
||||||
|
event: 'postPersist'
|
||||||
|
|
||||||
# inventory manager
|
# inventory manager
|
||||||
App\Service\InventoryManager:
|
App\Service\InventoryManager:
|
||||||
arguments:
|
arguments:
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
|
|
||||||
use Catalyst\MenuBundle\Annotation\Menu;
|
use Catalyst\MenuBundle\Annotation\Menu;
|
||||||
|
|
||||||
|
use InfluxDB\Client;
|
||||||
|
|
||||||
class UserController extends Controller
|
class UserController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -484,4 +486,67 @@ class UserController extends Controller
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Menu(selected="user_list")
|
||||||
|
*/
|
||||||
|
public function viewLogsForm($id)
|
||||||
|
{
|
||||||
|
$this->denyAccessUnlessGranted('user.logs', null, 'No access.');
|
||||||
|
|
||||||
|
$params['id'] = $id;
|
||||||
|
|
||||||
|
// response
|
||||||
|
return $this->render('user/audit.log.html.twig', $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAuditLogs(Client $client, $id)
|
||||||
|
{
|
||||||
|
// fetch database
|
||||||
|
$log_db = $this->getParameter('log_db');
|
||||||
|
$database = $client->selectDB($log_db);
|
||||||
|
|
||||||
|
// query will return a resultset object
|
||||||
|
$query_string = 'SELECT * FROM entity_log WHERE "user" = ' . $id;
|
||||||
|
$result = $database->query($query_string);
|
||||||
|
|
||||||
|
// get the points from the resultset, which is an array
|
||||||
|
$points = $result->getPoints();
|
||||||
|
|
||||||
|
return $this->json([
|
||||||
|
'data' => $points,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Menu(selected="user_list")
|
||||||
|
*/
|
||||||
|
public function viewChangeHistoryForm($id)
|
||||||
|
{
|
||||||
|
$this->denyAccessUnlessGranted('user.change.history', null, 'No access.');
|
||||||
|
|
||||||
|
$params['id'] = $id;
|
||||||
|
|
||||||
|
// response
|
||||||
|
return $this->render('user/change.history.log.html.twig', $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getChangeHistory(Client $client, $id)
|
||||||
|
{
|
||||||
|
// fetch database
|
||||||
|
$log_db = $this->getParameter('log_db');
|
||||||
|
$database = $client->selectDB($log_db);
|
||||||
|
|
||||||
|
// query will return a resultset object
|
||||||
|
$query_string = 'SELECT * FROM entity_log WHERE entity_id = \'' . $id . '\'';
|
||||||
|
$result = $database->query($query_string);
|
||||||
|
|
||||||
|
// get the points from the resultset, which is an array
|
||||||
|
$points = $result->getPoints();
|
||||||
|
|
||||||
|
return $this->json([
|
||||||
|
'data' => $points,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
src/Entity/AuditableEntity.php
Normal file
8
src/Entity/AuditableEntity.php
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
interface AuditableEntity
|
||||||
|
{
|
||||||
|
public function fieldDump();
|
||||||
|
}
|
||||||
|
|
@ -14,7 +14,7 @@ use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||||
* @UniqueEntity("id")
|
* @UniqueEntity("id")
|
||||||
* @UniqueEntity("name")
|
* @UniqueEntity("name")
|
||||||
*/
|
*/
|
||||||
class Role extends BaseRole
|
class Role extends BaseRole implements AuditableEntity
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @ORM\ManyToMany(targetEntity="User", mappedBy="roles", fetch="EXTRA_LAZY")
|
* @ORM\ManyToMany(targetEntity="User", mappedBy="roles", fetch="EXTRA_LAZY")
|
||||||
|
|
@ -25,4 +25,18 @@ class Role extends BaseRole
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function fieldDump()
|
||||||
|
{
|
||||||
|
// get all fields and their values into an array
|
||||||
|
$field_array = [
|
||||||
|
'id' => $this->getID(),
|
||||||
|
'name' => $this->getName(),
|
||||||
|
'acl_attributes' => $this->getACLAttributes(),
|
||||||
|
];
|
||||||
|
|
||||||
|
$fields = json_encode($field_array);
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ use Serializable;
|
||||||
* @UniqueEntity("username")
|
* @UniqueEntity("username")
|
||||||
* @UniqueEntity("email")
|
* @UniqueEntity("email")
|
||||||
*/
|
*/
|
||||||
class User extends BaseUser implements Serializable
|
class User extends BaseUser implements Serializable, AuditableEntity
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @ORM\Id
|
* @ORM\Id
|
||||||
|
|
@ -309,4 +309,24 @@ class User extends BaseUser implements Serializable
|
||||||
{
|
{
|
||||||
return $this->partners_created;
|
return $this->partners_created;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function fieldDump()
|
||||||
|
{
|
||||||
|
// get all fields and their values into an array
|
||||||
|
$field_array = [
|
||||||
|
'id' => $this->getID(),
|
||||||
|
'username' => $this->getUsername(),
|
||||||
|
'password' => $this->getPassword(),
|
||||||
|
'first_name' => $this->getFirstName(),
|
||||||
|
'last_name' => $this->getLastName(),
|
||||||
|
'email' => $this->getEmail(),
|
||||||
|
'contact_number' => $this->getContactNumber(),
|
||||||
|
'roles' => $this->getRoles(),
|
||||||
|
'hubs' => $this->getHubs(),
|
||||||
|
];
|
||||||
|
|
||||||
|
$fields = json_encode($field_array);
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
194
src/EventListener/EntityListener.php
Normal file
194
src/EventListener/EntityListener.php
Normal file
|
|
@ -0,0 +1,194 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\EventListener;
|
||||||
|
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||||
|
|
||||||
|
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
|
||||||
|
use Doctrine\ORM\Event\OnFlushEventArgs;
|
||||||
|
|
||||||
|
use InfluxDB\Point;
|
||||||
|
|
||||||
|
use App\Entity\AuditableEntity;
|
||||||
|
|
||||||
|
class EntityListener
|
||||||
|
{
|
||||||
|
protected $token_storage;
|
||||||
|
protected $log_db;
|
||||||
|
protected $entities;
|
||||||
|
|
||||||
|
public function __construct(TokenStorageInterface $token_storage, $log_db,
|
||||||
|
$entities)
|
||||||
|
{
|
||||||
|
$this->token_storage = $token_storage;
|
||||||
|
$this->log_db = $log_db;
|
||||||
|
|
||||||
|
// reconstruct entity array with class name as keys
|
||||||
|
// with values of true
|
||||||
|
foreach ($entities as $entity)
|
||||||
|
{
|
||||||
|
$this->entities[$entity] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function postPersist(LifecycleEventArgs $args)
|
||||||
|
{
|
||||||
|
$object = $args->getObject();
|
||||||
|
|
||||||
|
$object_class = get_class($object);
|
||||||
|
|
||||||
|
if (isset($this->entities[$object_class]))
|
||||||
|
{
|
||||||
|
if ($object instanceof AuditableEntity)
|
||||||
|
{
|
||||||
|
// get user id for logging
|
||||||
|
$user = $this->token_storage->getToken()->getUser();
|
||||||
|
$user_id = $user->getID();
|
||||||
|
|
||||||
|
// get entity name
|
||||||
|
//$obj_class = preg_replace('/.*\\\\/', '', $object_class);
|
||||||
|
|
||||||
|
// get fields of object
|
||||||
|
$fields = $object->fieldDump();
|
||||||
|
|
||||||
|
$this->writeToLogDB($object_class, $object->getID(), 'create', $fields, $user_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error_log($object_class . ' does not implement the AuditableEntity interface.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onFlush(OnFlushEventArgs $args)
|
||||||
|
{
|
||||||
|
$em = $args->getEntityManager();
|
||||||
|
|
||||||
|
// get date time of event for logging
|
||||||
|
//$event_time = new DateTime();
|
||||||
|
|
||||||
|
// get user for logging
|
||||||
|
$user = $this->token_storage->getToken()->getUser();
|
||||||
|
$user_id = $user->getID();
|
||||||
|
|
||||||
|
$field_changes = [];
|
||||||
|
|
||||||
|
$unit_of_work = $em->getUnitOfWork();
|
||||||
|
$created_entities = $unit_of_work->getScheduledEntityInsertions();
|
||||||
|
$deleted_entities = $unit_of_work->getScheduledEntityDeletions();
|
||||||
|
$updated_entities = $unit_of_work->getScheduledEntityUpdates();
|
||||||
|
$updated_collections = $unit_of_work->getScheduledCollectionUpdates();
|
||||||
|
$deleted_collections = $unit_of_work->getScheduledCollectionDeletions();
|
||||||
|
|
||||||
|
// get updated fields. This doesn't include lists of other entities.
|
||||||
|
foreach ($updated_entities as $updated_entity)
|
||||||
|
{
|
||||||
|
// check if entity is in list of entities to log
|
||||||
|
$entity_class = get_class($updated_entity);
|
||||||
|
if (isset($this->entities[$entity_class]))
|
||||||
|
{
|
||||||
|
if ($updated_entity instanceof AuditableEntity)
|
||||||
|
{
|
||||||
|
// get entity name
|
||||||
|
//$obj_class = preg_replace('/.*\\\\/', '', $entity_class);
|
||||||
|
|
||||||
|
$changeset = $unit_of_work->getEntityChangeSet($updated_entity);
|
||||||
|
|
||||||
|
$entity_fields = array_keys($changeset);
|
||||||
|
foreach ($entity_fields as $field)
|
||||||
|
{
|
||||||
|
$values = $changeset[$field];
|
||||||
|
|
||||||
|
$old_value = $values[0];
|
||||||
|
$new_value = $values[1];
|
||||||
|
|
||||||
|
$field_changes[$field] = [
|
||||||
|
'old_value' => $values[0],
|
||||||
|
'new_value' => $values[1],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$fields = json_encode($field_changes);
|
||||||
|
|
||||||
|
$this->writeToLogDB($entity_class, $updated_entity->getID(), 'update', $fields, $user_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error_log($entity_class . ' does not implement the AuditableEntity interface.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get deleted objects
|
||||||
|
foreach ($deleted_entities as $deleted_entity)
|
||||||
|
{
|
||||||
|
// check if entity is in list of entities to log
|
||||||
|
$entity_class = get_class($deleted_entity);
|
||||||
|
if (isset($this->entities[$entity_class]))
|
||||||
|
{
|
||||||
|
if ($deleted_entity instanceof AuditableEntity)
|
||||||
|
{
|
||||||
|
// get entity name
|
||||||
|
//$obj_class = preg_replace('/.*\\\\/', '', get_class($deleted_entity));
|
||||||
|
|
||||||
|
$deleted_id = $deleted_entity->getID();
|
||||||
|
|
||||||
|
// get fields of deleted entity
|
||||||
|
$fields = $deleted_entity->fieldDump();
|
||||||
|
|
||||||
|
$this->writeToLogDB($entity_class, $deleted_id, 'delete', $fields, $user_id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error_log($entity_class . ' does not implement the AuditableEntity interface.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: find a way to get the list of "old" items, compare with list of updated items
|
||||||
|
// so we can find out what was added/removed
|
||||||
|
/*
|
||||||
|
foreach ($updated_collections as $updated_collection)
|
||||||
|
{
|
||||||
|
error_log('in updated_collection snippet');
|
||||||
|
|
||||||
|
foreach ($updated_collection as $item)
|
||||||
|
{
|
||||||
|
if ($item instanceof Role)
|
||||||
|
{
|
||||||
|
error_log('updated_collection item ' . $item->getName());
|
||||||
|
}
|
||||||
|
if ($item instanceof Hub)
|
||||||
|
{
|
||||||
|
error_log('updated_collection item ' . $item->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($deleted_collections as $deleted_collection)
|
||||||
|
{
|
||||||
|
error_log('in deleted_collection snippet');
|
||||||
|
|
||||||
|
foreach ($deleted_collection as $item)
|
||||||
|
{
|
||||||
|
if ($item instanceof Role)
|
||||||
|
{
|
||||||
|
error_log('deleted_collection item ' . $item->getName());
|
||||||
|
}
|
||||||
|
if ($item instanceof Hub)
|
||||||
|
{
|
||||||
|
error_log('deleted_collection item ' . $item->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function writeToLogDB($entity_type, $entity_id, $action, $content, $user_id)
|
||||||
|
{
|
||||||
|
$new_point = new Point(
|
||||||
|
'entity_log', // measurement
|
||||||
|
null, // measurement value
|
||||||
|
['entity_type' => $entity_type, 'entity_id' => $entity_id], // measurement tags
|
||||||
|
['action' => $action, 'content' => $content, 'user' => $user_id], // measurement fields
|
||||||
|
exec('date +%s%N') // timestamp in nanoseconds on Linux only
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->log_db->writePoints([$new_point]);
|
||||||
|
}
|
||||||
|
}
|
||||||
91
src/EventListener/JobOrderStatusListener.php
Normal file
91
src/EventListener/JobOrderStatusListener.php
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\EventListener;
|
||||||
|
|
||||||
|
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;
|
||||||
|
|
||||||
|
use App\Entity\JobOrder;
|
||||||
|
use App\Entity\Warranty;
|
||||||
|
|
||||||
|
use App\Service\WarrantyHandler;
|
||||||
|
use App\Service\JobOrderHandlerInterface;
|
||||||
|
|
||||||
|
use App\Ramcar\JOStatus;
|
||||||
|
|
||||||
|
class JobOrderStatusListener
|
||||||
|
{
|
||||||
|
protected $wh;
|
||||||
|
protected $jo_handler;
|
||||||
|
|
||||||
|
public function __construct(WarrantyHandler $wh, JobOrderHandlerInterface $jo_handler)
|
||||||
|
{
|
||||||
|
$this->wh = $wh;
|
||||||
|
$this->jo_handler = $jo_handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
// when a JO is updated
|
||||||
|
public function postUpdate(JobOrder $jo, LifecycleEventArgs $args)
|
||||||
|
{
|
||||||
|
$status = $jo->getStatus();
|
||||||
|
|
||||||
|
if ($status == JOStatus::FULFILLED)
|
||||||
|
{
|
||||||
|
$this->createWarrantyFromJO($jo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// when a new job order comes in and status is already fulfilled
|
||||||
|
public function postPersist(JobOrder $jo, LifecycleEventArgs $args)
|
||||||
|
{
|
||||||
|
$status = $jo->getStatus();
|
||||||
|
|
||||||
|
if ($status == JOStatus::FULFILLED)
|
||||||
|
{
|
||||||
|
$this->createWarrantyFromJO($jo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function createWarrantyFromJO(JobOrder $jo)
|
||||||
|
{
|
||||||
|
// create warranty
|
||||||
|
if ($this->jo_handler->checkIfNewBattery($jo))
|
||||||
|
{
|
||||||
|
$serial = null;
|
||||||
|
$warranty_class = $jo->getWarrantyClass();
|
||||||
|
$first_name = $jo->getCustomer()->getFirstName();
|
||||||
|
$last_name = $jo->getCustomer()->getLastName();
|
||||||
|
$mobile_number = $jo->getCustomer()->getPhoneMobile();
|
||||||
|
|
||||||
|
// check if date fulfilled is null
|
||||||
|
if ($jo->getDateFulfill() == null)
|
||||||
|
$date_purchase = $jo->getDateCreate();
|
||||||
|
else
|
||||||
|
$date_purchase = $jo->getDateFulfill();
|
||||||
|
|
||||||
|
// validate plate number
|
||||||
|
// $plate_number = $this->wh->cleanPlateNumber($jo->getCustomerVehicle()->getPlateNumber());
|
||||||
|
$plate_number = Warranty::cleanPlateNumber($jo->getCustomerVehicle()->getPlateNumber());
|
||||||
|
if ($plate_number != false)
|
||||||
|
{
|
||||||
|
$batt_list = array();
|
||||||
|
$invoice = $jo->getInvoice();
|
||||||
|
if (!empty($invoice))
|
||||||
|
{
|
||||||
|
// get battery
|
||||||
|
$invoice_items = $invoice->getItems();
|
||||||
|
foreach ($invoice_items as $item)
|
||||||
|
{
|
||||||
|
$battery = $item->getBattery();
|
||||||
|
if ($battery != null)
|
||||||
|
{
|
||||||
|
$batt_list[] = $item->getBattery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -24,7 +24,6 @@ use App\Entity\Hub;
|
||||||
use App\Entity\Promo;
|
use App\Entity\Promo;
|
||||||
use App\Entity\Rider;
|
use App\Entity\Rider;
|
||||||
use App\Entity\JORejection;
|
use App\Entity\JORejection;
|
||||||
use App\Entity\Warranty;
|
|
||||||
use App\Entity\Customer;
|
use App\Entity\Customer;
|
||||||
use App\Entity\ServiceCharge;
|
use App\Entity\ServiceCharge;
|
||||||
|
|
||||||
|
|
@ -44,7 +43,6 @@ use App\Service\InvoiceGeneratorInterface;
|
||||||
use App\Service\JobOrderHandlerInterface;
|
use App\Service\JobOrderHandlerInterface;
|
||||||
use App\Service\RiderAssignmentHandlerInterface;
|
use App\Service\RiderAssignmentHandlerInterface;
|
||||||
use App\Service\CustomerHandlerInterface;
|
use App\Service\CustomerHandlerInterface;
|
||||||
use App\Service\WarrantyHandler;
|
|
||||||
use App\Service\MQTTClient;
|
use App\Service\MQTTClient;
|
||||||
use App\Service\APNSClient;
|
use App\Service\APNSClient;
|
||||||
use App\Service\MapTools;
|
use App\Service\MapTools;
|
||||||
|
|
@ -67,7 +65,6 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
||||||
protected $translator;
|
protected $translator;
|
||||||
protected $rah;
|
protected $rah;
|
||||||
protected $country_code;
|
protected $country_code;
|
||||||
protected $wh;
|
|
||||||
protected $cust_handler;
|
protected $cust_handler;
|
||||||
|
|
||||||
protected $template_hash;
|
protected $template_hash;
|
||||||
|
|
@ -75,8 +72,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
||||||
public function __construct(Security $security, EntityManagerInterface $em,
|
public function __construct(Security $security, EntityManagerInterface $em,
|
||||||
InvoiceGeneratorInterface $ic, ValidatorInterface $validator,
|
InvoiceGeneratorInterface $ic, ValidatorInterface $validator,
|
||||||
TranslatorInterface $translator, RiderAssignmentHandlerInterface $rah,
|
TranslatorInterface $translator, RiderAssignmentHandlerInterface $rah,
|
||||||
string $country_code, WarrantyHandler $wh,
|
string $country_code, CustomerHandlerInterface $cust_handler)
|
||||||
CustomerHandlerInterface $cust_handler)
|
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->ic = $ic;
|
$this->ic = $ic;
|
||||||
|
|
@ -85,7 +81,6 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->rah = $rah;
|
$this->rah = $rah;
|
||||||
$this->country_code = $country_code;
|
$this->country_code = $country_code;
|
||||||
$this->wh = $wh;
|
|
||||||
$this->cust_handler = $cust_handler;
|
$this->cust_handler = $cust_handler;
|
||||||
|
|
||||||
$this->loadTemplates();
|
$this->loadTemplates();
|
||||||
|
|
@ -977,6 +972,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
||||||
// call rider assignment handler's fulfillJobOrder
|
// call rider assignment handler's fulfillJobOrder
|
||||||
$this->rah->fulfillJobOrder($obj, $image_url, $rider);
|
$this->rah->fulfillJobOrder($obj, $image_url, $rider);
|
||||||
|
|
||||||
|
/*
|
||||||
// create the warranty if new battery only
|
// create the warranty if new battery only
|
||||||
if ($this->checkIfNewBattery($obj))
|
if ($this->checkIfNewBattery($obj))
|
||||||
{
|
{
|
||||||
|
|
@ -1019,7 +1015,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
||||||
|
|
||||||
$this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class);
|
$this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class);
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
|
||||||
// validated! save the entity
|
// validated! save the entity
|
||||||
$em->flush();
|
$em->flush();
|
||||||
|
|
@ -2658,7 +2654,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
||||||
$cust_vehicle->setWarrantyCode($req->request->get('warranty_code'));
|
$cust_vehicle->setWarrantyCode($req->request->get('warranty_code'));
|
||||||
|
|
||||||
$em->persist($cust_vehicle);
|
$em->persist($cust_vehicle);
|
||||||
|
/*
|
||||||
// create the warranty if new battery only
|
// create the warranty if new battery only
|
||||||
if ($this->checkIfNewBattery($jo))
|
if ($this->checkIfNewBattery($jo))
|
||||||
{
|
{
|
||||||
|
|
@ -2701,7 +2697,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
|
||||||
|
|
||||||
$this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class);
|
$this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class);
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
|
||||||
$em->flush();
|
$em->flush();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ use App\Entity\Hub;
|
||||||
use App\Entity\Promo;
|
use App\Entity\Promo;
|
||||||
use App\Entity\Rider;
|
use App\Entity\Rider;
|
||||||
use App\Entity\JORejection;
|
use App\Entity\JORejection;
|
||||||
use App\Entity\Warranty;
|
|
||||||
use App\Entity\Customer;
|
use App\Entity\Customer;
|
||||||
|
|
||||||
use App\Ramcar\InvoiceCriteria;
|
use App\Ramcar\InvoiceCriteria;
|
||||||
|
|
@ -41,7 +40,6 @@ use App\Ramcar\JORejectionReason;
|
||||||
use App\Service\InvoiceGeneratorInterface;
|
use App\Service\InvoiceGeneratorInterface;
|
||||||
use App\Service\JobOrderHandlerInterface;
|
use App\Service\JobOrderHandlerInterface;
|
||||||
use App\Service\RiderAssignmentHandlerInterface;
|
use App\Service\RiderAssignmentHandlerInterface;
|
||||||
use App\Service\WarrantyHandler;
|
|
||||||
use App\Service\MQTTClient;
|
use App\Service\MQTTClient;
|
||||||
use App\Service\APNSClient;
|
use App\Service\APNSClient;
|
||||||
use App\Service\MapTools;
|
use App\Service\MapTools;
|
||||||
|
|
@ -64,14 +62,13 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
protected $translator;
|
protected $translator;
|
||||||
protected $rah;
|
protected $rah;
|
||||||
protected $country_code;
|
protected $country_code;
|
||||||
protected $wh;
|
|
||||||
|
|
||||||
protected $template_hash;
|
protected $template_hash;
|
||||||
|
|
||||||
public function __construct(Security $security, EntityManagerInterface $em,
|
public function __construct(Security $security, EntityManagerInterface $em,
|
||||||
InvoiceGeneratorInterface $ic, ValidatorInterface $validator,
|
InvoiceGeneratorInterface $ic, ValidatorInterface $validator,
|
||||||
TranslatorInterface $translator, RiderAssignmentHandlerInterface $rah,
|
TranslatorInterface $translator, RiderAssignmentHandlerInterface $rah,
|
||||||
string $country_code, WarrantyHandler $wh)
|
string $country_code)
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->ic = $ic;
|
$this->ic = $ic;
|
||||||
|
|
@ -80,7 +77,6 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
$this->rah = $rah;
|
$this->rah = $rah;
|
||||||
$this->country_code = $country_code;
|
$this->country_code = $country_code;
|
||||||
$this->wh = $wh;
|
|
||||||
|
|
||||||
$this->loadTemplates();
|
$this->loadTemplates();
|
||||||
}
|
}
|
||||||
|
|
@ -824,6 +820,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
// call rider assignment handler's fulfillJobOrder
|
// call rider assignment handler's fulfillJobOrder
|
||||||
$this->rah->fulfillJobOrder($obj, $image_url, $rider);
|
$this->rah->fulfillJobOrder($obj, $image_url, $rider);
|
||||||
|
|
||||||
|
/*
|
||||||
// create the warranty if new battery only
|
// create the warranty if new battery only
|
||||||
if ($this->checkIfNewBattery($obj))
|
if ($this->checkIfNewBattery($obj))
|
||||||
{
|
{
|
||||||
|
|
@ -862,7 +859,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
|
||||||
|
|
||||||
$this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class);
|
$this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class);
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ use App\Service\RiderAPIHandlerInterface;
|
||||||
use App\Service\RedisClientProvider;
|
use App\Service\RedisClientProvider;
|
||||||
use App\Service\RiderCache;
|
use App\Service\RiderCache;
|
||||||
use App\Service\MQTTClient;
|
use App\Service\MQTTClient;
|
||||||
use App\Service\WarrantyHandler;
|
|
||||||
use App\Service\JobOrderHandlerInterface;
|
use App\Service\JobOrderHandlerInterface;
|
||||||
use App\Service\InvoiceGeneratorInterface;
|
use App\Service\InvoiceGeneratorInterface;
|
||||||
|
|
||||||
|
|
@ -30,7 +29,6 @@ use App\Entity\Promo;
|
||||||
use App\Entity\Battery;
|
use App\Entity\Battery;
|
||||||
use App\Entity\BatteryModel;
|
use App\Entity\BatteryModel;
|
||||||
use App\Entity\BatterySize;
|
use App\Entity\BatterySize;
|
||||||
use App\Entity\Warranty;
|
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
|
||||||
|
|
@ -42,7 +40,6 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
|
||||||
protected $rcache;
|
protected $rcache;
|
||||||
protected $country_code;
|
protected $country_code;
|
||||||
protected $mclient;
|
protected $mclient;
|
||||||
protected $wh;
|
|
||||||
protected $jo_handler;
|
protected $jo_handler;
|
||||||
protected $ic;
|
protected $ic;
|
||||||
protected $session;
|
protected $session;
|
||||||
|
|
@ -50,8 +47,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
|
||||||
public function __construct(EntityManagerInterface $em, RedisClientProvider $redis,
|
public function __construct(EntityManagerInterface $em, RedisClientProvider $redis,
|
||||||
EncoderFactoryInterface $ef, RiderCache $rcache,
|
EncoderFactoryInterface $ef, RiderCache $rcache,
|
||||||
string $country_code, MQTTClient $mclient,
|
string $country_code, MQTTClient $mclient,
|
||||||
WarrantyHandler $wh, JobOrderHandlerInterface $jo_handler,
|
JobOrderHandlerInterface $jo_handler, InvoiceGeneratorInterface $ic)
|
||||||
InvoiceGeneratorInterface $ic)
|
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->redis = $redis;
|
$this->redis = $redis;
|
||||||
|
|
@ -59,7 +55,6 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
|
||||||
$this->rcache = $rcache;
|
$this->rcache = $rcache;
|
||||||
$this->country_code = $country_code;
|
$this->country_code = $country_code;
|
||||||
$this->mclient = $mclient;
|
$this->mclient = $mclient;
|
||||||
$this->wh = $wh;
|
|
||||||
$this->jo_handler = $jo_handler;
|
$this->jo_handler = $jo_handler;
|
||||||
$this->ic = $ic;
|
$this->ic = $ic;
|
||||||
|
|
||||||
|
|
@ -523,6 +518,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
|
||||||
|
|
||||||
$this->em->flush();
|
$this->em->flush();
|
||||||
|
|
||||||
|
/*
|
||||||
// create warranty
|
// create warranty
|
||||||
if($this->jo_handler->checkIfNewBattery($jo))
|
if($this->jo_handler->checkIfNewBattery($jo))
|
||||||
{
|
{
|
||||||
|
|
@ -561,7 +557,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
|
||||||
|
|
||||||
$this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class);
|
$this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class);
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
|
||||||
// send mqtt event (fulfilled)
|
// send mqtt event (fulfilled)
|
||||||
$rider = $this->session->getRider();
|
$rider = $this->session->getRider();
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ use App\Service\RiderAPIHandlerInterface;
|
||||||
use App\Service\RedisClientProvider;
|
use App\Service\RedisClientProvider;
|
||||||
use App\Service\RiderCache;
|
use App\Service\RiderCache;
|
||||||
use App\Service\MQTTClient;
|
use App\Service\MQTTClient;
|
||||||
use App\Service\WarrantyHandler;
|
|
||||||
use App\Service\JobOrderHandlerInterface;
|
use App\Service\JobOrderHandlerInterface;
|
||||||
use App\Service\InvoiceGeneratorInterface;
|
use App\Service\InvoiceGeneratorInterface;
|
||||||
|
|
||||||
|
|
@ -41,7 +40,6 @@ class ResqRiderAPIHandler implements RiderAPIHandlerInterface
|
||||||
protected $rcache;
|
protected $rcache;
|
||||||
protected $country_code;
|
protected $country_code;
|
||||||
protected $mclient;
|
protected $mclient;
|
||||||
protected $wh;
|
|
||||||
protected $jo_handler;
|
protected $jo_handler;
|
||||||
protected $ic;
|
protected $ic;
|
||||||
protected $session;
|
protected $session;
|
||||||
|
|
@ -49,8 +47,7 @@ class ResqRiderAPIHandler implements RiderAPIHandlerInterface
|
||||||
public function __construct(EntityManagerInterface $em, RedisClientProvider $redis,
|
public function __construct(EntityManagerInterface $em, RedisClientProvider $redis,
|
||||||
EncoderFactoryInterface $ef, RiderCache $rcache,
|
EncoderFactoryInterface $ef, RiderCache $rcache,
|
||||||
string $country_code, MQTTClient $mclient,
|
string $country_code, MQTTClient $mclient,
|
||||||
WarrantyHandler $wh, JobOrderHandlerInterface $jo_handler,
|
JobOrderHandlerInterface $jo_handler, InvoiceGeneratorInterface $ic)
|
||||||
InvoiceGeneratorInterface $ic)
|
|
||||||
{
|
{
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
$this->redis = $redis;
|
$this->redis = $redis;
|
||||||
|
|
@ -58,7 +55,6 @@ class ResqRiderAPIHandler implements RiderAPIHandlerInterface
|
||||||
$this->rcache = $rcache;
|
$this->rcache = $rcache;
|
||||||
$this->country_code = $country_code;
|
$this->country_code = $country_code;
|
||||||
$this->mclient = $mclient;
|
$this->mclient = $mclient;
|
||||||
$this->wh = $wh;
|
|
||||||
$this->jo_handler = $jo_handler;
|
$this->jo_handler = $jo_handler;
|
||||||
$this->ic = $ic;
|
$this->ic = $ic;
|
||||||
|
|
||||||
|
|
@ -525,6 +521,7 @@ class ResqRiderAPIHandler implements RiderAPIHandlerInterface
|
||||||
|
|
||||||
$this->em->flush();
|
$this->em->flush();
|
||||||
|
|
||||||
|
/*
|
||||||
// create warranty
|
// create warranty
|
||||||
if($this->jo_handler->checkIfNewBattery($jo))
|
if($this->jo_handler->checkIfNewBattery($jo))
|
||||||
{
|
{
|
||||||
|
|
@ -559,7 +556,7 @@ class ResqRiderAPIHandler implements RiderAPIHandlerInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class);
|
$this->wh->createWarranty($serial, $plate_number, $first_name, $last_name, $mobile_number, $batt_list, $date_purchase, $warranty_class);
|
||||||
}
|
} */
|
||||||
|
|
||||||
// send mqtt event (fulfilled)
|
// send mqtt event (fulfilled)
|
||||||
$rider = $this->session->getRider();
|
$rider = $this->session->getRider();
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,9 @@
|
||||||
"guzzlehttp/psr7": {
|
"guzzlehttp/psr7": {
|
||||||
"version": "1.4.2"
|
"version": "1.4.2"
|
||||||
},
|
},
|
||||||
|
"influxdb/influxdb-php": {
|
||||||
|
"version": "1.15.0"
|
||||||
|
},
|
||||||
"jdorn/sql-formatter": {
|
"jdorn/sql-formatter": {
|
||||||
"version": "v1.2.17"
|
"version": "v1.2.17"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
79
templates/user/audit.log.html.twig
Normal file
79
templates/user/audit.log.html.twig
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<!-- BEGIN: Subheader -->
|
||||||
|
<div class="m-subheader">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<div class="mr-auto">
|
||||||
|
<h3 class="m-subheader__title">Audit Logs</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- END: Subheader -->
|
||||||
|
<div class="m-content">
|
||||||
|
<!--Begin::Section-->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xl-12">
|
||||||
|
<div class="m-portlet m-portlet--mobile">
|
||||||
|
<div class="m-portlet__body">
|
||||||
|
<!--begin: Datatable -->
|
||||||
|
<div id="data-rows"></div>
|
||||||
|
<!--end: Datatable -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
console.log( {{ id }} );
|
||||||
|
var options = {
|
||||||
|
data: {
|
||||||
|
type: 'remote',
|
||||||
|
source: {
|
||||||
|
read: {
|
||||||
|
url: '{{ url('user_view_logs', {'id': id}) }}',
|
||||||
|
method: 'POST'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
saveState: {
|
||||||
|
cookie: false,
|
||||||
|
webstorage: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
field: 'time',
|
||||||
|
title: 'Time'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'action',
|
||||||
|
title: 'Action'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'content',
|
||||||
|
title: 'Content'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'entity_id',
|
||||||
|
title: 'Entity ID'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'entity_type',
|
||||||
|
title: 'Entity Type'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'user',
|
||||||
|
title: 'User'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
var table = $("#data-rows").mDatatable(options);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
79
templates/user/change.history.log.html.twig
Normal file
79
templates/user/change.history.log.html.twig
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<!-- BEGIN: Subheader -->
|
||||||
|
<div class="m-subheader">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<div class="mr-auto">
|
||||||
|
<h3 class="m-subheader__title">Audit Logs</h3>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- END: Subheader -->
|
||||||
|
<div class="m-content">
|
||||||
|
<!--Begin::Section-->
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xl-12">
|
||||||
|
<div class="m-portlet m-portlet--mobile">
|
||||||
|
<div class="m-portlet__body">
|
||||||
|
<!--begin: Datatable -->
|
||||||
|
<div id="data-rows"></div>
|
||||||
|
<!--end: Datatable -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
<script>
|
||||||
|
$(function() {
|
||||||
|
console.log( {{ id }} );
|
||||||
|
var options = {
|
||||||
|
data: {
|
||||||
|
type: 'remote',
|
||||||
|
source: {
|
||||||
|
read: {
|
||||||
|
url: '{{ url('user_view_change_history', {'id': id}) }}',
|
||||||
|
method: 'POST'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
saveState: {
|
||||||
|
cookie: false,
|
||||||
|
webstorage: false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
field: 'time',
|
||||||
|
title: 'Time'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'action',
|
||||||
|
title: 'Action'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'content',
|
||||||
|
title: 'Content'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'entity_id',
|
||||||
|
title: 'Entity ID'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'entity_type',
|
||||||
|
title: 'Entity Type'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
field: 'user',
|
||||||
|
title: 'User'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
var table = $("#data-rows").mDatatable(options);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
@ -57,6 +57,16 @@
|
||||||
<div class="form-control-feedback hide" data-field="username"></div>
|
<div class="form-control-feedback hide" data-field="username"></div>
|
||||||
<span class="m-form__help">Unique alias for this user</span>
|
<span class="m-form__help">Unique alias for this user</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-lg-3">
|
||||||
|
{% if mode == 'update' %}
|
||||||
|
<a href="{{ url('user_view_logs_form', {'id':obj.getID()}) }}" class="btn btn-success">View Audit Logs</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-3">
|
||||||
|
{% if mode == 'update' %}
|
||||||
|
<a href="{{ url('user_view_change_history_form', {'id':obj.getID()}) }}" class="btn btn-success">View Change History</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group m-form__group row">
|
<div class="form-group m-form__group row">
|
||||||
<div class="col-lg-6">
|
<div class="col-lg-6">
|
||||||
|
|
@ -182,72 +192,73 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script>
|
<script>
|
||||||
$(function() {
|
$(function() {
|
||||||
$("#row-form").submit(function(e) {
|
$("#row-form").submit(function(e) {
|
||||||
var form = $(this);
|
var form = $(this);
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: form.prop('action'),
|
url: form.prop('action'),
|
||||||
data: form.serialize()
|
data: form.serialize()
|
||||||
}).done(function(response) {
|
}).done(function(response) {
|
||||||
// remove all error classes
|
// remove all error classes
|
||||||
removeErrors();
|
removeErrors();
|
||||||
swal({
|
swal({
|
||||||
title: 'Done!',
|
title: 'Done!',
|
||||||
text: 'Your changes have been saved!',
|
text: 'Your changes have been saved!',
|
||||||
type: 'success',
|
type: 'success',
|
||||||
onClose: function() {
|
onClose: function() {
|
||||||
window.location.href = "{{ url(mode == 'profile' ? 'home' : 'user_list') }}";
|
window.location.href = "{{ url(mode == 'profile' ? 'home' : 'user_list') }}";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).fail(function(response) {
|
}).fail(function(response) {
|
||||||
if (response.status == 422) {
|
if (response.status == 422) {
|
||||||
var errors = response.responseJSON.errors;
|
var errors = response.responseJSON.errors;
|
||||||
var firstfield = false;
|
var firstfield = false;
|
||||||
|
|
||||||
// remove all error classes first
|
// remove all error classes first
|
||||||
removeErrors();
|
removeErrors();
|
||||||
|
|
||||||
// display errors contextually
|
// display errors contextually
|
||||||
$.each(errors, function(field, msg) {
|
$.each(errors, function(field, msg) {
|
||||||
var formfield = $("[name='" + field + "']");
|
var formfield = $("[name='" + field + "']");
|
||||||
var label = $("label[data-field='" + field + "']");
|
var label = $("label[data-field='" + field + "']");
|
||||||
var msgbox = $(".form-control-feedback[data-field='" + field + "']");
|
var msgbox = $(".form-control-feedback[data-field='" + field + "']");
|
||||||
|
|
||||||
// add error classes to bad fields
|
// add error classes to bad fields
|
||||||
formfield.addClass('form-control-danger');
|
formfield.addClass('form-control-danger');
|
||||||
label.addClass('has-danger');
|
label.addClass('has-danger');
|
||||||
msgbox.html(msg).addClass('has-danger').removeClass('hide');
|
msgbox.html(msg).addClass('has-danger').removeClass('hide');
|
||||||
|
|
||||||
// check if this field comes first in DOM
|
// check if this field comes first in DOM
|
||||||
var domfield = formfield.get(0);
|
var domfield = formfield.get(0);
|
||||||
|
|
||||||
if (!firstfield || (firstfield && firstfield.compareDocumentPosition(domfield) === 2)) {
|
if (!firstfield || (firstfield && firstfield.compareDocumentPosition(domfield) === 2)) {
|
||||||
firstfield = domfield;
|
firstfield = domfield;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// focus on first bad field
|
// focus on first bad field
|
||||||
firstfield.focus();
|
firstfield.focus();
|
||||||
|
|
||||||
// scroll to above that field to make it visible
|
// scroll to above that field to make it visible
|
||||||
$('html, body').animate({
|
$('html, body').animate({
|
||||||
scrollTop: $(firstfield).offset().top - 200
|
scrollTop: $(firstfield).offset().top - 200
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// remove all error classes
|
// remove all error classes
|
||||||
function removeErrors() {
|
function removeErrors() {
|
||||||
$(".form-control-danger").removeClass('form-control-danger');
|
$(".form-control-danger").removeClass('form-control-danger');
|
||||||
$("[data-field]").removeClass('has-danger');
|
$("[data-field]").removeClass('has-danger');
|
||||||
$(".form-control-feedback[data-field]").addClass('hide');
|
$(".form-control-feedback[data-field]").addClass('hide');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue