Merge branch '746-resq-2-0-final' of gitlab.com:jankstudio/resq into 744-new-invoice-service

This commit is contained in:
Korina Cordero 2023-07-06 05:39:07 -04:00
commit 37ce74f07d
108 changed files with 9610 additions and 1617 deletions

View file

@ -1,9 +0,0 @@
<?php
namespace Catalyst\APIBundle\Access;
use Catalyst\AuthBundle\Service\ACLGenerator as BaseGenerator;
class Generator extends BaseGenerator
{
}

View file

@ -1,10 +0,0 @@
<?php
namespace Catalyst\APIBundle\Access;
use Catalyst\AuthBundle\Service\ACLVoter as BaseVoter;
class Voter extends BaseVoter
{
}

View file

@ -1,9 +0,0 @@
<?php
namespace Catalyst\APIBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class CatalystAPIBundle extends Bundle
{
}

View file

@ -1,155 +0,0 @@
<?php
namespace Catalyst\APIBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Catalyst\APIBundle\Connector\Client as APIClient;
class TestAPICommand extends Command
{
protected function configure()
{
$this->setName('api:test-connector-all')
->setDescription('Test API connector with all commands.')
->setHelp('Test API Connector with all commands.')
->addArgument('protocol', InputArgument::REQUIRED, 'protocol')
->addArgument('server', InputArgument::REQUIRED, 'server')
->addArgument('api_key', InputArgument::REQUIRED, 'api_key')
->addArgument('secret_key', InputArgument::REQUIRED, 'secret_key');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$protocol = $input->getArgument('protocol');
$server = $input->getArgument('server');
$api_key = $input->getArgument('api_key');
$secret_key = $input->getArgument('secret_key');
// api client
$api = new APIClient($server, $api_key, $secret_key);
$api->setProtocol($protocol);
// test
$api->get('/capi/test');
// TODO: shift this out of the bundle, since it's project specific
// warranty register
$serial = 'AJ34LJADR12134LKJL5';
$plate_num = 'XEN918';
$params = [
'serial' => $serial,
'plate_number' => $plate_num,
'warranty_class' => 'private',
'sku' => 'WMEB24CB-CPN00-LX',
'date_purchase' => '20181001',
'date_expire' => '20191001',
'first_name' => 'First',
'last_name' => 'Last',
'mobile_number' => '09231234567',
];
//$api->post('/capi/warranties', $params);
// get all warranties
$params = [
'order' => 'DESC',
'limit' => '5',
'start' => '1',
];
//$api->get('/capi/warranties', $params);
// warranty find
//$api->get('/capi/warranties/' . $serial);
// warranty update
$id = 86811;
$params = [
'serial' => $serial,
'plate_number' => $plate_num,
'warranty_class' => 'private',
'sku' => 'WMEB24CB-CPN00-LX',
'date_purchase' => '20181001',
'date_expire' => '20191001',
'first_name' => 'First',
'last_name' => 'Last',
'mobile_number' => '123456789111',
];
//$api->post('/capi/warranties/'. $id, $params);
// warranty set privacy policy
$id = 86811;
$policy_id = 2;
$params = [
'privacy_policy_id' => $policy_id,
];
//$api->post('/capi/warranties/' . $id .'/privacypolicy', $params);
// warranty claim
$id = 86811;
$serial = 'AJ34LJADR12134LKJL5';
$params = [
'serial' => $serial,
];
//$api->post('/capi/warranties/' . $id . '/claim', $params);
// warranty cancel
$id = 86811;
//$api->get('/capi/warranties/' . $id . '/cancel');
// plate warranty
//$api->get('/capi/plates/' . $plate_num . '/warranties');
// warranty delete
$id = 86811;
//$api->post('/capi/warranties/' . $id . '/delete');
// battery
//$api->get('/capi/battery_brands');
//$api->get('/capi/battery_sizes');
//$api->get('/capi/batteries');
// vehicle
//$api->get('/capi/vehicle_manufacturers');
//$api->get('/capi/vehicles');
// privacy policy
$privacy_policy_id = 2;
//$api->get('/capi/privacy_policy/' . $privacy_policy_id );
// register new customer
$params = [
'first_name' => 'Krispups',
'last_name' =>'Porzindog',
'mobile_number' => '9221111111',
'v_make_id' => '22241',
'v_model_year' => '2018',
'v_plate_number' => 'KPP1234',
'v_color' => 'White',
'v_condition' => 'new',
'v_fuel_type' => 'gas',
];
//$api->post('/capi/quick_registration', $params);
// get warranties given list of serial numbers
$serial_list = [
'AJ34LJADR12134LKJM4',
'AJ34LJADR12134LKJL5',
'test',
];
$params = [
'serial_list' => $serial_list,
];
$api->post('/capi/warranties_list', $params);
}
}

View file

@ -1,104 +0,0 @@
<?php
namespace Catalyst\APIBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Catalyst\APIBundle\Connector\Client as APIClient;
class TestCommand extends Command
{
protected function configure()
{
$this->setName('api:test-connector')
->setDescription('Test API connector.')
->setHelp('Test API Connector.')
->addArgument('protocol', InputArgument::REQUIRED, 'protocol')
->addArgument('server', InputArgument::REQUIRED, 'server')
->addArgument('api_key', InputArgument::REQUIRED, 'api_key')
->addArgument('secret_key', InputArgument::REQUIRED, 'secret_key');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$protocol = $input->getArgument('protocol');
$server = $input->getArgument('server');
$api_key = $input->getArgument('api_key');
$secret_key = $input->getArgument('secret_key');
// api client
$api = new APIClient($server, $api_key, $secret_key);
$api->setProtocol($protocol);
// test
$api->get('/capi/test');
// TODO: shift this out of the bundle, since it's project specific
// warranty register
$serial = 'AJ34LJADR12134LKJL5';
$plate_num = 'XEN918';
$params = [
'serial' => $serial,
'plate_number' => $plate_num,
'warranty_class' => 'private',
'sku' => 'WMEB24CB-CPN00-LX',
'date_purchase' => '20181001',
'date_expire' => '20191001',
'first_name' => 'First',
'last_name' => 'Last',
'mobile_number' => '12345678910',
];
$api->post('/capi/warranties', $params);
// get all warranties
$api->get('/capi/warranties');
/*
// warranty find
$api->get('/capi/warranties/' . $serial);
*/
// warranty claim
$id = 86811;
$serial = 'AJ34LJADR12134LKJL';
$params = [
'serial' => $serial,
];
$api->post('/capi/warranties/' . $id . '/claim', $params);
// add battery
$sku = 'WZMB31QT-CPP00-S';
$brand_id = '4';
$size_id = '1';
$params = [
'sku' => $sku,
'brand_id' => $brand_id,
'size_id' => $size_id,
];
$api->post('/capi/batteries', $params);
/*
// plate warranty
$api->get('/capi/plates/' . $plate_num . '/warranties');
// battery
$api->get('/capi/battery_brands');
$api->get('/capi/battery_sizes');
$api->get('/capi/batteries');
// vehicle
// $api->get('/capi/vehicle_manufacturers');
// $api->get('/capi/vehicles');
*/
}
}

View file

@ -1,49 +0,0 @@
<?php
namespace Catalyst\APIBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Entity\User;
class UserCreateCommand extends Command
{
protected $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
parent::__construct();
}
protected function configure()
{
$this->setName('api:user-create')
->setDescription('Create new API user.')
->setHelp('Creates new API user and saves to database.')
->addArgument('name', InputArgument::REQUIRED, 'name');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$name = $input->getArgument('name');
$user = new User();
$user->setName($name);
$this->em->persist($user);
$this->em->flush();
$output->write('API Key - ' . $user->getAPIKey() . "\n");
$output->write('Secret Key - ' . $user->getSecretKey() . "\n");
}
}

View file

@ -1,151 +0,0 @@
<?php
namespace Catalyst\APIBundle\Connector;
use DateTime;
class Client
{
const HEADER_API_KEY = 'X-Cata-API-Key';
const HEADER_SIGNATURE = 'X-Cata-Signature';
const HEADER_DATE = 'X-Cata-Date';
const DATE_FORMAT = 'D, d M Y H:i:s T';
const USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36';
protected $protocol;
protected $server;
protected $port;
protected $api_key;
protected $secret_key;
protected $curl;
public function __construct($server, $api_key, $secret_key)
{
$this->protocol = 'https';
$this->port = null;
$this->server = $server;
$this->api_key = $api_key;
$this->secret_key = $secret_key;
$this->curl = curl_init();
}
public function __destruct()
{
curl_close($this->curl);
}
public function setProtocol($protocol)
{
if ($protocol != 'http' && $protocol != 'https')
return $this;
$this->protocol = $protocol;
return $this;
}
protected function getDateString()
{
$date = new DateTime();
return $date->format(self::DATE_FORMAT);
}
public function get($url, $params = [])
{
curl_reset($this->curl);
$date_string = $this->getDateString();
$headers = $this->generateHeaders('GET', $url, $date_string);
// build query string
if (count($params) > 0)
$query_string = '?' . http_build_query($params);
else
$query_string = '';
// build url
if ($this->port == null)
$full_url = $this->protocol . '://' . $this->server . $url . $query_string;
else
$full_url = $this->protocol . '://' . $this->server . ':' . $this->port . $url . $query_string;
error_log($full_url);
// curl
// curl_setopt($this->curl, CURLOPT_VERBOSE, true);
curl_setopt($this->curl, CURLOPT_URL, $full_url);
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($this->curl, CURLOPT_USERAGENT, self::USER_AGENT);
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->curl, CURLOPT_TIMEOUT, 0);
$res = curl_exec($this->curl);
error_log($res);
}
public function post($url, $params = [])
{
curl_reset($this->curl);
$date_string = $this->getDateString();
$headers = $this->generateHeaders('POST', $url, $date_string);
// build query string
$query_string = http_build_query($params);
// build url
if ($this->port == null)
$full_url = $this->protocol . '://' . $this->server . $url;
else
$full_url = $this->protocol . '://' . $this->server . ':' . $this->port . $url;
error_log($full_url);
// curl
// curl_setopt($this->curl, CURLOPT_VERBOSE, true);
curl_setopt($this->curl, CURLOPT_URL, $full_url);
curl_setopt($this->curl, CURLOPT_POST, true);
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $query_string);
curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($this->curl, CURLOPT_USERAGENT, self::USER_AGENT);
curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->curl, CURLOPT_TIMEOUT, 0);
$res = curl_exec($this->curl);
error_log($res);
}
protected function generateSignature($method, $url, $date_string)
{
$creds = [
$method,
$url,
$date_string,
$this->secret_key,
];
$sig_source = implode('|', $creds);
error_log('SIG SOURCE - ' . $sig_source);
$raw_sig = hash_hmac('sha1', $sig_source, $this->secret_key, true);
$enc_sig = base64_encode($raw_sig);
return $enc_sig;
}
protected function generateHeaders($method, $url, $date_string)
{
$sig = $this->generateSignature($method, $url, $date_string);
$headers = [
self::HEADER_API_KEY . ': ' . $this->api_key,
self::HEADER_SIGNATURE . ': ' . $sig,
self::HEADER_DATE . ': ' . $date_string,
];
return $headers;
}
}

View file

@ -1,42 +0,0 @@
<?php
namespace Catalyst\APIBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
abstract class APIController extends Controller
{
protected function checkRequiredParameters(Request $req, $params = [])
{
$missing = [];
// check if parameters are there
foreach ($params as $param)
{
if ($req->getMethod() == 'GET')
{
$check = $req->query->get($param);
if (empty($check))
$missing[] = $param;
}
// else if ($req->getMethod() == 'POST')
else
{
$check = $req->request->get($param);
//if (empty($check))
if (!isset($check))
$missing[] = $param;
}
}
// check missing parameters
if (count($missing) > 0)
{
$miss_string = implode(', ', $missing);
return 'Missing required parameter(s): ' . $miss_string;
}
return false;
}
}

View file

@ -1,20 +0,0 @@
<?php
namespace Catalyst\APIBundle\DataFixtures;
use Catalyst\APIBundle\Entity\Role;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
class APIRoleFixtures extends Fixture
{
public function load(ObjectManager $em)
{
// setup super user account
$role = new Role();
$role->setID(Role::SUPER_ADMIN)
->setName('Super Administrator');
$em->persist($role);
$em->flush();
}
}

View file

@ -1,28 +0,0 @@
<?php
namespace Catalyst\APIBundle\Entity;
use Catalyst\AuthBundle\Entity\Role as BaseRole;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* @ORM\Entity
* @ORM\Table(name="api_role")
* @UniqueEntity("id")
* @UniqueEntity("name")
*/
class Role extends BaseRole
{
/**
* @ORM\ManyToMany(targetEntity="User", mappedBy="roles", fetch="EXTRA_LAZY")
*/
protected $users;
public function __construct()
{
parent::__construct();
}
}

View file

@ -1,186 +0,0 @@
<?php
namespace Catalyst\APIBundle\Entity;
use Catalyst\AuthBundle\Entity\User as BaseUser;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\Common\Collections\ArrayCollection;
use DateTime;
/**
* @ORM\Entity
* @ORM\Table(name="api_user")
*/
class User extends BaseUser
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// api key
/**
* @ORM\Column(type="string", length=32)
*/
protected $api_key;
// secret key
/**
* @ORM\Column(type="string", length=32)
*/
protected $secret_key;
/**
* @ORM\Column(type="string", length=80)
*/
protected $name;
// date created
/**
* @ORM\Column(type="datetime")
*/
protected $date_create;
// roles
/**
* @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
* @ORM\JoinTable(name="api_user_role")
*/
protected $roles;
// rider linked to user
// NOTE: we're directly linking this only because we don't have to care about other apps using this library
/**
* @ORM\OneToOne(targetEntity="App\Entity\Rider", mappedBy="api_user")
*/
protected $rider;
/**
* @ORM\Column(type="json")
*/
protected $metadata;
public function __construct()
{
parent::__construct();
// generate keys
$this->setAPIKey($this->generateAPIKey())
->setSecretKey($this->generateSecretKey());
// set date created
$this->date_create = new DateTime();
$this->metadata = [];
}
public function getID()
{
return $this->id;
}
public function setAPIKey($api_key)
{
$this->api_key = $api_key;
return $this;
}
public function getAPIKey()
{
return $this->api_key;
}
public function setSecretKey($key)
{
$this->secret_key = $key;
return $this;
}
public function getSecretKey()
{
return $this->secret_key;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
public function getDateCreate()
{
return $this->date_create;
}
public function getPassword()
{
// we don't need this for API
return 'notneeded';
}
public function getSalt()
{
return null;
}
public function getUsername()
{
// since it's an api, the api key IS the username
return $this->api_key;
}
public function eraseCredentials()
{
return;
}
public function generateAPIKey()
{
return $this->generateKey('api');
}
public function generateSecretKey()
{
return $this->generateKey('secret');
}
public function setMetadata($meta)
{
$this->metadata = $meta;
return $this;
}
public function getMetadata()
{
if ($this->metadata == null)
return [];
return $this->metadata;
}
protected function generateKey($prefix = '')
{
return md5(uniqid($prefix, true));
}
public function setRider($rider)
{
$this->rider = $rider;
return $this;
}
public function getRider()
{
return $this->rider;
}
}

View file

@ -1,20 +0,0 @@
<?php
namespace Catalyst\APIBundle\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
class APIResponse extends JsonResponse
{
public function __construct($success = true, $message = '', $data = null, $status = 200, $headers = [])
{
$data = [
'success' => (bool) $success,
'message' => (string) $message,
'data' => $data,
];
parent::__construct($data, $status, $headers);
}
}

View file

@ -1,160 +0,0 @@
<?php
namespace Catalyst\APIBundle\Security;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Http\Authentication\SimplePreAuthenticatorInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
use Doctrine\ORM\EntityManagerInterface;
use DateTime;
class APIKeyAuthenticator implements SimplePreAuthenticatorInterface, AuthenticationFailureHandlerInterface
{
const HEADER_API_KEY = 'X-Cata-API-Key';
const HEADER_SIGNATURE = 'X-Cata-Signature';
const HEADER_DATE = 'X-Cata-Date';
const DATE_FORMAT = 'D, d M Y H:i:s T';
// 30 minute time limit
const TIME_LIMIT = 1800;
protected $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
protected function validateSignature($creds, $secret_key)
{
$elements = [
$creds['method'],
$creds['uri'],
$creds['date'],
$secret_key,
];
$sig_source = implode('|', $elements);
error_log($sig_source);
// generate signature
$raw_sig = hash_hmac('sha1', $sig_source, $secret_key, true);
$enc_sig = base64_encode($raw_sig);
error_log($enc_sig);
if ($enc_sig != trim($creds['signature']))
throw new CustomUserMessageAuthenticationException('Invalid signature.');
}
public function createToken(Request $req, $provider_key)
{
// api key header
$api_key = $req->headers->get(self::HEADER_API_KEY);
if ($api_key == null)
throw new BadCredentialsException('No API key sent.');
// check date from headers
$hdate_string = $req->headers->get(self::HEADER_DATE);
if ($hdate_string == null)
throw new BadCredentialsException('No date specified.');
$hdate = DateTime::createFromFormat(self::DATE_FORMAT, $hdate_string);
if ($hdate == null)
throw new BadCredentialsException('Invalid date specified.');
// get number of seconds difference
$date_now = new DateTime();
$date_diff = abs($date_now->getTimestamp() - $hdate->getTimestamp());
// time difference is too much
if ($date_diff > self::TIME_LIMIT)
throw new BadCredentialsException('Clock synchronization error.');
// signature header
$sig = $req->headers->get(self::HEADER_SIGNATURE);
if ($sig == null)
throw new BadCredentialsException('No signature sent.');
// credentials
$creds = [
'api_key' => $api_key,
'date' => $hdate_string,
'signature' => $sig,
'method' => $req->getRealMethod(),
'uri' => $req->getPathInfo(),
];
return new PreAuthenticatedToken(
'anonymous',
$creds,
$provider_key
);
}
public function supportsToken(TokenInterface $token, $provider_key)
{
return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $provider_key;
}
public function authenticateToken(TokenInterface $token, UserProviderInterface $user_provider, $provider_key)
{
if (!$user_provider instanceof APIKeyUserProvider)
{
throw new \InvalidArgumentException(
sprintf(
'The user provider must be an instance of APIKeyUserProvider (%s was given).',
get_class($user_provider)
)
);
}
$creds = $token->getCredentials();
$api_key = $creds['api_key'];
$user = $user_provider->getUserByAPIKey($api_key);
// check if api key is valid
if (!$user)
throw new CustomUserMessageAuthenticationException('Invalid API Key');
// check if signature is valid
$this->validateSignature($creds, $user->getSecretKey());
// check if user is enabled
if (!$user->isEnabled())
{
throw new CustomUserMessageAuthenticationException('User account is disabled');
}
// $user = $user_provider->loadUserByUsername($username);
return new PreAuthenticatedToken(
$user,
$api_key,
$provider_key,
$user->getRoles()
);
}
public function onAuthenticationFailure(Request $req, AuthenticationException $exception)
{
$data = [
'success' => false,
'error' => [
'message' => $exception->getMessage(),
],
];
return new JsonResponse($data, 401);
}
}

View file

@ -1,62 +0,0 @@
<?php
namespace Catalyst\APIBundle\Security;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Entity\User;
class APIKeyUserProvider implements UserProviderInterface
{
protected $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
public function getUserByAPIKey($api_key)
{
$user = $this->em->getRepository(User::class)->findOneBy(array('api_key' => $api_key));
return $user;
}
public function getUsernameForAPIKey($apiKey)
{
// Look up the username based on the token in the database, via
// an API call, or do something entirely different
$username = 'test';
return $username;
}
public function loadUserByUsername($username)
{
return new User(
$username,
null,
// the roles for the user - you may choose to determine
// these dynamically somehow based on the user
array('ROLE_API')
);
}
public function refreshUser(UserInterface $user)
{
// this is used for storing authentication in the session
// but in this example, the token is sent in each request,
// so authentication can be stateless. Throwing this exception
// is proper to make things stateless
throw new UnsupportedUserException();
}
public function supportsClass($class)
{
return User::class === $class;
}
}

View file

@ -1,18 +0,0 @@
<?php
namespace Catalyst\APIBundle\Service;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Http\Authorization\AccessDeniedHandlerInterface;
class AccessDeniedHandler implements AccessDeniedHandlerInterface
{
public function handle(Request $req, AccessDeniedException $exception)
{
$content = $exception->getMessage();
return new Response($content, 403);
}
}

View file

@ -4,20 +4,25 @@
"repositories": [
{
"type": "vcs",
"url": "git@gitlab.com:jankstudio-catalyst/auth-bundle.git"
"url": "https://github.com/jankstudio/doctrine2-spatial.git"
},
{
"type": "vcs",
"url": "git@gitlab.com:jankstudio-catalyst/menu-bundle.git"
"url": "git@gitlab.com:jankstudio1/catalyst-2/api-bundle.git"
},
{
"type": "vcs",
"url": "git@gitlab.com:jankstudio1/catalyst-2/auth-bundle.git"
},
{
"type": "vcs",
"url": "git@gitlab.com:jankstudio1/catalyst-2/menu-bundle.git"
}
],
"require": {
"php": "^7.1.3",
"ext-iconv": "*",
"catalyst/auth-bundle": "dev-master",
"catalyst/menu-bundle": "dev-master",
"composer/package-versions-deprecated": "1.11.99.4",
"creof/doctrine2-spatial": "^1.2",
"data-dog/audit-bundle": "^0.1.10",
"doctrine/common": "^2",
"doctrine/doctrine-bundle": "^2",
@ -26,6 +31,10 @@
"edwinhoksberg/php-fcm": "^1.0",
"guzzlehttp/guzzle": "^6.3",
"hashids/hashids": "^4.1",
"jankstudio/catalyst-api-bundle": "dev-master",
"jankstudio/catalyst-auth-bundle": "dev-master",
"jankstudio/catalyst-menu-bundle": "dev-master",
"jankstudio/doctrine-spatial": "dev-master",
"microsoft/azure-storage-blob": "^1.5",
"predis/predis": "^1.1",
"sensio/framework-extra-bundle": "^5.1",
@ -65,8 +74,7 @@
},
"autoload": {
"psr-4": {
"App\\": "src/",
"Catalyst\\APIBundle\\": "catalyst/api-bundle/"
"App\\": "src/"
}
},
"autoload-dev": {

420
composer.lock generated
View file

@ -4,90 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5b5acb546514b41ab347ef37b85425c9",
"content-hash": "6e52016d46fa06387dbd9db37e6feb93",
"packages": [
{
"name": "catalyst/auth-bundle",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://gitlab.com/jankstudio-catalyst/auth-bundle.git",
"reference": "803e38f58907513c8df30c31d51303b68c645a17"
},
"dist": {
"type": "zip",
"url": "https://gitlab.com/api/v4/projects/jankstudio-catalyst%2Fauth-bundle/repository/archive.zip?sha=803e38f58907513c8df30c31d51303b68c645a17",
"reference": "803e38f58907513c8df30c31d51303b68c645a17",
"shasum": ""
},
"require": {
"doctrine/dbal": "^2.5.12",
"doctrine/doctrine-cache-bundle": "~1.2",
"php": "^7.0",
"symfony/framework-bundle": "~4.0"
},
"default-branch": true,
"type": "symfony-bundle",
"autoload": {
"psr-4": {
"Catalyst\\AuthBundle\\": ""
}
},
"license": [
"MIT"
],
"authors": [
{
"name": "Kendrick Chan",
"email": "kc@jankstudio.com"
}
],
"support": {
"issues": "https://gitlab.com/api/v4/projects/12709261/issues"
},
"time": "2019-07-01T09:45:41+00:00"
},
{
"name": "catalyst/menu-bundle",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://gitlab.com/jankstudio-catalyst/menu-bundle.git",
"reference": "2cf9a05862fcc6f956da4b095962915e07f14f64"
},
"dist": {
"type": "zip",
"url": "https://gitlab.com/api/v4/projects/jankstudio-catalyst%2Fmenu-bundle/repository/archive.zip?sha=2cf9a05862fcc6f956da4b095962915e07f14f64",
"reference": "2cf9a05862fcc6f956da4b095962915e07f14f64",
"shasum": ""
},
"require": {
"doctrine/dbal": "^2.5.12",
"doctrine/doctrine-cache-bundle": "~1.2",
"php": "^7.0",
"symfony/framework-bundle": "~4.0"
},
"default-branch": true,
"type": "symfony-bundle",
"autoload": {
"psr-4": {
"Catalyst\\MenuBundle\\": ""
}
},
"license": [
"MIT"
],
"authors": [
{
"name": "Kendrick Chan",
"email": "kc@jankstudio.com"
}
],
"support": {
"issues": "https://gitlab.com/api/v4/projects/12712039/issues"
},
"time": "2019-06-14T09:43:30+00:00"
},
{
"name": "composer/package-versions-deprecated",
"version": "1.11.99.4",
@ -161,67 +79,6 @@
],
"time": "2021-09-13T08:41:34+00:00"
},
{
"name": "creof/doctrine2-spatial",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/creof/doctrine2-spatial.git",
"reference": "58ea5fae1c1b450ee08d7dac25cd9e8f5e6fdebd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/creof/doctrine2-spatial/zipball/58ea5fae1c1b450ee08d7dac25cd9e8f5e6fdebd",
"reference": "58ea5fae1c1b450ee08d7dac25cd9e8f5e6fdebd",
"shasum": ""
},
"require": {
"creof/geo-parser": "~2.0",
"creof/wkb-parser": "~2.0",
"creof/wkt-parser": "~2.0",
"doctrine/orm": ">=2.3"
},
"require-dev": {
"phpunit/phpcov": "*",
"phpunit/phpunit": "<5.0",
"satooshi/php-coveralls": "~1.0"
},
"type": "library",
"autoload": {
"psr-0": {
"CrEOF\\Spatial": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Derek Lambert",
"email": "dlambert@dereklambert.com"
}
],
"description": "Doctrine2 multi-platform support for spatial types and functions",
"keywords": [
"database",
"dbal",
"geography",
"geometry",
"gis",
"mysql",
"opengis",
"orm",
"postgis",
"postgresql",
"spatial"
],
"support": {
"issues": "https://github.com/creof/doctrine2-spatial/issues",
"source": "https://github.com/creof/doctrine2-spatial/tree/master"
},
"time": "2017-07-13T16:48:25+00:00"
},
{
"name": "creof/geo-parser",
"version": "2.2.1",
@ -1069,102 +926,6 @@
],
"time": "2021-05-06T19:21:22+00:00"
},
{
"name": "doctrine/doctrine-cache-bundle",
"version": "1.4.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/DoctrineCacheBundle.git",
"reference": "6bee2f9b339847e8a984427353670bad4e7bdccb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/DoctrineCacheBundle/zipball/6bee2f9b339847e8a984427353670bad4e7bdccb",
"reference": "6bee2f9b339847e8a984427353670bad4e7bdccb",
"shasum": ""
},
"require": {
"doctrine/cache": "^1.4.2",
"doctrine/inflector": "^1.0",
"php": "^7.1",
"symfony/doctrine-bridge": "^3.4|^4.0"
},
"require-dev": {
"instaclick/coding-standard": "~1.1",
"instaclick/object-calisthenics-sniffs": "dev-master",
"instaclick/symfony2-coding-standard": "dev-remaster",
"phpunit/phpunit": "^7.0",
"predis/predis": "~0.8",
"satooshi/php-coveralls": "^1.0",
"squizlabs/php_codesniffer": "~1.5",
"symfony/console": "^3.4|^4.0",
"symfony/finder": "^3.4|^4.0",
"symfony/framework-bundle": "^3.4|^4.0",
"symfony/phpunit-bridge": "^3.4|^4.0",
"symfony/security-acl": "^2.8",
"symfony/validator": "^3.4|^4.0",
"symfony/yaml": "^3.4|^4.0"
},
"suggest": {
"symfony/security-acl": "For using this bundle to cache ACLs"
},
"type": "symfony-bundle",
"extra": {
"branch-alias": {
"dev-master": "1.4.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Bundle\\DoctrineCacheBundle\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Fabio B. Silva",
"email": "fabio.bat.silva@gmail.com"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@hotmail.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
},
{
"name": "Doctrine Project",
"homepage": "http://www.doctrine-project.org/"
}
],
"description": "Symfony Bundle for Doctrine Cache",
"homepage": "https://www.doctrine-project.org",
"keywords": [
"cache",
"caching"
],
"support": {
"issues": "https://github.com/doctrine/DoctrineCacheBundle/issues",
"source": "https://github.com/doctrine/DoctrineCacheBundle/tree/1.4.0"
},
"abandoned": true,
"time": "2019-11-29T11:22:01+00:00"
},
{
"name": "doctrine/doctrine-migrations-bundle",
"version": "2.2.3",
@ -2480,6 +2241,177 @@
},
"time": "2020-11-26T19:24:33+00:00"
},
{
"name": "jankstudio/catalyst-api-bundle",
"version": "dev-master",
"source": {
"type": "git",
"url": "git@gitlab.com:jankstudio1/catalyst-2/api-bundle.git",
"reference": "042d16534265adf81ae67c803b1ae8f0a94f3bb6"
},
"dist": {
"type": "zip",
"url": "https://gitlab.com/api/v4/projects/jankstudio1%2Fcatalyst-2%2Fapi-bundle/repository/archive.zip?sha=042d16534265adf81ae67c803b1ae8f0a94f3bb6",
"reference": "042d16534265adf81ae67c803b1ae8f0a94f3bb6",
"shasum": ""
},
"default-branch": true,
"type": "symfony-bundle",
"autoload": {
"psr-4": {
"Catalyst\\ApiBundle\\": ""
}
},
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Kendrick Chan",
"email": "kc@jankstudio.com"
}
],
"support": {
"source": "https://gitlab.com/jankstudio1/catalyst-2/api-bundle/-/tree/master",
"issues": "https://gitlab.com/jankstudio1/catalyst-2/api-bundle/-/issues"
},
"time": "2022-10-09T14:02:41+08:00"
},
{
"name": "jankstudio/catalyst-auth-bundle",
"version": "dev-master",
"source": {
"type": "git",
"url": "git@gitlab.com:jankstudio1/catalyst-2/auth-bundle.git",
"reference": "50f18ac6d4f6198b7bfe888487e0a4009193403e"
},
"dist": {
"type": "zip",
"url": "https://gitlab.com/api/v4/projects/jankstudio1%2Fcatalyst-2%2Fauth-bundle/repository/archive.zip?sha=50f18ac6d4f6198b7bfe888487e0a4009193403e",
"reference": "50f18ac6d4f6198b7bfe888487e0a4009193403e",
"shasum": ""
},
"require": {
"symfony/cache": "^5.0"
},
"default-branch": true,
"type": "symfony-bundle",
"autoload": {
"psr-4": {
"Catalyst\\AuthBundle\\": ""
}
},
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Kendrick Chan",
"email": "kc@jankstudio.com"
}
],
"support": {
"source": "https://gitlab.com/jankstudio1/catalyst-2/auth-bundle/-/tree/master",
"issues": "https://gitlab.com/jankstudio1/catalyst-2/auth-bundle/-/issues"
},
"time": "2022-01-19T16:21:57+08:00"
},
{
"name": "jankstudio/catalyst-menu-bundle",
"version": "dev-master",
"source": {
"type": "git",
"url": "git@gitlab.com:jankstudio1/catalyst-2/menu-bundle.git",
"reference": "9cddeecbbbb7d61868e1b319d9abc8eda4f34ab0"
},
"dist": {
"type": "zip",
"url": "https://gitlab.com/api/v4/projects/jankstudio1%2Fcatalyst-2%2Fmenu-bundle/repository/archive.zip?sha=9cddeecbbbb7d61868e1b319d9abc8eda4f34ab0",
"reference": "9cddeecbbbb7d61868e1b319d9abc8eda4f34ab0",
"shasum": ""
},
"default-branch": true,
"type": "symfony-bundle",
"autoload": {
"psr-4": {
"Catalyst\\MenuBundle\\": ""
}
},
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Kendrick Chan",
"email": "kc@jankstudio.com"
}
],
"support": {
"source": "https://gitlab.com/jankstudio1/catalyst-2/menu-bundle/-/tree/master",
"issues": "https://gitlab.com/jankstudio1/catalyst-2/menu-bundle/-/issues"
},
"time": "2022-10-07T11:55:32+08:00"
},
{
"name": "jankstudio/doctrine-spatial",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://github.com/jankstudio/doctrine-spatial.git",
"reference": "32b0fd126f3d81758ee74363535a44ccb3adae19"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jankstudio/doctrine-spatial/zipball/32b0fd126f3d81758ee74363535a44ccb3adae19",
"reference": "32b0fd126f3d81758ee74363535a44ccb3adae19",
"shasum": ""
},
"require": {
"creof/geo-parser": "~2.0",
"creof/wkb-parser": "~2.0",
"creof/wkt-parser": "~2.0",
"doctrine/orm": ">=2.3"
},
"require-dev": {
"phpunit/phpcov": "*",
"phpunit/phpunit": "<5.0",
"satooshi/php-coveralls": "~1.0"
},
"default-branch": true,
"type": "library",
"autoload": {
"psr-0": {
"CrEOF\\Spatial": "lib/"
}
},
"license": [
"MIT"
],
"authors": [
{
"name": "Derek Lambert",
"email": "dlambert@dereklambert.com"
}
],
"description": "Doctrine2 multi-platform support for spatial types and functions",
"keywords": [
"database",
"dbal",
"geography",
"geometry",
"gis",
"mysql",
"opengis",
"orm",
"postgis",
"postgresql",
"spatial"
],
"support": {
"source": "https://github.com/jankstudio/doctrine-spatial/tree/master"
},
"time": "2021-08-23T01:41:57+00:00"
},
{
"name": "laminas/laminas-code",
"version": "3.4.1",
@ -8021,8 +7953,10 @@
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {
"catalyst/auth-bundle": 20,
"catalyst/menu-bundle": 20
"jankstudio/catalyst-api-bundle": 20,
"jankstudio/catalyst-auth-bundle": 20,
"jankstudio/catalyst-menu-bundle": 20,
"jankstudio/doctrine-spatial": 20
},
"prefer-stable": false,
"prefer-lowest": false,
@ -8031,5 +7965,5 @@
"ext-iconv": "*"
},
"platform-dev": [],
"plugin-api-version": "2.0.0"
"plugin-api-version": "2.3.0"
}

