mirror of
https://gitlab.com/signalytic/client-external/streamline/streamline-emr.git
synced 2026-09-11 18:51:31 +00:00
Removed image mapping in the config.json file
This commit is contained in:
+1
-8
@@ -4,12 +4,5 @@
|
|||||||
"version": "2.3",
|
"version": "2.3",
|
||||||
"platforms": [
|
"platforms": [
|
||||||
"linux/arm64"
|
"linux/arm64"
|
||||||
],
|
]
|
||||||
"images": {
|
|
||||||
"linux/arm64": {
|
|
||||||
"registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/streamline-emr/arm64:2.3": "streamline-emr:latest",
|
|
||||||
"registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/statistics/arm64:2.3": "streamline-emr-statistics:latest",
|
|
||||||
"registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/redis/arm64:2.3": "streamline-emr-redis:latest"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
FROM redis:alpine
|
FROM streamline-emr-redis:latest
|
||||||
@@ -1,34 +1 @@
|
|||||||
FROM php:cli
|
FROM streamlinehealth/streamline:statistics
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y \
|
|
||||||
cron \
|
|
||||||
unzip \
|
|
||||||
curl \
|
|
||||||
libpng-dev \
|
|
||||||
libjpeg-dev \
|
|
||||||
supervisor \
|
|
||||||
&& pecl install redis \
|
|
||||||
&& docker-php-ext-install pdo pdo_mysql gd \
|
|
||||||
&& docker-php-ext-enable redis \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
RUN curl -sS https://getcomposer.org/installer | \
|
|
||||||
php -- --install-dir=/usr/local/bin --filename=composer
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# install composer dependencies
|
|
||||||
COPY statistics /app
|
|
||||||
|
|
||||||
RUN composer install
|
|
||||||
|
|
||||||
COPY statistics/crontab /etc/cron.d/crontab
|
|
||||||
|
|
||||||
COPY statistics/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
|
||||||
|
|
||||||
RUN chmod 0644 /etc/cron.d/crontab \
|
|
||||||
&& crontab /etc/cron.d/crontab \
|
|
||||||
&& touch /var/log/cron.log /app/sync.log \
|
|
||||||
&& chmod +x /app/sync.php
|
|
||||||
|
|
||||||
CMD ["supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
################################################################################
|
|
||||||
# Use known working image to pull in working wkhtmltopdf libraries
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
FROM surnet/alpine-wkhtmltopdf:3.16.2-0.12.6-full as wkhtmltopdf
|
|
||||||
FROM php:8.2-fpm-alpine3.17 AS app
|
|
||||||
|
|
||||||
# wkhtmltopdf install dependencies
|
|
||||||
RUN apk add --no-cache \
|
|
||||||
libstdc++ \
|
|
||||||
libx11 \
|
|
||||||
libxrender \
|
|
||||||
libxext \
|
|
||||||
libssl1.1 \
|
|
||||||
ca-certificates \
|
|
||||||
fontconfig \
|
|
||||||
freetype \
|
|
||||||
ttf-droid \
|
|
||||||
ttf-freefont \
|
|
||||||
ttf-liberation \
|
|
||||||
# more fonts
|
|
||||||
;
|
|
||||||
# wkhtmltopdf copy bins from ext image
|
|
||||||
COPY --from=wkhtmltopdf /bin/wkhtmltopdf /bin/wkhtmltoimage /bin/libwkhtmltox.so /usr/bin/
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Copied from previous Streamline Dockerfile
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
# Install necessary packages and cleanup
|
|
||||||
RUN set -ex; \
|
|
||||||
apk update && \
|
|
||||||
apk add --no-cache curl gnupg mysql mysql-client pwgen && \
|
|
||||||
docker-php-ext-install pdo pdo_mysql && \
|
|
||||||
rm -rf /var/cache/apk/*
|
|
||||||
|
|
||||||
# Install Composer
|
|
||||||
RUN curl -sS https://getcomposer.org/installer | \
|
|
||||||
php -- --install-dir=/usr/bin/ --filename=composer
|
|
||||||
|
|
||||||
# Set the working directory and copy the application code
|
|
||||||
COPY streamline-src /var/www/html
|
|
||||||
|
|
||||||
COPY my.cnf /etc/mysql/my.cnf
|
|
||||||
|
|
||||||
WORKDIR /var/www/html
|
|
||||||
|
|
||||||
# Create the 'streamline' user and adjust permissions
|
|
||||||
RUN addgroup -g 1000 streamline && adduser -G streamline -g streamline -s /bin/sh -D streamline && \
|
|
||||||
composer install && \
|
|
||||||
chmod -R 777 /var/www/html/storage/ && \
|
|
||||||
chown -R streamline:streamline /var/www/html && \
|
|
||||||
mkdir -p /docker-entrypoint-initdb.d/
|
|
||||||
|
|
||||||
# Initialize MySQL
|
|
||||||
COPY streamline_initial.sql /docker-entrypoint-initdb.d/
|
|
||||||
|
|
||||||
RUN mkdir /scripts && \
|
|
||||||
mkdir /scripts/pre-exec.d && \
|
|
||||||
mkdir /scripts/pre-init.d && \
|
|
||||||
chmod -R 755 /scripts
|
|
||||||
|
|
||||||
VOLUME ["/var/lib/mysql"]
|
|
||||||
|
|
||||||
# Set the startup script as executable
|
|
||||||
RUN chmod +x /var/www/html/start_up.sh
|
|
||||||
|
|
||||||
# Define the entry point and expose port 80, 3306
|
|
||||||
ENTRYPOINT ["/bin/sh", "/var/www/html/start_up.sh"]
|
|
||||||
|
|
||||||
EXPOSE 80 3306
|
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Update snappy config to fix issues with wkhtmltopdf
|
|
||||||
################################################################################
|
|
||||||
COPY snappy.php /var/www/html/config/snappy.php
|
|
||||||
@@ -1,2 +1 @@
|
|||||||
FROM streamlinehealth/streamline:signalytic
|
FROM streamlinehealth/streamline:signalytic
|
||||||
COPY ./start_up.sh /var/www/html/start_up.sh
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
#! /bin/sh
|
|
||||||
|
|
||||||
# Required script variables
|
|
||||||
APP_NAME=${APP_NAME:-'streamline'}
|
|
||||||
export MYSQL_DATABASE=${DB_DATABASE:-'streamline'}
|
|
||||||
export MYSQL_USER=${DB_USERNAME:-'root'}
|
|
||||||
export MYSQL_PASSWORD=${DB_PASSWORD:-'streamline'}
|
|
||||||
export MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD:-'streamline'}
|
|
||||||
|
|
||||||
# execute run.sh script for MySQL initialisation
|
|
||||||
chmod +x .docker/mysql/mysql-init.sh
|
|
||||||
|
|
||||||
# run the MariaDB initialization script
|
|
||||||
echo "[info] running mariadb init script"
|
|
||||||
./.docker/mysql/mysql-init.sh
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
|
|
||||||
echo "[info] waiting for DB to start..."
|
|
||||||
for i in $(seq 1 30); do
|
|
||||||
mariadb-admin ping -u $MYSQL_USER -p$MYSQL_PASSWORD &>/dev/null
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "[info] DB ready"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
mariadb-admin ping -u $MYSQL_USER -p$MYSQL_PASSWORD
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "[info] timed out waiting for DB"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[info] MySQL server started. checking for '$MYSQL_DATABASE' database. "
|
|
||||||
|
|
||||||
mysql -u $MYSQL_USER -p$MYSQL_PASSWORD -e "use streamline;"
|
|
||||||
|
|
||||||
# Guard condition to re-check existence of database schema
|
|
||||||
# If it doesnt exist, create it and import streamline_initial.sql file
|
|
||||||
if [ $? -eq 1 ]; then
|
|
||||||
|
|
||||||
mysql -u $MYSQL_USER -p$MYSQL_PASSWORD -e "CREATE DATABASE $MYSQL_DATABASE;"
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "[info] Database: $MYSQL_DATABASE created."
|
|
||||||
|
|
||||||
mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE < ./.docker/mysql/scripts/streamline_initial.sql
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "[info] populated database."
|
|
||||||
else
|
|
||||||
echo "[error] database not populated."
|
|
||||||
fi
|
|
||||||
|
|
||||||
else
|
|
||||||
echo "[error] database not created."
|
|
||||||
fi
|
|
||||||
|
|
||||||
else
|
|
||||||
echo "[info] Database: $MYSQL_DATABASE exists. "
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[info] starting $APP_NAME ..."
|
|
||||||
|
|
||||||
echo "[info] artisan migrate"
|
|
||||||
php /var/www/html/artisan migrate
|
|
||||||
echo "[info] migrate result: $?"
|
|
||||||
|
|
||||||
echo "[info] seed: PermissionTableSeeder"
|
|
||||||
php /var/www/html/artisan db:seed --class=PermissionTableSeeder
|
|
||||||
echo "[info] seed result: $?"
|
|
||||||
|
|
||||||
echo "[info] seed: PermissionsCategoryTableSeeder"
|
|
||||||
php /var/www/html/artisan db:seed --class=PermissionsCategoryTableSeeder
|
|
||||||
echo "[info] seed result: $?"
|
|
||||||
|
|
||||||
echo "serving app..."
|
|
||||||
php /var/www/html/artisan serve --host=0.0.0.0 --port=80
|
|
||||||
|
|
||||||
else
|
|
||||||
echo "[error] MariaDB server couldnt be started."
|
|
||||||
|
|
||||||
# terminate script if database isnt running
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"require": {
|
|
||||||
"monolog/monolog": "^3.9",
|
|
||||||
"guzzlehttp/guzzle": "^7.0",
|
|
||||||
"vlucas/phpdotenv": "^5.6"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Generated
-1228
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
|||||||
0 * * * * /usr/local/bin/php /app/sync.php >> /var/log/cron.log 2>&1
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
[supervisord]
|
|
||||||
nodaemon=true
|
|
||||||
loglevel=info
|
|
||||||
logfile=/dev/stdout
|
|
||||||
logfile_maxbytes=0
|
|
||||||
|
|
||||||
[program:cron]
|
|
||||||
command=cron -f
|
|
||||||
autorestart=true
|
|
||||||
stdout_logfile=/dev/stdout
|
|
||||||
stdout_logfile_maxbytes=0
|
|
||||||
stderr_logfile=/dev/stderr
|
|
||||||
stderr_logfile_maxbytes=0
|
|
||||||
priority=10
|
|
||||||
|
|
||||||
[program:sync-log]
|
|
||||||
command=tail -f /app/sync.log
|
|
||||||
autorestart=true
|
|
||||||
stdout_logfile=/dev/stdout
|
|
||||||
stdout_logfile_maxbytes=0
|
|
||||||
stderr_logfile=/dev/stderr
|
|
||||||
stderr_logfile_maxbytes=0
|
|
||||||
priority=20
|
|
||||||
|
|
||||||
[program:cron-log]
|
|
||||||
command=tail -f /var/log/cron.log
|
|
||||||
autorestart=true
|
|
||||||
stdout_logfile=/dev/stdout
|
|
||||||
stdout_logfile_maxbytes=0
|
|
||||||
stderr_logfile=/dev/stderr
|
|
||||||
stderr_logfile_maxbytes=0
|
|
||||||
priority=30
|
|
||||||
@@ -1,422 +0,0 @@
|
|||||||
<?php
|
|
||||||
require __DIR__ . "/vendor/autoload.php";
|
|
||||||
|
|
||||||
use GuzzleHttp\Client;
|
|
||||||
|
|
||||||
use Monolog\Logger;
|
|
||||||
use Monolog\Level;
|
|
||||||
use Monolog\Handler\StreamHandler;
|
|
||||||
|
|
||||||
|
|
||||||
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__, 'statistics.env');
|
|
||||||
$dotenv->load();
|
|
||||||
|
|
||||||
class sync{
|
|
||||||
|
|
||||||
protected $db_host;
|
|
||||||
protected $db_name;
|
|
||||||
protected $db_user;
|
|
||||||
protected $db_password;
|
|
||||||
protected $server;
|
|
||||||
|
|
||||||
protected $redis;
|
|
||||||
protected $redis_port;
|
|
||||||
protected $redis_host;
|
|
||||||
protected $redis_ttl;
|
|
||||||
protected $redis_timeout = 5;
|
|
||||||
|
|
||||||
protected $db;
|
|
||||||
protected $http;
|
|
||||||
|
|
||||||
protected $endpoint;
|
|
||||||
|
|
||||||
protected $logger;
|
|
||||||
protected $log_file = __DIR__."/sync.log";
|
|
||||||
|
|
||||||
private $payload;
|
|
||||||
protected $server_status_url;
|
|
||||||
|
|
||||||
function __construct(){
|
|
||||||
# log service
|
|
||||||
$this->logger = new Logger("data-sync");
|
|
||||||
|
|
||||||
$stream_handler = new StreamHandler($this->log_file);
|
|
||||||
$this->logger->pushHandler($stream_handler);
|
|
||||||
|
|
||||||
$this->logger->info("initializing sync.");
|
|
||||||
|
|
||||||
# database setup
|
|
||||||
$this->db_name = $_ENV['DB_DATABASE'];
|
|
||||||
$this->db_host = $_ENV['DB_HOST'];
|
|
||||||
$this->db_user = $_ENV['DB_USERNAME'];
|
|
||||||
$this->db_password = $_ENV['DB_PASSWORD'];
|
|
||||||
|
|
||||||
$this->db = new PDO("mysql:host=". $this->db_host .";dbname=". $this->db_name, $this->db_user, $this->db_password);
|
|
||||||
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
||||||
|
|
||||||
if(!$this->db) $this->logger->error("failed to connect to database.");
|
|
||||||
|
|
||||||
$this->logger->debug("Connected to database.");
|
|
||||||
|
|
||||||
# redis
|
|
||||||
$this->redis_host = $_ENV["REDIS_HOST"];
|
|
||||||
$this->redis_port = $_ENV["REDIS_PORT"];
|
|
||||||
$this->redis_ttl = $_ENV["REDIS_TTL"];
|
|
||||||
|
|
||||||
$this->redis = new Redis();
|
|
||||||
$this->redis->connect($this->redis_host, $this->redis_port, $this->redis_timeout);
|
|
||||||
if(!$this->redis) $this->logger->error('Failed to connect to redis server.');
|
|
||||||
|
|
||||||
$this->logger->debug("Connected to redis server.");
|
|
||||||
|
|
||||||
# remote server/endpoint
|
|
||||||
$this->server = $_ENV["SERVER"];
|
|
||||||
$this->server_status_url = $_ENV["SERVER_STATUS_URL"];
|
|
||||||
$this->endpoint = $_ENV['SERVER_ENDPOINT'];
|
|
||||||
|
|
||||||
$this->http = new Client([
|
|
||||||
'base_uri' => $this->server,
|
|
||||||
'timeout' => 3.0,
|
|
||||||
]);
|
|
||||||
|
|
||||||
# fetch data
|
|
||||||
$db_data = $this->fetchData();
|
|
||||||
}
|
|
||||||
|
|
||||||
function startSync(){
|
|
||||||
|
|
||||||
try{
|
|
||||||
if(!$this->endpoint) throw new Exception("No remote server-endpoint specified. sync terminated.");
|
|
||||||
|
|
||||||
$this->logger->info("Checking internet connection.", ["url"=> $this->endpoint ]);
|
|
||||||
|
|
||||||
$response = $this->http->get($this->server_status_url, [
|
|
||||||
'timeout'=> 10,
|
|
||||||
'http_errors'=> true,
|
|
||||||
'headers' => [
|
|
||||||
'Accept' => 'application/json',
|
|
||||||
'X-Requested-With' => 'XMLHttpRequest'
|
|
||||||
],
|
|
||||||
'verify'=> true,
|
|
||||||
'allow_redirects'=> false
|
|
||||||
]);
|
|
||||||
|
|
||||||
$status_code = $response->getStatusCode();
|
|
||||||
$response_body = $response->getBody()->getContents();
|
|
||||||
|
|
||||||
if($status_code != 200) throw new Exception("Internet connection unavailable, saving to cache.");
|
|
||||||
|
|
||||||
$this->logger->debug("Internet connection available.", ["status_code"=> $status_code, "response"=> $response_body]);
|
|
||||||
|
|
||||||
$upload_cache = $this->uploadCache();
|
|
||||||
if(!$upload_cache) throw new Exception("Upload failed. [". $upload_cache."]");
|
|
||||||
|
|
||||||
$this->logger->info("Internet connection available. uploading data.", ["upload"=> $upload_cache ]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}catch(Exception $ex){
|
|
||||||
$this->logger->error($ex->getMessage());
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function fetchData(){
|
|
||||||
$this->logger->info("Querying database. ", ["db"=> $this->db_name]);
|
|
||||||
|
|
||||||
try{
|
|
||||||
$previous = $this->db->query("SELECT * FROM signalytic_data")->fetch(PDO::FETCH_ASSOC)['last_fetch_date'];
|
|
||||||
|
|
||||||
if(!$previous) $this->logger->error("last fetch date not found. ");
|
|
||||||
|
|
||||||
$hospitalInformation = $this->db->query("SELECT * FROM hospital_information")->fetch(PDO::FETCH_ASSOC);
|
|
||||||
|
|
||||||
$episodes = $this->db->query("SELECT triage_id, consultation_id, gender, clinic_id, name, slug FROM patient_episodes
|
|
||||||
JOIN patients ON patient_episodes.patient_id = patients.id
|
|
||||||
LEFT JOIN clinics ON patient_episodes.clinic_id = clinics.id
|
|
||||||
WHERE patient_episodes.created_at > '{$previous}'");
|
|
||||||
|
|
||||||
$episodes_created_male = 0;
|
|
||||||
$episodes_created_female = 0;
|
|
||||||
$episodes_completed_with_outcome = [];
|
|
||||||
$episodes_per_clinic = [];
|
|
||||||
$episodes_triaged = 0;
|
|
||||||
|
|
||||||
while ($row = $episodes->fetch(PDO::FETCH_ASSOC)) {
|
|
||||||
if ($row['gender'] == 1) {
|
|
||||||
$episodes_created_male++;
|
|
||||||
} else if ($row['gender'] == 2) {
|
|
||||||
$episodes_created_female++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_null($row['triage_id'])) {
|
|
||||||
$episodes_triaged++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_null($row['clinic_id'])) {
|
|
||||||
$episodes_per_clinic[$row['clinic_id']] = [
|
|
||||||
'clinic_name' => $row['name'],
|
|
||||||
'clinic_type' => $row['slug'],
|
|
||||||
'clinic_count' => ($episodes_per_clinic[$row['clinic_id']]['clinic_count'] ?? 0) + 1,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_null($row['consultation_id'])) {
|
|
||||||
$cons = $this->db->query("SELECT consultations.outcome_id, outcomes.name FROM consultations
|
|
||||||
JOIN outcomes ON consultations.outcome_id = outcomes.id
|
|
||||||
WHERE consultations.id = '{$row['consultation_id']}'")->fetch(PDO::FETCH_ASSOC);
|
|
||||||
$episodes_completed_with_outcome[$cons['outcome_id']] = [
|
|
||||||
'outcome_name' => $cons['name'],
|
|
||||||
'outcome_count' => ($episodes_completed_with_outcome[$cons['outcome_id']]['outcome_count'] ?? 0) + 1,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$users_seen = $this->db->query("SELECT * FROM users WHERE last_seen > '{$previous}'")->rowCount();
|
|
||||||
$male_patients = $this->db->query("SELECT * FROM patients WHERE created_at > '{$previous}' AND gender = '1'")->rowCount();
|
|
||||||
$female_patients = $this->db->query("SELECT * FROM patients WHERE created_at > '{$previous}' AND gender = '2'")->rowCount();
|
|
||||||
$receipts = $this->db->query("SELECT * FROM track_receipts WHERE created_at > '{$previous}'")->rowCount();
|
|
||||||
$pharmacyRec = $this->db->query("SELECT * FROM pharmacy_stock_reconciliations WHERE created_at > '{$previous}' AND completion_status = 1")->rowCount();
|
|
||||||
$storeRec = $this->db->query("SELECT * FROM store_stock_reconciliations WHERE created_at > '{$previous}' AND completion_status = 1")->rowCount();
|
|
||||||
$quotations = $this->db->query("SELECT * FROM quotations WHERE created_at > '{$previous}' AND receive_date IS NOT NULL")->rowCount();
|
|
||||||
|
|
||||||
$inpatients = $this->db->query("SELECT inpatient_info.discharged, inpatient_info.died_on, patients.gender FROM inpatient_info JOIN patients ON inpatient_info.patient_id = patients.id WHERE inpatient_info.created_at > '{$previous}'");
|
|
||||||
|
|
||||||
$patients_admitted_male = 0;
|
|
||||||
$patients_admitted_female = 0;
|
|
||||||
$patients_discharged_male = 0;
|
|
||||||
$patients_discharged_female = 0;
|
|
||||||
|
|
||||||
while ($row = $inpatients->fetch(PDO::FETCH_ASSOC)) {
|
|
||||||
if ($row['gender'] == 1) {
|
|
||||||
$patients_admitted_male++;
|
|
||||||
} else if ($row['gender'] == 2) {
|
|
||||||
$patients_admitted_female++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($row['discharged'] === 1 || !is_null($row['died_on'])) {
|
|
||||||
if ($row['gender'] == 1) {
|
|
||||||
$patients_discharged_male++;
|
|
||||||
} else if ($row['gender'] == 2) {
|
|
||||||
$patients_discharged_female++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$investigations = $this->db->query("SELECT * FROM ordered_investigations WHERE created_at > '{$previous}'");
|
|
||||||
|
|
||||||
$investigation_requests = 0;
|
|
||||||
$investigation_results = 0;
|
|
||||||
|
|
||||||
while ($row = $investigations->fetch(PDO::FETCH_ASSOC)) {
|
|
||||||
$investigation_requests++;
|
|
||||||
|
|
||||||
// top_investigations
|
|
||||||
if ($row['investigation_status'] === 1) {
|
|
||||||
$investigation_results++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$treatments = $this->db->query("SELECT * FROM treatments WHERE created_at > '{$previous}'");
|
|
||||||
|
|
||||||
$prescriptions = 0;
|
|
||||||
$prescriptions_dispensed = 0;
|
|
||||||
|
|
||||||
while ($row = $treatments->fetch(PDO::FETCH_ASSOC)) {
|
|
||||||
$prescriptions++;
|
|
||||||
|
|
||||||
if ($row['dispense_status'] === 1) {
|
|
||||||
$prescriptions_dispensed++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$top_diagnosis = $this->db->query("SELECT primary_diagnosis, COUNT(*) AS freq, name FROM consultations JOIN diagnoses ON consultations.primary_diagnosis = diagnoses.id WHERE consultations.created_at > '{$previous}' GROUP BY primary_diagnosis ORDER BY freq DESC LIMIT 5")->fetchAll();
|
|
||||||
|
|
||||||
$data = json_encode([
|
|
||||||
'facility_name' => $hospitalInformation['name'],
|
|
||||||
'facility_email' => $hospitalInformation['email'],
|
|
||||||
'facility_address' => $hospitalInformation['address'],
|
|
||||||
'facility_unique_identifier' => $hospitalInformation['unique_hospital_identifier'] ?? '',
|
|
||||||
'time_period' => "{$previous} to " . date("Y-m-d H:i:s"),
|
|
||||||
'episodes_created_male' => $episodes_created_male,
|
|
||||||
'episodes_created_female' => $episodes_created_female,
|
|
||||||
'episodes_completed_with_outcome' => $episodes_completed_with_outcome,
|
|
||||||
'episodes_triaged' => $episodes_triaged,
|
|
||||||
'patients_admitted_male' => $patients_admitted_male,
|
|
||||||
'patients_admitted_female' => $patients_admitted_female,
|
|
||||||
'patients_discharged_male' => $patients_discharged_male,
|
|
||||||
'patients_discharged_female' => $patients_discharged_female,
|
|
||||||
'number_of_prescriptions' => $prescriptions,
|
|
||||||
'number_of_prescriptions_dispensed' => $prescriptions_dispensed,
|
|
||||||
'payment_receipts_generated' => $receipts,
|
|
||||||
'active_users' => $users_seen,
|
|
||||||
'male_patients_registered' => $male_patients,
|
|
||||||
'female_patients_registered' => $female_patients,
|
|
||||||
'investigation_requests' => $investigation_requests,
|
|
||||||
'investigation_requests_with_results' => $investigation_results,
|
|
||||||
'times_inventory_stock_received' => $quotations,
|
|
||||||
'times_stock_reconciled_pharmacy' => $pharmacyRec,
|
|
||||||
'times_stock_reconciled_store' => $storeRec,
|
|
||||||
'top_diagnosis' => $top_diagnosis,
|
|
||||||
'top_investigations' => [],
|
|
||||||
'top_prescribed_drugs_opd' => [],
|
|
||||||
'top_prescribed_drugs_ipd' => [],
|
|
||||||
'top_dispensed_drugs_opd' => [],
|
|
||||||
'top_dispensed_drugs_ipd' => [],
|
|
||||||
'episodes_per_clinic' => $episodes_per_clinic]);
|
|
||||||
|
|
||||||
$this->logger->debug("Fetched: ". $data);
|
|
||||||
$this->logger->info("Queries executed successfully. data saved.", ['size'=> strlen($data)]);
|
|
||||||
|
|
||||||
return $this->saveToCache($data);
|
|
||||||
}catch(Exception $ex){
|
|
||||||
$this->logger->error($ex->getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function uploadData($endpoint = null, $data = null)
|
|
||||||
{
|
|
||||||
$this->logger->info("Uploading payload.", ["url"=> $this->server. $this->endpoint ]);
|
|
||||||
|
|
||||||
try{
|
|
||||||
if(!$endpoint) throw new Exception("No endpoint specified.");
|
|
||||||
|
|
||||||
if(empty($data)) throw new Exception("Payload is empty.");
|
|
||||||
|
|
||||||
$options = [
|
|
||||||
'json' => json_decode($data),
|
|
||||||
'allow_redirects' => false,
|
|
||||||
'timeout' => 5,
|
|
||||||
'headers' => [
|
|
||||||
'Accept' => 'application/json',
|
|
||||||
'X-Requested-With' => 'XMLHttpRequest'
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
$response = $this->http->post($endpoint, $options);
|
|
||||||
|
|
||||||
$statusCode = $response->getStatusCode();
|
|
||||||
$response_body = $response->getBody()->getContents();
|
|
||||||
|
|
||||||
if($statusCode != 200) throw new Exception("Unexpected http-response: ". $response_body);
|
|
||||||
|
|
||||||
$this->logger->info("Data uploaded.", ["remote"=> $this->server. $endpoint, "status_code"=> $statusCode, "response"=> $response_body ]);
|
|
||||||
|
|
||||||
$this->updateLastFetchDate();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}catch(Exception $ex){
|
|
||||||
$this->logger->error($ex->getMessage());
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateLastFetchDate(){
|
|
||||||
try {
|
|
||||||
$update_date = $this->db->prepare("UPDATE signalytic_data SET last_fetch_date = ? WHERE id = ?");
|
|
||||||
$update_date->execute([date("Y-m-d H:i:s"), 1]);
|
|
||||||
|
|
||||||
$this->logger->info("Last fetch updated.");
|
|
||||||
return true;
|
|
||||||
}catch(Exception $ex){
|
|
||||||
$this->logger->error("Last fetch failed. ", [ 'error_msg'=> $ex->getMessage()]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveToCache($data = null){
|
|
||||||
try{
|
|
||||||
if(!$data) throw new Exception("No data fetched.");
|
|
||||||
|
|
||||||
$cache_key = "data:". date("d_m_Y_H");
|
|
||||||
|
|
||||||
$result = $this->redis->setex($cache_key, $this->redis_ttl, $data);
|
|
||||||
if (!$result) $this->logger->error("cache: $cache_key failed", ["error"=> $result]);
|
|
||||||
|
|
||||||
$this->logger->info("Cached: $cache_key");
|
|
||||||
return true;
|
|
||||||
}catch(Exception $ex){
|
|
||||||
$this->logger->error($ex->getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function uploadCache(){
|
|
||||||
$this->logger->info("Checking cache.");
|
|
||||||
try{
|
|
||||||
$cache_keys = $this->getCacheKeys();
|
|
||||||
if(empty($cache_keys)) throw new Exception("Cache is empty. ");
|
|
||||||
|
|
||||||
foreach($cache_keys as $cache_key)
|
|
||||||
{
|
|
||||||
$cached_data = $this->redis->get($cache_key);
|
|
||||||
$this->logger->debug("[key] $cache_key found.", ["key"=>$cache_key, "data"=> $cached_data]);
|
|
||||||
|
|
||||||
$result = $this->uploadData($this->endpoint, $cached_data);
|
|
||||||
$this->logger->debug("[key] $cache_key uploaded", ["upload"=> $result]);
|
|
||||||
|
|
||||||
if($result) $this->clearCache($cache_key); # clear cache
|
|
||||||
}
|
|
||||||
|
|
||||||
}catch(Exception $ex){
|
|
||||||
$this->logger->warning($ex->getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getCacheKeys(){
|
|
||||||
$keys = [];
|
|
||||||
$iterator = null;
|
|
||||||
|
|
||||||
do {
|
|
||||||
//get all keys
|
|
||||||
$result = $this->redis->scan($iterator, 'data:*');
|
|
||||||
|
|
||||||
if ($result !== false) $keys = array_merge($keys, $result);
|
|
||||||
|
|
||||||
} while ($iterator > 0);
|
|
||||||
|
|
||||||
return $keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearCache($cache_key = null){
|
|
||||||
if(!$cache_key){
|
|
||||||
$this->logger->error("No cache key provided. exiting ...");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try{
|
|
||||||
$clear = $this->redis->del($cache_key);
|
|
||||||
|
|
||||||
if($clear === 0) throw new Exception("Invalid cache key. [ $cache_key ]");
|
|
||||||
|
|
||||||
$this->logger->info("Cache cleared", ["key"=> $cache_key, "result"=> $clear ]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}catch(Exception $ex){
|
|
||||||
$this->logger->error($ex->getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetCache(){
|
|
||||||
try{
|
|
||||||
$this->logger->warning("Flushing cache");
|
|
||||||
$clear = $this->redis->flushDB();
|
|
||||||
|
|
||||||
if(!$clear) throw new Exception("Clearing cache failed. ($clear) ");
|
|
||||||
|
|
||||||
$this->logger->info("Cache cleared", ["result"=> $clear]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}catch(Exception $ex){
|
|
||||||
$this->logger->error($ex->getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$sync = new Sync();
|
|
||||||
$sync->startSync();
|
|
||||||
+1
-1
Submodule hosted-app-utils updated: 3785af3094...6af4c4ae85
@@ -1,7 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
streamline-emr:
|
streamline-emr:
|
||||||
image: ${APP_IMAGE:-streamline-emr:latest}
|
image: registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/streamline-emr/arm64:2.3
|
||||||
container_name: ${APP_CONTAINER:-streamline-emr}
|
container_name: streamline-emr
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- "${DATA_DIR:-./data}:/var/lib/mysql"
|
- "${DATA_DIR:-./data}:/var/lib/mysql"
|
||||||
@@ -20,8 +20,8 @@ services:
|
|||||||
- streamline
|
- streamline
|
||||||
|
|
||||||
statistics:
|
statistics:
|
||||||
image: ${STATISTICS_IMAGE:-streamline-emr-statistics:latest}
|
image: registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/statistics/arm64:2.3
|
||||||
container_name: ${STATISTICS_CONTAINER:-streamline-emr-statistics}
|
container_name: streamline-emr-statistics
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- "${STATISTICS_ENV:-./resources/statistics.env}:/app/statistics.env"
|
- "${STATISTICS_ENV:-./resources/statistics.env}:/app/statistics.env"
|
||||||
@@ -33,8 +33,8 @@ services:
|
|||||||
- streamline
|
- streamline
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
image: ${REDIS_IMAGE:-streamline-emr-redis:latest}
|
image: registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/redis/arm64:2.3
|
||||||
container_name: ${REDIS_CONTAINER:-streamline-emr-redis}
|
container_name: streamline-emr-redis
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "${REDIS_PORT:-6379}:6379"
|
- "${REDIS_PORT:-6379}:6379"
|
||||||
|
|||||||
Reference in New Issue
Block a user