Merge branch 'master' of gitlab.com:jankstudio/resq into 194-catalyst-api-bundle-acl
This commit is contained in:
commit
29f574e25c
35 changed files with 1104 additions and 136 deletions
|
|
@ -28,3 +28,10 @@ RT_SHORTCODE=1234
|
|||
MQTT_IP_ADDRESS=localhost
|
||||
MQTT_PORT=8883
|
||||
MQTT_CERT=/location/of/cert/file.crt
|
||||
|
||||
# redis client
|
||||
REDIS_CLIENT_SCHEME=tcp
|
||||
REDIS_CLIENT_HOST=127.0.0.1
|
||||
REDIS_CLIENT_PORT=6379
|
||||
REDIS_CLIENT_PASSWORD=foobared
|
||||
#
|
||||
|
|
|
|||
|
|
@ -72,14 +72,19 @@ services:
|
|||
|
||||
App\Service\MQTTClient:
|
||||
arguments:
|
||||
$ip_address: "%env(MQTT_IP_ADDRESS)%"
|
||||
$port: "%env(MQTT_PORT)%"
|
||||
$cert: "%env(MQTT_CERT)%"
|
||||
$redis_client: "@App\\Service\\RedisClientProvider"
|
||||
|
||||
App\Service\APNSClient:
|
||||
arguments:
|
||||
$ip_address: "%env(APNS_REDIS_IP_ADDRESS)%"
|
||||
$port: "%env(APNS_REDIS_PORT)%"
|
||||
$redis_client: "@App\\Service\\RedisClientProvider"
|
||||
|
||||
App\Service\RedisClientProvider:
|
||||
arguments:
|
||||
$scheme: "%env(REDIS_CLIENT_SCHEME)%"
|
||||
$host: "%env(REDIS_CLIENT_HOST)%"
|
||||
$port: "%env(REDIS_CLIENT_PORT)%"
|
||||
$password: "%env(REDIS_CLIENT_PASSWORD)%"
|
||||
$env_flag: "dev"
|
||||
|
||||
Catalyst\APIBundle\Security\APIKeyUserProvider:
|
||||
arguments:
|
||||
|
|
|
|||
104
src/Command/GenerateBatteryCompatibilityCommand.php
Normal file
104
src/Command/GenerateBatteryCompatibilityCommand.php
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
|
||||
use App\Entity\VehicleManufacturer;
|
||||
use App\Entity\Vehicle;
|
||||
use App\Entity\Battery;
|
||||
use App\Entity\BatteryManufacturer;
|
||||
use App\Entity\BatteryModel;
|
||||
use App\Entity\BatterySize;
|
||||
|
||||
class GenerateBatteryCompatibilityCommand extends Command
|
||||
{
|
||||
protected $em;
|
||||
protected $vmfg_index;
|
||||
|
||||
public function __construct(ObjectManager $om)
|
||||
{
|
||||
$this->em = $om;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function populateVehicleManufacturerIndex()
|
||||
{
|
||||
$vms = $this->em->getRepository(VehicleManufacturer::class)->findAll();
|
||||
|
||||
$this->vmfg_index = [];
|
||||
foreach ($vms as $vm)
|
||||
{
|
||||
$mfg_name = $vm->getName();
|
||||
// $this->vmfg_index[$mfg_name] = [];
|
||||
|
||||
// get vehicles from manufacturer
|
||||
$make_array = [];
|
||||
$vehicles = $vm->getVehicles();
|
||||
foreach ($vehicles as $vehicle)
|
||||
{
|
||||
$batteries = $vehicle->getBatteries();
|
||||
$comp_batt = [];
|
||||
foreach ($batteries as $battery)
|
||||
{
|
||||
// set to the first compatible battery found until a more expensive one is found
|
||||
$comp_batt['id'] = $battery->getID();
|
||||
$comp_batt['name'] = $battery->getModel()->getName() . ' ' .
|
||||
$battery->getSize()->getName();
|
||||
$comp_batt['image_url'] = '/assets/img/products/' . strtolower($battery->getModel()->getName()) . '.png';
|
||||
$comp_batt['description'] = '';
|
||||
//$comp_batt['description'] = $battery->getDescription();
|
||||
|
||||
// store the selling price for comparison
|
||||
$batt_price = $battery->getSellingPrice();
|
||||
|
||||
// find the most expensive compatible battery
|
||||
if ($battery->getSellingPrice() > $batt_price)
|
||||
{
|
||||
$comp_batt['id'] = $battery->getID();
|
||||
$comp_batt['name'] = $battery->getModel()->getName() . ' ' .
|
||||
$battery->getSize()->getName();
|
||||
$comp_batt['image_url'] = $battery->getImageFile();
|
||||
//$comp_batt['description'] = $battery->getDescription();
|
||||
}
|
||||
}
|
||||
|
||||
// check if no compatible batteries
|
||||
if (!empty($comp_batt))
|
||||
$make_array[$vehicle->getMake()][$vehicle->getModelYearFormatted()] = $comp_batt;
|
||||
|
||||
}
|
||||
|
||||
// check if empty
|
||||
if (!empty($make_array))
|
||||
$this->vmfg_index[$mfg_name] = $make_array;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('battery:generate_compatibility_json')
|
||||
->setDescription('Generate a json file containing the vehicles and their compatible batteries')
|
||||
->setHelp('Generate a json file containing the vehicles and their compatible batteries')
|
||||
->addArgument('file', InputArgument::REQUIRED, 'Path and name for JSON file.');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$filename = $input->getArgument('file');
|
||||
$this->populateVehicleManufacturerIndex();
|
||||
|
||||
$json_file = fopen($filename, 'w');
|
||||
fwrite($json_file, json_encode($this->vmfg_index, JSON_PRETTY_PRINT));
|
||||
fclose($json_file);
|
||||
|
||||
}
|
||||
}
|
||||
215
src/Command/GenerateWarrantyFromJobOrderCommand.php
Normal file
215
src/Command/GenerateWarrantyFromJobOrderCommand.php
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use DateTime;
|
||||
use DateInterval;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
|
||||
use App\Entity\JobOrder;
|
||||
use App\Entity\Warranty;
|
||||
use App\Entity\SAPBattery;
|
||||
|
||||
use App\Ramcar\ServiceType;
|
||||
use App\Ramcar\WarrantyStatus;
|
||||
|
||||
class GenerateWarrantyFromJobOrderCommand extends Command
|
||||
{
|
||||
protected $em;
|
||||
protected $sapbatt_hash;
|
||||
protected $warranties_hash;
|
||||
|
||||
public function __construct(ObjectManager $em)
|
||||
{
|
||||
$this->em = $em;
|
||||
|
||||
$this->loadSAPBatteries();
|
||||
$this->loadWarranties();
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('warranty:generate')
|
||||
->setDescription('Generates warranty from job order and inserts into database')
|
||||
->setHelp('Generate warranty from job order');
|
||||
}
|
||||
|
||||
protected function computeDateExpire($date_create, $warranty_period)
|
||||
{
|
||||
$expire_date = clone $date_create;
|
||||
$expire_date->add(new DateInterval('P'.$warranty_period.'M'));
|
||||
return $expire_date;
|
||||
}
|
||||
|
||||
protected function loadSAPBatteries()
|
||||
{
|
||||
$this->sapbatt_hash = [];
|
||||
|
||||
$sap_batteries = $this->em->getRepository(SAPBattery::class)->findAll();
|
||||
foreach($sap_batteries as $sap_batt)
|
||||
{
|
||||
$id = $sap_batt->getID();
|
||||
$brand_size = $sap_batt->getBrand()->getID() . " " . $sap_batt->getSize()->getID();
|
||||
$this->sapbatt_hash[$id] = $brand_size;
|
||||
}
|
||||
}
|
||||
|
||||
protected function loadWarranties()
|
||||
{
|
||||
$this->warranties_hash = [];
|
||||
|
||||
/*
|
||||
$warranties = $this->em->getRepository(Warranty::class)->findAll();
|
||||
foreach($warranties as $warranty)
|
||||
{
|
||||
$plate_number = $warranty->getPlateNumber();
|
||||
$date_expire = $warranty->getDateExpire();
|
||||
|
||||
// skip null date expire
|
||||
if ($date_expire == null)
|
||||
continue;
|
||||
|
||||
$expiry_date = $date_expire->format('Y-m-d');
|
||||
|
||||
$this->warranties_hash[$plate_number][$expiry_date] = $warranty->getID();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
protected function findSAPBattery($batt_id)
|
||||
{
|
||||
if (!isset($this->sapbatt_hash[$batt_id]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function findWarranty($plate_number, $expiry_date)
|
||||
{
|
||||
$date_expire = $expiry_date->format('Y-m-d');
|
||||
if (!isset($this->warranties_hash[$plate_number][$date_expire]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$em = $this->em;
|
||||
|
||||
// to save on joins, go with invoice item first
|
||||
$query = $em->createQuery('select ii,i,jo,cv from App\Entity\InvoiceItem ii inner join ii.invoice i inner join i.job_order jo inner join jo.cus_vehicle cv join jo.customer c where ii.battery is not null and jo.service_type = :service_type');
|
||||
$query->setParameter('service_type', ServiceType::BATTERY_REPLACEMENT_NEW);
|
||||
/*
|
||||
$query = $em->createQuery('SELECT jo FROM App\Entity\JobOrder jo
|
||||
WHERE jo.service_type = :service_type');
|
||||
$query->setParameter('service_type', ServiceType::BATTERY_REPLACEMENT_NEW);
|
||||
*/
|
||||
|
||||
$result = $query->iterate();
|
||||
|
||||
foreach ($result as $row)
|
||||
{
|
||||
$invoice_item = $row[0];
|
||||
$invoice = $invoice_item->getInvoice();
|
||||
$jo = $invoice->getJobOrder();
|
||||
$cv = $jo->getCustomerVehicle();
|
||||
$customer = $jo->getCustomer();
|
||||
/*
|
||||
$invoice_items = [];
|
||||
// for now, one invoice == one battery
|
||||
|
||||
|
||||
$invoice_items = $jo->getInvoice()->getItems();
|
||||
$invoice_item = $invoice_items[0];
|
||||
*/
|
||||
if ($invoice_item != null)
|
||||
{
|
||||
if($invoice_item->getBattery() != null)
|
||||
{
|
||||
// manually retrieve the SAPBattery using the SAPCode
|
||||
$battery_sap_code = $invoice_item->getBattery()->getSAPCode();
|
||||
$found_battery = $this->findSAPBattery($battery_sap_code);
|
||||
$sap_code = '\'' . $battery_sap_code . '\'';
|
||||
if (!$found_battery)
|
||||
{
|
||||
$sap_code = 'NULL';
|
||||
}
|
||||
|
||||
// get warranty period for battery
|
||||
// TODO: base it on the battery type
|
||||
$warranty_period = 0;
|
||||
if ($invoice_item->getBattery()->getWarrantyPrivate() != null)
|
||||
{
|
||||
$warranty_period = $invoice_item->getBattery()->getWarrantyPrivate();
|
||||
}
|
||||
if ($invoice_item->getBattery()->getWarrantyCommercial() != null)
|
||||
{
|
||||
$warranty_period = $invoice_item->getBattery()->getWarrantyCommercial();
|
||||
}
|
||||
if ($invoice_item->getBattery()->getWarrantyTnv() != null)
|
||||
{
|
||||
$warranty_period = $invoice_item->getBattery()->getWarrantyTnv();
|
||||
}
|
||||
|
||||
if ($invoice->getDateCreate() != null)
|
||||
{
|
||||
// check if plate number is "clean". If not, do not insert into warranty
|
||||
if (!(Warranty::cleanPlateNumber($cv->getPlateNumber())))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if warranty already exists
|
||||
$cleaned_plate_number = Warranty::cleanPlateNumber($cv->getPlateNumber());
|
||||
|
||||
$expiry_date = $this->computeDateExpire($jo->getInvoice()->getDateCreate(), $warranty_period);
|
||||
$found_warranty = $this->findWarranty($cleaned_plate_number, $expiry_date);
|
||||
if (!$found_warranty)
|
||||
{
|
||||
$bty_model_id = $invoice_item->getBattery()->getModel()->getID();
|
||||
$bty_size_id = $invoice_item->getBattery()->getSize()->getID();
|
||||
$warranty_class = $jo->getWarrantyClass();
|
||||
|
||||
$date = $jo->getInvoice()->getDateCreate();
|
||||
$date_purchase = $date->format('Y-m-d');
|
||||
|
||||
$date_create = date('Y-m-d H:i:s');
|
||||
|
||||
$date_expire = $expiry_date->format('Y-m-d');
|
||||
|
||||
$first_name = addslashes(trim($customer->getFirstName()));
|
||||
$last_name = addslashes(trim($customer->getLastName()));
|
||||
$mobile_number = addslashes(trim($customer->getPhoneMobile()));
|
||||
|
||||
$values = '(' . $bty_model_id . ',' . $bty_size_id . ',NULL,\'' . $warranty_class . '\',\''
|
||||
. $cleaned_plate_number . '\',\'' . WarrantyStatus::ACTIVE . '\',\'' . $date_create . '\',\'' . $date_purchase
|
||||
. '\',\'' . $date_expire . '\',NULL,'
|
||||
. $sap_code . ',NULL,\'' . $first_name . '\',\'' . $last_name . '\',\'' . $mobile_number . '\');';
|
||||
|
||||
$sql_statement = 'INSERT INTO `warranty` (bty_model_id,bty_size_id,serial,warranty_class,plate_number,status,date_create,date_purchase,date_expire,date_claim,sap_bty_id,claim_id,first_name,last_name,mobile_number) VALUES ' . $values . "\n";
|
||||
|
||||
echo $sql_statement;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$em->detach($row[0]);
|
||||
$em->clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
39
src/Command/TestHubCounterCommand.php
Normal file
39
src/Command/TestHubCounterCommand.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use App\Service\HubCounter;
|
||||
|
||||
class TestHubCounterCommand extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('test:hubcounter')
|
||||
->setDescription('Test hubcounter service. Currently tests addAvailableRider and getAvailableRiderCount.')
|
||||
->setHelp('Test hubcounter service. Currently tests addAvailableRider and getAvailableRiderCount.')
|
||||
->addArgument('hub_id', InputArgument::REQUIRED, 'Hub ID');
|
||||
}
|
||||
|
||||
public function __construct(HubCounter $hc)
|
||||
{
|
||||
$this->hc = $hc;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$hub_id = $input->getArgument('hub_id');
|
||||
|
||||
$this->hc->addAvailableRider($hub_id);
|
||||
|
||||
$available_rc = $this->hc->getAvailableRiderCount($hub_id);
|
||||
|
||||
echo "Available Riders in Hub: " . $available_rc . "\n";
|
||||
}
|
||||
}
|
||||
40
src/Command/TestJobOrderManagerCommand.php
Normal file
40
src/Command/TestJobOrderManagerCommand.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use App\Service\JobOrderManager;
|
||||
|
||||
class TestJobOrderManagerCommand extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('test:fulfilljoborder')
|
||||
->setDescription('Test fulfill job order service.')
|
||||
->setHelp('Test the fulfill job order service.')
|
||||
->addArgument('job_order_id', InputArgument::REQUIRED, 'Job Order ID');
|
||||
}
|
||||
|
||||
public function __construct(JobOrderManager $jo_manager)
|
||||
{
|
||||
$this->jo_manager = $jo_manager;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$jo_id = $input->getArgument('job_order_id');
|
||||
|
||||
$result = $this->jo_manager->fulfillJobOrder($jo_id);
|
||||
|
||||
if ($result)
|
||||
echo "Job Order successfully updated" . "\n";
|
||||
else
|
||||
echo "Job Order not updated" . "\n";
|
||||
}
|
||||
}
|
||||
40
src/Command/TestRegAPNSCommand.php
Normal file
40
src/Command/TestRegAPNSCommand.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
|
||||
use App\Service\APNSClient;
|
||||
|
||||
use DateTime;
|
||||
|
||||
class TestRegAPNSCommand extends Command
|
||||
{
|
||||
protected $apns;
|
||||
|
||||
public function __construct( APNSClient $apns)
|
||||
{
|
||||
$this->apns = $apns;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('apns:test_reg')
|
||||
->setDescription('Test new format for Apple Push Notification.')
|
||||
->setHelp('Test new format for Apple Push Notification.')
|
||||
->addArgument('push_id', InputArgument::REQUIRED, 'push_id');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$push_id = $input->getArgument('push_id');
|
||||
$this->apns->sendReg($push_id, 'Test Delay', 'Body');
|
||||
}
|
||||
}
|
||||
46
src/Command/TestRiderTrackerCommand.php
Normal file
46
src/Command/TestRiderTrackerCommand.php
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
||||
|
||||
use App\Service\RiderTracker;
|
||||
|
||||
class TestRiderTrackerCommand extends Command
|
||||
{
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('test:ridertracker')
|
||||
->setDescription('Test the rider tracker service')
|
||||
->setHelp('Test the rider tracker service.')
|
||||
->addArgument('rider_id', InputArgument::REQUIRED, 'Rider ID');
|
||||
}
|
||||
|
||||
public function __construct(RiderTracker $rtracker)
|
||||
{
|
||||
$this->rtracker = $rtracker;
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$rider_id = $input->getArgument('rider_id');
|
||||
|
||||
$coordinates = $this->rtracker->getRiderLocation($rider_id);
|
||||
|
||||
if ($coordinates != null)
|
||||
{
|
||||
echo "Rider Location: " . $coordinates->getLongitude() . "," . $coordinates->getLatitude() . "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "Invalid rider id." . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
67
src/Command/UpdateCustomerVehicleBatteryCommand.php
Normal file
67
src/Command/UpdateCustomerVehicleBatteryCommand.php
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
use Doctrine\Common\Persistence\ObjectManager;
|
||||
|
||||
use App\Entity\JobOrder;
|
||||
|
||||
use App\Ramcar\JOStatus;
|
||||
|
||||
class UpdateCustomerVehicleBatteryCommand extends Command
|
||||
{
|
||||
protected $em;
|
||||
protected $custvehicle_hash;
|
||||
|
||||
public function __construct(ObjectManager $om)
|
||||
{
|
||||
$this->em = $om;
|
||||
$this->custvehicle_hash = [];
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
protected function configure()
|
||||
{
|
||||
$this->setName('joborder:updatebattery')
|
||||
->setDescription('Update customer vehicle battery information.')
|
||||
->setHelp('Updates the customer vehicle battery based on the latest battery purchased. ');
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
// get all job orders with fulfilled status
|
||||
$jos = $this->em->getRepository(JobOrder::class)->findBy(['status' => JOStatus::FULFILLED], ['date_create' => 'DESC']);
|
||||
foreach ($jos as $jo)
|
||||
{
|
||||
if ($jo->getCustomerVehicle() != null)
|
||||
{
|
||||
$custvehicle_id = $jo->getCustomerVehicle()->getID();
|
||||
// check if custvehicle is in hash. This would mean that the battery has already been set
|
||||
if(!isset($this->custvehicle_hash[$custvehicle_id]))
|
||||
{
|
||||
// get battery purchased from job order
|
||||
$items = $jo->getInvoice()->getItems();
|
||||
foreach($items as $item)
|
||||
{
|
||||
if ($item->getBattery() != null)
|
||||
{
|
||||
// set battery of vehicle to the latest battery purchased
|
||||
$new_battery = $item->getBattery();
|
||||
$jo->getCustomerVehicle()->setCurrentBattery($new_battery);
|
||||
|
||||
// add customer vehicle to hash
|
||||
$this->custvehicle_hash[$custvehicle_id] = true;
|
||||
}
|
||||
}
|
||||
$this->em->flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ use App\Service\InvoiceCreator;
|
|||
use App\Service\RisingTideGateway;
|
||||
use App\Service\MQTTClient;
|
||||
use App\Service\GeofenceTracker;
|
||||
use App\Service\RiderTracker;
|
||||
|
||||
use App\Entity\MobileSession;
|
||||
use App\Entity\Customer;
|
||||
|
|
@ -1116,7 +1117,7 @@ class APIController extends Controller
|
|||
return $res->getReturnResponse();
|
||||
}
|
||||
|
||||
public function getRiderStatus(Request $req)
|
||||
public function getRiderStatus(Request $req, RiderTracker $rt)
|
||||
{
|
||||
$required_params = [];
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
|
|
@ -1243,8 +1244,9 @@ class APIController extends Controller
|
|||
case JOStatus::ASSIGNED:
|
||||
case JOStatus::IN_TRANSIT:
|
||||
case JOStatus::IN_PROGRESS:
|
||||
$coord = $jo->getHub()->getCoordinates();
|
||||
$rider = $jo->getRider();
|
||||
// get rider coordinates from redis
|
||||
$coord = $rt->getRiderLocation($rider->getID());
|
||||
|
||||
// default image url
|
||||
$url_prefix = $req->getSchemeAndHttpHost();
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use Doctrine\ORM\Query;
|
|||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
|
||||
|
||||
use App\Menu\Generator as MenuGenerator;
|
||||
use App\Access\Generator as ACLGenerator;
|
||||
|
|
@ -275,7 +276,19 @@ class RoleController extends BaseController
|
|||
], 422);
|
||||
} else {
|
||||
// validated! save the entity
|
||||
$em->flush();
|
||||
// catch the exception in case user updated the id
|
||||
try
|
||||
{
|
||||
$em->flush();
|
||||
}
|
||||
catch(ForeignKeyConstraintViolationException $e)
|
||||
{
|
||||
$error_array['id'] = 'Role has already been assigned to user/s and id cannot be updated';
|
||||
return $this->json([
|
||||
'success' => false,
|
||||
'errors' => $error_array
|
||||
], 403);
|
||||
}
|
||||
|
||||
// return successful response
|
||||
return $this->json([
|
||||
|
|
|
|||
|
|
@ -162,30 +162,37 @@ class Warranty
|
|||
// trim and make upper case
|
||||
$clean_plate = strtoupper(trim($plate));
|
||||
|
||||
// remove invalid characters
|
||||
$clean_plate = preg_replace("/[^A-Z0-9]/", '', $clean_plate);
|
||||
|
||||
// check for 4 to 5 digit diplomatic plate
|
||||
$res = preg_match("/^[0-9]{4,5}$/", $clean_plate);
|
||||
if ($res)
|
||||
return $clean_plate;
|
||||
|
||||
// ABC-1234 or ABC-123 or ABC-12 format
|
||||
$res = preg_match("/^[A-Z]{3}[0-9]{2,4}$/", $clean_plate);
|
||||
if ($res)
|
||||
return $clean_plate;
|
||||
|
||||
// AB-123 or AB-12345 or AB-1234 format (motorcycles)
|
||||
$res = preg_match("/^[A-Z]{2}[0-9]{3,5}$/", $clean_plate);
|
||||
if ($res)
|
||||
return $clean_plate;
|
||||
|
||||
// 1234-AB format (motorcycles)
|
||||
$res = preg_match("/^[0-9]{4}[A-Z]{2}$/", $clean_plate);
|
||||
// check if alphanumeric, max length is 11, no spaces
|
||||
$res = preg_match("/^[A-Z0-9]{1,11}+$/", $clean_plate);
|
||||
if ($res)
|
||||
return $clean_plate;
|
||||
|
||||
return false;
|
||||
|
||||
// remove invalid characters
|
||||
//$clean_plate = preg_replace("/[^A-Z0-9]/", '', $clean_plate);
|
||||
|
||||
// check for 4 to 5 digit diplomatic plate
|
||||
//$res = preg_match("/^[0-9]{4,5}$/", $clean_plate);
|
||||
//if ($res)
|
||||
// return $clean_plate;
|
||||
|
||||
// ABC-1234 or ABC-123 or ABC-12 format
|
||||
//$res = preg_match("/^[A-Z]{3}[0-9]{2,4}$/", $clean_plate);
|
||||
//if ($res)
|
||||
// return $clean_plate;
|
||||
|
||||
// AB-123 or AB-12345 or AB-1234 format (motorcycles)
|
||||
//$res = preg_match("/^[A-Z]{2}[0-9]{3,5}$/", $clean_plate);
|
||||
//if ($res)
|
||||
// return $clean_plate;
|
||||
|
||||
// 1234-AB format (motorcycles)
|
||||
//$res = preg_match("/^[0-9]{4}[A-Z]{2}$/", $clean_plate);
|
||||
//if ($res)
|
||||
// return $clean_plate;
|
||||
|
||||
//return false;
|
||||
}
|
||||
|
||||
public function setPlateNumber($plate)
|
||||
|
|
|
|||
|
|
@ -5,25 +5,24 @@ namespace App\Service;
|
|||
use Mosquitto\Client as MosquittoClient;
|
||||
use App\Entity\JobOrder;
|
||||
use App\Ramcar\MobileOSType;
|
||||
use Redis;
|
||||
|
||||
class APNSClient
|
||||
{
|
||||
// TODO: make this a config entry
|
||||
const REDIS_KEY = 'apns_push';
|
||||
|
||||
// protected $mclient;
|
||||
protected $redis;
|
||||
|
||||
public function __construct($ip_address, $port)
|
||||
public function __construct(RedisClientProvider $redis_client)
|
||||
{
|
||||
$this->redis = new Redis();
|
||||
$this->redis->connect($ip_address, $port);
|
||||
$this->redis = $redis_client->getRedisClient();
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
public function __destruct()
|
||||
{
|
||||
// $this->mclient->disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public function push($token, $message)
|
||||
{
|
||||
|
|
@ -53,4 +52,9 @@ class APNSClient
|
|||
$this->push($push_id, $message);
|
||||
}
|
||||
}
|
||||
|
||||
public function sendReg($push_id, $message)
|
||||
{
|
||||
$this->push($push_id, $message);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,13 +15,10 @@ class HubCounter
|
|||
protected $em;
|
||||
protected $redis;
|
||||
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
public function __construct(EntityManagerInterface $em, RedisClientProvider $redis_client)
|
||||
{
|
||||
$this->em = $em;
|
||||
|
||||
// TODO: make it read redis settings from config
|
||||
// build a service maybe?
|
||||
$this->redis = new Predis\Client();
|
||||
$this->redis = $redis_client->getRedisClient();
|
||||
}
|
||||
|
||||
// get rider key based on id
|
||||
|
|
@ -45,7 +42,7 @@ class HubCounter
|
|||
return $value;
|
||||
|
||||
// not in cache
|
||||
$hub = $em->getRepository(Hub::class)->find($hub_id);
|
||||
$hub = $this->em->getRepository(Hub::class)->find($hub_id);
|
||||
$riders = $hub->getActiveRiders();
|
||||
$rider_count = count($riders);
|
||||
|
||||
|
|
|
|||
53
src/Service/JobOrderManager.php
Normal file
53
src/Service/JobOrderManager.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Entity\JobOrder;
|
||||
|
||||
use App\Ramcar\ServiceType;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
class JobOrderManager
|
||||
{
|
||||
protected $em;
|
||||
|
||||
public function __construct(EntityManagerInterface $em)
|
||||
{
|
||||
$this->em = $em;
|
||||
}
|
||||
|
||||
public function fulfillJobOrder($jo_id)
|
||||
{
|
||||
$results = $this->em->getRepository(JobOrder::class)->findby(array('id' => $jo_id, 'service_type' => ServiceType::BATTERY_REPLACEMENT_NEW));
|
||||
if (isset($results[0]))
|
||||
{
|
||||
$jo = $results[0];
|
||||
$jo->fulfill();
|
||||
|
||||
$cust_vehicle = $jo->getCustomerVehicle();
|
||||
$invoice = $jo->getInvoice();
|
||||
$this->updateCustomerVehicleBattery($cust_vehicle, $invoice);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function updateCustomerVehicleBattery($cust_vehicle, $invoice)
|
||||
{
|
||||
if (($cust_vehicle != null) && ($invoice != null))
|
||||
{
|
||||
$items = $invoice->getItems();
|
||||
foreach ($items as $item)
|
||||
{
|
||||
$new_battery = $item->getBattery();
|
||||
$cust_vehicle->setCurrentBattery($new_battery);
|
||||
}
|
||||
|
||||
$this->em->flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ namespace App\Service;
|
|||
|
||||
use Mosquitto\Client as MosquittoClient;
|
||||
use App\Entity\JobOrder;
|
||||
use Redis;
|
||||
|
||||
class MQTTClient
|
||||
{
|
||||
|
|
@ -15,27 +14,15 @@ class MQTTClient
|
|||
// protected $mclient;
|
||||
protected $redis;
|
||||
|
||||
public function __construct($ip_address, $port, $cert)
|
||||
public function __construct(RedisClientProvider $redis_client)
|
||||
{
|
||||
// we use redis now
|
||||
// we have an mqtt server listening on redis and sending to mqtt
|
||||
$this->redis = new Redis();
|
||||
$this->redis->connect('127.0.0.1', 6379);
|
||||
|
||||
/*
|
||||
error_log("connecting to mqtt server - $ip_address : $port");
|
||||
error_log("using $cert");
|
||||
$this->mclient = new MosquittoClient();
|
||||
$this->mclient->setTlsCertificates($cert);
|
||||
$this->mclient->setTlsOptions(MosquittoClient::SSL_VERIFY_NONE, 'tlsv1');
|
||||
$this->mclient->connect($ip_address, $port);
|
||||
*/
|
||||
$this->redis = $redis_client->getRedisClient();
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
public function __destruct()
|
||||
{
|
||||
// $this->mclient->disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public function publish($channel, $message)
|
||||
{
|
||||
|
|
|
|||
44
src/Service/RedisClientProvider.php
Normal file
44
src/Service/RedisClientProvider.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use Predis\Client as PredisClient;
|
||||
|
||||
class RedisClientProvider
|
||||
{
|
||||
protected $redis;
|
||||
protected $scheme;
|
||||
protected $host;
|
||||
protected $port;
|
||||
protected $password;
|
||||
protected $env_flag;
|
||||
|
||||
public function __construct($scheme, $host, $port, $password, $env_flag)
|
||||
{
|
||||
$this->scheme = $scheme;
|
||||
$this->host = $host;
|
||||
$this->port = $port;
|
||||
$this->password = $password;
|
||||
$this->env_flag = $env_flag;
|
||||
}
|
||||
|
||||
public function getRedisClient()
|
||||
{
|
||||
if ($this->env_flag == 'dev')
|
||||
{
|
||||
$this->redis = new PredisClient([
|
||||
"scheme"=>$this->scheme,
|
||||
"host"=>$this->host,
|
||||
"port"=>$this->port]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->redis = new PredisClient([
|
||||
"scheme"=>$this->scheme,
|
||||
"host"=>$this->host,
|
||||
"port"=>$this->port,
|
||||
"password"=>$this->password]);
|
||||
}
|
||||
return $this->redis;
|
||||
}
|
||||
}
|
||||
52
src/Service/RiderTracker.php
Normal file
52
src/Service/RiderTracker.php
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Entity\Rider;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
|
||||
use CrEOF\Spatial\PHP\Types\Geometry\Point;
|
||||
|
||||
class RiderTracker
|
||||
{
|
||||
const RIDER_PREFIX_KEY = 'rider.location';
|
||||
|
||||
protected $em;
|
||||
protected $redis;
|
||||
|
||||
public function __construct(EntityManagerInterface $em, RedisClientProvider $redis_client)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->redis = $redis_client->getRedisClient();
|
||||
}
|
||||
|
||||
protected function getRiderKey($rider_id)
|
||||
{
|
||||
return self::RIDER_PREFIX_KEY . '.' . $rider_id;
|
||||
}
|
||||
|
||||
public function getRiderLocation($rider_id)
|
||||
{
|
||||
$coordinates = new Point(0,0);
|
||||
$key = $this->getRiderKey($rider_id);
|
||||
|
||||
// check redis cache for rider information
|
||||
if (($this->redis->hexists($key, 'longitude')) &&
|
||||
($this->redis->hexists($key, 'latitude')))
|
||||
{
|
||||
$long = $this->redis->hget($key, 'longitude');
|
||||
$lat = $this->redis->hget($key, 'latitude');
|
||||
|
||||
$coordinates = new Point($long, $lat);
|
||||
}
|
||||
else
|
||||
{
|
||||
$rider = $this->em->getRepository(Rider::class)->find($rider_id);
|
||||
$coordinates = $rider->getHub()->getCoordinates();
|
||||
}
|
||||
|
||||
return $coordinates;
|
||||
|
||||
}
|
||||
}
|
||||
15
symfony.lock
15
symfony.lock
|
|
@ -1,4 +1,16 @@
|
|||
{
|
||||
"creof/doctrine2-spatial": {
|
||||
"version": "1.2.0"
|
||||
},
|
||||
"creof/geo-parser": {
|
||||
"version": "2.1.0"
|
||||
},
|
||||
"creof/wkb-parser": {
|
||||
"version": "v2.3.0"
|
||||
},
|
||||
"creof/wkt-parser": {
|
||||
"version": "2.2.0"
|
||||
},
|
||||
"data-dog/audit-bundle": {
|
||||
"version": "v0.1.10"
|
||||
},
|
||||
|
|
@ -263,6 +275,9 @@
|
|||
"symfony/stopwatch": {
|
||||
"version": "v4.0.2"
|
||||
},
|
||||
"symfony/thanks": {
|
||||
"version": "v1.1.0"
|
||||
},
|
||||
"symfony/twig-bridge": {
|
||||
"version": "v4.0.2"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -114,11 +114,11 @@
|
|||
var actions = '';
|
||||
|
||||
if (row.meta.update_url != '') {
|
||||
actions += '<a href="' + row.meta.update_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-edit" data-id="' + row.username + '" title="Edit"><i class="la la-edit"></i></a>';
|
||||
actions += '<a href="' + row.meta.update_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-edit" data-id="' + row.name + '" title="Edit"><i class="la la-edit"></i></a>';
|
||||
}
|
||||
|
||||
if (row.meta.delete_url != '') {
|
||||
actions += '<a href="' + row.meta.delete_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-delete" data-id="' + row.username + '" title="Delete"><i class="la la-trash"></i></a>';
|
||||
actions += '<a href="' + row.meta.delete_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-delete" data-id="' + row.name + '" title="Delete"><i class="la la-trash"></i></a>';
|
||||
}
|
||||
|
||||
return actions;
|
||||
|
|
|
|||
|
|
@ -893,7 +893,8 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="//maps.google.com/maps/api/js?key={{ gmaps_api_key }}" type="text/javascript"></script>
|
||||
<!-- <script src="//maps.google.com/maps/api/js?key={{ gmaps_api_key }}" type="text/javascript"></script> -->
|
||||
<script src="//maps.googleapis.com/maps/api/js?key={{ gmaps_api_key }}" type="text/javascript"></script>
|
||||
<script src="/assets/vendors/custom/gmaps/gmaps.js" type="text/javascript"></script>
|
||||
|
||||
<script>
|
||||
|
|
|
|||
|
|
@ -118,11 +118,11 @@
|
|||
var actions = '';
|
||||
|
||||
if (row.meta.update_url != '') {
|
||||
actions += '<a href="' + row.meta.update_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-edit" data-id="' + row.username + '" title="Edit"><i class="la la-edit"></i></a>';
|
||||
actions += '<a href="' + row.meta.update_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-edit" data-id="' + row.name + '" title="Edit"><i class="la la-edit"></i></a>';
|
||||
}
|
||||
|
||||
if (row.meta.delete_url != '') {
|
||||
actions += '<a href="' + row.meta.delete_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-delete" data-id="' + row.username + '" title="Delete"><i class="la la-trash"></i></a>';
|
||||
actions += '<a href="' + row.meta.delete_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-delete" data-id="' + row.name + '" title="Delete"><i class="la la-trash"></i></a>';
|
||||
}
|
||||
|
||||
return actions;
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@
|
|||
}
|
||||
});
|
||||
}).fail(function(response) {
|
||||
if (response.status == 422) {
|
||||
if (response.status == 422 || response.status == 403) {
|
||||
var errors = response.responseJSON.errors;
|
||||
var firstfield = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -93,11 +93,11 @@
|
|||
var actions = '';
|
||||
|
||||
if (row.meta.update_url != '') {
|
||||
actions += '<a href="' + row.meta.update_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-edit" data-id="' + row.username + '" title="Edit"><i class="la la-edit"></i></a>';
|
||||
actions += '<a href="' + row.meta.update_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-accent m-btn--icon m-btn--icon-only m-btn--pill btn-edit" data-id="' + row.name + '" title="Edit"><i class="la la-edit"></i></a>';
|
||||
}
|
||||
|
||||
if (row.meta.delete_url != '') {
|
||||
actions += '<a href="' + row.meta.delete_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-delete" data-id="' + row.username + '" title="Delete"><i class="la la-trash"></i></a>';
|
||||
actions += '<a href="' + row.meta.delete_url + '" class="m-portlet__nav-link btn m-btn m-btn--hover-danger m-btn--icon m-btn--icon-only m-btn--pill btn-delete" data-id="' + row.id + '" title="Delete"><i class="la la-trash"></i></a>';
|
||||
}
|
||||
|
||||
return actions;
|
||||
|
|
@ -139,4 +139,4 @@
|
|||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class APNSClient():
|
|||
def setupConnection(self):
|
||||
# socket
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
wsock = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_TLSv1, certfile=self.cert_file)
|
||||
wsock = ssl.wrap_socket(sock, ssl_version=ssl.PROTOCOL_TLSv1_2, certfile=self.cert_file)
|
||||
wsock.connect((self.host, self.port))
|
||||
|
||||
self.is_connected = True
|
||||
|
|
|
|||
12
utils/apns_sender/apns_sender.service
Normal file
12
utils/apns_sender/apns_sender.service
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[Unit]
|
||||
Description=Apple Push Notification Sender Service
|
||||
After=mosquitto.service redis.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/python /root/www/resq/utils/apns_sender/new_sender.py
|
||||
StandardInput=tty-force
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
90
utils/apns_sender/new_sender.py
Normal file
90
utils/apns_sender/new_sender.py
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
from daemonize import Daemonize
|
||||
from apns import APNs, Frame, Payload
|
||||
import redis
|
||||
import time
|
||||
import signal
|
||||
import sys
|
||||
import os
|
||||
import logging
|
||||
import socket
|
||||
|
||||
import ssl
|
||||
import struct
|
||||
import binascii
|
||||
|
||||
|
||||
|
||||
def sigint_handler(signal, frame):
|
||||
sys.exit(0)
|
||||
os._exit(0)
|
||||
|
||||
def redisLoop(apns, logger):
|
||||
r = redis.StrictRedis(host='localhost', port=6379, db=0)
|
||||
while 1:
|
||||
#logger.info("Checking queue for messages to send...")
|
||||
time.sleep(0)
|
||||
data = r.brpop("apns_push", 10)
|
||||
if data:
|
||||
info = data[1].split('|')
|
||||
logger.info("Token: " + info[0] + " message: " + info[1])
|
||||
try:
|
||||
apns.sendNotification(info[0], info[1], "notification")
|
||||
except TypeError:
|
||||
logger.info("Invalid token: " + info[0])
|
||||
|
||||
|
||||
def sigint_handler(signal, frame):
|
||||
sys.exit(0)
|
||||
|
||||
def get_logger():
|
||||
logger = logging.getLogger("apns_logger")
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
fh = logging.FileHandler("/tmp/apns_sender.log")
|
||||
fmt = '%(asctime)s - %(threadName)s - %(levelname)s - %(message)s'
|
||||
formatter = logging.Formatter(fmt)
|
||||
fh.setFormatter(formatter)
|
||||
|
||||
logger.addHandler(fh)
|
||||
return logger
|
||||
|
||||
class APNSClient():
|
||||
def __init__(self, title, cert_file, logger):
|
||||
self.title = title
|
||||
self.cert_file = cert_file
|
||||
self.logger = logger
|
||||
# connect
|
||||
self.apns = APNs(cert_file=self.cert_file)
|
||||
|
||||
def sendNotification(self, token, body, notif_type):
|
||||
# apns packet
|
||||
alert = {"title" : self.title,
|
||||
"body" : body,
|
||||
"type" : notif_type}
|
||||
|
||||
payload = Payload(alert=alert, sound="default", badge=1, content_available=True)
|
||||
self.apns.gateway_server.send_notification(token, payload)
|
||||
|
||||
|
||||
def main():
|
||||
logger = get_logger()
|
||||
logger.info("Starting apns_sender")
|
||||
|
||||
#apns = APNs(use_sandbox=False, cert_file=cert_file)
|
||||
#apns = setup_apns()
|
||||
|
||||
# TODO: load from config file
|
||||
cert_file = "/root/ios_push_test/ios_prod.pem"
|
||||
apns = APNSClient("Motolite Res-q", cert_file, logger)
|
||||
|
||||
logger.info("Starting redis loop")
|
||||
redisLoop(apns, logger)
|
||||
|
||||
signal.signal(signal.SIGINT, sigint_handler)
|
||||
|
||||
|
||||
|
||||
pid = "/tmp/apns_sender.pid"
|
||||
#daemon = Daemonize(app="apns_sender", pid=pid, action=main)
|
||||
#daemon.start()
|
||||
main()
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
load data local infile '/tmp/plate_numbers.csv' into table plate_number fields terminated by ',';
|
||||
load data infile '/tmp/legacy_jo.csv' into table legacy_job_order fields terminated by '|' (id, trans_date, trans_type, origin, car_brand, car_make, car_model, car_color, cust_name, cust_first_name, cust_middle_name, cust_last_name, cust_contact, cust_mobile, cust_landline, delivery_instructions, agent_notes_1, delivery_date, delivery_time, advance_order, stage, cancel_reason, cancel_reason_specify, payment_method, prepared_by, dispatch_time, dispatch_date, dispatched_by, address, landmark, date_purchase, plate_number);
|
||||
load data infile '/tmp/legacy_jo_row.csv' into table legacy_job_order_row fields terminated by ',' enclosed by '"' lines terminated by '\n' (job_order_id, item, qty, price, price_level, status, account, enrollee) set id = null;
|
||||
load data local infile '/tmp/warranty.csv' into table warranty fields terminated by ',' (bty_model_id, bty_size_id, serial, warranty_class, plate_number, status, date_create, date_purchase, date_expire, date_claim, claim_id, sap_bty_id, first_name, last_name, mobile_number) set id = null;
|
||||
load data infile '/tmp/legacy_jo.csv' into table legacy_job_order fields terminated by '|' (id, trans_date, trans_type, origin, car_brand, car_make, car_model, car_color, cust_name, cust_first_name, cust_middle_name, cust_last_name, cust_contact, cust_mobile, cust_landline, delivery_instructions, agent_notes_1, delivery_date, delivery_time, advance_order, stage, cancel_reason, cancel_reason_specify, payment_method, prepared_by, dispatch_time, dispatch_date, dispatched_by, address, landmark, date_purchase, plate_number);
|
||||
|
|
|
|||
104
utils/legacy_load/sap_battery.sql
Normal file
104
utils/legacy_load/sap_battery.sql
Normal file
File diff suppressed because one or more lines are too long
12
utils/mqtt_sender/mqtt_sender.service
Normal file
12
utils/mqtt_sender/mqtt_sender.service
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[Unit]
|
||||
Description=MQTT Sender Service
|
||||
After=mosquitto.service redis.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/python /root/www/resq/utils/mqtt_sender/mqtt_sender.py
|
||||
StandardInput=tty-force
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
@ -1,42 +1,38 @@
|
|||
import paho.mqtt.client as mqtt
|
||||
import ssl
|
||||
from threading import Thread
|
||||
import redis
|
||||
import time
|
||||
import signal
|
||||
import sys
|
||||
import os
|
||||
import mysql.connector
|
||||
import json
|
||||
|
||||
def mysql_connect(user, password, host, database):
|
||||
conn = mysql.connector.connect(user=user,
|
||||
password=password,
|
||||
host=host,
|
||||
database=database)
|
||||
return conn
|
||||
class RiderLocationCache(object):
|
||||
|
||||
def init_subscriptions(client, conn):
|
||||
# given mysql connection, get all rider sessions
|
||||
query = ("select id from rider_session")
|
||||
cursor = conn.cursor()
|
||||
cursor.execute(query)
|
||||
for (id) in cursor:
|
||||
print "subscribing to rider session %s" % id
|
||||
client.subscribe('motorider_%s' % id)
|
||||
cursor.close()
|
||||
def run(self, client):
|
||||
print "running loop..."
|
||||
client.loop_forever()
|
||||
|
||||
# TODO: fix this and put these guys back under the class
|
||||
def init_subscriptions(client):
|
||||
print "subscribing to wildcard #"
|
||||
client.subscribe('#')
|
||||
|
||||
def on_connect(client, userdata, flags, rc):
|
||||
conn = mysql_connect('resq', 'Motolite456', '127.0.0.1', 'resq')
|
||||
init_subscriptions(client, conn)
|
||||
print("Connected with result code "+str(rc))
|
||||
client.subscribe("$SYS/#")
|
||||
init_subscriptions(client)
|
||||
#print("Connected with result code "+str(rc))
|
||||
# client.subscribe("$SYS/#")
|
||||
|
||||
def user_data_set(userdata):
|
||||
conn = redis.StrictRedis(host='localhost', port=6379, db=0)
|
||||
return conn
|
||||
|
||||
def on_publish(client, userdata, mid):
|
||||
pass
|
||||
|
||||
def on_message(client, userdata, message):
|
||||
print("message topic=",message.topic[0:10])
|
||||
redis_conn = user_data_set(userdata)
|
||||
#print("message topic=", message.topic[0:10])
|
||||
|
||||
if message.topic[0:10] != 'motorider_':
|
||||
return
|
||||
|
|
@ -44,6 +40,7 @@ def on_message(client, userdata, message):
|
|||
|
||||
# check if json decodable
|
||||
res = json.loads(message.payload)
|
||||
#print res
|
||||
|
||||
# get rider session id
|
||||
sess_id = message.topic[10:]
|
||||
|
|
@ -56,51 +53,17 @@ def on_message(client, userdata, message):
|
|||
if res['event'] != 'driver_location':
|
||||
return
|
||||
|
||||
# save the longitude and latitude
|
||||
# get the rider id from sess_id
|
||||
rider_key = "rider.location.%s" % sess_id
|
||||
rider_long = str(res['longitude'])
|
||||
rider_lat = str(res['latitude'])
|
||||
|
||||
# set the location
|
||||
redis_conn.hmset(rider_key, {'longitude': rider_long, 'latitude': rider_lat})
|
||||
|
||||
# update our redis key
|
||||
key = 'location_%s' % sess_id
|
||||
print "setting %s" % key
|
||||
#print "setting %s" % key
|
||||
redis_conn.setex(key, 1600, message.payload)
|
||||
|
||||
|
||||
|
||||
def getRedis(i):
|
||||
r = redis.StrictRedis(host='localhost', port=6379, db=0)
|
||||
while 1:
|
||||
time.sleep(0)
|
||||
data = r.brpop("events", 10)
|
||||
if data:
|
||||
info = data[1].split('|')
|
||||
print "Channel: " + info[0] + " message: " + info[1]
|
||||
client.publish(info[0], info[1])
|
||||
|
||||
|
||||
def sigint_handler(signal, frame):
|
||||
print 'Interrupted'
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
|
||||
client = mqtt.Client()
|
||||
client.on_connect = on_connect
|
||||
# client.on_publish = on_publish
|
||||
client.on_message = on_message
|
||||
|
||||
redis_conn = redis.StrictRedis(host='localhost', port=6379, db=0)
|
||||
|
||||
|
||||
#client.tls_set(
|
||||
# "/etc/letsencrypt/live/resqaws.jankstudio.com/fullchain.pem", cert_reqs=ssl.CERT_NONE,
|
||||
# tls_version=ssl.PROTOCOL_TLSv1)
|
||||
client.tls_set(
|
||||
"/root/aws_ssl_keys/fullchain.pem", cert_reqs=ssl.CERT_NONE,
|
||||
tls_version=ssl.PROTOCOL_TLSv1)
|
||||
client.connect("resqaws.jankstudio.com", 8883, 60)
|
||||
|
||||
|
||||
#t = Thread(target=getRedis, args=(1,))
|
||||
|
||||
#t.start()
|
||||
|
||||
#signal.signal(signal.SIGINT, sigint_handler)
|
||||
client.loop_forever()
|
||||
|
||||
|
|
|
|||
23
utils/rider_location_cache/riderloc.py
Normal file
23
utils/rider_location_cache/riderloc.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import paho.mqtt.client as mqtt
|
||||
import rider_location_cache as rlc
|
||||
import ssl
|
||||
import logging
|
||||
|
||||
|
||||
client = mqtt.Client()
|
||||
client.on_connect = rlc.on_connect
|
||||
# client.on_publish = on_publish
|
||||
client.on_message = rlc.on_message
|
||||
|
||||
#client.tls_set(
|
||||
# "/etc/letsencrypt/live/resqaws.jankstudio.com/fullchain.pem", cert_reqs=ssl.CERT_NONE,
|
||||
# tls_version=ssl.PROTOCOL_TLSv1)
|
||||
client.tls_set(
|
||||
"/root/aws_ssl_keys/fullchain.pem", cert_reqs=ssl.CERT_NONE,
|
||||
tls_version=ssl.PROTOCOL_TLSv1)
|
||||
#client.connect("resqaws.jankstudio.com", 8883, 60)
|
||||
client.connect("localhost", 8883, 60)
|
||||
|
||||
|
||||
rider_location = rlc.RiderLocationCache()
|
||||
rider_location.run(client)
|
||||
12
utils/rider_location_cache/riderloc.service
Normal file
12
utils/rider_location_cache/riderloc.service
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[Unit]
|
||||
Description=Rider Location Cache Service
|
||||
After=mosquitto.service redis.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/python /root/www/resq/utils/rider_location_cache/riderloc.py
|
||||
StandardInput=tty-force
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
13
utils/test_apns/test_apns.py
Normal file
13
utils/test_apns/test_apns.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
from apns import APNs, Frame, Payload
|
||||
|
||||
|
||||
#apns = APNs(use_sandbox=True, cert_file='/root/ios_push_test/motoliteUserDev.pem')
|
||||
apns = APNs(cert_file='/root/ios_push_test/motoliteUserProd.pem')
|
||||
|
||||
alert = {"title" : "Motolite Res-q Notification",
|
||||
"body" : "Test Notification",
|
||||
"type" : "register"}
|
||||
|
||||
token_hex = "0D89F702B8E5A235E5100C47912DCBC346CE503DBB860572402031595D6F4C6C"
|
||||
payload = Payload(alert=alert, sound="default", badge=1, content_available=True)
|
||||
apns.gateway_server.send_notification(token_hex, payload)
|
||||
1
utils/warranty_expire/warranty_expire.sql
Normal file
1
utils/warranty_expire/warranty_expire.sql
Normal file
|
|
@ -0,0 +1 @@
|
|||
update warranty set status='expired' where date_expire is not null and date_expire < now() - interval 1 day;
|
||||
Loading…
Reference in a new issue