View file

@ -2,7 +2,6 @@
return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle::class => ['all' => true],
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
@ -11,8 +10,8 @@ return [
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
Catalyst\APIBundle\CatalystAPIBundle::class => ['all' => true],
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
Catalyst\ApiBundle\CatalystApiBundle::class => ['all' => true],
Catalyst\AuthBundle\CatalystAuthBundle::class => ['all' => true],
Catalyst\MenuBundle\CatalystMenuBundle::class => ['all' => true],
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
];

View file

@ -42,20 +42,6 @@ services:
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
Catalyst\AuthBundle\Service\ACLGenerator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
$acl_file: "%app_acl_file%"
Catalyst\AuthBundle\Service\ACLVoter:
arguments:
$user_class: "App\\Entity\\User"
tags: ['security.voter']
Catalyst\AuthBundle\Service\UserChecker:
App\Service\FileUploader:
arguments:
$target_dir: '%image_upload_directory%'
@ -114,50 +100,6 @@ services:
arguments:
$redis_client: "@App\\Service\\RedisClientProvider"
Catalyst\APIBundle\Security\APIKeyUserProvider:
arguments:
$em: "@doctrine.orm.entity_manager"
Catalyst\APIBundle\Security\APIKeyAuthenticator:
arguments:
$em: "@doctrine.orm.entity_manager"
Catalyst\APIBundle\Command\UserCreateCommand:
arguments:
$em: "@doctrine.orm.entity_manager"
tags: ['console.command']
Catalyst\APIBundle\Command\TestCommand:
tags: ['console.command']
Catalyst\APIBundle\Command\TestAPICommand:
tags: ['console.command']
Catalyst\APIBundle\Access\Voter:
arguments:
$acl_gen: "@Catalyst\\APIBundle\\Access\\Generator"
$user_class: "Catalyst\\APIBundle\\Entity\\User"
tags: ['security.voter']
Catalyst\APIBundle\Access\Generator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
$acl_file: "%api_acl_file%"
Catalyst\MenuBundle\Menu\Generator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
Catalyst\MenuBundle\Listener\MenuAnnotationListener:
arguments:
$menu_name: "main_menu"
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
# invoice generator
App\Service\InvoiceGenerator\CMBInvoiceGenerator: ~

View file

@ -0,0 +1,879 @@
catalyst_auth:
main:
user_entity: "App\\Entity\\User"
acl_data:
- id: dashboard
label: Dashboard Access
acls:
- id: dashboard.menu
label: Menu
- id: user
label: User Access
acls:
- id: user.menu
label: Menu
- id: user.list
label: List
- id: user.add
label: Add
- id: user.update
label: Update
- id: user.delete
label: Delete
- id: user.role.sadmin
label: Super Admin Role
- id: user.profile
label: User Profile
- id: role
label: Role Access
acls:
- id: role.menu
label: Menu
- id: role.list
label: List
- id: role.add
label: Add
- id: role.update
label: Update
- id: role.delete
label: Delete
- id: apiuser
label: API User Access
acls:
- id: apiuser.menu
label: Menu
- id: apiuser.list
label: List
- id: apiuser.add
label: Add
- id: apiuser.update
label: Update
- id: apiuser.delete
label: Delete
- id: apirole
label: API Role Access
acls:
- id: apirole.menu
label: Menu
- id: apirole.list
label: List
- id: apirole.add
label: Add
- id: apirole.update
label: Update
- id: apirole.delete
label: Delete
- id: logistics
label: Logistics Access
acls:
- id: logistics.menu
label: Menu
- id: battery
label: Battery Access
acls:
- id: battery.menu
label: Menu
- id: battery.list
label: List
- id: battery.add
label: Add
- id: battery.update
label: Update
- id: battery.delete
label: Delete
- id: bmfg
label: Battery Manufacturer Access
acls:
- id: bmfg.menu
label: Menu
- id: bmfg.list
label: List
- id: bmfg.add
label: Add
- id: bmfg.update
label: Update
- id: bmfg.delete
label: Delete
- id: bmodel
label: Battery Model Access
acls:
- id: bmodel.menu
label: Menu
- id: bmodel.list
label: List
- id: bmodel.add
label: Add
- id: bmodel.update
label: Update
- id: bmodel.delete
label: Delete
- id: bsize
label: Battery Size Access
acls:
- id: bsize.menu
label: Menu
- id: bsize.list
label: List
- id: bsize.add
label: Add
- id: bsize.update
label: Update
- id: bsize.delete
label: Delete
- id: vehicle
label: Vehicle Access
acls:
- id: vehicle.menu
label: Menu
- id: vehicle.list
label: List
- id: vehicle.add
label: Add
- id: vehicle.update
label: Update
- id: vehicle.delete
label: Delete
- id: vmfg
label: Vehicle Manufacturer Access
acls:
- id: vmfg.menu
label: Menu
- id: vmfg.list
label: List
- id: vmfg.add
label: Add
- id: vmfg.update
label: Update
- id: vmfg.delete
label: Delete
- id: customer
label: Customer Access
acls:
- id: customer.menu
label: Menu
- id: customer.list
label: List
- id: customer.add
label: Add
- id: customer.update
label: Update
- id: customer.delete
label: Delete
- id: customer.dpa
label: Display DPA
- id: location
label: Location Access
acls:
- id: location.menu
label: Menu
- id: outlet
label: Outlet Access
acls:
- id: outlet.menu
label: Menu
- id: outlet.list
label: List
- id: outlet.add
label: Add
- id: outlet.update
label: Update
- id: outlet.delete
label: Delete
- id: hub
label: Hub Access
acls:
- id: hub.menu
label: Menu
- id: hub.list
label: List
- id: hub.add
label: Add
- id: hub.update
label: Update
- id: hub.delete
label: Delete
- id: geofence
label: Geofence
acls:
- id: geofence.menu
label: Menu
- id: geofence.list
label: List
- id: geofence.add
label: Add
- id: geofence.delete
label: Delete
- id: rider
label: Rider Access
acls:
- id: rider.menu
label: Menu
- id: rider.list
label: List
- id: rider.add
label: Add
- id: rider.update
label: Update
- id: rider.delete
label: Delete
- id: servicecharge
label: Service Charge
acls:
- id: service_charge.menu
label: Menu
- id: service_charge.list
label: List
- id: service_charge.add
label: Add
- id: service_charge.update
label: Update
- id: service_charge.delete
label: Delete
- id: joborder
label: Job Order
acls:
- id: joborder.menu
label: Menu
- id: jo_in.list
label: Incoming
- id: jo_proc.list
label: Dispatch
- id: jo_proc.unlock
label: Dispatch Unlock
- id: jo_assign.list
label: Rider Assignment
- id: jo_assign.unlock
label: Rider Assignment Unlock
- id: jo_fulfill.list
label: Fulfillment
- id: jo_open.list
label: Open
- id: jo_all.list
label: View All
- id: jo_pdf.list
label: PDF
- id: jo_open.edit
label: Edit
- id: joborder.cancel
label: Cancel
- id: jo_onestep.form
label: One-step Process
- id: jo_onestep.edit
label: One-step Process Edit
- id: jo_walkin.form
label: Walk-in
- id: jo_walkin.edit
label: Walk-in Edit
- id: jo_autoassign.test
label: Autoassign Test
- id: jo_hub.list
label: Hub View
- id: jo_cancel.fulfill
label: Fulfill Cancelled JO
- id: jo_resq_proc.list
label: RESQ Dispatch
- id: support
label: Customer Support Access
acls:
- id: support.menu
label: Menu
- id: general.search
label: Search
- id: warranty.search
label: Customer Battery Search
- id: warranty.upload
label: Warranty Upload
- id: ticket
label: Ticket Access
acls:
- id: ticket.menu
label: Menu
- id: ticket.list
label: List
- id: ticket.add
label: Add
- id: ticket.update
label: Update
- id: ticket.delete
label: Delete
- id: promo
label: Promo Access
acls:
- id: promo.menu
label: Menu
- id: promo.list
label: List
- id: promo.add
label: Add
- id: promo.update
label: Update
- id: promo.delete
label: Delete
- id: report
label: Reports
acls:
- id: report.menu
label: Menu
- id: report.reject
label: Rejection Report
- id: report.battery.conflict
label: Battery Conflict Report
- id: report.popapp.comparison
label: Popapp Comparison Report
- id: report.meh.customer
label: RESQ MEH Customer Report
- id: report.warranty.class
label: Warranty Class Report
- id: report.vehicle.battery.compatibility
label: Vehicle Battery Compatibility Report
- id: report.warranty.details
label: Warranty Details Report
- id: report.jo.details
label: Job Order Details Report
- id: report.jo_events
label: Job Order Events Report
- id: report.sms_messages
label: SMS Messages Report
- id: report.jo.auto_assign
label: Auto Assigned Job Order Report
- id: report.jo.advance_order
label: Advance Order Job Order Report
- id: report.customer.source
label: Customer Source Report
- id: report.hub.filter
label: Hub Filter Report
- id: report.warranty.raffle
label: Warranty Raffle Report
- id: report.jo.raffle
label: JO Raffle Report
- id: service
label: Other Services
acls:
- id: service.menu
label: Menu
- id: service.list
label: List
- id: service.add
label: Add
- id: service.update
label: Update
- id: service.delete
label: Delete
- id: partner
label: Partners
acls:
- id: partner.menu
label: Menu
- id: partner.list
label: List
- id: partner.add
label: Add
- id: partner.update
label: Update
- id: partner.delete
label: Delete
- id: motolite_event
label: Motolite Events
acls:
- id: motolite_event.menu
label: Menu
- id: motolite_event.list
label: List
- id: motolite_event.add
label: Add
- id: motolite_event.update
label: Update
- id: motolite_event.delete
label: Delete
- id: review
label: Reviews
acls:
- id: review.menu
label: Menu
- id: review.list
label: List
- id: review.view
label: View
- id: review.delete
label: Delete
- id: privacypolicy
label: Privacy Policy
acls:
- id: privacy_policy.menu
label: Menu
- id: privacy_policy.list
label: List
- id: privacy_policy.add
label: Add
- id: privacy_policy.update
label: Update
- id: privacy_policy.delete
label: Delete
- id: warranty
label: Warranty
acls:
- id: warranty.menu
label: Menu
- id: warranty.list
label: List
- id: warranty.add
label: Add
- id: warranty.update
label: Update
- id: staticcontent
label: Static Content
acls:
- id: static_content.menu
label: Menu
- id: static_content.list
label: List
- id: static_content.add
label: Add
- id: static_content.update
label: Update
- id: static_content.delete
label: Delete
- id: analytics
label: Analytics
acls:
- id: analytics.menu
label: Menu
- id: analytics.forecast
label: Forecasting
- id: sap_battery
label: SAP Battery Access
acls:
- id: sap_battery.menu
label: Menu
- id: sap_battery.list
label: List
- id: sap_battery.add
label: Add
- id: sap_battery.update
label: Update
- id: sap_battery.delete
label: Delete
- id: sap_brand
label: SAP Battery Brand Access
acls:
- id: sap_brand.menu
label: Menu
- id: sap_brand.list
label: List
- id: sap_brand.add
label: Add
- id: sap_brand.update
label: Update
- id: sap_brand.delete
label: Delete
- id: sap_bsize
label: SAP Battery Size Access
acls:
- id: sap_bsize.menu
label: Menu
- id: sap_bsize.list
label: List
- id: sap_bsize.add
label: Add
- id: sap_bsize.update
label: Update
- id: sap_bsize.delete
label: Delete
- id: sap_csize
label: SAP Battery Container Size Access
acls:
- id: sap_csize.menu
label: Menu
- id: sap_csize.list
label: List
- id: sap_csize.add
label: Add
- id: sap_csize.update
label: Update
- id: sap_csize.delete
label: Delete
- id: customer_tag
label: Customer Tags Access
acls:
- id: customer_tag.menu
label: Menu
- id: customer_tag.list
label: List
- id: customer_tag.add
label: Add
- id: customer_tag.update
label: Update
- id: customer_tag.delete
label: Delete
- id: review_tag
label: Review Tags Access
acls:
- id: review_tag.menu
label: Menu
- id: review_tag.list
label: List
- id: review_tag.add
label: Add
- id: review_tag.update
label: Update
- id: review_tag.delete
label: Delete
- id: dealer
label: Dealer Access
acls:
- id: dealer.menu
label: Menu
- id: dealer.list
label: List
- id: dealer.add
label: Add
- id: dealer.update
label: Update
- id: dealer.delete
label: Delete
- id: database
label: Database Access
acls:
- id: database.menu
label: Menu
- id: ticket_type
label: Ticket Type Access
acls:
- id: ticket_type.menu
label: Menu
- id: ticket_type.list
label: List
- id: ticket_type.add
label: Add
- id: ticket_type.update
label: Update
- id: ticket_type.delete
label: Delete
- id: subticket_type
label: Sub Ticket Type Access
acls:
- id: subticket_type.menu
label: Menu
- id: subticket_type.list
label: List
- id: subticket_type.add
label: Add
- id: subticket_type.update
label: Update
- id: subticket_type.delete
label: Delete
- id: emergency_type
label: Emergency Type Access
acls:
- id: emergency_type.menu
label: Menu
- id: emergency_type.list
label: List
- id: emergency_type.add
label: Add
- id: emergency_type.update
label: Update
- id: emergency_type.delete
label: Delete
- id: ownership_type
label: Ownership Type Access
acls:
- id: ownership_type.menu
label: Menu
- id: ownership_type.list
label: List
- id: ownership_type.add
label: Add
- id: ownership_type.update
label: Update
- id: ownership_type.delete
label: Delete
api:
user_entity: "App\\Entity\\ApiUser"
acl_data:
- id: warranty
label: Warranty Access
acls:
- id: warranty.list
label: List
- id: warranty.find.serial
label: Find by Serial
- id: warranty.find.platenumber
label: Find by Plate Number
- id: warranty.register.battery
label: Register Battery
- id: warranty.claim
label: Claim
- id: warranty.update
label: Update
- id: warranty.cancel
label: Cancel
- id: warranty.delete
label: Delete
- id: warranty.set.privacypolicy
label: Set Privacy Policy
- id: warranty.list.serial
label: List by Serial
- id: batterybrand
label: Battery Brand Access
acls:
- id: batterybrand.list
label: List
- id: batterysize
label: Battery Size Access
acls:
- id: batterysize.list
label: List
- id: battery
label: Battery Access
acls:
- id: battery.list
label: List
- id: vmanufacturer
label: Vehicle Manufacturer Access
acls:
- id: vmanufacturer.list
label: List
- id: vehicle
label: Vehicle Access
acls:
- id: vehicle.list
label: List
- id: privacypolicy
label: Privacy Policy
acls:
- id: privacypolicy.find
label: Find Privacy Policy
- id: customer
label: Customer
acls:
- id: customer.register
label: Register Customer
- id: customer.verify
label: Verify Customer
- id: municipality
label: Municipality
acls:
- id: municipality.list
label: List
- id: dealer
label: Dealer
acls:
- id: dealer.list
label: List
- id: warrantyserial
label: Warranty Serial
acls:
- id: warrantyserial.upload
label: Upload
- id: tapi_vmanufacturer
label: Third Party Vehicle Manufacturer Access
acls:
- id: tapi_vmanufacturer.list
label: List Third Party Vehicle Manufacturers
- id: tapi_vehicle
label: Third Party Vehicle Make Access
acls:
- id: tapi_vehicle.list
label: List Third Party Vehicles
- id: tapi_promo
label: Third Party Promo Access
acls:
- id: tapi_promo.list
label: List Third Party Promos
- id: tapi_battery
label: Third Party Battery Access
acls:
- id: tapi_battery_compatible.list
label: List Third Party Compatible Batteries
- id: tapi_jo
label: Third Party Job Order Access
acls:
- id: tapi_jo.request
label: Third Party Request Job Order
- id: tapi_jo.get.estimate
label: Third Party Get Estimate
- id: tapi_jo.get.ongoing
label: Third Party Get Ongoing Job Order
- id: tapi_jo.cancel
label: Third Party Cancel Job Order
- id: tapi_jo.get.invoice
label: Third Party Get Job Order Invoice
- id: tapi_jo.location.support
label: Third Party Check Location Support
- id: tapi_jo.nearest_hub.get
label: Third Party Get Nearest Hub and Slots
- id: tapi_jo.schedule_option.status
label: Third Party Schedule Option Status
- id: tapi_jo.get.info
label: Third Party Get Job Order Info
- id: tapi_service
label: Third Party Service Access
acls:
- id: tapi_service.list
label: List Third Party Services
cust_api_v2:
user_entity: "App\\Entity\\CustomerUser"
acl_data:
- id: cust_api_v2.auth
label: Authentication
acls:
- id: cust_api_v2.auth.register
label: Register
- id: cust_api_v2.auth.confirm
label: Confirm Number
- id: cust_api_v2.auth.validate
label: Validate Code
- id: cust_api_v2.auth.resend_code
label: Resend Code
- id: cust_api_v2.customer
label: Customer
acls:
- id: cust_api_v2.customer.info
label: Info
- id: cust_api_v2.customer.update
label: Update
- id: cust_api_v2.customer.status
label: Status
- id: cust_api_v2.customer.hash
label: Hash
- id: cust_api_v2.device
label: Device
acls:
- id: cust_api_v2.device.id
label: Update
- id: cust_api_v2.invoice
label: Invoice
acls:
- id: cust_api_v2.invoice.estimate
label: Estimate
- id: cust_api_v2.jo
label: Job Order
acls:
- id: cust_api_v2.jo.ongoing
label: List Ongoing
- id: cust_api_v2.jo.invoice
label: Get Invoice
- id: cust_api_v2.jo.cancel
label: Cancel
- id: cust_api_v2.jo.info
label: Info
- id: cust_api_v2.jo.history
label: History
- id: cust_api_v2.jo.latest
label: Latest
- id: cust_api_v2.jo.all_ongoing
label: List All Ongoing
- id: cust_api_v2.jo.ongoing_count
label: List Ongoing Count
- id: cust_api_v2.jo.create
label: Create
- id: cust_api_v2.jo.request
label: Request
- id: cust_api_v2.jo.completed
label: List Completed
- id: cust_api_v2.location
label: Location
acls:
- id: cust_api_v2.location.support
label: Get Support Status
- id: cust_api_v2.location.nearest_hub_and_slots
label: List Nearest Hub and Slots
- id: cust_api_v2.location.create
label: Create
- id: cust_api_v2.location.list
label: List
- id: cust_api_v2.partner
label: Partner
acls:
- id: cust_api_v2.partner.info
label: Info
- id: cust_api_v2.partner.closest
label: List Closest Partners
- id: cust_api_v2.partner.review
label: Review
- id: cust_api_v2.privacy
label: Privacy
acls:
- id: cust_api_v2.privacy.settings
label: Get Privacy Settings
- id: cust_api_v2.promo
label: Promo
acls:
- id: cust_api_v2.promo.list
label: Get Promos
- id: cust_api_v2.rider
label: Rider
acls:
- id: cust_api_v2.rider.status
label: Status
- id: cust_api_v2.rider.rating
label: Rate
- id: cust_api_v2.schedule
label: Schedule
acls:
- id: cust_api_v2.schedule.status
label: Get Schedule Option Status
- id: cust_api_v2.service
label: Service
acls:
- id: cust_api_v2.service.list
label: List
- id: cust_api_v2.vehicle
label: Vehicle
acls:
- id: cust_api_v2.vehicle.mfgs
label: List Manufacturers
- id: cust_api_v2.vehicle.makes
label: List Makes
- id: cust_api_v2.vehicle.create
label: Add
- id: cust_api_v2.vehicle.update
label: Update
- id: cust_api_v2.vehicle.list
label: List
- id: cust_api_v2.vehicle.batteries
label: Compatible Batteries
- id: cust_api_v2.vehicle.delete
label: Delete
- id: cust_api_v2.warranty
label: Warranty
acls:
- id: cust_api_v2.warranty.activate
label: Activate
- id: cust_api_v2.warranty.check
label: Check Status
- id: cust_api_v2.warranty.register
label: Register

View file

