diff --git a/.env.dist b/.env.dist
index 2829219e..4c0b202a 100644
--- a/.env.dist
+++ b/.env.dist
@@ -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
+#
diff --git a/config/services.yaml b/config/services.yaml
index 78696a45..10547ce6 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -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:
diff --git a/src/Command/GenerateBatteryCompatibilityCommand.php b/src/Command/GenerateBatteryCompatibilityCommand.php
new file mode 100644
index 00000000..57e20076
--- /dev/null
+++ b/src/Command/GenerateBatteryCompatibilityCommand.php
@@ -0,0 +1,104 @@
+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);
+
+ }
+}
diff --git a/src/Command/GenerateWarrantyFromJobOrderCommand.php b/src/Command/GenerateWarrantyFromJobOrderCommand.php
new file mode 100644
index 00000000..86653d97
--- /dev/null
+++ b/src/Command/GenerateWarrantyFromJobOrderCommand.php
@@ -0,0 +1,215 @@
+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();
+ }
+ }
+}
diff --git a/src/Command/TestHubCounterCommand.php b/src/Command/TestHubCounterCommand.php
new file mode 100644
index 00000000..e08c11dd
--- /dev/null
+++ b/src/Command/TestHubCounterCommand.php
@@ -0,0 +1,39 @@
+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";
+ }
+}
diff --git a/src/Command/TestJobOrderManagerCommand.php b/src/Command/TestJobOrderManagerCommand.php
new file mode 100644
index 00000000..4beeea46
--- /dev/null
+++ b/src/Command/TestJobOrderManagerCommand.php
@@ -0,0 +1,40 @@
+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";
+ }
+}
diff --git a/src/Command/TestRegAPNSCommand.php b/src/Command/TestRegAPNSCommand.php
new file mode 100644
index 00000000..d9615141
--- /dev/null
+++ b/src/Command/TestRegAPNSCommand.php
@@ -0,0 +1,40 @@
+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');
+ }
+}
diff --git a/src/Command/TestRiderTrackerCommand.php b/src/Command/TestRiderTrackerCommand.php
new file mode 100644
index 00000000..7b26a9ed
--- /dev/null
+++ b/src/Command/TestRiderTrackerCommand.php
@@ -0,0 +1,46 @@
+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";
+ }
+ }
+}
diff --git a/src/Command/UpdateCustomerVehicleBatteryCommand.php b/src/Command/UpdateCustomerVehicleBatteryCommand.php
new file mode 100644
index 00000000..f7e09e30
--- /dev/null
+++ b/src/Command/UpdateCustomerVehicleBatteryCommand.php
@@ -0,0 +1,67 @@
+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();
+ }
+ }
+ }
+ }
+}
diff --git a/src/Controller/APIController.php b/src/Controller/APIController.php
index 4925cf9b..d85978a8 100644
--- a/src/Controller/APIController.php
+++ b/src/Controller/APIController.php
@@ -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();
diff --git a/src/Controller/RoleController.php b/src/Controller/RoleController.php
index 49c03bc5..3d34eb50 100644
--- a/src/Controller/RoleController.php
+++ b/src/Controller/RoleController.php
@@ -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([
diff --git a/src/Entity/Warranty.php b/src/Entity/Warranty.php
index 30d1afd4..c1e16d32 100644
--- a/src/Entity/Warranty.php
+++ b/src/Entity/Warranty.php
@@ -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)
diff --git a/src/Service/APNSClient.php b/src/Service/APNSClient.php
index 2fc02fe9..1c493b4f 100644
--- a/src/Service/APNSClient.php
+++ b/src/Service/APNSClient.php
@@ -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);
+ }
}
diff --git a/src/Service/HubCounter.php b/src/Service/HubCounter.php
index 6fa52819..62d663ac 100644
--- a/src/Service/HubCounter.php
+++ b/src/Service/HubCounter.php
@@ -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);
diff --git a/src/Service/JobOrderManager.php b/src/Service/JobOrderManager.php
new file mode 100644
index 00000000..94d923a3
--- /dev/null
+++ b/src/Service/JobOrderManager.php
@@ -0,0 +1,53 @@
+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();
+ }
+ }
+}
diff --git a/src/Service/MQTTClient.php b/src/Service/MQTTClient.php
index 79fa9dac..aa0932a3 100644
--- a/src/Service/MQTTClient.php
+++ b/src/Service/MQTTClient.php
@@ -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)
{
diff --git a/src/Service/RedisClientProvider.php b/src/Service/RedisClientProvider.php
new file mode 100644
index 00000000..04ac1f80
--- /dev/null
+++ b/src/Service/RedisClientProvider.php
@@ -0,0 +1,44 @@
+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;
+ }
+}
diff --git a/src/Service/RiderTracker.php b/src/Service/RiderTracker.php
new file mode 100644
index 00000000..1e377ec7
--- /dev/null
+++ b/src/Service/RiderTracker.php
@@ -0,0 +1,52 @@
+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;
+
+ }
+}
diff --git a/symfony.lock b/symfony.lock
index 80750229..45250b81 100644
--- a/symfony.lock
+++ b/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"
},
diff --git a/templates/hub/list.html.twig b/templates/hub/list.html.twig
index 398e9c26..d1a7bedc 100644
--- a/templates/hub/list.html.twig
+++ b/templates/hub/list.html.twig
@@ -114,11 +114,11 @@
var actions = '';
if (row.meta.update_url != '') {
- actions += '';
+ actions += '';
}
if (row.meta.delete_url != '') {
- actions += '';
+ actions += '';
}
return actions;
diff --git a/templates/job-order/form.html.twig b/templates/job-order/form.html.twig
index 352ba4e4..1d3e0275 100644
--- a/templates/job-order/form.html.twig
+++ b/templates/job-order/form.html.twig
@@ -893,7 +893,8 @@
{% endblock %}
{% block scripts %}
-
+
+
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/utils/apns_sender/apns_sender.py b/utils/apns_sender/apns_sender.py
index ce3a4823..b9034ab1 100644
--- a/utils/apns_sender/apns_sender.py
+++ b/utils/apns_sender/apns_sender.py
@@ -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
diff --git a/utils/apns_sender/apns_sender.service b/utils/apns_sender/apns_sender.service
new file mode 100644
index 00000000..807c33f7
--- /dev/null
+++ b/utils/apns_sender/apns_sender.service
@@ -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
diff --git a/utils/apns_sender/new_sender.py b/utils/apns_sender/new_sender.py
new file mode 100644
index 00000000..557cd605
--- /dev/null
+++ b/utils/apns_sender/new_sender.py
@@ -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()
diff --git a/utils/legacy_load/import_legacy_data.sql b/utils/legacy_load/import_legacy_data.sql
index 0f12390e..3f1a7055 100644
--- a/utils/legacy_load/import_legacy_data.sql
+++ b/utils/legacy_load/import_legacy_data.sql
@@ -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);
diff --git a/utils/legacy_load/sap_battery.sql b/utils/legacy_load/sap_battery.sql
new file mode 100644
index 00000000..38302a6d
--- /dev/null
+++ b/utils/legacy_load/sap_battery.sql
@@ -0,0 +1,104 @@
+-- MySQL dump 10.16 Distrib 10.2.12-MariaDB, for Linux (x86_64)
+--
+-- Host: localhost Database: resq
+-- ------------------------------------------------------
+-- Server version 10.2.12-MariaDB
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `sap_battery`
+--
+
+DROP TABLE IF EXISTS `sap_battery`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `sap_battery` (
+ `id` varchar(25) COLLATE utf8_unicode_ci NOT NULL,
+ `brand_id` int(11) DEFAULT NULL,
+ `size_id` int(11) DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ KEY `IDX_385E33F44F5D008` (`brand_id`),
+ KEY `IDX_385E33F498DA827` (`size_id`),
+ CONSTRAINT `FK_385E33F44F5D008` FOREIGN KEY (`brand_id`) REFERENCES `sap_battery_brand` (`id`),
+ CONSTRAINT `FK_385E33F498DA827` FOREIGN KEY (`size_id`) REFERENCES `sap_battery_size` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `sap_battery`
+--
+
+LOCK TABLES `sap_battery` WRITE;
+/*!40000 ALTER TABLE `sap_battery` DISABLE KEYS */;
+INSERT INTO `sap_battery` VALUES ('ECHB20AB-CPN00-LX',3,3),('ECHB20AB-SPN00-LX',3,3),('ECHB24AB-SPN00-L',3,4),('ECHC24AL-SPN00-L',3,6),('ECHD23AL-SPN00-LX',3,5),('ECHD26AL-SPN00-L',3,2),('ECHD26AL-SPN00-LX',3,1),('ECHD31AL-SPN00-L',3,3),('ECHD31AL-SPN00-LX',3,2),('ECHE41AL-SPN00-L',3,6),('ECHE41AL-SPN00-LX',3,7),('ECHF51AL-SPN00-LX',3,8),('ECHG51AL-SPN00-L',3,4),('ECHG51AL-SPN00-LX',3,9),('ECHH52AL-SPN00-LX',3,10),('EDFB20AB-CPN00-L',18,3),('EDFB24AB-SPN00-L',18,4),('EDFD23AL-SPN00-L',18,5),('EDFD26AL-SPN00-L',18,1),('EDFD31AL-SPN00-L',18,2),('EDFE41AL-SPN00-L',18,7),('EDFF51AL-SPN00-L',18,8),('EDFG51AL-SPN00-L',18,9),('EDFH52AL-SPN00-L',18,10),('EDPB20AB-CPN00-LX',19,3),('EDPB24AB-SPN00-LX',19,4),('EDPD23AL-SPN00-LX',19,5),('EDPD26AL-SPN00-LX',19,1),('EDPD31AL-SPN00-LX',19,2),('EDPE41AL-SPN00-LX',19,7),('EDPF51AL-SPN00-LX',19,8),('EDPG51AL-SPN00-LX',19,9),('EEFB24BB-SPN00-L',12,4),('EEFD23BL-SPN00-L',12,5),('EEFD26BL-SPN00-L',12,1),('EEFD31BL-SPN00-L',12,2),('EEFE41BL-SPN00-L',12,7),('EEFF51BL-SPN00-L',12,8),('EEFG51BL-SPN00-L',12,9),('EEFH52BL-SPN00-L',12,10),('EELB20AB-CPN00-L',6,3),('EELB24AB-SPN00-L',6,4),('EELD23AL-SPN00-L',6,5),('EELD26AL-SPN00-L',6,1),('EELD31AL-SPN00-L',6,2),('EELE41AL-SPN00-L',6,7),('EELF51AL-SPN00-L',6,8),('EELG51AL-SPN00-L',6,9),('EELH52AL-SPN00-L',6,10),('EMC6TNPR-SPN00-L',11,36),('EMFD26AL-SPN00-L',10,1),('EMFD31AL-SPN00-L',10,2),('EMFE41AL-SPN00-L',10,7),('EMFF51AL-SPN00-L',10,8),('EMFG51AL-SPN00-L',10,9),('EMSD26DL-SPN00-L',13,1),('EMSD31DL-SPN00-L',13,2),('EMTD26CL-SPN00-L',16,1),('EMTD31CL-SPN00-L',16,2),('EMTE41CL-SPN00-L',16,7),('EMTF51CL-SPN00-L',16,8),('EMTG51CF-SPN00-L',16,9),('EMTG51CL-SPN00-L',16,9),('EMTH52CF-SPN00-L',16,37),('EMTH52CL-SPN00-L',16,10),('EPLD23AL-SPN00-L',14,5),('EPLD26AL-SPN00-L',14,1),('EPLD31AL-SPN00-L',14,2),('EPLE41AL-SPN00-L',14,7),('EPLF51AL-SPN00-L',14,8),('EPLG51AL-SPN00-L',14,9),('ERMB24AB-SPN00-L',15,4),('ERMD26AL-SPN00-L',15,1),('ERMD31AL-SPN00-L',15,2),('ERME41AL-SPN00-L',15,7),('ERMF51AL-SPN00-L',15,8),('ERMG51AL-SPN00-L',15,9),('ESRB24LF-SPN00-L',4,4),('ESRD31NG-SPN00-L',4,2),('ESRE41PG-SPN00-L',4,7),('ESRF51QG-SPN00-L',4,8),('ESRG51RF-SPN00-L',4,9),('ESRH52TF-SPN00-L',4,10),('EVLD26AL-SPN00-L',17,1),('EVLD31AL-SPN00-L',17,2),('EVLE41AL-SPN00-L',17,7),('EVLF51AL-SPN00-L',17,8),('EVLG51AL-SPN00-L',17,9),('EYKB20CB-SPN00-L',21,3),('EYKB24CB-SPN00-L',21,4),('EYKD26CL-SPN00-L',21,1),('EYKD31CL-SPN00-L',21,2),('EYKE41CL-SPN00-L',21,7),('EYKF51CL-SPN00-L',21,8),('EYKG51CL-SPN00-L',21,9),('EYSD26AL-CPN00-L',23,1),('EYSD31AL-CPN00-L',23,2),('EYSE41AL-CPN00-L',23,7),('EYSG51AL-CPN00-L',23,9),('EYTB20AB-CPN00-L',22,3),('EYTB20AB-CPN00-LX',22,3),('EYTD26AL-SPN00-L',22,1),('EYTD26AL-SPN00-LX',22,1),('EYTD31AL-SPN00-L',22,2),('EYTD31CL-SPN00-LX',22,2),('EYTE41AL-SPN00-L',22,7),('EYTE41AL-SPN00-LX',22,7),('EYTF51AL-SPN00-L',22,8),('EYTF51BL-SPN00-LX',22,8),('EYTG51AL-SPN00-L',22,9),('EYTG51BL-SPN00-LX',22,9),('WATB31QT-CPP00-L',4,2),('WCHB20BB-CPN00-LX',2,3),('WCHB24BB-CPN00-LX',2,4),('WCHD23BL-CPN00-LX',2,5),('WCHD26BL-CPN00-LX',2,1),('WCHD31BL-CPN00-LX',2,2),('WCMG24BL-CPN00-L',1,1),('WCMG27HL-CPN00-L',1,2),('WCYG24IL-CPN00-L',1,1),('WDPB20BB-CPN00-LX',19,3),('WDPB20CA-CPN00-LX',19,3),('WDPB24BB-CPN00-LX',19,4),('WDPB24CB-CPN00-LX',19,4),('WDPL23BL-CPN00-LX',19,5),('WDPL23CL-CPN00-LX',19,5),('WDPL26BL-CPN00-LX',19,1),('WDPL26CL-CPN00-LX',19,1),('WDPL31BL-CPN00-LX',19,2),('WDPL31CL-CPN00-LX',19,2),('WDSB24DA-CPN00-LX',20,4),('WDSB24DB-CPN00-LX',20,4),('WDSL23DL-CPN00-LX',20,5),('WDSL26DL-CPN00-LX',20,1),('WDSL26DR-CPN00-LX',20,29),('WDSL31DL-CPN00-LX',20,2),('WDSL31DR-CPN00-LX',20,17),('WEBL23EL-CPNMD-L',5,5),('WMEB20CB-CPN00-LX',7,3),('WMEB21CB-CPN00-LX',7,3),('WMEB24CA-CPN00-LX',7,15),('WMEB24CB-CPN00-LX',7,4),('WMEC24CL-CPN00-LX',7,6),('WMEL23CL-CPN00-L',7,1),('WMEL23CL-CPN00-LX',7,5),('WMEL26CL-CPN00-L',7,2),('WMEL26CL-CPN00-LX',7,1),('WMEL31CL-CPN00-L',7,3),('WMEL31CL-CPN00-LX',7,2),('WMEN44CL-CPN00-LX',7,16),('WMGB20CB-CPNHD-L',9,3),('WMGB20DA-CPN00-LX',9,18),('WMGB20DB-CPN00-LX',9,3),('WMGB20DB-CPNSZ-L',9,3),('WMGB20DI-CPNTY-L',9,3),('WMGB21DA-CPN00-LX',9,18),('WMGB21DA-CPNHY-L',9,18),('WMGB21DB-CPN00-LX',9,3),('WMGB24DA-CPN00-LX',9,15),('WMGB24DB-CPN00-LX',9,4),('WMGB24DB-CPNNI-L',9,4),('WMGB24DL-CPNTY-L',9,4),('WMGB24EB-CPNNI-L',9,4),('WMGD204L-TSP00-L',9,19),('WMGD23BL-CPN00-L',9,5),('WMGD23DL-CPNFD-L',9,5),('WMGD23ER-CPNIZ-L',9,5),('WMGD23FR-CPPIZ-L',9,5),('WMGD317R-CPNMB-L',9,2),('WMGD31EL-CPNM0-L',9,2),('WMGD31EL-CPNMB-L',9,2),('WMGD31IR-SPNIZ-L',9,17),('WMGD78DD-CPP00-L',9,20),('WMGG275R-CPNIZ-L',9,17),('WMGG47DL-CPN00-L',9,21),('WMGG47DL-CPNTY-L',9,22),('WMGG48DL-CPN00-L',9,23),('WMGG48EL-CPNTY-L',9,24),('WMGG49EL-CPN00-L',9,25),('WMGG65DE-CPP00-L',9,26),('WMGG65FR-CPPFD-L',9,26),('WMGG94DL-TSP00-L',9,27),('WMGL23DL-CPN00-L',9,1),('WMGL23DL-CPN00-LX',9,5),('WMGL23DL-CPNM0-L',9,5),('WMGL23DL-CPNMB-L',9,5),('WMGL23DR-CPN00-LX',9,28),('WMGL26DL-CPN00-L',9,2),('WMGL26DL-CPN00-LX',9,1),('WMGL26DR-CPN00-L',9,2),('WMGL26DR-CPN00-LX',9,29),('WMGL31DL-CPN00-L',9,3),('WMGL31DL-CPN00-LX',9,2),('WMGL31DL-CPNIZ-L',9,2),('WMGL31DR-CPN00-L',9,3),('WMGL31DR-CPN00-LX',9,17),('WMGLN2DL-CPNTY-L',9,1),('WMGLN3EL-CPNTY-L',9,2),('WMGN44DL-CPN00-L',9,16),('WMGN44DL-CPNFD-L',9,16),('WMGN44DL-CPNHY-L',9,16),('WMGN55DL-CPN00-L',9,30),('WMGN55DR-CPN00-L',9,31),('WMGN66DL-CPN00-L',9,32),('WMGN66DL-CPNFD-L',9,32),('WMGN66DR-CPN00-L',9,33),('WMGN77DL-CPN00L',9,2),('WMGN77DL-TSP00-L',9,34),('WMGN88DL-CPN00-L',9,35),('WMGR31DR-CPN00-L',9,3),('WMMGC2UH-SPN00-L',4,11),('WMMGC8SH-SPN00-L',4,12),('WMMGT6UH-SPN00-L',4,13),('WMMGT8SH-SPN00-L',4,14),('WMTE41CL-CPN00-L',16,38),('WMTF51CL-CPN00-L',16,39),('WMTG51CL-CPN00-L',16,40),('WMTH52CL-CPN00-L',16,41),('WMXB24EA-CPN00-LX',8,15),('WMXB24EB-CPN00-LX',8,4),('WMXB24FA-CPNSZ-L',8,15),('WMXD235L-CPNIZ-L',8,5),('WMXD23FL-CPPIZ-L',8,5),('WMXD26FL-SPNIZ-L',8,1),('WMXD31FL-CPNUM-L',8,2),('WMXD31IR-CPNFD-L',8,2),('WMXG24FI-CPNIZ-L',8,1),('WMXG24FI-CPPIZ-L',8,1),('WMXG278E-CPNFD-L',8,2),('WMXL23EL-CPN00-L',8,1),('WMXL23EL-CPN00-LX',8,5),('WMXL31EL-CPNKI-L',8,2),('WMXN87EL-CPN00-LX',8,2),('WMXX26EL-CPN00-L',1,2),('WMXX26EL-CPN00-LX',8,1),('WMXX31EL-CPN00-L',8,2),('WMXX31EL-CPN00-LX',8,2),('WMXX31ER-CPNSY-LX',8,17),('WMXY26EL-CPN00-LX',8,1),('WODD236L-CPPMB-L',9,5),('WODG247L-CPPMB-L',9,1),('WODG278L-CPPMB-L',9,2),('WODR23DI-CPNMB-L',9,5),('WODR26EL-CPNMB-L',9,1),('WODR31EL-CPNMB-L',9,2),('WOLB20DB-CPNMB-L',9,3),('WPLB24DB-CPN00-L',14,4),('WPLG24DL-CPN00-L',14,1),('WPLG27DL-CPN00-L',14,2),('WSOA465F-TSP00-L',4,5),('WSOD317M-CP403-E',4,2),('WSOD317M-CPP00-L',4,2),('WTGB20DA-CPNTY-L',9,18),('WTGB20DB-CPNTY-L',9,3),('WTGB20DL-CPNTY-L',9,18),('WTGB24DL-CPNTY-L',9,4),('WTGG47DL-CPNTY-L',9,22),('WTGG48EL-CPNTY-L',9,24),('WTGL26EL-CPNTY-LX',9,1),('WTGL26ER-CPNTY-LX',9,29),('WTGL31EL-CPNTY-LX',9,2),('WTGR23DL-CPNTY-L',9,5),('WTGR26EL-CPNTY-L',9,1),('WTGR26ER-CPNTY-L',9,29),('WTGR31EL-CPNTY-L',9,2),('WYKB20CB-CPN00-L',21,3),('WYKB20DB-CPN00-L',21,3),('WYKB24CB-CPN00-L',21,4),('WYKB24DB-CPN00-L',21,4),('WYKL26CL-CPN00-L',21,1),('WYKL26CR-CPN00-L',21,29),('WYKL26DL-CPN00-L',21,1),('WYKL26DR-CPN00-L',21,29),('WYKL31CL-CPN00-L',21,2),('WYKL31CR-CPN00-L',21,17),('WYKL31DL-CPN00-L',21,2),('WYKL31DR-CPN00-L',21,17),('WYKN44DL-CPN00-L',21,16),('WYKN55DL-CPN00-L',21,30),('WYKN66DL-CPN00-L',21,32),('WZMB31QT-CPP00-L',4,2);
+/*!40000 ALTER TABLE `sap_battery` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `sap_battery_brand`
+--
+
+DROP TABLE IF EXISTS `sap_battery_brand`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `sap_battery_brand` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `sap_battery_brand`
+--
+
+LOCK TABLES `sap_battery_brand` WRITE;
+/*!40000 ALTER TABLE `sap_battery_brand` DISABLE KEYS */;
+INSERT INTO `sap_battery_brand` VALUES (1,'CENTURY MARATHONER'),(2,'CHAMPION MF12'),(3,'CHAMPION PM'),(4,'SOLAR'),(5,'EFB MAZDA'),(6,'ELECTRON'),(7,'ENDURO'),(8,'EXCEL'),(9,'GOLD'),(10,'MAGIC FORCE'),(11,'MOTOLITE'),(12,'MOTOLITE ENFORCER'),(13,'MOTOLITE SUPER PREMIUM'),(14,'POWERLAST'),(15,'ROADMASTER'),(16,'TRUCKMASTER'),(17,'VALIANT'),(18,'DYNA FORCE'),(19,'DYNA POWER'),(20,'XTP-CALCIUM'),(21,'YOKOHAMA'),(22,'YUASA MERCURY'),(23,'YUASA SUPER PREMIUM MERCURY');
+/*!40000 ALTER TABLE `sap_battery_brand` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
+-- Table structure for table `sap_battery_size`
+--
+
+DROP TABLE IF EXISTS `sap_battery_size`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `sap_battery_size` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `sap_battery_size`
+--
+
+LOCK TABLES `sap_battery_size` WRITE;
+/*!40000 ALTER TABLE `sap_battery_size` DISABLE KEYS */;
+INSERT INTO `sap_battery_size` VALUES (1,'2SMF'),(2,'3SMF'),(3,'NS40'),(4,'NS60'),(5,'1SMF'),(6,'1SNF'),(7,'6SMF'),(8,'2D'),(9,'4D'),(10,'8D'),(11,'GC2'),(12,'GC8'),(13,'GC2-TUBULAR'),(14,'GC8-TUBULAR'),(15,'NS60 REVERSE'),(16,'DIN44'),(17,'3SMF REVERSE'),(18,'NS40 REVERSE'),(19,'D20'),(20,'G34'),(21,'DIN55H'),(22,'DIN55 H'),(23,'DIN66H'),(24,'DIN66 H'),(25,'DIN110'),(26,'G65'),(27,'DIN77H'),(28,'1SMF REVERSE'),(29,'2SMF REVERSE'),(30,'DIN55'),(31,'DIN55 REVERSE'),(32,'DIN66'),(33,'DIN66 REVERSE'),(34,'DIN77'),(35,'DIN88'),(36,'6TN'),(37,'8D LUG TYPE'),(38,'6SMF MF'),(39,'2D MF'),(40,'4D MF'),(41,'8D MF'),(42,'B20'),(43,'B24');
+/*!40000 ALTER TABLE `sap_battery_size` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2019-05-27 23:35:07
diff --git a/utils/mqtt_sender/mqtt_sender.service b/utils/mqtt_sender/mqtt_sender.service
new file mode 100644
index 00000000..d747522d
--- /dev/null
+++ b/utils/mqtt_sender/mqtt_sender.service
@@ -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
diff --git a/utils/rider_location_cache/rider_location_cache.py b/utils/rider_location_cache/rider_location_cache.py
index 441938e4..54a47ddd 100644
--- a/utils/rider_location_cache/rider_location_cache.py
+++ b/utils/rider_location_cache/rider_location_cache.py
@@ -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()
-
diff --git a/utils/rider_location_cache/riderloc.py b/utils/rider_location_cache/riderloc.py
new file mode 100644
index 00000000..26a1a92f
--- /dev/null
+++ b/utils/rider_location_cache/riderloc.py
@@ -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)
diff --git a/utils/rider_location_cache/riderloc.service b/utils/rider_location_cache/riderloc.service
new file mode 100644
index 00000000..f3d43264
--- /dev/null
+++ b/utils/rider_location_cache/riderloc.service
@@ -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
diff --git a/utils/test_apns/test_apns.py b/utils/test_apns/test_apns.py
new file mode 100644
index 00000000..8ee22b17
--- /dev/null
+++ b/utils/test_apns/test_apns.py
@@ -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)
diff --git a/utils/warranty_expire/warranty_expire.sql b/utils/warranty_expire/warranty_expire.sql
new file mode 100644
index 00000000..c1b9a089
--- /dev/null
+++ b/utils/warranty_expire/warranty_expire.sql
@@ -0,0 +1 @@
+update warranty set status='expired' where date_expire is not null and date_expire < now() - interval 1 day;