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;