@ -0,0 +1,282 @@
catalyst_menu:
main:
- id: home
acl: dashboard.menu
label: '[menu.dashboard]'
icon: flaticon-line-graph
order: 1
- id: user
acl: user.menu
label: '[menu.user]'
icon: flaticon-users
order: 2
- id: user_list
acl: user.list
label: '[menu.user.users]'
parent: user
- id: role_list
acl: role.list
label: '[menu.user.roles]'
parent: user
- id: apiuser
acl: apiuser.menu
label: '[menu.apiuser]'
icon: flaticon-users
order: 3
- id: api_user_list
acl: apiuser.list
label: '[menu.apiuser.users]'
parent: apiuser
- id: api_role_list
acl: apirole.list
label: '[menu.apiuser.roles]'
parent: apiuser
- id: logistics
acl: logistics.menu
label: '[menu.logistics]'
icon: fa fa-truck
order: 4
- id: rider_list
acl: rider.list
label: '[menu.logistics.riders]'
parent: logistics
- id: battery
acl: battery.menu
label: '[menu.battery]'
icon: fa fa-battery-3
order: 5
- id: battery_list
acl: battery.list
label: '[menu.battery.batteries]'
parent: battery
- id: bmfg_list
acl: bmfg.list
label: '[menu.battery.manufacturers]'
parent: battery
- id: bmodel_list
acl: bmodel.list
label: '[menu.battery.models]'
parent: battery
- id: bsize_list
acl: bsize.list
label: '[menu.battery.sizes]'
parent: battery
- id: promo_list
acl: promo.list
label: '[menu.battery.promos]'
parent: battery
- id: sapbattery
acl: sap_battery.menu
label: '[menu.sapbattery]'
icon: fa fa-battery
order: 6
- id: sapbattery_list
acl: sap_battery.list
label: '[menu.sapbattery.batteries]'
parent: sapbattery
- id: sapbrand_list
acl: sap_brand.list
label: '[menu.sapbattery.brands]'
parent: sapbattery
- id: sapbsize_list
acl: sap_bsize.list
label: '[menu.sapbattery.sizes]'
parent: sapbattery
- id: sapcsize_list
acl: sap_csize.list
label: '[menu.sapbattery.csizes]'
parent: sapbattery
- id: vehicle
acl: vehicle.menu
label: '[menu.vehicle]'
icon: fa fa-car
order: 7
- id: vehicle_list
acl: vehicle.list
label: '[menu.vehicle.vehicles]'
parent: vehicle
- id: vmfg_list
acl: vmfg.list
label: '[menu.vehicle.manufacturers]'
parent: vehicle
- id: location
acl: location.menu
label: '[menu.location]'
icon: fa fa-home
order: 8
- id: outlet_list
acl: outlet.menu
label: '[menu.location.outlets]'
parent: location
- id: hub_list
acl: hub.menu
label: '[menu.location.hubs]'
parent: location
- id: dealer_list
acl: dealer.list
label: '[menu.location.dealers]'
parent: location
- id: geofence_list
acl: geofence.menu
label: '[menu.location.geofence]'
parent: location
- id: joborder
acl: joborder.menu
label: '[menu.joborder]'
icon: flaticon-calendar-3
order: 9
- id: jo_in
acl: jo_in.list
label: '[menu.joborder.incoming]'
parent: joborder
- id: jo_proc
acl: jo_proc.list
label: '[menu.joborder.dispatch]'
parent: joborder
- id: jo_resq_proc
acl: jo_resq_proc.list
label: '[menu.joborder.resqdispatch]'
parent: joborder
- id: jo_assign
acl: jo_assign.list
label: '[menu.joborder.assignment]'
parent: joborder
- id: jo_fulfill
acl: jo_fulfill.list
label: '[menu.joborder.fulfillment]'
parent: joborder
- id: jo_open
acl: jo_open.list
label: '[menu.joborder.open]'
parent: joborder
- id: jo_all
acl: jo_all.list
label: '[menu.joborder.viewall]'
parent: joborder
- id: jo_hub_view
acl: jo_hub.list
label: '[menu.joborder.hubview]'
parent: joborder
- id: support
acl: support.menu
label: '[menu.support]'
icon: flaticon-support
order: 10
- id: customer_list
acl: customer.list
label: '[menu.support.customers]'
parent: support
- id: ticket_list
acl: ticket.list
label: '[menu.support.tickets]'
parent: support
- id: general_search
acl: general.search
label: '[menu.support.search]'
parent: support
- id: warranty_search
acl: warranty.search
label: '[menu.support.warrantysearch]'
parent: support
- id: privacy_policy_list
acl: privacy_policy.list
label: '[menu.support.privacypolicy]'
parent: support
- id: warranty_list
acl: warranty.list
label: '[menu.support.warranty]'
parent: support
- id: warranty_upload
acl: warranty.upload
label: '[menu.support.warrantyupload]'
parent: support
- id: static_content_list
acl: static_content.list
label: '[menu.support.staticcontent]'
parent: support
- id: customertag_list
acl: customer_tag.list
label: '[menu.support.customertags]'
parent: support
- id: reviewtag_list
acl: review_tag.list
label: '[menu.support.reviewtags]'
parent: support
- id: service
acl: service.menu
label: '[menu.service]'
icon: flaticon-squares
order: 11
- id: service_list
acl: service.list
label: '[menu.service.services]'
parent: service
- id: partner
acl: partner.menu
label: '[menu.partner]'
icon: flaticon-network
order: 12
- id: partner_list
acl: partner.list
label: '[menu.partner.partners]'
parent: partner
- id: review_list
acl: review.list
label: '[menu.partner.reviews]'
parent: partner
- id: motolite_event
acl: motolite_event.menu
label: '[menu.motolite_event]'
icon: flaticon-event-calendar-symbol
order: 13
- id: motolite_event_list
acl: motolite_event.list
label: '[menu.motolite_event.events]'
parent: motolite_event
- id: analytics
acl: analytics.menu
label: '[menu.analytics]'
icon: flaticon-graphic
order: 14
- id: analytics_forecast_form
acl: analytics.forecast
label: '[menu.analytics.forecasting]'
parent: analytics
- id: database
acl: database.menu
label: '[menu.database]'
icon: fa fa-database
order: 15
- id: ticket_type_list
acl: ticket_type.menu
label: '[menu.database.tickettypes]'
parent: database
- id: subticket_type_list
acl: subticket_type.menu
label: '[menu.database.subtickettypes]'
parent: database
- id: emergency_type_list
acl: emergency_type.menu
label: '[menu.database.emergencytypes]'
parent: database
- id: ownership_type_list
acl: ownership_type.menu
label: '[menu.database.ownershiptypes]'
parent: database

View file

@ -9,8 +9,14 @@ security:
entity:
class: App\Entity\User
property: username
api_key_user_provider:
id: Catalyst\APIBundle\Security\APIKeyUserProvider
api_provider:
entity:
class: App\Entity\ApiUser
property: api_key
api_v2_provider:
entity:
class: App\Entity\CustomerUser
property: api_key
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
@ -47,29 +53,45 @@ security:
pattern: ^\/test_capi\/
security: false
cust_api_v2:
pattern: ^\/apiv2\/(?!register|register\/|number_confirm|number_confirm\/|code_validate|code_validate\/|resend_code|resend_code\/)
provider: api_v2_provider
access_denied_handler: Catalyst\ApiBundle\Service\AccessDeniedHandler
stateless: true
guard:
authenticators:
- Catalyst\ApiBundle\Security\Authenticator
cust_api_v2_guest:
pattern: ^\/apiv2\/(register|register\/|number_confirm|number_confirm\/|code_validate|code_validate\/|resend_code|resend_code\/)
security: false
warranty_api:
pattern: ^\/capi\/
provider: api_provider
access_denied_handler: Catalyst\ApiBundle\Service\AccessDeniedHandler
stateless: true
simple_preauth:
authenticator: Catalyst\APIBundle\Security\APIKeyAuthenticator
provider: api_key_user_provider
user_checker: Catalyst\AuthBundle\Service\UserChecker
guard:
authenticators:
- Catalyst\ApiBundle\Security\Authenticator
new_rider_api:
pattern: ^\/rider_api\/
provider: api_provider
access_denied_handler: Catalyst\ApiBundle\Service\AccessDeniedHandler
stateless: true
simple_preauth:
authenticator: Catalyst\APIBundle\Security\APIKeyAuthenticator
provider: api_key_user_provider
user_checker: Catalyst\AuthBundle\Service\UserChecker
guard:
authenticators:
- Catalyst\ApiBundle\Security\Authenticator
third_party_api:
pattern: ^\/tapi\/
provider: api_provider
access_denied_handler: Catalyst\ApiBundle\Service\AccessDeniedHandler
stateless: true
simple_preauth:
authenticator: Catalyst\APIBundle\Security\APIKeyAuthenticator
provider: api_key_user_provider
user_checker: Catalyst\AuthBundle\Service\UserChecker
guard:
authenticators:
- Catalyst\ApiBundle\Security\Authenticator
main:
provider: user_provider
@ -84,6 +106,7 @@ security:
lifetime: 604800
path: /
user_checker: Catalyst\AuthBundle\Service\UserChecker
switch_user: { role: ROLE_SUPER_ADMIN }
# activate different ways to authenticate

View file

@ -43,20 +43,6 @@ services:
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
Catalyst\AuthBundle\Service\ACLGenerator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
$acl_file: "%app_acl_file%"
Catalyst\AuthBundle\Service\ACLVoter:
arguments:
$user_class: "App\\Entity\\User"
tags: ['security.voter']
Catalyst\AuthBundle\Service\UserChecker:
App\Service\FileUploader:
arguments:
$target_dir: '%image_upload_directory%'
@ -115,50 +101,6 @@ services:
arguments:
$redis_client: "@App\\Service\\RedisClientProvider"
Catalyst\APIBundle\Security\APIKeyUserProvider:
arguments:
$em: "@doctrine.orm.entity_manager"
Catalyst\APIBundle\Security\APIKeyAuthenticator:
arguments:
$em: "@doctrine.orm.entity_manager"
Catalyst\APIBundle\Command\UserCreateCommand:
arguments:
$em: "@doctrine.orm.entity_manager"
tags: ['console.command']
Catalyst\APIBundle\Command\TestCommand:
tags: ['console.command']
Catalyst\APIBundle\Command\TestAPICommand:
tags: ['console.command']
Catalyst\APIBundle\Access\Voter:
arguments:
$acl_gen: "@Catalyst\\APIBundle\\Access\\Generator"
$user_class: "Catalyst\\APIBundle\\Entity\\User"
tags: ['security.voter']
Catalyst\APIBundle\Access\Generator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
$acl_file: "%api_acl_file%"
Catalyst\MenuBundle\Menu\Generator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
Catalyst\MenuBundle\Listener\MenuAnnotationListener:
arguments:
$menu_name: "main_menu"
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
# invoice generator
App\Service\InvoiceGenerator\ResqInvoiceGenerator: ~

247
config/routes/apiv2.yaml Normal file
View file

@ -0,0 +1,247 @@
# api
apiv2_register:
path: /apiv2/register
controller: App\Controller\CustomerAppAPI\AuthController::register
methods: [POST]
apiv2_confirm:
path: /apiv2/number_confirm
controller: App\Controller\CustomerAppAPI\AuthController::confirmNumber
methods: [POST]
apiv2_validate:
path: /apiv2/code_validate
controller: App\Controller\CustomerAppAPI\AuthController::validateCode
methods: [POST]
apiv2_info_get:
path: /apiv2/info
controller: App\Controller\CustomerAppAPI\CustomerController::getInfo
methods: [GET]
apiv2_info_update:
path: /apiv2/info
controller: App\Controller\CustomerAppAPI\CustomerController::updateInfo
methods: [POST]
apiv2_status:
path: /apiv2/status
controller: App\Controller\CustomerAppAPI\CustomerController::getStatus
methods: [GET]
apiv2_vehicle_mfg_list:
path: /apiv2/vehicle/mfgs
controller: App\Controller\CustomerAppAPI\VehicleController::listVehicleManufacturers
methods: [GET]
apiv2_vehicle_make_list:
path: /apiv2/vehicle/mfgs/{mfg_id}/makes
controller: App\Controller\CustomerAppAPI\VehicleController::listVehicleMakes
methods: [GET]
apiv2_cust_vehicle_add:
path: /apiv2/vehicles
controller: App\Controller\CustomerAppAPI\VehicleController::addVehicle
methods: [POST]
apiv2_cust_vehicle_update:
path: /apiv2/vehicles/{id}
controller: App\Controller\CustomerAppAPI\VehicleController::updateVehicle
methods: [POST]
apiv2_cust_vehicle_list:
path: /apiv2/vehicles
controller: App\Controller\CustomerAppAPI\VehicleController::listVehicles
methods: [GET]
apiv2_promo_list:
path: /apiv2/promos
controller: App\Controller\CustomerAppAPI\PromoController::listPromos
methods: [GET]
apiv2_battery_list:
path: /apiv2/vehicles/{vid}/compatible_batteries
controller: App\Controller\CustomerAppAPI\VehicleController::getCompatibleBatteries
methods: [GET]
apiv2_jo_request:
path: /apiv2/job_order
controller: App\Controller\CustomerAppAPI\JobOrderController::requestJobOrder
methods: [POST]
apiv2_estimate:
path: /apiv2/estimate
controller: App\Controller\CustomerAppAPI\InvoiceController::getEstimate
methods: [POST]
apiv2_ongoing:
path: /apiv2/job_order/ongoing
controller: App\Controller\CustomerAppAPI\JobOrderController::getOngoing
methods: [GET]
apiv2_rider_status:
path: /apiv2/rider
controller: App\Controller\CustomerAppAPI\RiderController::getRiderStatus
methods: [GET]
apiv2_rider_rating_add:
path: /apiv2/rider_rating
controller: App\Controller\CustomerAppAPI\RiderController::addRiderRating
methods: [POST]
apiv2_jo_cancel:
path: /apiv2/job_order/cancel
controller: App\Controller\CustomerAppAPI\JobOrderController:cancelJobOrder
methods: [POST]
apiv2_jo_history:
path: /apiv2/job_order/history
controller: App\Controller\CustomerAppAPI\JobOrderController:getJOHistory
methods: [GET]
apiv2_jo_invoice:
path: /apiv2/job_order/invoice
controller: App\Controller\CustomerAppAPI\JobOrderController:getJOInvoice
methods: [GET]
apiv2_device_id:
path: /apiv2/device_id
controller: App\Controller\CustomerAppAPI\DeviceController:updateDeviceID
methods: [POST]
apiv2_privacy:
path: /apiv2/privacy
controller: App\Controller\CustomerAppAPI\PrivacyController:privacySettings
methods: [POST]
apiv2_resend_code:
path: /apiv2/resend_code
controller: App\Controller\CustomerAppAPI\AuthController:resendCode
methods: [POST]
apiv2_location_support:
path: /apiv2/location_support
controller: App\Controller\CustomerAppAPI\LocationController:locationSupport
methods: [GET]
apiv2_activate_warranty:
path: /apiv2/activate_warranty
controller: App\Controller\CustomerAppAPI\WarrantyController:activateWarranty
methods: [POST]
apiv2_service_list:
path: /apiv2/services
controller: App\Controller\CustomerAppAPI\ServiceController:listServices
methods: [GET]
apiv2_partner_info:
path: /apiv2/partners/{pid}
controller: App\Controller\CustomerAppAPI\PartnerController:getPartnerInformation
methods: [GET]
apiv2_partner:
path: /apiv2/partners
controller: App\Controller\CustomerAppAPI\PartnerController:getClosestPartners
methods: [GET]
apiv2_partner_review:
path: /apiv2/partners/{pid}/review
controller: App\Controller\CustomerAppAPI\PartnerController:reviewPartner
methods: [POST]
apiv2_nearest_hub_slots:
path: /apiv2/hub_slots
controller: App\Controller\CustomerAppAPI\LocationController::getNearestHubAndSlots
methods: [GET]
apiv2_new_jo_request:
path: /apiv2/new_job_order
controller: App\Controller\CustomerAppAPI\JobOrderController::newRequestJobOrder
methods: [POST]
apiv2_version_check:
path: /apiv2/version_check
controller: App\Controller\CustomerAppAPI\AppController::versionCheck
methods: [GET]
apiv2_schedule_option_status:
path: /apiv2/schedule_option_status
controller: App\Controller\CustomerAppAPI\ScheduleController::scheduleOptionStatus
methods: [GET]
# paperless warranty / qr code
apiv2_warr_serial_check:
path: /apiv2/warranty/{serial}
controller: App\Controller\CustomerAppAPI\WarrantyController::warrantyCheck
methods: [GET]
apiv2_warr_serial_register:
path: /apiv2/warranty/{serial}
controller: App\Controller\CustomerAppAPI\WarrantyController::warrantyRegister
methods: [POST]
apiv2_jo_info:
path: /apiv2/job_order/{id}/info
controller: App\Controller\CustomerAppAPI\JobOrderController::getJobOrderInfo
methods: [GET]
apiv2_ongoing_job_orders:
path: /apiv2/job_orders/ongoing
controller: App\Controller\CustomerAppAPI\JobOrderController::getAllOngoingJobOrders
methods: [GET]
apiv2_ongoing_jo_count:
path: /apiv2/job_orders/ongoing/count
controller: App\Controller\CustomerAppAPI\JobOrderController::getOngoingJobOrderCount
methods: [GET]
apiv2_new_location:
path: /apiv2/new_location
controller: App\Controller\CustomerAppAPI\LocationController::addLocation
methods: [POST]
apiv2_locations:
path: /apiv2/locations
controller: App\Controller\CustomerAppAPI\LocationController::getLocations
methods: [GET]
apiv2_location_remove:
path: /apiv2/locations/{id}/remove
controller: App\Controller\CustomerAppAPI\LocationController::removeLocation
methods: [POST]
apiv2_cust_vehicle_remove:
path: /apiv2/vehicles/{id}/remove
controller: App\Controller\CustomerAppAPI\VehicleController::removeVehicle
methods: [POST]
apiv2_latest_job_order:
path: /apiv2/job_order/latest
controller: App\Controller\CustomerAppAPI\JobOrderController::getLatestJobOrder
methods: [GET]
apiv2_customer_hash_get:
path: /apiv2/customer_hash
controller: App\Controller\CustomerAppAPI\CustomerController::getCustomerHash
methods: [GET]
#apiv2_completed_job_orders:
# path: /apiv2/job_orders/completed
# controller: App\Controller\CustomerAppAPI\JobOrderController::getCompletedJobOrders
# methods: [GET]
# motolite events
apiv2_motolite_events:
path: /apiv2/motolite_events
controller: App\Controller\CustomerAppAPI\MotoliteEventController::getEvents
methods: [GET]
# review tags
apiv2_partner_review_tags:
path: /apiv2/review_tags/partner
controller: App\Controller\CustomerAppAPI\ReviewTagController::getPartnerReviewTags
apiv2_rider_review_tags:
path: /apiv2/review_tags/rider
controller: App\Controller\CustomerAppAPI\ReviewTagController::getRiderReviewTags

View file

@ -0,0 +1,227 @@
# api
cust_api_register:
path: /apiv2/register
controller: App\Controller\CustomerAppAPI\AuthController::register
methods: [POST]
cust_api_confirm:
path: /apiv2/number_confirm
controller: App\Controller\CustomerAppAPI\AuthController::confirmNumber
methods: [POST]
cust_api_validate:
path: /apiv2/code_validate
controller: App\Controller\CustomerAppAPI\AuthController::validateCode
methods: [POST]
cust_api_info_get:
path: /apiv2/info
controller: App\Controller\CustomerAppAPI\CustomerController::getInfo
methods: [GET]
cust_api_info_update:
path: /apiv2/info
controller: App\Controller\CustomerAppAPI\CustomerController::updateInfo
methods: [POST]
cust_api_status:
path: /apiv2/status
controller: App\Controller\CustomerAppAPI\CustomerController::getStatus
methods: [GET]
cust_api_vehicle_mfg_list:
path: /apiv2/vehicle/mfgs
controller: App\Controller\CustomerAppAPI\VehicleController::listVehicleManufacturers
methods: [GET]
cust_api_vehicle_make_list:
path: /apiv2/vehicle/mfgs/{mfg_id}/makes
controller: App\Controller\CustomerAppAPI\VehicleController::listVehicleMakes
methods: [GET]
cust_api_cust_vehicle_add:
path: /apiv2/vehicles
controller: App\Controller\CustomerAppAPI\VehicleController::addVehicle
methods: [POST]
cust_api_cust_vehicle_update:
path: /apiv2/vehicles/{id}
controller: App\Controller\CustomerAppAPI\VehicleController::updateVehicle
methods: [POST]
cust_api_cust_vehicle_list:
path: /apiv2/vehicles
controller: App\Controller\CustomerAppAPI\VehicleController::listVehicles
methods: [GET]
cust_api_promo_list:
path: /apiv2/promos
controller: App\Controller\CustomerAppAPI\PromoController::listPromos
methods: [GET]
cust_api_battery_list:
path: /apiv2/vehicles/{vid}/compatible_batteries
controller: App\Controller\CustomerAppAPI\VehicleController::getCompatibleBatteries
methods: [GET]
cust_api_jo_request:
path: /apiv2/job_order
controller: App\Controller\CustomerAppAPI\JobOrderController::requestJobOrder
methods: [POST]
cust_api_estimate:
path: /apiv2/estimate
controller: App\Controller\CustomerAppAPI\EstimateController::getEstimate
methods: [POST]
cust_api_ongoing:
path: /apiv2/job_order/ongoing
controller: App\Controller\CustomerAppAPI\JobOrderController::getOngoing
methods: [GET]
cust_api_rider_status:
path: /apiv2/rider
controller: App\Controller\CustomerAppAPI\RiderController::getRiderStatus
methods: [GET]
cust_api_rider_rating_add:
path: /apiv2/rider_rating
controller: App\Controller\CustomerAppAPI\RiderController::addRiderRating
methods: [POST]
cust_api_jo_cancel:
path: /apiv2/job_order/cancel
controller: App\Controller\CustomerAppAPI\JobOrderController:cancelJobOrder
methods: [POST]
cust_api_jo_history:
path: /apiv2/job_order/history
controller: App\Controller\CustomerAppAPI\JobOrderController:getJOHistory
methods: [GET]
cust_api_jo_invoice:
path: /apiv2/job_order/invoice
controller: App\Controller\CustomerAppAPI\JobOrderController:getJOInvoice
methods: [GET]
cust_api_device_id:
path: /apiv2/device_id
controller: App\Controller\CustomerAppAPI\DeviceController:updateDeviceID
methods: [POST]
cust_api_privacy:
path: /apiv2/privacy
controller: App\Controller\CustomerAppAPI\PrivacyController:privacySettings
methods: [POST]
cust_api_resend_code:
path: /apiv2/resend_code
controller: App\Controller\CustomerAppAPI\AuthController:resendCode
methods: [POST]
cust_api_location_support:
path: /apiv2/location_support
controller: App\Controller\CustomerAppAPI\LocationController:locationSupport
methods: [GET]
cust_api_activate_warranty:
path: /apiv2/activate_warranty
controller: App\Controller\CustomerAppAPI\WarrantyController:activateWarranty
methods: [POST]
cust_api_service_list:
path: /apiv2/services
controller: App\Controller\CustomerAppAPI\ServiceController:listServices
methods: [GET]
cust_api_partner_info:
path: /apiv2/partners/{pid}
controller: App\Controller\CustomerAppAPI\PartnerController:getPartnerInformation
methods: [GET]
cust_api_partner:
path: /apiv2/partners
controller: App\Controller\CustomerAppAPI\PartnerController:getClosestPartners
methods: [GET]
cust_api_partner_review:
path: /apiv2/partners/{pid}/review
controller: App\Controller\CustomerAppAPI\PartnerController:reviewPartner
methods: [POST]
cust_api_nearest_hub_slots:
path: /apiv2/hub_slots
controller: App\Controller\CustomerAppAPI\LocationController::getNearestHubAndSlots
methods: [GET]
cust_api_new_jo_request:
path: /apiv2/new_job_order
controller: App\Controller\CustomerAppAPI\JobOrderController::newRequestJobOrder
methods: [POST]
cust_api_version_check:
path: /apiv2/version_check
controller: App\Controller\CustomerAppAPI\AppController::versionCheck
methods: [GET]
cust_api_schedule_option_status:
path: /apiv2/schedule_option_status
controller: App\Controller\CustomerAppAPI\ScheduleController::scheduleOptionStatus
methods: [GET]
# paperless warranty / qr code
cust_api_warr_serial_check:
path: /apiv2/warranty/{serial}
controller: App\Controller\CustomerAppAPI\WarrantyController::warrantyCheck
methods: [GET]
cust_api_warr_serial_register:
path: /apiv2/warranty/{serial}
controller: App\Controller\CustomerAppAPI\WarrantyController::warrantyRegister
methods: [POST]
cust_api_jo_info:
path: /apiv2/job_order/{id}/info
controller: App\Controller\CustomerAppAPI\JobOrderController::getJobOrderInfo
methods: [GET]
cust_api_ongoing_job_orders:
path: /apiv2/job_orders/ongoing
controller: App\Controller\CustomerAppAPI\JobOrderController::getAllOngoingJobOrders
methods: [GET]
cust_api_ongoing_jo_count:
path: /apiv2/job_orders/ongoing/count
controller: App\Controller\CustomerAppAPI\JobOrderController::getOngoingJobOrderCount
methods: [GET]
cust_api_new_location:
path: /apiv2/new_location
controller: App\Controller\CustomerAppAPI\LocationController::addLocation
methods: [POST]
cust_api_locations:
path: /apiv2/locations
controller: App\Controller\CustomerAppAPI\LocationController::getLocations
methods: [GET]
cust_api_cust_vehicle_remove:
path: /apiv2/vehicles/{id}/remove
controller: App\Controller\CustomerAppAPI\VehicleController::removeVehicle
methods: [POST]
cust_api_latest_job_order:
path: /apiv2/job_order/latest
controller: App\Controller\CustomerAppAPI\JobOrderController::getLatestJobOrder
methods: [GET]
cust_api_customer_hash_get:
path: /apiv2/customer_hash
controller: App\Controller\CustomerAppAPI\CustomerController::getCustomerHash
methods: [GET]
#cust_api_completed_job_orders:
# path: /apiv2/job_orders/completed
# controller: App\Controller\CustomerAppAPI\JobOrderController::getCompletedJobOrders
# methods: [GET]

View file

@ -0,0 +1,6 @@
# insurance
insurance_listener:
path: /api/insurance/listen
controller: App\Controller\InsuranceController::listen
methods: [POST]

View file

@ -0,0 +1,38 @@
motolite_event_list:
path: /motolite_events
controller: App\Controller\MotoliteEventController::index
motolite_event_rows:
path: /motolite_events/rows
controller: App\Controller\MotoliteEventController::rows
methods: [POST]
motolite_event_create:
path: /motolite_events/create
controller: App\Controller\MotoliteEventController::addForm
methods: [GET]
motolite_event_create_submit:
path: /motolite_events/create
controller: App\Controller\MotoliteEventController::addSubmit
methods: [POST]
motolite_event_upload_image:
path: /motolite_events/upload
controller: App\Controller\MotoliteEventController::uploadImage
methods: [POST]
motolite_event_update:
path: /motolite_events/{id}
controller: App\Controller\MotoliteEventController::updateForm
methods: [GET]
motolite_event_update_submit:
path: /motolite_events/{id}
controller: App\Controller\MotoliteEventController::updateSubmit
methods: [POST]
motolite_event_delete:
path: /motolite_events/{id}
controller: App\Controller\MotoliteEventController::destroy
methods: [DELETE]

View file

@ -0,0 +1,33 @@
reviewtag_list:
path: /review_tags
controller: App\Controller\ReviewTagController::index
reviewtag_rows:
path: /review_tags/rows
controller: App\Controller\ReviewTagController::rows
methods: [POST]
reviewtag_create:
path: /review_tags/create
controller: App\Controller\ReviewTagController::addForm
methods: [GET]
reviewtag_create_submit:
path: /review_tags/create
controller: App\Controller\ReviewTagController::addSubmit
methods: [POST]
reviewtag_update:
path: /review_tags/{id}
controller: App\Controller\ReviewTagController::updateForm
methods: [GET]
reviewtag_update_submit:
path: /review_tags/{id}
controller: App\Controller\ReviewTagController::updateSubmit
methods: [POST]
reviewtag_delete:
path: /review_tags/{id}
controller: App\Controller\ReviewTagController::destroy
methods: [DELETE]

View file

@ -43,20 +43,6 @@ services:
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
Catalyst\AuthBundle\Service\ACLGenerator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
$acl_file: "%app_acl_file%"
Catalyst\AuthBundle\Service\ACLVoter:
arguments:
$user_class: "App\\Entity\\User"
tags: ['security.voter']
Catalyst\AuthBundle\Service\UserChecker:
App\Service\FileUploader:
arguments:
$target_dir: '%image_upload_directory%'
@ -81,6 +67,11 @@ services:
$redis_client: "@App\\Service\\RedisClientProvider"
$key: "mqtt_events"
App\Service\MQTTClientApiv2:
arguments:
$redis_client: "@App\\Service\\RedisClientProvider"
$key: "mqtt_events"
App\Service\APNSClient:
arguments:
$redis_client: "@App\\Service\\RedisClientProvider"
@ -120,50 +111,6 @@ services:
arguments:
$redis_client: "@App\\Service\\RedisClientProvider"
Catalyst\APIBundle\Security\APIKeyUserProvider:
arguments:
$em: "@doctrine.orm.entity_manager"
Catalyst\APIBundle\Security\APIKeyAuthenticator:
arguments:
$em: "@doctrine.orm.entity_manager"
Catalyst\APIBundle\Command\UserCreateCommand:
arguments:
$em: "@doctrine.orm.entity_manager"
tags: ['console.command']
Catalyst\APIBundle\Command\TestCommand:
tags: ['console.command']
Catalyst\APIBundle\Command\TestAPICommand:
tags: ['console.command']
Catalyst\APIBundle\Access\Voter:
arguments:
$acl_gen: "@Catalyst\\APIBundle\\Access\\Generator"
$user_class: "Catalyst\\APIBundle\\Entity\\User"
tags: ['security.voter']
Catalyst\APIBundle\Access\Generator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
$acl_file: "%api_acl_file%"
Catalyst\MenuBundle\Menu\Generator:
arguments:
$router: "@router.default"
$cache_dir: "%kernel.cache_dir%"
$config_dir: "%kernel.root_dir%/../config"
Catalyst\MenuBundle\Listener\MenuAnnotationListener:
arguments:
$menu_name: "main_menu"
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
# invoice generator
App\Service\InvoiceGenerator\ResqInvoiceGenerator: ~
@ -260,6 +207,13 @@ services:
$sub_key: "%env(MOTIV_KEY)%"
$token: "%env(MOTIV_TOKEN)%"
# insurance connector
App\Service\InsuranceConnector:
arguments:
$base_url: "%env(INSURANCE_BASE_URL)%"
$username: "%env(INSURANCE_USERNAME)%"
$password: "%env(INSURANCE_PASSWORD)%"
# entity listener for customer vehicle warranty code history
App\EntityListener\CustomerVehicleSerialListener:
arguments:
@ -331,3 +285,9 @@ services:
App\Service\WarrantySerialLoadLogger:
arguments:
$em: "@doctrine.orm.entity_manager"
# FCM sender
App\Service\FCMSender:
arguments:
$server_key: "%env(FCM_SERVER_KEY)%"
$sender_id: "%env(FCM_SENDER_ID)%"

BIN
public/assets/images/image.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -10,8 +10,8 @@ use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Entity\User as APIUser;
use Catalyst\APIBundle\Entity\Role as APIRole;
use App\Entity\ApiUser as APIUser;
use Catalyst\ApiBundle\Entity\Role as APIRole;
use App\Entity\Rider;

View file

@ -10,6 +10,8 @@ use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use App\Service\MQTTClient;
use App\Service\MQTTClientApiv2;
use App\Service\FCMSender;
use App\Entity\JobOrder;
use App\Entity\Rider;
@ -21,11 +23,19 @@ class UpdateUnacceptedJobOrdersCommand extends Command
protected $em;
protected $mclient;
public function __construct(EntityManagerInterface $em, MQTTClient $mclient)
// NOTE: for resq2 app
protected $mclientv2;
protected $fcmclient;
public function __construct(EntityManagerInterface $em, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient)
{
$this->em = $em;
$this->mclient = $mclient;
// NOTE: for resq2 app
$this->mclientv2 = $mclientv2;
$this->fcmclient = $fcmclient;
parent::__construct();
}
@ -41,6 +51,10 @@ class UpdateUnacceptedJobOrdersCommand extends Command
$em = $this->em;
$mclient = $this->mclient;
// NOTE: for resq2 app
$mclientv2 = $this->mclientv2;
$fcmclient = $this->fcmclient;
// TODO: get the timeout limit from .env
$timeout = 3;
$current_status = 'assigned';
@ -107,6 +121,10 @@ class UpdateUnacceptedJobOrdersCommand extends Command
'jo_id' => $id,
];
$mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($jo, $payload);
$fcmclient->sendJoEvent($jo, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign");
}
$rider = $jo->getRider();

View file

@ -2,8 +2,8 @@
namespace App\Controller;
use Catalyst\APIBundle\Entity\Role as APIRole;
use Catalyst\APIBundle\Access\Generator as APIACLGenerator;
use Catalyst\ApiBundle\Entity\Role as APIRole;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@ -19,7 +19,7 @@ class APIRoleController extends Controller
{
protected $api_acl_gen;
public function __construct(APIACLGenerator $api_acl_gen)
public function __construct(ACLGenerator $api_acl_gen)
{
$this->api_acl_gen = $api_acl_gen;
}

View file

@ -2,8 +2,8 @@
namespace App\Controller;
use Catalyst\APIBundle\Entity\User as APIUser;
use Catalyst\APIBundle\Entity\Role as APIRole;
use App\Entity\ApiUser as APIUser;
use Catalyst\ApiBundle\Entity\Role as APIRole;
use Doctrine\ORM\Query;
use Symfony\Component\HttpFoundation\Request;

View file

@ -6,14 +6,14 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
use App\Entity\SAPBattery;
use App\Entity\SAPBatterySize;
use App\Entity\SAPBatteryBrand;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class BatteryController extends APIController
{

View file

@ -8,8 +8,9 @@ use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
//use Catalyst\ApiBundle\Response\APIResponse;
use Catalyst\ApiBundle\Component\Response as APIResponse;
use App\Entity\Customer;
use App\Entity\CustomerVehicle;
@ -17,7 +18,7 @@ use App\Entity\Vehicle;
use App\Service\HashGenerator;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class CustomerController extends APIController
{

View file

@ -10,8 +10,8 @@ use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
use App\Service\RisingTideGateway;
use App\Service\WarrantyAPILogger;
@ -37,7 +37,7 @@ use App\Ramcar\WarrantySource;
use DateTime;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
// third party API
class CustomerWarrantyController extends APIController

View file

@ -6,12 +6,12 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
use App\Entity\Dealer;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class DealerController extends APIController
{

View file

@ -6,12 +6,12 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
use App\Entity\Municipality;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class MunicipalityController extends APIController
{

View file

@ -7,12 +7,12 @@ use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
use App\Entity\PrivacyPolicy;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
// third party API
class PrivacyPolicyController extends APIController

View file

@ -11,8 +11,8 @@ use Symfony\Contracts\Translation\TranslatorInterface;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Component\Response as APIResponse;
use App\Entity\Rider;
use App\Entity\JOEvent;
@ -22,11 +22,13 @@ use App\Entity\BatteryModel;
use App\Entity\BatterySize;
use App\Entity\RiderAPISession;
use App\Entity\User;
use Catalyst\APIBundle\Entity\User as APIUser;
use App\Entity\ApiUser as APIUser;
use App\Service\RedisClientProvider;
use App\Service\RiderCache;
use App\Service\MQTTClient;
use App\Service\MQTTClientApiv2;
use App\Service\FCMSender;
use App\Service\WarrantyHandler;
use App\Service\JobOrderHandlerInterface;
use App\Service\InvoiceGeneratorInterface;
@ -437,7 +439,7 @@ class RiderAppController extends APIController
}
public function cancelJobOrder(Request $req, EntityManagerInterface $em, MQTTClient $mclient)
public function cancelJobOrder(Request $req, EntityManagerInterface $em, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient)
{
$required_params = ['jo_id'];
@ -483,6 +485,10 @@ class RiderAppController extends APIController
];
$mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($jo, $payload);
$fcmclient->sendJoEvent($jo, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign");
$data = [];
return new APIResponse(true, 'Job order requeued.', $data);
}
@ -648,7 +654,7 @@ class RiderAppController extends APIController
}
public function arrive(Request $req, EntityManagerInterface $em, MQTTClient $mclient)
public function arrive(Request $req, EntityManagerInterface $em, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient)
{
$required_params = ['jo_id'];
@ -698,6 +704,10 @@ class RiderAppController extends APIController
];
$mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($jo, $payload);
$fcmclient->sendJoEvent($jo, "jo_fcm_title_driver_arrived", "jo_fcm_body_driver_arrived");
$data = [];
return new APIResponse(true, 'Rider arrived at customer location.', $data);
}
@ -749,7 +759,7 @@ class RiderAppController extends APIController
}
public function payment(Request $req, EntityManagerInterface $em, JobOrderHandlerInterface $jo_handler,
RisingTideGateway $rt, WarrantyHandler $wh, MQTTClient $mclient, TranslatorInterface $translator)
RisingTideGateway $rt, WarrantyHandler $wh, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient, TranslatorInterface $translator)
{
$required_params = ['jo_id'];
@ -871,6 +881,10 @@ class RiderAppController extends APIController
];
$mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($jo, $payload);
$fcmclient->sendJoEvent($jo, "jo_fcm_title_fulfilled", "jo_fcm_body_fulfilled");
$data = [];
return new APIResponse(true, 'Job order paid and fulfilled.', $data);
}

View file

@ -5,8 +5,8 @@ namespace App\Controller\CAPI;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
class TestController extends APIController
{

View file

@ -6,12 +6,12 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
use App\Entity\Vehicle;
use App\Entity\VehicleManufacturer;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class VehicleController extends APIController
{

View file

@ -7,8 +7,8 @@ use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
use App\Entity\Warranty;
use App\Entity\BatteryModel;
@ -33,7 +33,7 @@ use App\Ramcar\WarrantySource;
use DateTime;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
// third party API
class WarrantyController extends APIController

View file

@ -10,8 +10,8 @@ use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
use App\Entity\WarrantySerialQueue;
@ -19,7 +19,7 @@ use App\Service\WarrantySerialUploadLogger;
use DateTime;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
// third party API
class WarrantySerialController extends APIController

View file

@ -0,0 +1,166 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\HttpKernel\KernelInterface;
use Catalyst\ApiBundle\Controller\ApiController as BaseApiController;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Ramcar\JOStatus;
use App\Entity\Warranty;
use App\Entity\JobOrder;
use App\Entity\CustomerSession;
class ApiController extends BaseApiController
{
protected $em;
protected $session;
public function __construct(EntityManagerInterface $em, KernelInterface $kernel)
{
$this->session = new CustomerSession; // NOTE: original was null
$this->em = $em;
// load env file
$dotenv = new Dotenv();
$dotenv->loadEnv($kernel->getProjectDir() . '/.env');
}
protected function debugRequest(Request $req)
{
$all = $req->request->all();
error_log(print_r($all, true));
}
protected function hasMissingParams(Request $req, $params = [])
{
return $this->checkRequiredParameters($req, $params);
}
protected function validateSession($session_key)
{
// check if the session exists
$session = $this->em->getRepository(CustomerSession::class)->find($session_key);
if ($session === null) {
return false;
}
$this->session = $session;
return true;
}
protected function validateRequest(Request $req, $params = [])
{
$error = $this->hasMissingParams($req, $params);
$session_key = $req->query->get('session_key');
if (!$error) {
if (empty($session_key) || !$this->validateSession($session_key)) {
$error = 'Invalid session key.';
}
}
return [
'is_valid' => !$error,
'error' => $error,
];
}
protected function findWarranty($plate_number)
{
// NOTE: Modify the search for the latest warranty. This seems hacky.
// get latest warranty using plate number
$warranty_results = $this->em->getRepository(Warranty::class)->findBy(
['plate_number' => $plate_number],
['date_create' => 'desc']
);
$warr = [];
// check if warranty_results is empty
if (empty($warranty_results)) {
/*
$res->setError(true)
->setErrorMessage('No warranty found for plate number');
return $res->getReturnResponse();
*/
return $warr;
}
// get first entry
$warranty = current($warranty_results);
// check for null values for battery and date claim and date expire
$batt_model = '';
$batt_size = '';
$sap_batt = '';
$claim_date = '';
$expiry_date = '';
if (!(is_null($warranty->getBatteryModel()))) {
$batt_model = $warranty->getBatteryModel()->getName();
}
if (!(is_null($warranty->getBatterySize()))) {
$batt_size = $warranty->getBatterySize()->getName();
}
if (!(is_null($warranty->getSAPBattery()))) {
$sap_batt = $warranty->getSAPBattery()->getID();
}
if (!(is_null($warranty->getDateClaim()))) {
$claim_date = $warranty->getDateClaim()->format("d M Y");
}
if (!(is_null($warranty->getDateExpire()))) {
$expiry_date = $warranty->getDateExpire()->format("d M Y");
}
$warr[] = [
'id' => $warranty->getID(),
'serial' => $warranty->getSerial(),
'warranty_class' => $warranty->getWarrantyClass(),
'plate_number' => $warranty->getPlateNumber(),
'first_name' => $warranty->getFirstName(),
'last_name' => $warranty->getLastName(),
'mobile_number' => $warranty->getMobileNumber(),
'battery_model' => $batt_model,
'battery_size' => $batt_size,
'sap_battery' => $sap_batt,
'status' => $warranty->getStatus(),
'date_create' => $warranty->getDateCreate()->format("d M Y g:i A"),
'date_purchase' => $warranty->getDatePurchase()->format("d M Y"),
'date_expire' => $expiry_date,
'date_claim' => $claim_date,
'claim_from' => $warranty->getClaimedFrom(),
'is_activated' => $warranty->isActivated() ? 1 : 0,
];
return $warr;
}
protected function getBatteryImageURL($req, $batt)
{
// TODO: workaround for now, we get static image of battery based on model name
$filename = trim(strtolower($batt->getModel()->getName())) . '_mobile.jpg';
$file_path = $req->getSchemeAndHttpHost() . $this->generateUrl('static_battery_image') . '/' . $filename;
return $file_path;
}
protected function getOngoingJobOrders($cust)
{
$ongoing_jos = $this->em->getRepository(JobOrder::class)->findBy([
'customer' => $cust,
'status' => [JOStatus::PENDING, JOStatus::RIDER_ASSIGN, JOStatus::IN_TRANSIT, JOStatus::ASSIGNED, JOStatus::IN_PROGRESS],
], ['date_schedule' => 'desc']);
return $ongoing_jos;
}
protected function getGeoErrorMessage()
{
return 'Oops! Our service is limited to some areas in Metro Manila, Laguna, Cavite, Pampanga and Baguio only. We will update you as soon as we are able to cover your area';
}
}

View file

@ -0,0 +1,49 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
class AppController extends ApiController
{
public function versionCheck(Request $req)
{
// validate params
$missing = $this->hasMissingParams($req, [
'version',
]);
if ($missing) {
return new ApiResponse(false, $missing);
}
$need_update = false;
$msg = 'Version is up to date.';
$api_version = $this->getParameter('api_version');
$app_version = $req->query->get('version');
// putting this in for the future, in case we have diverging versions
$os = $req->query->get('os');
$platform = $req->query->get('platform');
$api_v = explode('.', $api_version);
$app_v = explode('.', $app_version);
if ($api_v[0] < $app_v[0]) {
return new ApiResponse(false, 'Invalid application version: ' . $app_version);
}
if ($api_v[0] > $app_v[0]) {
$need_update = true;
$msg = 'Your version is outdated and needs an update to use the latest features RES-Q has to offer.';
}
// response
return new ApiResponse(true, '', [
'need_update' => $need_update,
'message' => $msg,
]);
}
}

View file

@ -0,0 +1,290 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Doctrine\DBAL\DBALException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Contracts\Translation\TranslatorInterface;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Entity\Customer;
use App\Entity\CustomerUser;
use App\Entity\CustomerSession;
use App\Service\RisingTideGateway;
use DateTime;
class AuthController extends ApiController
{
public function register(Request $req)
{
// validate params
$missing = $this->hasMissingParams($req, [
'phone_model',
'os_type',
'os_version',
'phone_id',
]);
if ($missing) {
return new ApiResponse(false, $missing);
}
// retry until we get a unique id
while (true) {
try {
// instantiate session
$sess = new CustomerSession();
$sess->setPhoneModel($req->request->get('phone_model'))
->setOSType($req->request->get('os_type'))
->setOSVersion($req->request->get('os_version'))
->setPhoneID($req->request->get('phone_id'));
// reopen in case we get an exception
if (!$this->em->isOpen()) {
$this->em = $this->em->create(
$this->em->getConnection(),
$this->em->getConfiguration()
);
}
// save
$this->em->persist($sess);
$this->em->flush();
} catch (DBALException $e) {
error_log($e->getMessage());
// delay one second and try again
sleep(1);
continue;
}
break;
}
// return data
return new ApiResponse(true, '', [
'session_key' => $sess->getID(),
]);
}
public function confirmNumber(RisingTideGateway $rt, Request $req, TranslatorInterface $translator)
{
// validate request
$validity = $this->validateRequest($req, [
'phone_number'
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// phone number
$phone_number = $req->request->get('phone_number');
// get otp_mode from .env
$otp_mode = $_ENV['OTP_MODE'];
// check for hardcoded phone number for app store testing
if ($phone_number == '639221111111') {
$code = '123456';
$this->session->setConfirmCode($code)
->setPhoneNumber($phone_number);
$this->em->flush();
return new ApiResponse();
}
// check if otp_mode is test
if ($otp_mode == 'test') {
$code = '123456';
$this->session->setConfirmCode($code)
->setPhoneNumber($phone_number);
$this->em->flush();
return new ApiResponse();
}
// TODO: spam protection
// TODO: validate phone number
// generate code and save
$code = $this->generateConfirmCode();
$this->session->setConfirmCode($code)
->setPhoneNumber($phone_number);
$this->em->flush();
if ($otp_mode != 'test') {
// send sms to number
$this->sendConfirmationCode($rt, $phone_number, $code, $translator);
}
// response
return new ApiResponse();
}
public function validateCode(Request $req)
{
// validate request
$validity = $this->validateRequest($req, [
'code',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// already confirmed
if ($this->session->isConfirmed()) {
return new ApiResponse(false, 'User is already confirmed.');
}
// code is wrong
$code = $req->request->get('code');
if ($this->session->getConfirmCode() != $code) {
return new ApiResponse(false, 'Wrong confirm code.');
}
// set confirm date
$date = new DateTime();
$this->session->setDateConfirmed($date)
->setConfirmed();
// figure out if we have customer and customer user already
$customer_user = false;
// TODO: check if we have the number registered before and merge
$dupe_sess = $this->findNumberSession($this->session->getPhoneNumber());
if ($dupe_sess != null) {
error_log("Found existing customer session for " . $this->session->getPhoneNumber());
$dupe_cust = $dupe_sess->getCustomer();
$this->session->setCustomer($dupe_cust);
// set customer user if it exists
$customer_user = $dupe_sess->getCustomerUser() ?? $dupe_cust->getCustomerUser();
}
// TODO: check if mobile matches mobile of customer
$customer = $this->findCustomerByNumber($this->session->getPhoneNumber());
if ($customer != null) {
// TODO: if there is a dupe_sess, do we need to check if
// dupe_cust is the same as the customer we found?
$this->session->setCustomer($customer);
}
if (!$customer_user) {
error_log("We don't have a customer user for session " . $this->session->getID());
$customer_user = $this->findCustomerUserByNumber($this->session->getPhoneNumber());
if ($customer_user === null) {
error_log("Creating a new customer user for " . $this->session->getPhoneNumber());
$customer_user = new CustomerUser();
$customer_user->setCustomer($this->session->getCustomer())
->setPhoneNumber($this->session->getPhoneNumber());
// save
$this->em->persist($customer_user);
$this->em->flush();
} else {
error_log("Found existing customer user for " . $this->session->getPhoneNumber());
}
}
error_log("Customer user ID is " . $customer_user->getID());
// set session customer user
$this->session->setCustomerUser($customer_user);
$this->em->flush();
// response
return new ApiResponse(true, '', [
'api_key' => $customer_user->getApiKey(),
'secret_key'=> $customer_user->getSecretKey(),
]);
}
public function resendCode(Request $req, RisingTideGateway $rt, TranslatorInterface $translator)
{
// validate request
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// already confirmed
if ($this->session->isConfirmed()) {
return new ApiResponse(false, 'User is already confirmed.');
}
// have sent code before
if ($this->session->getDateCodeSent() != null) {
return new ApiResponse(false, 'Can only send confirm code every 5 mins.');
}
// TODO: send via sms
$phone_number = $this->session->getPhoneNumber();
$code = $this->session->getConfirmCode();
$this->sendConfirmationCode($rt, $phone_number, $code, $translator);
// response
return new ApiResponse();
}
protected function generateConfirmCode()
{
return sprintf("%06d", mt_rand(100000, 999999));
}
protected function sendConfirmationCode(RisingTideGateway $rt, $phone_number, $code, TranslatorInterface $translator)
{
// send sms to number
$message = $translator->trans('message.confirmation_code') . ' ' . $code;
$rt->sendSMS($phone_number, $translator->trans('message.battery_brand_allcaps'), $message);
}
// TODO: find session customer by phone number
protected function findNumberSession($number)
{
$query = $this->em->getRepository(CustomerSession::class)->createQueryBuilder('s')
->where('s.phone_number = :number')
->andWhere('s.customer is not null')
->andWhere('s.customer_user is not null')
->andWhere('s.confirm_flag = 1')
->setParameter('number', $number)
->setMaxResults(1)
->getQuery();
// we just need one
$res = $query->getOneOrNullResult();
return $res;
}
protected function findCustomerByNumber($number)
{
$customers = $this->em->getRepository(Customer::class)->findBy(['phone_mobile' => $number]);
// find the customer with the most number of cars
$car_count = 0;
$cust = null;
foreach ($customers as $customer) {
$vehicles = $customer->getVehicles();
if (count($vehicles) > $car_count) {
$car_count = count($vehicles);
// "save" customer object
$cust = $customer;
}
}
return $cust;
}
protected function findCustomerUserByNumber($number)
{
return $this->em->getRepository(CustomerUser::class)->findOneBy(['phone_number' => $number]);
}
}

View file

@ -0,0 +1,145 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Ramcar\CustomerSource;
use App\Entity\Customer;
use App\Entity\PrivacyPolicy;
use App\Service\HashGenerator;
class CustomerController extends ApiController
{
public function getInfo(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// if no customer found
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(true, '', [
'first_name' => '',
'last_name' => '',
'priv_third_party' => (bool) false,
'priv_promo' => (bool) false,
]);
}
// send back customer details
return new ApiResponse(true, '', [
'first_name' => $cust->getFirstName(),
'last_name' => $cust->getLastName(),
'priv_third_party' => (bool) $cust->getPrivacyThirdParty(),
'priv_promo' => (bool) $cust->getPrivacyPromo(),
]);
}
public function updateInfo(Request $req)
{
// validate params
$validity = $this->validateRequest($req, [
'first_name',
'last_name',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
$cust = $this->updateCustomerInfo($req);
$policy_mobile_id = $_ENV['POLICY_MOBILE'];
$mobile_policy = $this->em->getRepository(PrivacyPolicy::class)->find($policy_mobile_id);
// set policy id
if ($mobile_policy != null) {
$cust->setPrivacyPolicyMobile($mobile_policy);
}
$this->em->flush();
// response
return new ApiResponse();
}
public function getStatus(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// set data
$data = [];
if ($this->session->isConfirmed()) {
$data['status'] = 'confirmed';
} else {
$data['status'] = 'unconfirmed';
}
return new ApiResponse(true, '', $data);
}
public function getCustomerHash(Request $req, HashGenerator $hash)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get customer
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// hash customer id
$hashed_id = $hash->getHash($cust->getID());
// response
return new ApiResponse(true, '', [
'cust_hash' => $hashed_id,
]);
}
protected function updateCustomerInfo(Request $req)
{
// create new customer if it's not there
$cust = $this->session->getCustomer();
if ($cust == null) {
$cust = new Customer();
// set customer source
$cust->setCreateSource(CustomerSource::MOBILE);
$this->em->persist($cust);
$this->session->setCustomer($cust);
}
$cust->setFirstName($req->request->get('first_name'))
->setLastName($req->request->get('last_name'))
->setEmail($req->request->get('email', ''))
->setConfirmed($this->session->isConfirmed());
// if customer user isn't set, set it now
if ($cust->getCustomerUser() == null) {
$cust->setCustomerUser($this->session->getCustomerUser());
}
// update mobile phone of customer
$cust->setPhoneMobile($this->session->getPhoneNumber());
return $cust;
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
class DeviceController extends ApiController
{
public function updateDeviceID(Request $req)
{
// validate params
$validity = $this->validateRequest($req, [
'device_id',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
$device_id = $req->request->get('device_id');
$this->session->setDevicePushID($device_id);
$this->em->flush();
// response
return new ApiResponse();
}
}

View file

@ -0,0 +1,132 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Service\InvoiceGeneratorInterface;
use App\Ramcar\InvoiceCriteria;
use App\Ramcar\TradeInType;
use App\Entity\CustomerVehicle;
use App\Entity\Promo;
use App\Entity\Battery;
class InvoiceController extends ApiController
{
public function getEstimate(Request $req, InvoiceGeneratorInterface $ic)
{
// $this->debugRequest($req);
// validate params
$validity = $this->validateRequest($req, [
'service_type',
'cv_id',
// 'batt_id',
'trade_in',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// customer
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// make invoice criteria
$icrit = new InvoiceCriteria();
$icrit->setServiceType($req->request->get('service_type'));
// check promo
$promo_id = $req->request->get('promo_id');
if (!empty($promo_id)) {
$promo = $this->em->getRepository(Promo::class)->find($promo_id);
if ($promo == null) {
return new ApiResponse(false, 'Invalid promo id.');
}
// put in criteria
$icrit->addPromo($promo);
}
// check customer vehicle
$cv = $this->em->getRepository(CustomerVehicle::class)->find($req->request->get('cv_id'));
if ($cv == null) {
return new ApiResponse(false, 'Invalid customer vehicle id.');
}
$icrit->setCustomerVehicle($cv);
// check if customer owns vehicle
if ($cust->getID() != $cv->getCustomer()->getID()) {
return new ApiResponse(false, 'Customer does not own vehicle.');
}
// check battery
$batt_id = $req->request->get('batt_id');
if ($batt_id != null) {
$batt = $this->em->getRepository(Battery::class)->find($batt_id);
if ($batt == null) {
return new ApiResponse(false, 'Invalid battery id.');
}
} else
$batt = null;
/*
// put battery in criteria
$icrit->addBattery($batt);
*/
// check trade-in
// only allow motolite, other, none
$trade_in = $req->request->get('trade_in');
switch ($trade_in) {
case TradeInType::MOTOLITE:
case TradeInType::OTHER:
break;
default:
$trade_in = '';
break;
}
$icrit->addEntry($batt, $trade_in, 1);
// send to invoice generator
$invoice = $ic->generateInvoice($icrit);
// make invoice json data
$data = [
'total_price' => (float) $invoice->getTotalPrice(),
'vat_ex_price' => (float) $invoice->getVATExclusivePrice(),
'vat' => (float) $invoice->getVAT(),
'discount' => (float) $invoice->getDiscount(),
'trade_in' => (float) $invoice->getTradeIn(),
];
$items = $invoice->getItems();
$items_data = [];
foreach ($items as $item) {
$my_data = [
'title' => $item->getTitle(),
'qty' => (int) $item->getQuantity() + 0,
'price' => (float) $item->getPrice() + 0.0,
];
$item_batt = $item->getBattery();
if ($item_batt != null) {
$my_data['image_url'] = $this->getBatteryImageURL($req, $item_batt);
}
$items_data[] = $my_data;
}
$data['items'] = $items_data;
// error_log(print_r($data, true));
// response
return new ApiResponse(true, '', $data);
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,633 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use CrEOF\Spatial\PHP\Types\Geometry\Point;
use App\Ramcar\JOStatus;
use App\Service\GeofenceTracker;
use App\Service\InventoryManager;
use App\Service\MapTools;
use App\Entity\Hub;
use App\Entity\Battery;
use App\Entity\CustomerMetadata;
use DateTime;
use DateInterval;
class LocationController extends ApiController
{
public function locationSupport(Request $req, GeofenceTracker $geo)
{
// validate params
$validity = $this->validateRequest($req, [
'longitude',
'latitude',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
$long = $req->query->get('longitude');
$lat = $req->query->get('latitude');
// NOTE: had to add this for promo tag
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
$is_covered = false;
// check if customer still has promo
if (($cust->getCustomerTag('TAG_CAR_CLUB_OFFICER_PROMO')) ||
($cust->getCustomerTag('TAG_CAR_CLUB_MEMBER_PROMO'))
) {
// if has customer tag, customer has not availed of promo
$is_covered = true;
} else {
// geofence
$is_covered = $geo->isCovered($long, $lat);
}
// geofence
// $is_covered = $geo->isCovered($long, $lat);
$data = [
'longitude' => $long,
'latitude' => $lat,
'supported' => $is_covered,
];
// check if is_covered is false. If so, we need to set the error part in the response
if (!$is_covered) {
return new ApiResponse(false, $this->getGeoErrorMessage(), $data);
}
// response
return new ApiResponse(true, '', $data);
}
public function getNearestHubAndSlots(
Request $req,
MapTools $map_tools
) {
// validate params
$validity = $this->validateRequest($req, [
'longitude',
'latitude',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
$coordinates = new Point($req->query->get('longitude'), $req->query->get('latitude'));
// add checking if customer has a pre-registered hub
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// check if customer has customer tag promo
if (($cust->getCustomerTag('TAG_CAR_CLUB_OFFICER_PROMO')) ||
($cust->getCustomerTag('TAG_CAR_CLUB_MEMBER_PROMO'))
) {
// if has customer tag, customer has not availed of promo, get the hub where customer is pre-registered
$car_club_cust_hub = $cust->getCarClubCustomerHub();
if ($car_club_cust_hub != null) {
// need to get the rider slots for the pre-registered hub
$hub = $car_club_cust_hub->getHub();
$nearest_hub_slots = $this->findAdvanceNearestHubAndSlots($coordinates, $map_tools, $hub);
} else {
$nearest_hub_slots = $this->findAdvanceNearestHubAndSlots($coordinates, $map_tools);
if (empty($nearest_hub_slots['hub'])) {
return new ApiResponse(false, 'Thank you for reaching out to us. Please expect a call from us and we will assist you with your request. Thank you and stay safe!');
}
}
} else {
$nearest_hub_slots = $this->findAdvanceNearestHubAndSlots($coordinates, $map_tools);
if (empty($nearest_hub_slots['hub'])) {
return new ApiResponse(false, 'Thank you for reaching out to us. Please expect a call from us and we will assist you with your request. Thank you and stay safe!');
}
}
// response
return new ApiResponse(true, '', [
'hub_id' => $nearest_hub_slots['hub']->getID(),
'hub_slots' => $nearest_hub_slots['slots'],
]);
}
public function addLocation(Request $req)
{
// validate params
$validity = $this->validateRequest($req, [
'name',
'address',
'longitude',
'latitude',
'landmark',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get customer
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// get the information
$name = $req->request->get('name');
$address = $req->request->get('address');
$lng = $req->request->get('longitude');
$lat = $req->request->get('latitude');
$landmark = $req->request->get('landmark');
$loc_info = [
'address' => $address,
'longitude' => $lng,
'latitude' => $lat,
'landmark' => $landmark,
];
// check if customer already has existing metadata
$c_meta = $this->em->getRepository(CustomerMetadata::class)->findOneBy(['customer' => $cust]);
if ($c_meta == null) {
// create new customer meta
$cust_meta = new CustomerMetadata();
$cust_meta->setCustomer($cust);
$cust_meta->addMetaInfo($name, $loc_info);
$this->em->persist($cust_meta);
} else {
// limit locations to 6. If more than 6, pop the first one out
// add location to existing customer meta
$meta_count = count($c_meta->getAllMetaInfo());
if ($meta_count >= 6)
$c_meta->popMetaInfo();
$c_meta->addMetaInfo($name, $loc_info);
}
$this->em->flush();
// response
return new ApiResponse();
}
public function removeLocation($id, Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get customer
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// find customer metadata and delete entry if present
$cv = $this->em->getRepository(CustomerMetadata::class)->findOneBy(['customer' => $cust]);
if ($cv != null) {
$cv->deleteMetadataInfo(base64_decode($id));
}
$this->em->flush();
// response
return new ApiResponse();
}
public function getLocations(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get customer
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// get the customer meta for customer
$locations = [];
$cust_meta = $this->em->getRepository(CustomerMetadata::class)->findOneBy(['customer' => $cust]);
if ($cust_meta != null) {
$locations = $cust_meta->getAllMetaInfo();
}
$data = [
'locations' => $locations,
];
// response
return new ApiResponse(true, '', $data);
}
protected function findAdvanceNearestHubAndSlots(Point $coordinates, MapTools $map_tools, $hub = null)
{
$hub_data = [];
if ($hub != null) {
// get the slots of hub
$hub_slots = $this->getHubRiderSlots($hub);
$slots = $hub_slots['slot_data'];
$hub_data = [
'hub' => $hub,
'slots' => $slots,
];
return $hub_data;
}
// get the nearest 10 hubs
$nearest_hubs_with_distance = [];
$hubs = $map_tools->getClosestOpenHubs($coordinates, 10);
foreach ($hubs as $hub) {
$nearest_hubs_with_distance[] = $hub;
// TODO: insert checking for branch code here when inventory manager is up
}
$nearest = null;
$hub_slots = [];
$slot_found = false;
// find the nearest hub
if (!empty($nearest_hubs_with_distance)) {
// get slots of nearest hub right after getting nearest hub.
// then check if hub has available slots. If not, get next nearest hub.
foreach ($nearest_hubs_with_distance as $nhd) {
if (empty($nearest)) {
// get the slots for the hub to check if hub is available for assignment
$hub_slots = $this->getHubRiderSlots($nhd['hub']);
$flag_hub_available = $hub_slots['flag_hub_available'];
if ($flag_hub_available == true) {
$nearest = $nhd;
}
} else {
if ($nhd['distance'] < $nearest['distance']) {
// get the slots for nearest which is nhd right now
$hub_slots = $this->getHubRiderSlots($nhd['hub']);
$flag_hub_available = $hub_slots['flag_hub_available'];
// if hub is available, set hub to nearest
if ($flag_hub_available == true) {
$nearest = $nhd;
}
}
}
}
}
if ($nearest != null) {
// set hub data to what is in nearest
$hub_data = [
'hub' => $nearest['hub'],
'slots' => $hub_slots['slot_data'],
];
}
return $hub_data;
}
protected function getHubRiderSlots(Hub $hub)
{
// check hub's advance orders for the day
/*
// get number of advance orders for the next day if request came in before midnight
// or for current day if request came in after midnight
// check request_time
$request_time = time();
$midnight = strtotime('00:00');
*/
$start_date = new DateTime();
$end_date = new DateTime();
// to keep things simple, just start on next day regardless of midnight timer
$start_date->add(new DateInterval('P1D'));
$end_date->add(new DateInterval('P3D'));
/*
if ($request_time < $midnight)
{
// add +1 to start date to get the next day
// add +3 to date to end date to get the advance orders for the next three days
$start_date->add(new DateInterval('P1D'));
$end_date->add(new DateInterval('P1D'));
}
$end_date->add(new DateInterval('P2D'));
*/
// set time bounds for the start and end date
$start_date->setTime(0, 1);
$end_date->setTime(23, 59);
// NOTE: get advance orders via query
// get JOs assigned to hub that are advance orders and scheduled for the next three days with
// for hub assignment status
$query = $this->em->createQuery('select jo from App\Entity\JobOrder jo where jo.hub = :hub and jo.flag_advance = true and
jo.date_schedule >= :date_start and jo.date_schedule <= :date_end and jo.status != :status_cancelled
and jo.status != :status_fulfilled');
$jos_advance_orders = $query->setParameters([
'hub' => $hub,
'date_start' => $start_date,
'date_end' => $end_date,
'status_cancelled' => JOStatus::CANCELLED,
'status_fulfilled' => JOStatus::FULFILLED,
])
->getResult();
// check request_time
// define slots
$slots = [
'08_09' => '8:00 AM',
'09_10' => '9:00 AM',
'10_11' => '10:00 AM',
'11_12' => '11:00 AM',
'12_13' => '12:00 PM',
'13_14' => '1:00 PM',
'14_15' => '2:00 PM',
'15_16' => '3:00 PM',
'16_17' => '4:00 PM',
];
// get the dates for the next three days
$first_date = $start_date->format('Y-m-d');
$second_date = $start_date->add(new DateInterval('P1D'));
$sec_date = $second_date->format('Y-m-d');
$third_date = $end_date->format('Y-m-d');
// define days
$days = [
$first_date => $first_date,
$sec_date => $sec_date,
$third_date => $third_date,
];
// initialize hub rider slots
$hub_rider_slots = [];
foreach ($days as $day) {
foreach ($slots as $slot_key => $slot) {
$hub_rider_slots[$day][$slot_key] = $hub->getRiderSlots();
}
}
// check each JO's date_schedule, decrement rider_slots if date schedule falls in that slot
foreach ($jos_advance_orders as $jo) {
// get date key
$date_sched = $jo->getDateSchedule();
$date_string = $date_sched->format('Y-m-d');
$hour = $date_sched->format('H');
$slot_id = sprintf('%02d_%02d', $hour, $hour + 1);
// error_log("SLOT - $date_string - $slot_id");
// decrement rider slot
if (isset($hub_rider_slots[$date_string][$slot_id]))
$hub_rider_slots[$date_string][$slot_id]--;
// check if it goes through next slot (10 min allowance)
$mins = $date_sched->format('i');
if ($mins > 10) {
$next_slot_id = sprintf('%02d_%02d', $hour + 1, $hour + 2);
// error_log("NEXT SLOT - $date_string - $next_slot_id");
// decrement rider slot
if (isset($hub_rider_slots[$date_string][$next_slot_id]))
$hub_rider_slots[$date_string][$next_slot_id]--;
}
}
// error_log(print_r($hub_rider_slots, true));
$hub_slots = $this->generateHubSlots($hub_rider_slots, $slots);
// error_log(print_r($hub_slots, true));
return $hub_slots;
}
protected function generateHubSlots($rider_slots, $slots)
{
$data = [];
$total_rslots = 0;
$total_unavailable_rslots = 0;
foreach ($rider_slots as $day_id => $rslot) {
$data[$day_id] = [];
foreach ($rslot as $slot_id => $avail_slots) {
// increment total rider slots
$total_rslots++;
$slot_data = [
'id' => $slot_id,
'label' => $slots[$slot_id],
'available' => true,
];
// mark unavailable ones
if ($avail_slots <= 0) { // increment total number of unavailable slots
$total_unavailable_rslots++;
$slot_data['available'] = false;
}
// add to day data
$data[$day_id][] = $slot_data;
}
}
// check if hub has available slots
$hub_available = true;
// error_log('total rider slots ' . $total_rslots);
// error_log('total unavailable slots ' . $total_unavailable_rslots);
if ($total_rslots == $total_unavailable_rslots) {
// error_log('hub has no available slots');
$hub_available = false;
}
$hs_data = [
'flag_hub_available' => $hub_available,
'slot_data' => $data,
];
return $hs_data;
}
protected function findNearestHub($jo, MapTools $map_tools)
{
// get the nearest 10 hubs
$selected_hub = null;
$hubs = $map_tools->getClosestOpenHubs($jo->getCoordinates(), 10, date("H:i:s"));
$nearest_hubs_with_distance = [];
$nearest_branch_codes = [];
foreach ($hubs as $hub) {
$nearest_hubs_with_distance[] = $hub;
//if (!empty($hub['hub']->getBranchCode()))
// $nearest_branch_codes[] = $hub['hub']->getBranchCode();
}
// check if nearest hubs have branch codes
//if (count($nearest_branch_codes) == 0)
// return $selected_hub;
// assume all 10 have stock
// find the nearest hub with available riders
$nearest = null;
foreach ($nearest_hubs_with_distance as $nhd) {
// get number of available riders
$count_riders = count($nhd['hub']->getAvailableRiders());
// get number of advance orders in the next 3 hours
$time_now = new DateTime();
$date_end = new DateTime();
$date_end->add(new DateInterval('PT2H'));
// NOTE: get advance orders via query
// get JOs assigned to hub that are advance orders and scheduled within X hours with
// for rider assignment status
$query = $this->em->createQuery('select count(jo) from App\Entity\JobOrder jo where jo.hub = :hub and jo.flag_advance = true and jo.date_schedule <= :date_end and jo.status = :status');
$count_advance_orders = $query->setParameters([
'hub' => $nhd['hub'],
'date_end' => $date_end,
'status' => JOStatus::RIDER_ASSIGN,
])
->setMaxResults(1)
->getSingleScalarResult();
// error_log('HUB - ' . $nhd['hub']->getID());
// error_log('RIDER COUNT - ' . $count_riders);
// error_log('ADVANCE ORDER COUNT - ' . $count_advance_orders);
// if (count($nhd['hub']->getAvailableRiders()) > 0)
// if we have more riders than we have advance orders
if ($count_riders - $count_advance_orders > 0) {
if (empty($nearest))
$nearest = $nhd;
else {
if ($nhd['distance'] < $nearest['distance'])
$nearest = $nhd;
}
}
}
$selected_hub = $nearest['hub'];
return $selected_hub;
}
protected function findNearestHubWithInventory(
$jo,
Battery $batt,
MapTools $map_tools,
InventoryManager $im
) {
// get the nearest 10 hubs
$selected_hub = null;
$hubs = $map_tools->getClosestOpenHubs($jo->getCoordinates(), 10, date("H:i:s"));
$nearest_hubs_with_distance = [];
$nearest_branch_codes = [];
foreach ($hubs as $hub) {
$nearest_hubs_with_distance[] = $hub;
//if (!empty($hub['hub']->getBranchCode()))
// $nearest_branch_codes[] = $hub['hub']->getBranchCode();
}
// check if nearest hubs have branch codes
//if (count($nearest_branch_codes) == 0)
// return $selected_hub;
// assume all 10 have stock
// find the nearest hub with available riders
$nearest = null;
foreach ($nearest_hubs_with_distance as $nhd) {
if (count($nhd['hub']->getAvailableRiders()) > 0) {
if (empty($nearest))
$nearest = $nhd;
else {
if ($nhd['distance'] < $nearest['distance'])
$nearest = $nhd;
}
}
}
$selected_hub = $nearest['hub'];
// uncomment this snippet when inventory check becomes active
// get battery sku
/*
if ($batt != null)
{
$skus[] = $batt->getSAPCode();
// api call to check inventory
// pass the list of branch codes of nearest hubs and the skus
// go through returned list of branch codes
// bypass inventory check for now
// $hubs_with_inventory = $im->getBranchesInventory($nearest_branch_codes, $skus);
if (!empty($hubs_with_inventory))
{
$nearest = [];
$flag_hub_found = false;
foreach ($hubs_with_inventory as $hub_with_inventory)
{
// find hub according to branch code
$found_hub = $this->em->getRepository(Hub::class)->findOneBy(['branch_code' => $hub_with_inventory['BranchCode']]);
if ($found_hub != null)
{
// check rider availability
if (count($found_hub->getAvailableRiders()) > 0)
{
// check against nearest hubs with distance
foreach ($nearest_hubs_with_distance as $nhd)
{
// get distance of hub from location, compare with $nearest. if less, replace nearest
if ($found_hub->getID() == $nhd['hub']->getID())
{
if (empty($nearest))
{
$nearest = $nhd;
$flag_hub_found = true;
}
else
{
if ($nhd['distance'] < $nearest['distance'])
{
$nearest = $nhd;
$flag_hub_found = true;
}
}
}
}
}
}
}
$selected_hub = $nearest['hub'];
}
} */
return $selected_hub;
}
}

View file

@ -0,0 +1,51 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Entity\MotoliteEvent;
use App\Ramcar\MotoliteEventType;
class MotoliteEventController extends ApiController
{
public function getEvents(Request $req)
{
// validate params
$validity = $this->validateRequest($req, [
'limit',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
$limit = $req->query->get('limit');
// get all events
$results = $this->em->getRepository(MotoliteEvent::class)
->findBy([], ['event_time' => 'asc'], $limit);
if (empty($results)) {
return new ApiResponse(false, 'No events available.');
}
$events = [];
foreach ($results as $result) {
$events[] = [
'id' => $result->getID(),
'name' => $result->getName(),
'event_type' => MotoliteEventType::getName($result->getEventType()),
'event_time' => $result->getEventTime()->format("d M Y g:i A"),
'url' => $result->getUrl(),
'image_file' => $result->getImageFile(),
];
}
// response
return new ApiResponse(true, '', [
'events' => $events,
]);
}
}

View file

@ -0,0 +1,164 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Entity\Partner;
use App\Entity\Review;
class PartnerController extends ApiController
{
public function getPartnerInformation(Request $req, $pid)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get partner
$partner = $this->em->getRepository(Partner::class)->findOneBy(['id' => $pid]);
if ($partner == null) {
return new ApiResponse(false, 'No partner found.');
}
// get reviews for partner
$reviews = $this->em->getRepository(Review::class)->findBy(['partner' => $partner]);
// get average rating for all reviews
$average_rating = 0;
if (!empty($reviews)) {
$rating = 0;
foreach ($reviews as $review) {
$rating = $rating + $review->getRating();
}
$average_rating = $rating / sizeof($reviews);
}
$data = [];
$data['partner'] = [
'id' => $partner->getID(),
'name' => $partner->getName(),
'branch' => $partner->getBranch(),
'address' => $partner->getAddress(),
'contact_nums' => $partner->getContactNumbers(),
'time_open' => $partner->getTimeOpen()->format("g:i A"),
'time_close' => $partner->getTimeClose()->format("g:i A"),
'longitude' => $partner->getCoordinates()->getLongitude(),
'latitude' => $partner->getCoordinates()->getLatitude(),
'average_rating' => $average_rating,
];
// response
return new ApiResponse(true, '', $data);
}
public function getClosestPartners(Request $req)
{
// validate params
$validity = $this->validateRequest($req, [
'longitude',
'latitude',
'service_id',
'limit',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
$long = $req->query->get('longitude');
$lat = $req->query->get('latitude');
$service_id = $req->query->get('service_id');
$limit = $req->query->get('limit');
// get partners within range
$query = $this->em->createQuery('SELECT p, st_distance(p.coordinates, point(:lng, :lat)) as dist FROM App\Entity\Partner p
JOIN App\Entity\Service s where s.id = :service_id ORDER BY dist')
->setParameter('lat', $lat)
->setParameter('lng', $long)
->setParameter('service_id', $service_id);
$query->setMaxResults($limit);
$result = $query->getResult();
$data = [];
$partners = [];
foreach ($result as $row) {
// get all the reviews for each partner and average the ratings
$partner_id = $row[0]->getID();
$partner = $this->em->getRepository(Partner::class)->find($partner_id);
$partner_reviews = $this->em->getRepository(Review::class)->findBy(['partner' => $partner]);
$average_rating = 0;
if (count($partner_reviews) > 0) {
$rating = 0;
foreach ($partner_reviews as $review) {
$rating = $rating + $review->getRating();
}
$average_rating = $rating / sizeof($partner_reviews);
}
$partners[] = [
'id' => $row[0]->getID(),
'name' => $row[0]->getName(),
'branch' => $row[0]->getBranch(),
'address' => $row[0]->getAddress(),
'contact_nums' => $row[0]->getContactNumbers(),
'time_open' => $row[0]->getTimeOpen()->format("g:i A"),
'time_close' => $row[0]->getTimeClose()->format("g:i A"),
'longitude' => $row[0]->getCoordinates()->getLongitude(),
'latitude' => $row[0]->getCoordinates()->getLatitude(),
'db_distance' => $row['dist'],
'rating' => $average_rating,
];
}
$data['partners'] = $partners;
// response
return new ApiResponse(true, '', $data);
}
public function reviewPartner($pid, Request $req)
{
// validate params
$validity = $this->validateRequest($req, [
'rating',
'message',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
$rating = $req->request->get('rating');
$msg = $req->request->get('message');
// TODO: check rating if 1 - 5
// check if partner exists
$partner = $this->em->getRepository(Partner::class)->find($pid);
if ($partner == null) {
return new ApiResponse(false, 'No partner found.');
}
$rev = new Review();
$rev->setRating($rating)
->setMessage($msg)
->setPartner($partner)
->setCustomerSession($this->session); // NOTE: using new customer session entity
// save to db
$this->em->persist($rev);
$this->em->flush();
// response
return new ApiResponse();
}
}

View file

@ -0,0 +1,67 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Entity\PrivacyPolicy;
class PrivacyController extends ApiController
{
public function privacySettings(Request $req)
{
// validate params
$validity = $this->validateRequest($req, [
'priv_third_party',
// 'priv_promo',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get customer
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// set privacy settings
$priv_promo = $req->request->get('priv_promo', false);
$priv_third_party = $req->request->get('priv_third_party');
$cust->setPrivacyThirdParty($priv_third_party)
->setPrivacyPromo($priv_promo);
// get the policy ids from .env
$policy_promo_id = $_ENV['POLICY_PROMO'];
$policy_third_party_id = $_ENV['POLICY_THIRD_PARTY'];
// check if privacy settings are true
// if true, set the private policy for the customer
if ($priv_promo) {
// find the promo policy
$policy = $this->em->getRepository(PrivacyPolicy::class)->find($policy_promo_id);
// set policy id
if ($policy != null) {
$cust->setPrivacyPolicyPromo($policy);
}
}
if ($priv_third_party) {
// find the third party policy
$policy = $this->em->getRepository(PrivacyPolicy::class)->find($policy_third_party_id);
// set policy id
if ($policy != null) {
$cust->setPrivacyPolicyThirdParty($policy);
}
}
$this->em->flush();
// response
return new ApiResponse();
}
}

View file

@ -0,0 +1,22 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
class PromoController extends ApiController
{
public function listPromos(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// response
return new ApiResponse();
}
}

View file

@ -0,0 +1,46 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Entity\ReviewTag;
class ReviewTagController extends ApiController
{
public function getPartnerReviewTags(Request $req)
{
return $this->getTags($req, "partner");
}
public function getRiderReviewTags(Request $req)
{
return $this->getTags($req, "rider");
}
protected function getTags(Request $req, $tag_type)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get manufacturer list
$tags = $this->em->getRepository(ReviewTag::class)->findBy(['type' => $tag_type], ['name' => 'asc']);
$tag_list = [];
foreach ($tags as $tag) {
$tag_list[] = [
'id' => $tag->getID(),
'name' => $tag->getName(),
];
}
return new ApiResponse(true, '', [
'tags' => $tag_list,
]);
}
}

View file

@ -0,0 +1,241 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Ramcar\JOStatus;
use App\Ramcar\APIRiderStatus;
use App\Entity\RiderRating;
use App\Entity\JobOrder;
use App\Service\RiderTracker;
use Exception;
class RiderController extends ApiController
{
public function getRiderStatus(Request $req, RiderTracker $rt)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get customer
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// check if we have an ongoing job order
/*
$ongoing_jos = $em->getRepository(JobOrder::class)->findBy([
'customer' => $cust,
'status' => [JOStatus::PENDING, JOStatus::RIDER_ASSIGN, JOStatus::IN_TRANSIT, JOStatus::ASSIGNED, JOStatus::IN_PROGRESS],
]);
*/
$ongoing_jos = $this->getOngoingJobOrders($cust);
// $res->setData(['here' => count($ongoing_jos)]);
// return $res->getReturnResponse();
if (count($ongoing_jos) <= 0) {
try {
// check if the latest fulfilled jo they have needs rider rating
$query = $this->em->createQuery('select jo from App\Entity\JobOrder jo where jo.customer = :cust and jo.status = :status order by jo.date_fulfill desc');
$fulfill_jo = $query->setParameters([
'cust' => $cust,
'status' => JOStatus::FULFILLED,
])
->setMaxResults(1)
->getSingleResult();
} catch (Exception $e) {
// response
return new ApiResponse(true, '', [
'status' => APIRiderStatus::NO_PENDING_JO,
]);
}
// we got a recently fulfilled job order
if ($fulfill_jo) {
// check if the rider has been rated
if (!$fulfill_jo->hasRiderRating()) {
$dest = $fulfill_jo->getCoordinates();
$data = [
'jo_id' => $fulfill_jo->getID(),
'service_type' => $fulfill_jo->getServiceType(),
'destination' => [
'long' => $dest->getLongitude(),
'lat' => $dest->getLatitude(),
],
'delivery_address' => $fulfill_jo->getDeliveryAddress(),
'delivery_instructions' => $fulfill_jo->getDeliveryInstructions(),
];
$rider = $fulfill_jo->getRider();
// default image url
$url_prefix = $req->getSchemeAndHttpHost();
$image_url = $url_prefix . '/assets/images/user.gif';
if ($rider->getImageFile() != null)
$image_url = $url_prefix . '/uploads/' . $rider->getImageFile();
$data['status'] = APIRiderStatus::RIDER_RATING;
// default rider location to hub
$data['rider'] = [
'id' => $rider->getID(),
'name' => $rider->getFullName(),
'plate_num' => $rider->getPlateNumber(),
'contact_num' => $rider->getContactNumber(),
'image_url' => $image_url,
];
// response
return new ApiResponse(true, '', $data);
}
}
// response, no pending
return new ApiResponse(true, '', [
'status' => APIRiderStatus::NO_PENDING_JO,
]);
}
// get first jo that's pending
$jo = $ongoing_jos[0];
$dest = $jo->getCoordinates();
$data = [
'jo_id' => $jo->getID(),
'service_type' => $jo->getServiceType(),
'destination' => [
'long' => $dest->getLongitude(),
'lat' => $dest->getLatitude(),
],
'delivery_address' => $jo->getDeliveryAddress(),
'delivery_instructions' => $jo->getDeliveryInstructions(),
];
switch ($jo->getStatus()) {
case JOStatus::PENDING:
$data['status'] = APIRiderStatus::OUTLET_ASSIGN;
break;
case JOStatus::RIDER_ASSIGN:
$data['status'] = APIRiderStatus::RIDER_ASSIGN;
break;
case JOStatus::ASSIGNED:
case JOStatus::IN_TRANSIT:
case JOStatus::IN_PROGRESS:
$rider = $jo->getRider();
// get rider coordinates from redis
$coord = $rt->getRiderLocation($rider->getID());
// default image url
$url_prefix = $req->getSchemeAndHttpHost();
$image_url = $url_prefix . '/assets/images/user.gif';
if ($rider->getImageFile() != null)
$image_url = $url_prefix . '/uploads/' . $rider->getImageFile();
$data['status'] = APIRiderStatus::RIDER_PICK_UP;
// TODO: fix this to actual location of rider
// default rider location to hub
$data['rider'] = [
'id' => $rider->getID(),
'name' => $rider->getFullName(),
'plate_num' => $rider->getPlateNumber(),
'contact_num' => $rider->getContactNumber(),
'image_url' => $image_url,
'location' => [
'long' => $coord->getLongitude(),
'lat' => $coord->getLatitude()
]
];
break;
}
// response
return new ApiResponse(true, '', $data);
}
public function addRiderRating(Request $req)
{
// validate params
$validity = $this->validateRequest($req, [
'jo_id',
'rating',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get customer
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// get job order
$jo_id = $req->request->get('jo_id');
$jo = $this->em->getRepository(JobOrder::class)->find($jo_id);
if ($jo == null) {
return new ApiResponse(false, 'No job order found.');
}
// get rider
$rider = $jo->getRider();
if ($rider == null) {
return new ApiResponse(false, 'No rider found.');
}
// check that the customer owns the job order
$jo_cust = $jo->getCustomer();
if ($jo_cust->getID() != $cust->getID()) {
return new ApiResponse(false, 'Job order was not initiated by customer.');
}
// TODO: check job order status, if it's complete
// add rider rating
$rating_num = $req->request->get('rating', -1);
// if rating is -1
if ($rating_num == -1) {
$jo->setHasRiderRating();
$this->em->flush();
// response
return new ApiResponse();
}
$rating = new RiderRating();
$rating->setRider($rider)
->setCustomer($cust)
->setJobOrder($jo)
->setRating($rating_num);
// rider rating comment
$comment = $req->request->get('comment');
if (!empty($comment))
$rating->setComment($comment);
// mark jo as rider rated already
$jo->setHasRiderRating();
$this->em->persist($rating);
$this->em->flush();
// TODO: preliminary rating computation on the entity for now
$rider->updateRatingAverage();
$this->em->persist($rider);
$this->em->flush();
// response
return new ApiResponse();
}
}

View file

@ -0,0 +1,61 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use DateTime;
class ScheduleController extends ApiController
{
public function scheduleOptionStatus(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
$schedule_choice = true;
// remove the time check after ECQ. This will then always return true
// get current time
$current_datetime = new DateTime();
//$current_datetime = DateTime::createFromFormat('Y-m-d H:i', '2020-04-30 17:01');
// get the hour
$hour = $current_datetime->format('G');
// commenting out the time check since we can now book 24/7
// this will get uncommented out if and when ECQ will kick in
//if (($hour < 8) || ($hour > 16))
// $schedule_choice = false;
// add checking if customer has a pre-registered hub
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// check if customer has customer tag promo
if (($cust->getCustomerTag('TAG_CAR_CLUB_OFFICER_PROMO')) ||
($cust->getCustomerTag('TAG_CAR_CLUB_MEMBER_PROMO'))
) {
// if has customer tag, customer has not availed of promo, get the hub where customer is pre-registered
$car_club_hub = $cust->getCarClubCustomerHub();
if ($car_club_hub != null) {
$schedule_choice = false;
}
}
// schedule_choice will always be true aka customer can opt to
// Book Now or Schedule Order EXCEPT if customer has customer tag promo
// or ECQ comes back
// response
return new ApiResponse(true, '', [
'display_schedule_choice' => $schedule_choice,
]);
}
}

View file

@ -0,0 +1,60 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Entity\Service;
class ServiceController extends ApiController
{
public function listServices(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// services
$results = $this->em->getRepository(Service::class)->findAll();
if (empty($results)) {
return new ApiResponse(false, 'No services available.');
}
$services = [];
foreach ($results as $result) {
/*
// get partners
$partners = [];
$service_partners = $result->getPartners();
foreach($service_partners as $sp)
{
$partners[] = [
'id' => $sp->getID(),
'name' => $sp->getName(),
'branch' => $sp->getBranch(),
'address' => $sp->getAddress(),
'contact_nums' => $sp->getContactNumbers(),
'time_open' => $sp->getTimeOpen()->format("g:i A"),
'time_close' => $sp->getTimeClose()->format("g:i A"),
];
}
*/
$services[] = [
'id' => $result->getID(),
'name' => $result->getName(),
'icon' => $result->getIcon(),
// 'partners' => $partners,
];
}
// response
return new ApiResponse(true, '', [
'services' => $services,
]);
}
}

View file

@ -0,0 +1,375 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Entity\CustomerVehicle;
use App\Entity\VehicleManufacturer;
use App\Entity\Vehicle;
use DateTime;
class VehicleController extends ApiController
{
public function listVehicleManufacturers(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get manufacturer list
$mfgs = $this->em->getRepository(VehicleManufacturer::class)->findBy(['flag_mobile' => true], ['name' => 'asc']);
$mfg_list = [];
foreach ($mfgs as $mfg) {
$mfg_list[] = [
'id' => $mfg->getID(),
'name' => $mfg->getName(),
];
}
return new ApiResponse(true, '', [
'manufacturers' => $mfg_list,
]);
}
public function listVehicleMakes(Request $req, $mfg_id)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get manufacturer
$mfg = $this->em->getRepository(VehicleManufacturer::class)->find($mfg_id);
if ($mfg == null) {
// response
return new ApiResponse(false, 'Invalid vehicle manufacturer id.');
}
// get makes
$vehicles = $this->em->getRepository(Vehicle::class)->findBy(
[
'flag_mobile' => true,
'manufacturer' => $mfg_id,
],
['make' => 'asc']
);
// $vehicles = $mfg->getVehicles();
$vlist = [];
foreach ($vehicles as $v) {
$vlist[] = [
'id' => $v->getID(),
'make' => trim($v->getMake() . ' ' . $v->getModelYearFormatted(false)),
// 'make' => $v->getMake() . ' ' . $v->getModelYearFrom() . '-' . $v->getModelYearTo(),
];
}
// response
return new ApiResponse(true, '', [
'manufacturer' => [
'id' => $mfg->getID(),
'name' => $mfg->getName(),
],
'makes' => $vlist,
]);
}
public function addVehicle(Request $req)
{
// check requirements
$validity = $this->checkVehicleRequirements($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// customer vehicle
$cv = new CustomerVehicle();
// set object
$res = $this->setCustomerVehicleObject($req, $cv);
if (!$res['success']) {
return new ApiResponse(false, $res['error']);
}
// response
return new ApiResponse(true, '', [
'cv_id' => $res['cv_id'],
]);
}
public function updateVehicle(Request $req, $id)
{
// check requirements
$validity = $this->checkVehicleRequirements($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get customer vehicle
$cv = $this->em->getRepository(CustomerVehicle::class)->find($id);
// check if it exists
if ($cv == null) {
return new ApiResponse(false, 'Vehicle does not exist.');
}
// check if it's owned by customer
if ($cv->getCustomer()->getID() != $this->session->getCustomer()->getID()) {
return new ApiResponse(false, 'Invalid vehicle.');
}
// set object
$res = $this->setCustomerVehicleObject($req, $cv);
if (!$res['success']) {
return new ApiResponse(false, $res['error']);
}
// response
return new ApiResponse(true, '', [
'cv_id' => $res['cv_id'],
]);
}
public function listVehicles(Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// customer
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// vehicles
$cv_list = [];
// $cvs = $cust->getVehicles();
// only get the customer's vehicles whose flag_active is true
$cvs = $this->em->getRepository(CustomerVehicle::class)->findBy(['flag_active' => true, 'customer' => $cust]);
foreach ($cvs as $cv) {
$battery_id = null;
if ($cv->getCurrentBattery() != null)
$battery_id = $cv->getCurrentBattery()->getID();
$wty_ex = null;
if ($cv->getWarrantyExpiration() != null)
$wty_ex = $cv->getWarrantyExpiration()->format('Y-m-d');
$warranty = $this->findWarranty($cv->getPlateNumber());
$cv_name = '';
if ($cv->getName() != null)
$cv_name = $cv->getName();
$cv_list[] = [
'cv_id' => $cv->getID(),
'mfg_id' => $cv->getVehicle()->getManufacturer()->getID(),
'make_id' => $cv->getVehicle()->getID(),
'name' => $cv_name,
'plate_num' => $cv->getPlateNumber(),
'model_year' => $cv->getModelYear(),
'color' => $cv->getColor(),
'condition' => $cv->getStatusCondition(),
'fuel_type' => $cv->getFuelType(),
'wty_code' => $cv->getWarrantyCode(),
'wty_expire' => $wty_ex,
'curr_batt_id' => $battery_id,
'is_motolite' => $cv->hasMotoliteBattery() ? 1 : 0,
'is_active' => $cv->isActive() ? 1 : 0,
'warranty' => $warranty,
];
}
// response
return new ApiResponse(true, '', [
'vehicles' => $cv_list,
]);
}
public function getCompatibleBatteries(Request $req, $vid)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get vehicle
$vehicle = $this->em->getRepository(Vehicle::class)->find($vid);
if ($vehicle == null) {
return new ApiResponse(false, 'Invalid vehicle.');
}
// batteries
$batt_list = [];
$batts = $vehicle->getBatteries();
foreach ($batts as $batt) {
// TODO: Add warranty_tnv to battery information
$batt_list[] = [
'id' => $batt->getID(),
'mfg_id' => $batt->getManufacturer()->getID(),
'mfg_name' => $batt->getManufacturer()->getName(),
'model_id' => $batt->getModel()->getID(),
'model_name' => $batt->getModel()->getName(),
'size_id' => $batt->getSize()->getID(),
'size_name' => $batt->getSize()->getName(),
'price' => $batt->getSellingPrice(),
'wty_private' => $batt->getWarrantyPrivate(),
'wty_commercial' => $batt->getWarrantyCommercial(),
'image_url' => $this->getBatteryImageURL($req, $batt),
];
}
// response
return new ApiResponse(true, '', [
'vehicle' => [
'id' => $vehicle->getID(),
'mfg_id' => $vehicle->getManufacturer()->getID(),
'mfg_name' => $vehicle->getManufacturer()->getName(),
'make' => $vehicle->getMake(),
'model_year_from' => $vehicle->getModelYearFrom(),
'model_year_to' => $vehicle->getModelYearTo(),
],
'batteries' => $batt_list,
]);
}
public function removeVehicle($id, Request $req)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// get customer
$cust = $this->session->getCustomer();
if ($cust == null) {
return new ApiResponse(false, 'No customer information found.');
}
// find customer vehicle
$cv = $this->em->getRepository(CustomerVehicle::class)->find($id);
if ($cv == null) {
return new ApiResponse(false, 'Invalid customer vehicle id.');
}
// confirm that customer vehicle belongs to customer
if ($cv->getCustomer()->getID() != $cust->getID()) {
return new ApiResponse(false, 'Vehicle does not belong to customer.');
}
// we cannot remove a vehicle from customer if customer vehicle has already has JOs for it.
// instead we set the customer vehicle's flag_active to false
$cv->setActive(false);
$this->em->flush();
// response
return new ApiResponse();
}
protected function checkVehicleRequirements(Request $req)
{
// validate params
return $this->validateRequest($req, [
'make_id',
'name',
'plate_num',
'model_year',
'color',
'condition',
'fuel_type',
]);
// TODO: check valid plate number
// TODO: check valid fuel type (gas / diesel)
// TODO: check current battery id
// TODO: check condition (brand new / second-hand)
// TODO: check is_motolite and is_active (1 or 0)
// TODO: check warranty expiration date (YYYYMMDD)
// TODO: check model year coverage if it fits in between
}
protected function setCustomerVehicleObject(Request $req, CustomerVehicle $cv)
{
// check customer
$cust = $this->session->getCustomer();
if ($cust == null) {
return [
'success' => false,
'error' => 'No customer information found.',
];
}
// get vehicle
$vehicle = $this->em->getRepository(Vehicle::class)->find($req->request->get('make_id'));
if ($vehicle == null) {
return [
'success' => false,
'error' => 'Invalid vehicle make id.',
];
}
$cv->setCustomer($cust)
->setVehicle($vehicle)
->setName($req->request->get('name'))
->setPlateNumber($req->request->get('plate_num'))
->setModelYear($req->request->get('model_year'))
->setColor($req->request->get('color'))
->setFuelType($this->normalizeString($req->request->get('fuel_type')))
->setStatusCondition($this->normalizeString($req->request->get('condition')));
// set warranty code and expiration
// TODO: check warranty requirements
if (!empty($req->request->get('wty_code')))
$cv->setWarrantyCode($req->request->get('wty_code'));
if (!empty($req->request->get('wty_expire')))
$cv->setWarrantyExpiration(new DateTime($req->request->get('wty_expire')));
// TODO: get current battery
// is motolite
if ($req->request->get('is_motolite') == 0)
$cv->setHasMotoliteBattery(false);
else
$cv->setHasMotoliteBattery(true);
// is active
if ($req->request->get('is_active') == 0)
$cv->setActive(false);
else
$cv->setActive(true);
// save
$this->em->persist($cv);
$this->em->flush();
// response
return [
'success' => true,
'cv_id' => $cv->getID(),
];
}
protected function normalizeString($string)
{
return trim(strtolower($string));
}
}

View file

@ -0,0 +1,614 @@
<?php
namespace App\Controller\CustomerAppAPI;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Catalyst\ApiBundle\Component\Response as ApiResponse;
use App\Entity\Warranty;
use App\Entity\WarrantySerial;
use App\Entity\SAPBattery;
use App\Entity\CustomerVehicle;
use App\Service\WarrantyRaffleLogger;
use App\Service\WarrantyAPILogger;
use App\Service\RisingTideGateway;
use App\Ramcar\WarrantySource;
use DateTime;
class WarrantyController extends ApiController
{
public function activateWarranty(Request $req)
{
// validate params
$validity = $this->validateRequest($req, [
'plate_number',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
$plate_number = $req->request->get('plate_number');
// find warranty using plate number
$warranty_results = $this->em->getRepository(Warranty::class)->findBy(
['plate_number' => $plate_number],
['date_create' => 'desc']
);
// check if warranty_results is empty
if (empty($warranty_results)) {
return new ApiResponse(false, 'No warranty found for plate number.');
}
// activate all entries
foreach ($warranty_results as $warranty) {
$warranty->setActivated();
}
$this->em->flush();
// response
return new ApiResponse();
}
public function warrantyCheck($serial, Request $req, WarrantyRaffleLogger $raffle_logger)
{
// validate params
$validity = $this->validateRequest($req);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// check if warranty serial is there
$serial = $this->cleanSerial($serial);
$warr_serial = $this->em->getRepository(WarrantySerial::class)->find($serial);
$warr = $this->em->getRepository(Warranty::class)->findOneBy(['serial' => $serial]);
$batt = null;
$is_registered = false;
if ($warr_serial == null) {
return new ApiResponse(false, 'Invalid warranty serial code.');
}
$today = new DateTime();
$user_id = $req->query->get('session_key');
$raffle_data = [
'user_id' => $user_id,
'serial' => $serial,
'warranty_id' => null,
'action' => '',
'bmodel_name' => '',
'bsize_name' => '',
'first_name' => '',
'last_name' => '',
'plate_number' => '',
'contact_num' => '',
'email' => '',
'address' => '',
];
$data_sent = [];
// if we have a warranty entry for the serial already
if ($warr != null) {
$warr_plate = $warr->getPlateNumber();
$is_registered = true;
$is_customer_warranty = false;
// check if the warranty is registered to a car owned by the customer
$cust = $this->session->getCustomer();
$is_customer_warranty = $this->checkCustomerPlateNumber($warr_plate, $cust);
// null mobile number should be blank string instead
if ($warr->getMobileNumber() == null)
$mobile_num = '';
else
$mobile_num = $warr->getMobileNumber();
$can_edit = $is_customer_warranty;
// if customer plate number matches the one registered on the warranty
if ($is_customer_warranty) {
// purchase date of customer
if ($warr->getDatePurchaseCustomer() != null)
$date_purchase_cust = $warr->getDatePurchaseCustomer()->format('Y-m-d');
else
$date_purchase_cust = $today->format('Y-m-d');
// invoice
if ($warr->getFileInvoice() != null)
$invoice_url = $req->getSchemeAndHttpHost() . '/warranty_uploads/' . $warr->getFileInvoice();
else
$invoice_url = '';
// warranty card
if ($warr->getFileWarrantyCard() != null)
$warr_card_url = $req->getSchemeAndHttpHost() . '/warranty_uploads/' . $warr->getFileWarrantyCard();
else
$warr_card_url = '';
$customer = [
'first_name' => $warr->getFirstName() ?? '',
'last_name' => $warr->getLastName() ?? '',
'mobile_number' => $mobile_num,
'plate_number' => $warr_plate,
'email' => $warr->getEmail() ?? '',
'contact_num' => $warr->getContactNumber() ?? '',
'address' => $warr->getCustomerAddress() ?? '',
];
$other_data = [
'odometer' => (int) $warr->getOdometer() ?? 0,
'date_purchase' => $date_purchase_cust,
'invoice' => $invoice_url,
'warr_card' => $warr_card_url,
'dealer_name' => $warr->getDealerName() ?? '',
'dealer_address' => $warr->getDealerAddress() ?? '',
'branch_code' => $warr->getDealerBranchCode() ?? '',
];
// set customer info and action for raffle log
$raffle_data['action'] = 'serial_check_customer';
$raffle_data['first_name'] = $customer['first_name'];
$raffle_data['last_name'] = $customer['last_name'];
$raffle_data['plate_number'] = $customer['plate_number'];
$raffle_data['email'] = $customer['email'];
$raffle_data['contact_num'] = $customer['contact_num'];
$raffle_data['address'] = $customer['address'];
$raffle_data['warranty_id'] = $warr->getID();
} else {
// hide customer information if customer is not the one registered
$customer = [
'first_name' => '',
'last_name' => '',
'mobile_number' => '',
'plate_number' => '',
'email' => '',
'contact_num' => '',
'address' => '',
];
$other_data = [
'odometer' => 0,
'date_purchase' => $today->format('Y-m-d'),
'invoice' => '',
'warr_card' => '',
'dealer_name' => '',
'dealer_address' => '',
'branch_code' => '',
];
// set action for raffle log
$raffle_data['action'] = 'serial_check_not_customer';
}
} else {
$can_edit = true;
$customer = [
'first_name' => '',
'last_name' => '',
'mobile_number' => '',
'plate_number' => '',
'email' => '',
'contact_num' => '',
'address' => '',
];
$other_data = [
'odometer' => 0,
'date_purchase' => $today->format('Y-m-d'),
'invoice' => '',
'warr_card' => '',
'dealer_name' => '',
'dealer_address' => '',
'branch_code' => '',
];
// set action for raffle log
$raffle_data['action'] = 'serial_check_customer';
}
$sku = $warr_serial->getSKU();
$batt = null;
$cat_name = '';
if ($sku != null)
$batt = $this->em->getRepository(SAPBattery::class)->find($sku);
else {
// get the category name of the serial
$cat_name = $warr_serial->getMetaInfo('category_name');
}
// TODO: put this in a config file
$image_url = $req->getSchemeAndHttpHost() . '/battery/generic.png';
if ($batt != null) {
$battery = [
'brand' => $batt->getBrand()->getName(),
'size' => $batt->getSize()->getName(),
'image_url' => $image_url,
];
} else {
$battery = [
'brand' => $cat_name,
'size' => '',
'image_url' => '',
];
}
// set the rest of the raffle log entry
$raffle_data['bmodel_name'] = $battery['brand'];
$raffle_data['bsize_name'] = $battery['size'];
// log the raffle log
$raffle_logger->logRaffleInfo($data_sent, $raffle_data);
// response
return new ApiResponse(true, '', [
'is_valid' => true,
'is_registered' => $is_registered,
'can_edit' => $can_edit,
'customer' => $customer,
'battery' => $battery,
'odometer' => $other_data['odometer'],
'invoice' => $other_data['invoice'],
'warr_card' => $other_data['warr_card'],
'date_purchase' => $other_data['date_purchase'],
'dealer_name' => $other_data['dealer_name'],
'dealer_address' => $other_data['dealer_address'],
'branch_code' => $other_data['branch_code'],
'message' => [
'register_error' => 'Warranty serial code has already been registered.',
'edit_error' => 'Sorry, warranty is registered under another vehicle not in your list of vehicles.',
],
]);
}
public function warrantyRegister(
$serial,
Request $req,
KernelInterface $kernel,
RisingTideGateway $rt,
TranslatorInterface $trans,
WarrantyRaffleLogger $raffle_logger,
WarrantyAPILogger $logger
) {
// validate params
$validity = $this->validateRequest($req, [
'first_name',
'last_name',
'plate_number',
'date_purchase',
]);
if (!$validity['is_valid']) {
return new ApiResponse(false, $validity['error']);
}
// handle file uploads
$invoice = $req->files->get('invoice');
$warr_card = $req->files->get('warr_card');
// normalize serial
$serial = $this->cleanSerial($serial);
// $serial = trim(strtoupper($serial));
// process picture uploads
$upload_dir = $kernel->getProjectDir() . '/public/warranty_uploads';
$inv_filename = $this->handlePictureUpload($invoice, $upload_dir, $serial, 'invoice');
$wcard_filename = $this->handlePictureUpload($warr_card, $upload_dir, $serial, 'wcard');
$user_id = $req->query->get('session_key');
$log_data = [
'plate_number' => $req->request->get('plate_num'),
'first_name' => $req->request->get('first_name'),
'last_name' => $req->request->get('last_name'),
'date_purchase' => $req->request->get('date_purchase'),
];
$action = 'create/update';
$source = WarrantySource::MOBILE;
// update customer information
// $cust = $this->updateCustomerInfo($req, $em);
// update warranty
$res = $this->updateWarranty(
$rt,
$trans,
$req,
$serial,
$inv_filename,
$wcard_filename,
$logger,
$log_data,
$user_id,
$action,
$source,
$raffle_logger
);
if (!$res['success']) {
return new ApiResponse(false, $res['error']);
}
$this->em->flush();
return new ApiResponse();
}
protected function handlePictureUpload($file, $target_dir, $serial, $name)
{
// error_log("handling $name upload");
// no file sent
if ($file == null) {
error_log("handling $name upload - no file");
return null;
}
// create target dir if it doesn't exist
if (!file_exists($target_dir)) {
if (!mkdir($target_dir, 0744, true)) {
error_log('failed to create folder for warranty pictures');
return null;
}
}
// move file
$filename = $name . '.' . $file->getClientOriginalExtension();
$file->move($target_dir . '/' . $serial, $filename);
// error_log("filename - $filename");
// error_log($target_dir . '/' . $serial . '/' . $filename);
return $serial . '/' . $filename;
}
// TODO: put this in a service
protected function cleanSerial($serial)
{
// trim and make everything upper case
$clean_serial = trim(strtoupper($serial));
// remove QR prefix if it exists
// $prefix = substr($clean_serial, 0, 2);
// if ($prefix == 'QR')
// $clean_serial = substr($clean_serial, 2);
return $clean_serial;
}
protected function checkCustomerPlateNumber($plate_number, $cust)
{
// strip spaces and make all caps
$plate_number = preg_replace('/\s+/', '', strtoupper($plate_number));
// if there's no customer linked to session
if ($cust != null) {
// check all the customer vehicles
$cvs = $cust->getVehicles();
foreach ($cvs as $cv) {
$cv_plate = preg_replace('/\s+/', '', strtoupper($cv->getPlateNumber()));
// did we find a match?
if ($cv_plate == $plate_number) {
return true;
}
}
}
return false;
}
protected function updateWarranty($rt, $trans, $req, $serial, $inv_filename = null, $wcard_filename = null, $logger, $log_data, $user_id, $action, $source, $raffle_logger)
{
// prepare raffle log entry
$raffle_data = [
'user_id' => $user_id,
'serial' => $serial,
'warranty_id' => null,
'action' => '',
'bmodel_name' => '',
'bsize_name' => '',
'first_name' => '',
'last_name' => '',
'plate_number' => '',
'contact_num' => '',
'email' => '',
'address' => '',
];
// get serial
$warr_serial = $this->em->getRepository(WarrantySerial::class)->find($serial);
if ($warr_serial == null) {
return [
'success' => false,
'error' => 'Invalid warranty serial code.',
];
}
// check if warranty exists already
$warr = $this->em->getRepository(Warranty::class)->findOneBy(['serial' => $serial]);
// skip warranty if it already exists
if ($warr != null) {
/*
// NOTE: we could not update in the old version
$res->setError(true)
->setErrorMessage('Warranty registration entry already exists.');
return $res;
*/
// check if warranty is registered to a serial owned by customer
$warr_plate = $warr->getPlateNumber();
$cust = $this->session->getCustomer();
$is_customer_warranty = $this->checkCustomerPlateNumber($warr_plate, $cust);
if (!$is_customer_warranty) {
$error_msg = 'Warranty registered to a vehicle not in your list of vehicles.';
// set action to update
$action = 'update';
$logger->logWarrantyInfo($log_data, $error_msg, $user_id, $action, $source);
// response
return [
'success' => false,
'error' => $error_msg,
];
}
$sms_msg = $trans->trans('warranty_update_confirm');
// update raffle data action
$raffle_data['action'] = 'warranty_update';
} else {
$warr = new Warranty();
$sms_msg = $trans->trans('warranty_register_confirm');
// set warranty source
$warr->setCreateSource($source);
// update raffle data action
$raffle_data['action'] = 'warranty_create';
}
// get sap battery
$sku = $warr_serial->getSKU();
$sap_bty = null;
if ($sku != null) {
$sap_bty = $this->em->getRepository(SAPBattery::class)->find($sku);
if ($sap_bty == null) {
$error_msg = 'Could not find battery entry for warranty.';
$logger->logWarrantyInfo($log_data, $error_msg, $user_id, $action, $source);
// response
return [
'success' => false,
'error' => $error_msg,
];
}
}
// default date purchase to today
// NOTE: might need to change this later
$date_pur = new DateTime();
// get date purchase specified by customer
$date_pur_cust = DateTime::createFromFormat('Y-m-d', $req->request->get('date_purchase'));
if (!$date_pur_cust) {
$error_msg = 'Invalid date format for date of purchase.';
$logger->logWarrantyInfo($log_data, $error_msg, $user_id, $action, $source);
// response
return [
'success' => false,
'error' => $error_msg,
];
}
$customer = $this->session->getCustomer();
if ($customer != null) {
$warr->setCustomer($customer);
// get customer vehicles
$vehicle = $this->findCustomerVehicle($customer, $req->request->get('plate_number'));
if ($vehicle != null)
$warr->setVehicle($vehicle);
}
// TODO: make a standard clean plate number service
// clean plate number
$plate = $req->request->get('plate_number');
// upper case and remove spaces
$plate = strtoupper(str_replace(' ', '', $plate));
// remove special characters
$plate = preg_replace('/[^A-Za-z0-9. -]/', '', $plate);
// create or update warranty entry
$warr->setSerial($serial)
->setFirstName($req->request->get('first_name'))
->setLastName($req->request->get('last_name'))
->setEmail($req->request->get('email'))
->setPlateNumber($plate)
// TODO: figure out how to compute date of purchase
->setDatePurchase($date_pur)
// TODO: set status
// ->setStatus()
// TODO: set battery model and size id
// ->setBatterySize()
// ->setBatteryModel()
->setSAPBattery($sap_bty)
->setMobileNumber(substr($this->session->getPhoneNumber(), 2))
->setActivated(true)
// files
->setFileInvoice($inv_filename)
->setFileWarrantyCard($wcard_filename)
// new fields
->setOdometer($req->request->get('odometer', 0))
->setDatePurchaseCustomer($date_pur_cust)
->setContactNumber($req->request->get('contact_num'))
->setCustomerAddress($req->request->get('cust_address'))
->setDealerName($req->request->get('dealer_name'))
->setDealerAddress($req->request->get('dealer_address'))
->setDealerBranchCode($req->request->get('branch_code'))
->setValidated(false);
// TODO: check for date purchase and date expire
$this->em->persist($warr);
// TODO: check if we need to do anyting else
$logger->logWarrantyInfo($log_data, '', $user_id, $action, $source);
// send sms
// error_log('sending sms to - ' . $this->session->getPhoneNumber());
$rt->sendSMS($this->session->getPhoneNumber(), $trans->trans('message.battery_brand_allcaps'), $sms_msg);
// prepare the rest of the raffle log entry
$raffle_data['warranty_id'] = $warr->getID();
$raffle_data['bmodel_name'] = $sap_bty->getBrand()->getName();
$raffle_data['bsize_name'] = $sap_bty->getSize()->getName();
$raffle_data['first_name'] = $req->request->get('first_name', '');
$raffle_data['last_name'] = $req->request->get('last_name', '');
$raffle_data['plate_number'] = $plate;
$raffle_data['contact_num'] = $req->request->get('contact_num', '');
$raffle_data['email'] = $req->request->get('email', '');
$raffle_data['address'] = $req->request->get('cust_address', '');
$data_sent = [
'plate_number' => $req->request->get('plate_number'),
'first_name' => $req->request->get('first_name'),
'last_name' => $req->request->get('last_name'),
'date_purchase' => $req->request->get('date_purchase'),
'address' => $req->request->get('cust_address', ''),
'email' => $req->request->get('email', ''),
'contact_num' => $req->request->get('contact_num', ''),
];
// log raffle data
$raffle_logger->logRaffleInfo($data_sent, $raffle_data);
// response
return [
'success' => true,
];
}
protected function findCustomerVehicle($customer, $plate_number)
{
$clean_plate = Warranty::cleanPlateNumber($plate_number);
if ($clean_plate) {
// find the customer vehicle and get the vehicle
$cv = $this->em->getRepository(CustomerVehicle::class)->findOneBy(['plate_number' => $clean_plate, 'customer' => $customer]);
if ($cv != null) {
$vehicle = $cv->getVehicle();
return $vehicle;
}
}
return null;
}
}

View file

@ -0,0 +1,23 @@
<?php
namespace App\Controller;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class InsuranceController extends Controller
{
public function listen(Request $req, EntityManagerInterface $em)
{
$payload = $req->request->all();
error_log(print_r($payload, true));
return $this->json([
'success' => true,
'payload' => $payload,
]);
}
}

View file

@ -21,6 +21,8 @@ use App\Service\JobOrderHandlerInterface;
use App\Service\GISManagerInterface;
use App\Service\MapTools;
use App\Service\MQTTClient;
use App\Service\MQTTClientApiv2;
use App\Service\FCMSender;
use App\Service\APNSClient;
use App\Service\InventoryManager;
use App\Service\HubSelector;
@ -29,7 +31,6 @@ use App\Service\RiderTracker;
use App\Service\MotivConnector;
use App\Service\GeofenceTracker;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
@ -354,7 +355,7 @@ class JobOrderController extends Controller
return $this->render($template, $params);
}
public function processingSubmit(Request $req, JobOrderHandlerInterface $jo_handler, MQTTClient $mclient, $id)
public function processingSubmit(Request $req, JobOrderHandlerInterface $jo_handler, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient, $id)
{
$this->denyAccessUnlessGranted('jo_proc.list', null, 'No access.');
@ -362,7 +363,7 @@ class JobOrderController extends Controller
$error_array = [];
try
{
$error_array = $jo_handler->dispatchJobOrder($req, $id, $mclient);
$error_array = $jo_handler->dispatchJobOrder($req, $id, $mclient, $mclientv2, $fcmclient);
}
catch (AccessDeniedHttpException $e)
{
@ -421,7 +422,7 @@ class JobOrderController extends Controller
}
public function assigningSubmit(Request $req, JobOrderHandlerInterface $jo_handler, MQTTCLient $mclient, APNSClient $aclient, $id)
public function assigningSubmit(Request $req, JobOrderHandlerInterface $jo_handler, MQTTCLient $mclient, FCMSender $fcmclient, APNSClient $aclient, $id)
{
$this->denyAccessUnlessGranted('jo_assign.list', null, 'No access.');
@ -481,7 +482,7 @@ class JobOrderController extends Controller
return $this->render($template, $params);
}
public function fulfillmentSubmit(Request $req, JobOrderHandlerInterface $jo_handler, MQTTClient $mclient, $id)
public function fulfillmentSubmit(Request $req, JobOrderHandlerInterface $jo_handler, MQTTClient $mclient, FCMSender $fcmclient, $id)
{
$this->denyAccessUnlessGranted('jo_fulfill.list', null, 'No access.');
@ -540,7 +541,7 @@ class JobOrderController extends Controller
return $this->render($template, $params);
}
public function openHubSubmit(Request $req, JobOrderHandlerInterface $jo_handler, MQTTClient $mclient, $id)
public function openHubSubmit(Request $req, JobOrderHandlerInterface $jo_handler, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient, $id)
{
$this->denyAccessUnlessGranted('jo_open.list', null, 'No access.');
@ -549,7 +550,7 @@ class JobOrderController extends Controller
try
{
$error_array = $jo_handler->setHub($req, $id, $mclient);
$error_array = $jo_handler->setHub($req, $id, $mclient, $mclientv2, $fcmclient);
}
catch (NotFoundHttpException $e)
{
@ -598,7 +599,7 @@ class JobOrderController extends Controller
return $this->render($template, $params);
}
public function openRiderSubmit(Request $req, JobOrderHandlerInterface $jo_handler, MQTTClient $mclient, $id)
public function openRiderSubmit(Request $req, JobOrderHandlerInterface $jo_handler, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient, $id)
{
$this->denyAccessUnlessGranted('jo_open.list', null, 'No access.');
@ -607,7 +608,7 @@ class JobOrderController extends Controller
try
{
$error_array = $jo_handler->setRider($req, $id, $mclient);
$error_array = $jo_handler->setRider($req, $id, $mclient, $mclientv2, $fcmclient);
}
catch (NotFoundHttpException $e)
{
@ -681,7 +682,7 @@ class JobOrderController extends Controller
]);
}
public function cancelJobOrder(Request $req, JobOrderHandlerInterface $jo_handler, MQTTClient $mclient, $id)
public function cancelJobOrder(Request $req, JobOrderHandlerInterface $jo_handler, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient, $id)
{
$this->denyAccessUnlessGranted('joborder.cancel', null, 'No access.');
@ -698,7 +699,7 @@ class JobOrderController extends Controller
try
{
$jo_handler->cancelJobOrder($req, $id, $mclient);
$jo_handler->cancelJobOrder($req, $id, $mclient, $mclientv2, $fcmclient);
}
catch (NotFoundHttpException $e)
{

View file

@ -0,0 +1,304 @@
<?php
namespace App\Controller;
use App\Entity\MotoliteEvent;
use App\Ramcar\MotoliteEventType;
use App\Service\FileUploader;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Encoder\EncoderFactoryInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use DateTime;
use Catalyst\MenuBundle\Annotation\Menu;
class MotoliteEventController extends Controller
{
/**
* @Menu(selected="motolite_event_list")
*/
public function index()
{
$this->denyAccessUnlessGranted('motolite_event.list', null, 'No access.');
return $this->render('motolite-event/list.html.twig');
}
public function rows(Request $req)
{
$this->denyAccessUnlessGranted('motolite_event.list', null, 'No access.');
// get query builder
$qb = $this->getDoctrine()
->getRepository(MotoliteEvent::class)
->createQueryBuilder('q');
// get datatable params
$datatable = $req->request->get('datatable');
// count total records
$tquery = $qb->select('COUNT(q)');
$this->setQueryFilters($datatable, $tquery);
$total = $tquery->getQuery()
->getSingleScalarResult();
// get current page number
$page = $datatable['pagination']['page'] ?? 1;
$perpage = $datatable['pagination']['perpage'];
$offset = ($page - 1) * $perpage;
// add metadata
$meta = [
'page' => $page,
'perpage' => $perpage,
'pages' => ceil($total / $perpage),
'total' => $total,
'sort' => 'asc',
'field' => 'id'
];
// build query
$query = $qb->select('q');
$this->setQueryFilters($datatable, $query);
// check if sorting is present, otherwise use default
if (isset($datatable['sort']['field']) && !empty($datatable['sort']['field'])) {
$order = $datatable['sort']['sort'] ?? 'asc';
$query->orderBy('q.' . $datatable['sort']['field'], $order);
} else {
$query->orderBy('q.event_time', 'asc');
}
// get rows for this page
$obj_rows = $query->setFirstResult($offset)
->setMaxResults($perpage)
->getQuery()
->getResult();
// process rows
$rows = [];
foreach ($obj_rows as $orow) {
// add row data
$row['id'] = $orow->getID();
$row['name'] = $orow->getName();
$row['event_type'] = MotoliteEventType::getName($orow->getEventType());
$row['event_time'] = $orow->getEventTime()->format("d M Y g:i A");
$row['url'] = '<a href="' . $orow->getUrl() . '" target="_blank">Link</a>';
$row['image_file'] = $orow->getImageFile();
// add row metadata
$row['meta'] = [
'update_url' => '',
'delete_url' => ''
];
// add crud urls
if ($this->isGranted('motolite_event.update'))
$row['meta']['update_url'] = $this->generateUrl('motolite_event_update', ['id' => $row['id']]);
if ($this->isGranted('motolite_event.delete'))
$row['meta']['delete_url'] = $this->generateUrl('motolite_event_delete', ['id' => $row['id']]);
$rows[] = $row;
}
// response
return $this->json([
'meta' => $meta,
'data' => $rows
]);
}
/**
* @Menu(selected="motolite_event_list")
*/
public function addForm()
{
$this->denyAccessUnlessGranted('motolite_event.add', null, 'No access.');
$params = [];
$params['obj'] = new MotoliteEvent();
$params['mode'] = 'create';
$params['event_types'] = MotoliteEventType::getCollection();
$em = $this->getDoctrine()->getManager();
// response
return $this->render('motolite-event/form.html.twig', $params);
}
public function addSubmit(Request $req, EncoderFactoryInterface $ef, ValidatorInterface $validator)
{
$this->denyAccessUnlessGranted('motolite_event.add', null, 'No access.');
// create new object
$em = $this->getDoctrine()->getManager();
$obj = new MotoliteEvent();
$this->setObject($obj, $req);
// validate
$errors = $validator->validate($obj);
// initialize error list
$error_array = [];
// add errors to list
foreach ($errors as $error) {
$error_array[$error->getPropertyPath()] = $error->getMessage();
}
// check if any errors were found
if (!empty($error_array)) {
// return validation failure response
return $this->json([
'success' => false,
'errors' => $error_array
], 422);
}
// validated! save the entity
$em->persist($obj);
$em->flush();
// return successful response
return $this->json([
'success' => 'Changes have been saved!'
]);
}
/**
* @Menu(selected="motolite_event_list")
*/
public function updateForm($id)
{
$this->denyAccessUnlessGranted('motolite_event.update', null, 'No access.');
// get row data
$em = $this->getDoctrine()->getManager();
$obj = $em->getRepository(MotoliteEvent::class)->find($id);
// make sure this row exists
if (empty($obj))
throw $this->createNotFoundException('The item does not exist');
$params = [];
$params['obj'] = $obj;
$params['mode'] = 'update';
$params['event_types'] = MotoliteEventType::getCollection();
// response
return $this->render('motolite-event/form.html.twig', $params);
}
public function updateSubmit(Request $req, EncoderFactoryInterface $ef, ValidatorInterface $validator, $id)
{
$this->denyAccessUnlessGranted('motolite_event.update', null, 'No access.');
// get object data
$em = $this->getDoctrine()->getManager();
$obj = $em->getRepository(MotoliteEvent::class)->find($id);
// make sure this object exists
if (empty($obj))
throw $this->createNotFoundException('The item does not exist');
$this->setObject($obj, $req);
// validate
$errors = $validator->validate($obj);
// initialize error list
$error_array = [];
// add errors to list
foreach ($errors as $error) {
$error_array[$error->getPropertyPath()] = $error->getMessage();
}
// check if any errors were found
if (!empty($error_array)) {
// return validation failure response
return $this->json([
'success' => false,
'errors' => $error_array
], 422);
}
// validated! save the entity
$em->flush();
// return successful response
return $this->json([
'success' => 'Changes have been saved!'
]);
}
public function destroy($id)
{
$this->denyAccessUnlessGranted('motolite_event.delete', null, 'No access.');
// get object data
$em = $this->getDoctrine()->getManager();
$obj = $em->getRepository(MotoliteEvent::class)->find($id);
if (empty($obj))
throw $this->createNotFoundException('The item does not exist');
// delete this object
$em->remove($obj);
$em->flush();
// response
$response = new Response();
$response->setStatusCode(Response::HTTP_OK);
$response->send();
}
protected function setQueryFilters($datatable, QueryBuilder $query)
{
if (isset($datatable['query']['data-rows-search']) && !empty($datatable['query']['data-rows-search'])) {
$query->where('q.name LIKE :filter')
->orWhere('q.url LIKE :filter')
->orWhere('q.event_type LIKE :filter')
->setParameter('filter', '%' . $datatable['query']['data-rows-search'] . '%');
}
}
protected function setObject(MotoliteEvent $obj, Request $req)
{
// times
$format = "Y-m-d\TH:i";
$event_time = DateTime::createFromFormat($format, $req->request->get('event_time'));
$event_type = $req->request->get('event_type');
// set and save values
$obj->setName($req->request->get('name'))
->setEventType($event_type)
->setEventTime($event_time)
->setUrl($req->request->get('url'))
->setImageFile($req->request->get('image_file'));
}
public function uploadImage(Request $req, FileUploader $uploader)
{
// retrieve temporary info for file
$file = $req->files->get('image_file');
// upload the file
$filename = $uploader->upload($file);
// return response
return $this->json([
'success' => true,
'filename' => $filename
]);
}
}

View file

@ -82,12 +82,22 @@ class ReviewController extends Controller
$rows = [];
foreach ($obj_rows as $orow)
{
// get appropriate mobile session
$mobile_number = "";
$mobile_session = $orow->getMobileSession();
if (!empty($mobile_session)) {
$mobile_number = $mobile_session->getPhoneNumber();
} else {
$mobile_number = $orow->getCustomerSession()->getPhoneNumber();
}
// add row data
$row['id'] = $orow->getID();
$row['partner'] = $orow->getPartner()->getName();
$row['rating'] = $orow->getRating();
$row['message'] = $orow->getMessage();
$row['mobile_number'] = $orow->getMobileSession()->getPhoneNumber();
$row['mobile_number'] = $mobile_number;
// add row metadata
$row['meta'] = [

View file

@ -0,0 +1,267 @@
<?php
namespace App\Controller;
use App\Entity\ReviewTag;
use App\Ramcar\ReviewTagType;
use Doctrine\ORM\Query;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Catalyst\MenuBundle\Annotation\Menu;
use DateTime;
class ReviewTagController extends Controller
{
/**
* @Menu(selected="review_tag_list")
*/
public function index()
{
$this->denyAccessUnlessGranted('review_tag.list', null, 'No access.');
return $this->render('review-tag/list.html.twig');
}
public function rows(Request $req)
{
$this->denyAccessUnlessGranted('review_tag.list', null, 'No access.');
// get query builder
$qb = $this->getDoctrine()
->getRepository(ReviewTag::class)
->createQueryBuilder('q');
// get datatable params
$datatable = $req->request->get('datatable');
// count total records
$tquery = $qb->select('COUNT(q)');
$this->setQueryFilters($datatable, $tquery);
$total = $tquery->getQuery()
->getSingleScalarResult();
// get current page number
$page = $datatable['pagination']['page'] ?? 1;
$perpage = $datatable['pagination']['perpage'];
$offset = ($page - 1) * $perpage;
// add metadata
$meta = [
'page' => $page,
'perpage' => $perpage,
'pages' => ceil($total / $perpage),
'total' => $total,
'sort' => 'asc',
'field' => 'id'
];
// build query
$query = $qb->select('q');
$this->setQueryFilters($datatable, $query);
// check if sorting is present, otherwise use default
if (isset($datatable['sort']['field']) && !empty($datatable['sort']['field'])) {
$order = $datatable['sort']['sort'] ?? 'asc';
$query->orderBy('q.' . $datatable['sort']['field'], $order);
} else {
$query->orderBy('q.id', 'asc');
}
// get rows for this page
$obj_rows = $query->setFirstResult($offset)
->setMaxResults($perpage)
->getQuery()
->getResult();
// process rows
$rows = [];
foreach ($obj_rows as $orow) {
// add row data
$row['id'] = $orow->getID();
$row['name'] = $orow->getName();
$row['type'] = ucfirst($orow->getType());
// add row metadata
$row['meta'] = [
'update_url' => '',
'delete_url' => ''
];
// add crud urls
if ($this->isGranted('review_tag.update'))
$row['meta']['update_url'] = $this->generateUrl('reviewtag_update', ['id' => $row['id']]);
if ($this->isGranted('review_tag.delete'))
$row['meta']['delete_url'] = $this->generateUrl('reviewtag_delete', ['id' => $row['id']]);
$rows[] = $row;
}
// response
return $this->json([
'meta' => $meta,
'data' => $rows
]);
}
protected function setQueryFilters($datatable, QueryBuilder $query)
{
if (isset($datatable['query']['data-rows-search']) && !empty($datatable['query']['data-rows-search'])) {
$query->where('q.name LIKE :filter')
->setParameter('filter', '%' . $datatable['query']['data-rows-search'] . '%');
}
}
/**
* @Menu(selected="review_tag_list")
*/
public function addForm()
{
$this->denyAccessUnlessGranted('review_tag.add', null, 'No access.');
$params['obj'] = new ReviewTag();
$params['mode'] = 'create';
$params['types'] = ReviewTagType::getCollection();
// response
return $this->render('review-tag/form.html.twig', $params);
}
public function addSubmit(Request $req, ValidatorInterface $validator)
{
$this->denyAccessUnlessGranted('review_tag.add', null, 'No access.');
// create new object
$em = $this->getDoctrine()->getManager();
$obj = new ReviewTag();
$obj->setName($req->request->get('name'))
->setType($req->request->get('type'));
// validate
$errors = $validator->validate($obj);
// initialize error list
$error_array = [];
// add errors to list
foreach ($errors as $error) {
$error_array[$error->getPropertyPath()] = $error->getMessage();
}
// check if any errors were found
if (!empty($error_array)) {
// return validation failure response
return $this->json([
'success' => false,
'errors' => $error_array
], 422);
} else {
// validated! save the entity
$em->persist($obj);
$em->flush();
// return successful response
return $this->json([
'success' => 'Changes have been saved!'
]);
}
}
/**
* @Menu(selected="review_tag_list")
*/
public function updateForm($id)
{
$this->denyAccessUnlessGranted('review_tag.update', null, 'No access.');
// get row data
$em = $this->getDoctrine()->getManager();
$obj = $em->getRepository(ReviewTag::class)->find($id);
// make sure this row exists
if (empty($obj))
throw $this->createNotFoundException('The item does not exist');
$params['obj'] = $obj;
$params['mode'] = 'update';
$params['types'] = ReviewTagType::getCollection();
// response
return $this->render('review-tag/form.html.twig', $params);
}
public function updateSubmit(Request $req, ValidatorInterface $validator, $id)
{
$this->denyAccessUnlessGranted('review_tag.update', null, 'No access.');
// get object data
$em = $this->getDoctrine()->getManager();
$obj = $em->getRepository(ReviewTag::class)->find($id);
// make sure this object exists
if (empty($obj))
throw $this->createNotFoundException('The item does not exist');
$obj->setName($req->request->get('name'))
->setType($req->request->get('type'));
// validate
$errors = $validator->validate($obj);
// initialize error list
$error_array = [];
// add errors to list
foreach ($errors as $error) {
$error_array[$error->getPropertyPath()] = $error->getMessage();
}
// check if any errors were found
if (!empty($error_array)) {
// return validation failure response
return $this->json([
'success' => false,
'errors' => $error_array
], 422);
}
// validated! save the entity
$em->flush();
// return successful response
return $this->json([
'success' => 'Changes have been saved!'
]);
}
public function destroy($id)
{
$this->denyAccessUnlessGranted('review_tag.delete', null, 'No access.');
// get object data
$em = $this->getDoctrine()->getManager();
$obj = $em->getRepository(ReviewTag::class)->find($id);
if (empty($obj))
throw $this->createNotFoundException('The item does not exist');
// delete this object
$em->remove($obj);
$em->flush();
// response
$response = new Response();
$response->setStatusCode(Response::HTTP_OK);
$response->send();
}
}

View file

@ -25,8 +25,8 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Catalyst\MenuBundle\Annotation\Menu;
use Catalyst\APIBundle\Entity\User as APIUser;
use Catalyst\APIBundle\Entity\Role as APIRole;
use App\Entity\ApiUser as APIUser;
use Catalyst\ApiBundle\Entity\Role as APIRole;
use DateTime;

View file

@ -8,13 +8,13 @@ use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
use App\Ramcar\APIResult;
use App\Entity\Vehicle;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class BatteryController extends APIController
{

View file

@ -11,8 +11,8 @@ use Doctrine\ORM\EntityManagerInterface;
use CrEOF\Spatial\PHP\Types\Geometry\Point;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
use App\Ramcar\WarrantyClass;
use App\Ramcar\JOStatus;
@ -33,6 +33,8 @@ use App\Ramcar\DeliveryStatus;
use App\Service\InvoiceGeneratorInterface;
use App\Service\RisingTideGateway;
use App\Service\MQTTClient;
use App\Service\MQTTClientApiv2;
use App\Service\FCMSender;
use App\Service\GeofenceTracker;
use App\Service\InventoryManager;
use App\Service\RiderAssignmentHandlerInterface;
@ -59,7 +61,7 @@ use App\Entity\Warranty;
use DateTime;
use DateInterval;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class JobOrderController extends APIController
{
@ -72,7 +74,8 @@ class JobOrderController extends APIController
// TODO: break this monolithic method down
public function requestJobOrder(Request $req, InvoiceGeneratorInterface $ic, GeofenceTracker $geo,
InventoryManager $im, MQTTClient $mclient,
InventoryManager $im, MQTTClient $mclient, MQTTClientApiv2 $mclientv2,
FCMSender $fcmclient,
RiderAssignmentHandlerInterface $rah, PromoLogger $promo_logger,
HubSelector $hub_select, HubDistributor $hub_dist, HubFilterLogger $hub_filter_logger,
HubFilteringGeoChecker $hub_geofence, EntityManagerInterface $em)
@ -356,6 +359,10 @@ class JobOrderController extends APIController
];
$mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($jo, $payload);
$fcmclient->sendJoEvent($jo, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign");
$rah->assignJobOrder($jo, $jo->getRider());
}
@ -374,6 +381,10 @@ class JobOrderController extends APIController
'event' => 'outlet_assign'
];
$mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($jo, $payload);
$fcmclient->sendJoEvent($jo, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign");
}
$em->flush();

View file

@ -8,12 +8,12 @@ use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
use App\Entity\Promo;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class PromoController extends APIController
{

View file

@ -8,12 +8,12 @@ use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
use App\Entity\Service;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class ServiceController extends APIController
{

View file

@ -8,13 +8,13 @@ use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\Query;
use Doctrine\ORM\EntityManagerInterface;
use Catalyst\APIBundle\Controller\APIController;
use Catalyst\APIBundle\Response\APIResponse;
use Catalyst\ApiBundle\Controller\ApiController;
use Catalyst\ApiBundle\Response\APIResponse;
use App\Entity\VehicleManufacturer;
use App\Entity\Vehicle;
use Catalyst\APIBundle\Access\Generator as ACLGenerator;
use Catalyst\AuthBundle\Service\ACLGenerator as ACLGenerator;
class VehicleController extends APIController
{

66
src/Entity/ApiUser.php Normal file
View file

@ -0,0 +1,66 @@
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Catalyst\ApiBundle\Entity\User as BaseUser;
/**
* @ORM\Entity
* @ORM\Table(name="api_user")
*/
class ApiUser extends BaseUser
{
/**
* @ORM\Column(type="string", length=80)
*/
protected $name;
// rider linked to user
// NOTE: we're directly linking this only because we don't have to care about other apps using this library
/**
* @ORM\OneToOne(targetEntity="App\Entity\Rider", mappedBy="api_user")
*/
protected $rider;
/**
* @ORM\Column(type="json")
*/
protected $metadata;
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
public function setMetadata($meta)
{
$this->metadata = $meta;
return $this;
}
public function getMetadata()
{
if ($this->metadata == null)
return [];
return $this->metadata;
}
public function setRider($rider)
{
$this->rider = $rider;
return $this;
}
public function getRider()
{
return $this->rider;
}
}

View file

@ -0,0 +1,92 @@
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use DateTime;
/**
* @ORM\Entity
* @ORM\Table(name="credit_transaction")
*/
class CreditTransaction
{
// unique id
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// customer
/**
* @ORM\OneToOne(targetEntity="Customer")
* @ORM\JoinColumn(name="customer_id", referencedColumnName="id")
*/
protected $customer;
// date transaction was recorded
/**
* @ORM\Column(type="datetime")
*/
protected $date_create;
/**
* @ORM\Column(type="integer")
* @Assert\NotBlank()
*/
protected $amount;
/**
* @ORM\Column(type="string", length=80)
* @Assert\NotBlank()
*/
protected $transaction_type;
public function __construct()
{
$this->date_create = new DateTime();
}
public function getID()
{
return $this->id;
}
public function setCustomer(Customer $customer)
{
$this->customer = $customer;
return $this;
}
public function setType($transaction_type)
{
$this->transaction_type = $transaction_type;
return $this;
}
public function getType()
{
return $this->transaction_type;
}
public function setAmount($amount)
{
$this->amount = $amount;
return $this;
}
public function getAmount()
{
return $this->amount;
}
public function getCustomer()
{
return $this->customer;
}
}

View file

@ -96,6 +96,13 @@ class Customer
*/
protected $sessions;
// link to customer user
/**
* @ORM\OneToOne(targetEntity="CustomerUser", inversedBy="customer")
* @ORM\JoinColumn(name="customer_user_id", referencedColumnName="id", nullable=true)
*/
protected $customer_user;
// vehicles linked to customer
/**
* @ORM\OneToMany(targetEntity="CustomerVehicle", mappedBy="customer", cascade={"persist"})
@ -208,6 +215,11 @@ class Customer
*/
protected $create_source;
/**
* @ORM\Column(type="integer", options={"unsigned": true, "default":0})
*/
protected $credits;
// customer tags
/**
* @ORM\ManyToMany(targetEntity="CustomerTag", inversedBy="customers", indexBy="id")
@ -267,6 +279,8 @@ class Customer
$this->create_source = 'unknown';
$this->ratings = new ArrayCollection();
$this->credits = 0;
}
public function getID()
@ -682,4 +696,26 @@ class Customer
{
return $this->car_club_customer_hub;
}
public function setCustomerUser(CustomerUser $cust_user = null)
{
$this->customer_user = $cust_user;
return $this;
}
public function getCustomerUser()
{
return $this->customer_user;
}
public function modifyCredits($amount)
{
$this->credits = bcadd($this->credits, $amount);
return $this;
}
public function getCredits()
{
return $this->credits;
}
}

View file

@ -63,6 +63,12 @@ class CustomerMetadata
return $this;
}
public function deleteMetadataInfo($id)
{
unset($this->meta_info[$id]);
return $this;
}
public function getMetaInfo($id)
{
// return null if we don't have it

View file

@ -0,0 +1,273 @@
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use DateTime;
/**
* @ORM\Entity
* @ORM\Table(name="customer_session")
*/
class CustomerSession
{
// unique id
/**
* @ORM\Id
* @ORM\Column(type="string", length=13)
*/
protected $id;
// link to customer er
/**
* @ORM\ManyToOne(targetEntity="Customer")
* @ORM\JoinColumn(name="customer_id", referencedColumnName="id", nullable=true)
*/
protected $customer;
// link to customer user
/**
* @ORM\ManyToOne(targetEntity="CustomerUser", inversedBy="sessions")
* @ORM\JoinColumn(name="customer_user_id", referencedColumnName="id", nullable=true)
*/
protected $customer_user;
// phone number
/**
* @ORM\Column(type="string", length=12, nullable=true)
*/
protected $phone_number;
// phone model
/**
* @ORM\Column(type="string", length=50)
*/
protected $phone_model;
// operating system (android, ios, etc)
/**
* @ORM\Column(type="string", length=15)
*/
protected $os_type;
// os version
/**
* @ORM\Column(type="string", length=200)
*/
protected $os_version;
// device id or push id used by device
/**
* @ORM\Column(type="string", length=200, nullable=true)
*/
protected $device_push_id;
// phone id
/**
* @ORM\Column(type="string", length=50, nullable=true)
*/
protected $phone_id;
// confirm code that we send via SMS
/**
* @ORM\Column(type="string", length=6, nullable=true)
*/
protected $confirm_code;
// is confirmed?
/**
* @ORM\Column(type="boolean")
*/
protected $confirm_flag;
// date the session id was generated and sent to mobile app
/**
* @ORM\Column(type="datetime")
*/
protected $date_generated;
// date the phone number was confirmed
/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $date_confirmed;
// date and time that the confirmation code was last sent
/**
* @ORM\Column(type="datetime", nullable=true)
*/
protected $date_code_sent;
// reviews made by mobile session
/**
* @ORM\OneToMany(targetEntity="Review", mappedBy="mobile_session")
*/
protected $reviews;
public function __construct()
{
// default date generated to now
$this->id = $this->generateKeyID();
$this->date_generated = new DateTime();
$this->customer_user = null;
$this->confirm_flag = false;
$this->date_confirmed = null;
$this->date_code_sent = null;
$this->reviews = new ArrayCollection();
}
public function generateKeyID()
{
// use uniqid for now, since primary key dupes will trigger exceptions
return uniqid();
}
public function getID()
{
return $this->id;
}
public function setPhoneNumber($num)
{
$this->phone_number = $num;
return $this;
}
public function getPhoneNumber()
{
return $this->phone_number;
}
public function setPhoneModel($model)
{
$this->phone_model = $model;
return $this;
}
public function getPhoneModel()
{
return $this->phone_model;
}
public function setOSType($type)
{
$this->os_type = $type;
return $this;
}
public function getOSType()
{
return $this->os_type;
}
public function setOSVersion($version)
{
$this->os_version = $version;
return $this;
}
public function getOSVersion()
{
return $this->os_version;
}
public function setPhoneID($id)
{
$this->phone_id = $id;
return $this;
}
public function getPhoneID()
{
return $this->phone_id;
}
public function setDevicePushID($id)
{
$this->device_push_id = $id;
return $this;
}
public function getDevicePushID()
{
return $this->device_push_id;
}
public function setCustomer(Customer $cust = null)
{
$this->customer = $cust;
return $this;
}
public function getCustomer()
{
return $this->customer;
}
public function setCustomerUser(CustomerUser $cust_user = null)
{
$this->customer_user = $cust_user;
return $this;
}
public function getCustomerUser()
{
return $this->customer_user;
}
public function getDateGenerated()
{
return $this->date_generated;
}
public function setConfirmCode($code)
{
$this->confirm_code = $code;
return $this;
}
public function getConfirmCode()
{
return $this->confirm_code;
}
public function setConfirmed($flag = true)
{
$this->confirm_flag = $flag;
return $this;
}
public function isConfirmed()
{
return $this->confirm_flag;
}
public function setDateConfirmed(DateTime $date)
{
$this->date_confirmed = $date;
return $this;
}
public function getDateConfirmed()
{
return $this->date_confirmed;
}
public function setDateCodeSent(DateTime $date)
{
$this->date_code_sent = $date;
return $this;
}
public function getDateCodeSent()
{
return $this->date_code_sent;
}
public function getReviews()
{
return $this->reviews;
}
}

106
src/Entity/CustomerUser.php Normal file
View file

@ -0,0 +1,106 @@
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Catalyst\ApiBundle\Entity\User as BaseUser;
/**
* @ORM\Entity
* @ORM\Table(name="customer_user")
*/
class CustomerUser extends BaseUser
{
// link to customer
/**
* @ORM\OneToOne(targetEntity="Customer", inversedBy="customer_user")
* @ORM\JoinColumn(name="customer_id", referencedColumnName="id", nullable=true)
*/
protected $customer;
// phone number
/**
* @ORM\Column(type="string", length=12)
*/
protected $phone_number;
/**
* @ORM\Column(type="json")
*/
protected $metadata;
// roles
/**
* @ORM\ManyToMany(targetEntity="Catalyst\ApiBundle\Entity\Role", indexBy="id")
* @ORM\JoinTable(name="customer_user_role")
*/
protected $roles;
// mobile sessions linked to this customer
/**
* @ORM\OneToMany(targetEntity="CustomerSession", mappedBy="customer_user")
*/
protected $sessions;
public function __construct()
{
parent::__construct();
$this->metadata = [];
$this->sessions = new ArrayCollection();
}
public function setMetadata($meta)
{
$this->metadata = $meta;
return $this;
}
public function getMetadata()
{
if ($this->metadata == null)
return [];
return $this->metadata;
}
public function setPhoneNumber($num)
{
$this->phone_number = $num;
return $this;
}
public function getPhoneNumber()
{
return $this->phone_number;
}
public function addMobileSession(MobileSession $session)
{
$this->sessions->add($session);
return $this;
}
public function clearMobileSessions()
{
$this->sessions->clear();
return $this;
}
public function getMobileSessions()
{
return $this->sessions;
}
public function setCustomer(Customer $cust = null)
{
$this->customer = $cust;
return $this;
}
public function getCustomer()
{
return $this->customer;
}
}

View file

@ -0,0 +1,123 @@
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use DateTime;
/**
* @ORM\Entity
* @ORM\Table(name="motolite_event")
*/
class MotoliteEvent
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", length=80)
* @Assert\NotBlank()
*/
protected $name;
/**
* @ORM\Column(type="string", length=80)
* @Assert\NotBlank()
*/
protected $event_type;
/**
* @ORM\Column(type="datetime")
* @Assert\NotBlank()
*/
protected $event_time;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank()
*/
protected $url;
/**
* @ORM\Column(type="string")
* @Assert\NotBlank()
*/
protected $image_file;
public function __construct()
{
$this->event_time = new DateTime('today noon');
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getID()
{
return $this->id;
}
public function setID($id)
{
$this->id = $id;
return $this;
}
public function getName()
{
return $this->name;
}
public function setEventType($event_type)
{
$this->event_type = $event_type;
return $this;
}
public function getEventType()
{
return $this->event_type;
}
public function setEventTime($event_time)
{
$this->event_time = $event_time;
return $this;
}
public function setUrl($url)
{
$this->url = $url;
return $this;
}
public function getUrl()
{
return $this->url;
}
public function getEventTime()
{
return $this->event_time;
}
public function setImageFile($image_file = null)
{
$this->image_file = $image_file;
return $this;
}
public function getImageFile()
{
return $this->image_file;
}
}

View file

@ -48,10 +48,17 @@ class Review
// mobile session that sent review
/**
* @ORM\ManyToOne(targetEntity="MobileSession", inversedBy="reviews")
* @ORM\JoinColumn(name="mobile_session_id", referencedColumnName="id")
* @ORM\JoinColumn(name="mobile_session_id", referencedColumnName="id", nullable=true)
*/
protected $mobile_session;
// customer session (new) that sent review
/**
* @ORM\ManyToOne(targetEntity="CustomerSession", inversedBy="reviews")
* @ORM\JoinColumn(name="customer_session_id", referencedColumnName="id", nullable=true)
*/
protected $customer_session;
public function __construct()
{
$this->date_create = new DateTime();
@ -114,4 +121,14 @@ class Review
return $this->mobile_session;
}
public function setCustomerSession(CustomerSession $customer_session)
{
$this->customer_session = $customer_session;
return $this;
}
public function getCustomerSession()
{
return $this->customer_session;
}
}

62
src/Entity/ReviewTag.php Normal file
View file

@ -0,0 +1,62 @@
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ORM\Entity
* @ORM\Table(name="review_tag")
*/
class ReviewTag
{
// unique id
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", length=80)
* @Assert\NotBlank()
*/
protected $name;
/**
* @ORM\Column(type="string", length=80)
* @Assert\NotBlank()
*/
protected $type;
public function getID()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
return $this;
}
public function getName()
{
return $this->name;
}
public function setType($type)
{
$this->type = $type;
return $this;
}
public function getType()
{
return $this->type;
}
}

View file

@ -9,7 +9,7 @@ use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
use App\Ramcar\JOStatus;
use Catalyst\APIBundle\Entity\User as APIUser;
use App\Entity\ApiUser as APIUser;
/**
* @ORM\Entity
@ -81,7 +81,7 @@ class Rider
// current rating of rider
/**
* @ORM\Column(type="integer")
* @ORM\Column(type="float")
*/
protected $curr_rating;
@ -131,7 +131,7 @@ class Rider
protected $current_job_order;
/**
* @ORM\OneToOne(targetEntity="Catalyst\APIBundle\Entity\User", inversedBy="rider")
* @ORM\OneToOne(targetEntity="App\Entity\ApiUser", inversedBy="rider")
* @ORM\JoinColumn(name="api_user_id", referencedColumnName="id", nullable=true)
*/
protected $api_user;
@ -241,6 +241,17 @@ class Rider
return $this->image_file;
}
public function updateRatingAverage()
{
$total = 0;
foreach ($this->ratings as $rating) {
$total += $rating->getRating();
}
$this->setCurrentRating(round($total / $this->ratings->count(), 2));
}
public function setCurrentRating($rating)
{
$this->curr_rating = $rating;

View file

@ -28,6 +28,12 @@ class Service
*/
protected $name;
// icon used by service on app
/**
* @ORM\Column(type="string", length=80, nullable=true)
*/
protected $icon;
// link to partners with this service
/**
* @ORM\ManyToMany(targetEntity="Partner", mappedBy="services", fetch="EXTRA_LAZY")
@ -55,6 +61,17 @@ class Service
return $this->name;
}
public function setIcon($icon)
{
$this->icon = $icon;
return $this;
}
public function getIcon()
{
return $this->icon;
}
public function addPartner(Partner $partner)
{
$this->partners[$partner->getID()] = $partner;

View file

@ -0,0 +1,14 @@
<?php
namespace App\Ramcar;
class CreditTransactionType extends NameValue
{
const PURCHASE = 'purchase';
const REDEMPTION = 'redemption';
const COLLECTION = [
'purchase' => 'Purchase',
'redemption' => 'Redemption',
];
}

View file

@ -0,0 +1,16 @@
<?php
namespace App\Ramcar;
class MotoliteEventType extends NameValue
{
const EVENT = 'event';
const NEWS = 'news';
const BLOG = 'blog';
const COLLECTION = [
'event' => 'Event',
'news' => 'News',
'blog' => 'Blog',
];
}

View file

@ -0,0 +1,14 @@
<?php
namespace App\Ramcar;
class ReviewTagType extends NameValue
{
const RIDER = 'rider';
const PARTNER = 'partner';
const COLLECTION = [
'rider' => 'Rider',
'partner' => 'Partner',
];
}

View file

@ -17,7 +17,7 @@ class ServiceType extends NameValue
const COLLECTION = [
'battery_new' => 'Battery Sales',
'battery_warranty' => 'Under Warranty',
'jumpstart_troubleshoot' => 'General Service',
'jumpstart_troubleshoot' => 'General Service - Jumpstart',
'jumpstart_warranty' => 'General Service - Warranty',
'post_recharged' => 'Post - Recharged',
'post_replacement' => 'Post - Replacement',

View file

@ -0,0 +1,47 @@
<?php
namespace App\Service;
use App\Entity\Customer;
use App\Entity\CreditTransaction;
use App\Ramcar\CreditTransactionType;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
class CreditManager
{
protected $cust;
protected $em;
public function __construct(Customer $cust, EntityManagerInterface $em)
{
$this->cust = $cust;
$this->em = $em;
}
public function recordTransaction($type, $amount)
{
// make sure this is a valid transaction type
$this->validateType($type);
// update customer
$this->cust->modifyCredits($amount);
// create new record
$trans = new CreditTransaction();
$trans->setCustomer($this->cust)
->setAmount($amount)
->setType($type);
$this->em->persist($trans);
}
protected function validateType($type)
{
if (!CreditTransactionType::validate($type)) {
throw new Exception('Invalid transaction type');
}
}
}

94
src/Service/FCMSender.php Normal file
View file

@ -0,0 +1,94 @@
<?php
namespace App\Service;
use Symfony\Contracts\Translation\TranslatorInterface;
use Fcm\FcmClient;
use Fcm\Push\Notification;
use App\Entity\JobOrder;
class FCMSender
{
protected $client;
protected $translator;
public function __construct(TranslatorInterface $translator, $server_key, $sender_id)
{
$this->client = new FcmClient($server_key, $sender_id);
$this->translator = $translator;
}
public function send($recipients, $title, $body, $data = [], $color = null, $sound = null, $badge = null)
{
$notification = new Notification();
$notification->setTitle($title)
->setBody($body);
foreach ($recipients as $recipient) {
$notification->addRecipient($recipient);
}
if (!empty($color)) {
$notification->setColor($color);
}
if (!empty($sound)) {
$notification->setSound($sound);
}
if (!empty($color)) {
$notification->setColor($color);
}
if (!empty($badge)) {
$notification->setBadge($badge);
}
if (!empty($data)) {
$notification->addDataArray($data);
}
return $this->client->send($notification);
}
public function sendJoEvent(JobOrder $job_order, $title, $body, $data = [])
{
// get all v2 sessions
$sessions = [];
$cust_user = $job_order->getCustomer()->getCustomerUser();
if (!empty($cust_user)) {
$sessions = $cust_user->getMobileSessions();
}
if (empty($sessions)) {
error_log("no sessions to send fcm notification to");
return;
}
$device_ids = [];
// send to every customer session
foreach ($sessions as $sess) {
$device_id = $sess->getDevicePushID();
if (!empty($device_id)) {
// send fcm notification
$device_ids[] = $device_id;
}
}
if (empty($device_ids)) {
error_log("no devices to send fcm notification to");
return;
}
// attach jo info
$data['jo_id'] = $job_order->getID();
$data['jo_status'] = $job_order->getStatus();
// send fcm notification
$result = $this->send($device_ids, $this->translator->trans($title), $this->translator->trans($body), $data);
return $result;
}
}

View file

@ -0,0 +1,100 @@
<?php
namespace App\Service;
class InsuranceConnector
{
protected $base_url;
protected $username;
protected $password;
protected $hash;
public function __construct($base_url, $username, $password)
{
$this->base_url = $base_url;
$this->username = $username;
$this->password = $password;
$this->hash = $this->generateHash();
}
public function createApplication($notif_url, $client_info, $client_contact_info, $car_info)
{
$body = [
'notif_url' => $notif_url,
'client_info' => $client_info,
'client_contact_info' => $client_contact_info,
'car_info' => $car_info,
];
return $this->doRequest('/api/v1/ctpl/applications', true, $body);
}
public function tagApplicationPaid($application_id)
{
$url = '/api/v1/ctpl/application/' . $application_id . '/paid';
return $this->doRequest($url, true);
}
public function getVehicleMakers()
{
return $this->doRequest('/api/v1/ctpl/vehicle-makers');
}
public function getVehicleModels()
{
return $this->doRequest('/api/v1/ctpl/vehicle-models');
}
public function getVehicleTrims()
{
return $this->doRequest('/api/v1/ctpl/vehicle-trims');
}
protected function generateHash()
{
return base64_encode($this->username . ":" . $this->password);
}
protected function doRequest($url, $is_post = false, $body = [])
{
$curl = curl_init();
$options = [
CURLOPT_URL => $this->base_url . '/' . $url,
CURLOPT_POST => $is_post,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Basic ' . $this->hash,
],
];
// add post body if present
if (!empty($body)) {
$options[CURLOPT_POSTFIELDS] = json_encode($body);
}
curl_setopt_array($curl, $options);
$res = curl_exec($curl);
curl_close($curl);
error_log('Insurance API connector');
error_log(print_r($options, true));
error_log($res);
// response
return $this->handleResponse($res);
}
protected function handleResponse($res)
{
$inv_res = json_decode($res, true);
// make sure result is always an array
if ($inv_res == null)
return [];
return $inv_res;
}
}

View file

@ -46,6 +46,8 @@ use App\Service\RiderAssignmentHandlerInterface;
use App\Service\CustomerHandlerInterface;
use App\Service\WarrantyHandler;
use App\Service\MQTTClient;
use App\Service\MQTTClientApiv2;
use App\Service\FCMSender;
use App\Service\APNSClient;
use App\Service\MapTools;
@ -668,7 +670,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
}
// dispatch job order
public function dispatchJobOrder(Request $req, int $id, MQTTClient $mclient)
public function dispatchJobOrder(Request $req, int $id, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient)
{
// get object data
$em = $this->em;
@ -793,6 +795,10 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
'event' => 'outlet_assign'
];
$mclient->sendEvent($obj, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($obj, $payload);
$fcmclient->sendJoEvent($obj, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign");
}
return $error_array;
@ -1027,7 +1033,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
}
// cancel job order
public function cancelJobOrder(Request $req, int $id, MQTTClient $mclient)
public function cancelJobOrder(Request $req, int $id, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient)
{
// get object data
$em = $this->em;
@ -1068,10 +1074,14 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
];
$mclient->sendEvent($obj, $payload);
$mclient->sendRiderEvent($obj, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($obj, $payload);
$fcmclient->sendJoEvent($obj, "jo_fcm_title_cancelled", "jo_fcm_body_cancelled", ['reason' => $cancel_reason]);
}
// set hub for job order
public function setHub($req, $id, $mclient)
public function setHub($req, $id, $mclient, $mclientv2, $fcmclient)
{
// get object data
$em = $this->em;
@ -1171,6 +1181,10 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
'event' => 'outlet_assign'
];
$mclient->sendEvent($obj, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($obj, $payload);
$fcmclient->sendJoEvent($obj, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign");
}
return $error_array;
@ -1272,7 +1286,7 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
}
// set rider for job order
public function setRider($req, $id, $mclient)
public function setRider($req, $id, $mclient, $mclientv2, $fcmclient)
{
// initialize error list
$error_array = [];
@ -1372,6 +1386,10 @@ class CMBJobOrderHandler implements JobOrderHandlerInterface
];
$mclient->sendEvent($obj, $payload);
$mclient->sendRiderEvent($obj, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($obj, $payload);
$fcmclient->sendJoEvent($obj, "jo_fcm_title_driver_assigned", "jo_fcm_body_driver_assigned");
}
return $error_array;

View file

@ -59,6 +59,8 @@ use App\Service\JobOrderHandlerInterface;
use App\Service\RiderAssignmentHandlerInterface;
use App\Service\WarrantyHandler;
use App\Service\MQTTClient;
use App\Service\MQTTClientApiv2;
use App\Service\FCMSender;
use App\Service\APNSClient;
use App\Service\MapTools;
use App\Service\RisingTideGateway;
@ -396,8 +398,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
}
// check if landmark is set
if (empty($req->request->get('landmark')))
$error_array['landmark'] = 'Landmark is required.';
//if (empty($req->request->get('landmark')))
// $error_array['landmark'] = 'Landmark is required.';
// check if customer is not willing to wait
$will_wait = $req->request->get('flag_willing_to_wait');
@ -674,8 +676,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
}
// check if landmark is set
if (empty($req->request->get('landmark')))
$error_array['landmark'] = 'Landmark is required.';
//if (empty($req->request->get('landmark')))
// $error_array['landmark'] = 'Landmark is required.';
// check if customer is not willing to wait
$will_wait = $req->request->get('flag_willing_to_wait');
@ -841,7 +843,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
}
// dispatch job order
public function dispatchJobOrder(Request $req, int $id, MQTTClient $mclient)
public function dispatchJobOrder(Request $req, int $id, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient)
{
// get object data
$em = $this->em;
@ -914,8 +916,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
}
// check if landmark is set
if (empty($req->request->get('landmark')))
$error_array['landmark'] = 'Landmark is required.';
//if (empty($req->request->get('landmark')))
// $error_array['landmark'] = 'Landmark is required.';
// check if customer is not willing to wait
$will_wait = $req->request->get('flag_willing_to_wait');
@ -1038,6 +1040,10 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
];
$mclient->sendEvent($obj, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($obj, $payload);
$fcmclient->sendJoEvent($obj, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign");
// update redis hub jo count
$this->hub_dist->incrementJoCountForHub($hub);
}
@ -1081,8 +1087,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
}
// check if landmark is set
if (empty($req->request->get('landmark')))
$error_array['landmark'] = 'Landmark is required.';
//if (empty($req->request->get('landmark')))
// $error_array['landmark'] = 'Landmark is required.';
// check if customer is not willing to wait
$will_wait = $req->request->get('flag_willing_to_wait');
@ -1239,8 +1245,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
}
// check if landmark is set
if (empty($req->request->get('landmark')))
$error_array['landmark'] = 'Landmark is required.';
//if (empty($req->request->get('landmark')))
// $error_array['landmark'] = 'Landmark is required.';
// check if customer is not willing to wait
$will_wait = $req->request->get('flag_willing_to_wait');
@ -1429,7 +1435,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
}
// cancel job order
public function cancelJobOrder(Request $req, int $id, MQTTClient $mclient)
public function cancelJobOrder(Request $req, int $id, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient)
{
// get object data
$em = $this->em;
@ -1474,10 +1480,14 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
];
$mclient->sendEvent($obj, $payload);
$mclient->sendRiderEvent($obj, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($obj, $payload);
$fcmclient->sendJoEvent($obj, "jo_fcm_title_cancelled", "jo_fcm_body_cancelled", ['reason' => $cancel_reason]);
}
// set hub for job order
public function setHub($req, $id, $mclient)
public function setHub($req, $id, $mclient, $mclientv2, $fcmclient)
{
// get object data
$em = $this->em;
@ -1509,8 +1519,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
}
// check if landmark is set
if (empty($req->request->get('landmark')))
$error_array['landmark'] = 'Landmark is required.';
//if (empty($req->request->get('landmark')))
// $error_array['landmark'] = 'Landmark is required.';
// error_log($req->request->get('landmark'));
@ -1670,6 +1680,10 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
];
$mclient->sendEvent($obj, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($obj, $payload);
$fcmclient->sendJoEvent($obj, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign");
// update redis hub_jo_count for hub
// decrement old hub's count and increment new hub's count
if ($old_hub != null)
@ -1779,7 +1793,7 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
}
// set rider for job order
public function setRider($req, $id, $mclient)
public function setRider($req, $id, $mclient, $mclientv2, $fcmclient)
{
// initialize error list
$error_array = [];
@ -1811,8 +1825,8 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
}
// check if landmark is set
if (empty($req->request->get('landmark')))
$error_array['landmark'] = 'Landmark is required.';
//if (empty($req->request->get('landmark')))
// $error_array['landmark'] = 'Landmark is required.';
// check if customer is not willing to wait
$will_wait = $req->request->get('flag_willing_to_wait');
@ -1970,6 +1984,10 @@ class ResqJobOrderHandler implements JobOrderHandlerInterface
];
$mclient->sendEvent($obj, $payload);
$mclient->sendRiderEvent($obj, $payload);
// NOTE: for resq2 app
$mclientv2->sendEvent($obj, $payload);
$fcmclient->sendJoEvent($obj, "jo_fcm_title_driver_assigned", "jo_fcm_body_driver_assigned");
}
return $error_array;

View file

@ -5,6 +5,8 @@ namespace App\Service;
use Symfony\Component\HttpFoundation\Request;
use App\Service\MQTTClient;
use App\Service\MQTTClientApiv2;
use App\Service\FCMSender;
use App\Service\APNSClient;
use App\Service\MapTools;
use App\Service\HubSelector;
@ -29,7 +31,7 @@ interface JobOrderHandlerInterface
public function processOneStepJobOrder(Request $req, int $id);
// dispatch job order
public function dispatchJobOrder(Request $req, int $id, MQTTClient $mclient);
public function dispatchJobOrder(Request $req, int $id, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient);
// assign job order
public function assignJobOrder(Request $req, int $id);
@ -38,16 +40,16 @@ interface JobOrderHandlerInterface
public function fulfillJobOrder(Request $req, int $id);
// cancel job order
public function cancelJobOrder(Request $req, int $id, MQTTClient $mclient);
public function cancelJobOrder(Request $req, int $id, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient);
// set hub for job order
public function setHub(Request $req, int $id, MQTTClient $mclient);
public function setHub(Request $req, int $id, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient);
// reject hub for job order
public function rejectHub(Request $req, int $id);
// set rider for job order
public function setRider(Request $req, int $id, MQTTClient $mclient);
public function setRider(Request $req, int $id, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient);
// unlock processor
public function unlockProcessor(int $id);

View file

@ -0,0 +1,71 @@
<?php
namespace App\Service;
use Mosquitto\Client as MosquittoClient;
use App\Entity\JobOrder;
class MQTTClientApiv2
{
const PREFIX = 'motolite.control.v2.';
// protected $mclient;
protected $redis;
protected $key;
public function __construct(RedisClientProvider $redis_client, $key)
{
$this->redis = $redis_client->getRedisClient();
$this->key = $key;
}
public function __destruct()
{
// $this->mclient->disconnect();
}
public function publish($channel, $message)
{
// $this->mclient->publish($channel, $message);
$data = $channel . '|' . $message;
$this->redis->lpush($this->key, $data);
}
public function sendEvent(JobOrder $job_order, $payload)
{
//error_log('sending mqtt event: ');
//error_log(print_r($payload, true));
// get all v2 sessions
$sessions = [];
$cust_user = $job_order->getCustomer()->getCustomerUser();
if (!empty($cust_user)) {
$sessions = $cust_user->getMobileSessions();
}
if (empty($sessions)) {
error_log("no sessions to send mqtt event to");
return;
}
$channels = [];
// send to every customer session
foreach ($sessions as $sess) {
$phone_num = $sess->getPhoneNumber();
$channel = self::PREFIX . $phone_num;
// attach jo id to all payloads
$payload['jo_id'] = $job_order->getID();
// gather channels, so we only send once
$channels[$channel] = json_encode($payload);
}
foreach ($channels as $channel => $json_payload) {
$this->publish($channel, $json_payload);
// error_log('sent to ' . $channel);
}
}
}

View file

@ -18,6 +18,8 @@ use App\Service\RiderAPIHandlerInterface;
use App\Service\RedisClientProvider;
use App\Service\RiderCache;
use App\Service\MQTTClient;
use App\Service\MQTTClientApiv2;
use App\Service\FCMSender;
use App\Service\WarrantyHandler;
use App\Service\JobOrderHandlerInterface;
use App\Service\InvoiceGeneratorInterface;
@ -42,6 +44,8 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
protected $rcache;
protected $country_code;
protected $mclient;
protected $mclientv2;
protected $fcmclient;
protected $wh;
protected $jo_handler;
protected $ic;
@ -49,7 +53,7 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
public function __construct(EntityManagerInterface $em, RedisClientProvider $redis,
EncoderFactoryInterface $ef, RiderCache $rcache,
string $country_code, MQTTClient $mclient,
string $country_code, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient,
WarrantyHandler $wh, JobOrderHandlerInterface $jo_handler,
InvoiceGeneratorInterface $ic)
{
@ -59,6 +63,8 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
$this->rcache = $rcache;
$this->country_code = $country_code;
$this->mclient = $mclient;
$this->mclientv2 = $mclientv2;
$this->fcmclient = $fcmclient;
$this->wh = $wh;
$this->jo_handler = $jo_handler;
$this->ic = $ic;
@ -424,6 +430,10 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
];
$this->mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$this->mclientv2->sendEvent($jo, $payload);
$this->fcmclient->sendJoEvent($jo, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign");
return $data;
}
@ -465,6 +475,10 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
];
$this->mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$this->mclientv2->sendEvent($jo, $payload);
$this->fcmclient->sendJoEvent($jo, "jo_fcm_title_driver_arrived", "jo_fcm_body_driver_arrived");
return $data;
}
@ -578,6 +592,10 @@ class CMBRiderAPIHandler implements RiderAPIHandlerInterface
];
$this->mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$this->mclientv2->sendEvent($jo, $payload);
$this->fcmclient->sendJoEvent($jo, "jo_fcm_title_fulfilled", "jo_fcm_body_fulfilled");
return $data;
}

View file

@ -21,6 +21,8 @@ use App\Service\RiderAPIHandlerInterface;
use App\Service\RedisClientProvider;
use App\Service\RiderCache;
use App\Service\MQTTClient;
use App\Service\MQTTClientApiv2;
use App\Service\FCMSender;
use App\Service\WarrantyHandler;
use App\Service\JobOrderHandlerInterface;
use App\Service\InvoiceGeneratorInterface;
@ -47,6 +49,8 @@ class ResqRiderAPIHandler implements RiderAPIHandlerInterface
protected $rcache;
protected $country_code;
protected $mclient;
protected $mclientv2;
protected $fcmclient;
protected $wh;
protected $jo_handler;
protected $ic;
@ -56,7 +60,7 @@ class ResqRiderAPIHandler implements RiderAPIHandlerInterface
public function __construct(EntityManagerInterface $em, RedisClientProvider $redis,
EncoderFactoryInterface $ef, RiderCache $rcache,
string $country_code, MQTTClient $mclient,
string $country_code, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient,
WarrantyHandler $wh, JobOrderHandlerInterface $jo_handler,
InvoiceGeneratorInterface $ic, RisingTideGateway $rt,
RiderTracker $rider_tracker, TranslatorInterface $translator)
@ -67,6 +71,8 @@ class ResqRiderAPIHandler implements RiderAPIHandlerInterface
$this->rcache = $rcache;
$this->country_code = $country_code;
$this->mclient = $mclient;
$this->mclientv2 = $mclientv2;
$this->fcmclient = $fcmclient;
$this->wh = $wh;
$this->jo_handler = $jo_handler;
$this->ic = $ic;
@ -466,6 +472,10 @@ class ResqRiderAPIHandler implements RiderAPIHandlerInterface
];
$this->mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$this->mclientv2->sendEvent($jo, $payload);
$this->fcmclient->sendJoEvent($jo, "jo_fcm_title_outlet_assign", "jo_fcm_body_outlet_assign");
return $data;
}
@ -507,6 +517,10 @@ class ResqRiderAPIHandler implements RiderAPIHandlerInterface
];
$this->mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$this->mclientv2->sendEvent($jo, $payload);
$this->fcmclient->sendJoEvent($jo, "jo_fcm_title_driver_arrived", "jo_fcm_body_driver_arrived");
return $data;
}
@ -661,6 +675,10 @@ class ResqRiderAPIHandler implements RiderAPIHandlerInterface
];
$this->mclient->sendEvent($jo, $payload);
// NOTE: for resq2 app
$this->mclientv2->sendEvent($jo, $payload);
$fcmclient->sendJoEvent($jo, "jo_fcm_title_fulfilled", "jo_fcm_body_fulfilled");
return $data;
}

View file

@ -6,6 +6,8 @@ use Doctrine\ORM\EntityManagerInterface;
use App\Service\RiderAssignmentHandlerInterface;
use App\Service\MQTTClient;
use App\Service\MQTTClientApiv2;
use App\Service\FCMSender;
use App\Service\APNSClient;
use App\Entity\JobOrder;
@ -18,12 +20,15 @@ class CMBRiderAssignmentHandler implements RiderAssignmentHandlerInterface
protected $em;
protected $aclient;
protected $mclient;
protected $mclientv2;
protected $fcmclient;
public function __construct(EntityManagerInterface $em, MQTTClient $mclient,
APNSClient $aclient)
public function __construct(EntityManagerInterface $em, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient, APNSClient $aclient)
{
$this->em = $em;
$this->mclient = $mclient;
$this->mclientv2 = $mclientv2;
$this->fcmclient = $fcmclient;
$this->aclient = $aclient;
}
@ -38,6 +43,10 @@ class CMBRiderAssignmentHandler implements RiderAssignmentHandlerInterface
// send event
$this->mclient->sendEvent($obj, $payload);
// NOTE: for resq2 app
$this->mclientv2->sendEvent($obj, $payload);
$this->fcmclient->sendJoEvent($obj, "jo_fcm_title_driver_assigned", "jo_fcm_body_driver_assigned");
// check if rider is available
if ($rider->isAvailable())
{
@ -66,6 +75,10 @@ class CMBRiderAssignmentHandler implements RiderAssignmentHandlerInterface
];
$this->mclient->sendEvent($obj, $payload);
// NOTE: for resq2 app
$this->mclientv2->sendEvent($obj, $payload);
$this->fcmclient->sendJoEvent($obj, "jo_fcm_title_fulfilled", "jo_fcm_body_fulfilled");
// send fulfill/complete event to rider
$this->mclient->sendRiderEvent($obj, $payload);

View file

@ -8,6 +8,8 @@ use Symfony\Contracts\Translation\TranslatorInterface;
use App\Service\RiderAssignmentHandlerInterface;
use App\Service\MQTTClient;
use App\Service\MQTTClientApiv2;
use App\Service\FCMSender;
use App\Service\APNSClient;
use App\Entity\JobOrder;
@ -20,13 +22,16 @@ class ResqRiderAssignmentHandler implements RiderAssignmentHandlerInterface
protected $em;
protected $aclient;
protected $mclient;
protected $mclientv2;
protected $fcmclient;
protected $translator;
public function __construct(EntityManagerInterface $em, MQTTClient $mclient,
APNSClient $aclient, TranslatorInterface $translator)
public function __construct(EntityManagerInterface $em, MQTTClient $mclient, MQTTClientApiv2 $mclientv2, FCMSender $fcmclient, APNSClient $aclient, TranslatorInterface $translator)
{
$this->em = $em;
$this->mclient = $mclient;
$this->mclientv2 = $mclientv2;
$this->fcmclient = $fcmclient;
$this->aclient = $aclient;
$this->translator = $translator;
}
@ -42,6 +47,10 @@ class ResqRiderAssignmentHandler implements RiderAssignmentHandlerInterface
// send event
$this->mclient->sendEvent($obj, $payload);
// NOTE: for resq2 app
$this->mclientv2->sendEvent($obj, $payload);
$this->fcmclient->sendJoEvent($obj, "jo_fcm_title_driver_assigned", "jo_fcm_body_driver_assigned");
// check if rider is available
if ($rider->isAvailable())
{
@ -72,6 +81,10 @@ class ResqRiderAssignmentHandler implements RiderAssignmentHandlerInterface
];
$this->mclient->sendEvent($obj, $payload);
// NOTE: for resq2 app
$this->mclientv2->sendEvent($obj, $payload);
$this->fcmclient->sendJoEvent($obj, "jo_fcm_title_fulfilled", "jo_fcm_body_fulfilled");
// send fulfill/complete event to rider
$this->mclient->sendRiderEvent($obj, $payload);
}

Some files were not shown because too many files have changed in this diff Show more