diff --git a/.env.example b/.env.example index 668c06f..8144d9b 100644 --- a/.env.example +++ b/.env.example @@ -12,6 +12,20 @@ DB_DATABASE=homestead DB_USERNAME=homestead DB_PASSWORD=secret +DB_REPORT_GENERATOR_CONNECTION=mysql_report_generator +DB_REPORT_GENERATOR_HOST=127.0.0.1 +DB_REPORT_GENERATOR_PORT=3306 +DB_REPORT_GENERATOR_DATABASE=homestead +DB_REPORT_GENERATOR_USERNAME=homestead +DB_REPORT_GENERATOR_PASSWORD=secret + +DB_LIBREEHR_CONNECTION=mysql_libreehr +DB_LIBREEHR_HOST=127.0.0.1 +DB_LIBREEHR_PORT=3306 +DB_LIBREEHR_DATABASE=homestead +DB_LIBREEHR_USERNAME=homestead +DB_LIBREEHR_PASSWORD=secret + BROADCAST_DRIVER=log CACHE_DRIVER=file SESSION_DRIVER=file diff --git a/Documentation/install.txt b/Documentation/install.txt deleted file mode 100644 index 53fcedb..0000000 --- a/Documentation/install.txt +++ /dev/null @@ -1,25 +0,0 @@ -Laravel Installation : ----------------------- - -For installation purpose, official docs at https://laravel.com/docs/5.4/installation followed. Below is brief instructions to follow for unix based systems. - -Dependency: ------------ -1. PHP 7.0+ -2. OpenSSL PHP Extension -3. PDO PHP Extension -4. Mbstring PHP Extension -5. Composer - -Install Laravel: ----------------- --composer global require "laravel/installer" - -Above will install laravel via Laravel Installer, but to have a global access we need to export its path. So for this, follow below instructions : -1. Open your shell. (In my case bash shell) -2. open .bashrc -3. Add export PATH="$PATH:$HOME/.config/composer/vendor/bin" at the end of file. -4. Run source ~/.bashrc - - - diff --git a/Documentation/instructions.txt b/Documentation/instructions.txt deleted file mode 100644 index 061aa90..0000000 --- a/Documentation/instructions.txt +++ /dev/null @@ -1,67 +0,0 @@ -Instructions: -------------- - -1. Repository setup - * Fork the Repository at https://github.com/LibreHealthIO/lh-ehr-laravel-port.git - * Clone your fork of the Repository from your GitHub account at https://github.com/your_username/lh-ehr-laravel-port.git - - Command to clone fork: 'git clone https://github.com/your_username/lh-ehr-laravel-port.git' - * Add your upstream and origin remotes - - command to add upstream --> 'git remote add upstream https://github.com/LibreHealthIO/lh-ehr-laravel-port.git' - - command to add origin --> 'git remote add origin https://github.com/your_username/lh-ehr-laravel-port.git' - -2. Ensure to have the following dependencies - * PHP 7.0 (7.0.* is required for LibreEHR) - * OpenSSL PHP Extension - * PDO PHP Extension - * Mbstring PHP Extension - * composer - -3. Installing Composer - * Run 'sudo apt update' in the terminal - * Run 'sudo apt install curl php7.0-cli php7.0-mbstring git unzip' - * 'cd~' - * 'curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer' - * Test the installation by running 'composer' in the terminal - * Ensure that your home/'username'/.config/ folder is writtable - -3. Run the command below to install Laravel globally via Laravel Installer - 'composer global require "laravel/installer"' - -4. Now we have to add global access - * Open .bashrc by running this command 'sudo gedit .bashrc'. Feel free to use anything other than gedit. You'll be prompted to enter your password. - * Add this line at the end of the file and save it - 'PATH="$PATH:$HOME/.config/composer/vendor/bin"' - * Run this command after saving the .bashrc file - 'source ~/.bashrc' - -5. Navigate to lh-ehr-laravel-port directory - 'cd lh-ehr-laravel-port' - -6. Add you .env file by running this command: 'cp .env.example .env' - -7. Add your .env file to .gitignore filename. // It is already, just check! - -8. Generate key for your application by running the command below - 'php artisan key:generate' - Observe that the key is inserted in your .env file. - -9. Edit your database name, username and password in your .env file - DB_DATABASE = your_db_name - DB_USERNAME = your_username - DB_PASSWORD = your_password - -10. Now, you can create the database by running - 'php artisan make:database' - -11. Create tables by running - 'php artisan migrate' - -12. You can seed the database width - 'php artisan db:seed' - -13. Start the application by running the command below in the terminal: - 'php artisan serve' - -14. Head over to your browser and access http://localhost:8000 or 127.0.0.1:8000 - -15. You can also check your database at http://localhost/phpmyadmin/ diff --git a/Documentation/librereportgenerator.sql b/Documentation/librereportgenerator.sql new file mode 100644 index 0000000..4078a7c --- /dev/null +++ b/Documentation/librereportgenerator.sql @@ -0,0 +1,94 @@ +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +SET time_zone = "+00:00"; + +-- +-- Database: `librereportgenerator` +-- + +-- -------------------------------------------------------- + +-- +-- Dumping data for table `draggable_components` +-- + +INSERT INTO `draggable_components` (`id`, `option_id`, `is_default`, `user`, `title`, `order`, `active`, `note`, `toggle_sort`, `toggle_display`, `created_at`, `updated_at`) VALUES +(1, 'pfullname', 1, 'default', 'Patient Fullname', 5, 1, 'patient_data:fname:mname:lname', 0, 0, NULL, NULL), +(2, 'plfname', 1, 'default', 'Patient Last Firstname', 10, 1, 'patient_data:lname:fname', 0, 0, NULL, NULL), +(3, 'pflname', 1, 'default', 'Patient First Lastname', 15, 1, 'patient_data:fname:lname', 0, 0, NULL, NULL), +(4, 'preversedname', 1, 'default', 'Patient Full reversed name', 20, 1, 'patient_data:lname:mname:fname', 0, 0, NULL, NULL), +(5, 'pfmname', 1, 'default', 'Patient First Middlename', 25, 1, 'patient_data:fname:mname', 0, 0, NULL, NULL), +(6, 'pid', 1, 'default', 'Patient Id', 30, 1, 'patient_data:id', 0, 0, NULL, NULL), +(7, 'pstreet', 1, 'default', 'Patient Street', 35, 1, 'patient_data:street', 0, 0, NULL, NULL), +(8, 'pcity', 1, 'default', 'Patient First Lastname', 40, 1, 'patient_data:city', 0, 0, NULL, NULL), +(9, 'pstate', 1, 'default', 'Patient Full reversed name', 45, 1, 'patient_data:lname:mname:fname', 0, 0, NULL, NULL), +(10, 'pstreetcity', 1, 'default', 'Patient Street City', 50, 1, 'patient_data:street:city', 0, 0, NULL, NULL), +(11, 'pcitystate', 1, 'default', 'Patient City State', 55, 1, 'patient_data:city:state', 0, 0, NULL, NULL), +(12, 'pstreetcitystate', 1, 'default', 'Patient Street City State', 60, 1, 'patient_data:street:city:state', 0, 0, NULL, NULL), +(13, 'ppcode', 1, 'default', 'Patient Postal Code', 65, 1, 'patient_data:postal_code', 0, 0, NULL, NULL), +(14, 'poccupation', 1, 'default', 'Patient Occupation', 70, 1, 'patient_data:occupation', 0, 0, NULL, NULL), +(15, 'pemail', 1, 'default', 'Patient Email', 75, 1, 'patient_data:email', 0, 0, NULL, NULL), +(16, 'pphone', 1, 'default', 'Patient Phone Contact', 80, 1, 'patient_data:phone_contact', 0, 0, NULL, NULL), +(17, 'planguage', 1, 'default', 'Patient Language', 85, 1, 'patient_data:language', 0, 0, NULL, NULL), +(18, 'pregdate', 1, 'default', 'Patient Register date', 90, 1, 'patient_data:regdate', 0, 0, NULL, NULL), +(19, 'psex', 1, 'default', 'Patient Sex', 95, 1, 'patient_data:sex', 0, 0, NULL, NULL), +(20, 'pemailphone', 1, 'default', 'Patient Email Phone', 100, 1, 'patient_data:email:phone_contact', 0, 0, NULL, NULL), +(21, 'pidfullname', 1, 'default', 'Patient PID Fullname', 105, 1, 'patient_data:id:fname:mname:lname', 0, 0, NULL, NULL), +(22, 'pdob', 1, 'default', 'Patient Date of birth', 110, 1, 'patient_data:DOB', 0, 0, NULL, NULL), +(23, 'pss', 1, 'default', 'Patient SS', 115, 1, 'patient_data:ss', 0, 0, NULL, NULL), +(24, 'pstatus', 1, 'default', 'Patient Status', 120, 1, 'patient_data:status', 0, 0, NULL, NULL), +(25, 'preferrer', 1, 'default', 'Patient Referrer', 125, 1, 'patient_data:referrer', 0, 0, NULL, NULL), +(26, 'pstatussex', 1, 'default', 'Patient Status Sex', 130, 1, 'patient_data:status:sex', 0, 0, NULL, NULL), +(27, 'pidnamecontact', 1, 'default', 'Patient ID Name Contact', 135, 1, 'patient_data:id:fname:mname:phone_contact:email', 0, 0, NULL, NULL), +(28, 'pidnameAddress', 1, 'default', 'Patient ID Name Address', 140, 1, 'patient_data:id:fname:mname:street:city:state:postal_code', 0, 0, NULL, NULL), +(29, 'poccupationmonthlyincome', 1, 'default', 'Patient Occupation Monthly Income', 145, 1, 'patient_data:occupation:monthly_income', 0, 0, NULL, NULL), +(30, 'psexstatusfamilysize', 1, 'default', 'Patient Sex Status Family Size', 150, 1, 'patient_data:sex:status:family_size', 0, 0, NULL, NULL); + +-- -------------------------------------------------------- + +-- +-- Dumping data for table `draggable_component_report_format` +-- + +INSERT INTO `draggable_component_report_format` (`id`, `draggable_component_id`, `report_format_id`, `created_at`, `updated_at`) VALUES +(1, 21, 1, '2018-07-05 09:16:37', '2018-07-05 09:16:37'), +(2, 12, 1, '2018-07-05 09:16:37', '2018-07-05 09:16:37'), +(3, 19, 1, '2018-07-05 09:16:37', '2018-07-05 09:16:37'), +(4, 5, 2, '2018-07-05 09:21:59', '2018-07-05 09:21:59'), +(5, 20, 2, '2018-07-05 09:21:59', '2018-07-05 09:21:59'), +(6, 12, 2, '2018-07-05 09:21:59', '2018-07-05 09:21:59'), +(7, 21, 3, '2018-07-05 09:36:19', '2018-07-05 09:36:19'), +(8, 30, 3, '2018-07-05 09:36:19', '2018-07-05 09:36:19'), +(9, 21, 4, '2018-07-05 09:37:39', '2018-07-05 09:37:39'), +(10, 25, 4, '2018-07-05 09:37:39', '2018-07-05 09:37:39'), +(11, 18, 4, '2018-07-05 09:37:39', '2018-07-05 09:37:39'), +(12, 21, 5, '2018-07-05 09:40:59', '2018-07-05 09:40:59'), +(13, 23, 5, '2018-07-05 09:40:59', '2018-07-05 09:40:59'), +(14, 13, 5, '2018-07-05 09:40:59', '2018-07-05 09:40:59'), +(15, 15, 5, '2018-07-05 09:40:59', '2018-07-05 09:40:59'); + +-- -------------------------------------------------------- + +-- +-- Dumping data for table `report_formats` +-- + +INSERT INTO `report_formats` (`id`, `user`, `title`, `description`, `system_feature_id`, `created_at`, `updated_at`) VALUES +(1, 'default', 'Patient List', 'List of all patients with basic demographics.', 1, '2018-07-05 09:16:37', '2018-07-05 09:16:37'), +(2, 'default', 'Patients Contacts and Address', 'List of all patient\'s email, phone, street, city and state.', 1, '2018-07-05 09:21:59', '2018-07-05 09:21:59'), +(3, 'default', 'Patient Family Size', 'Information on patient\'s family size', 1, '2018-07-05 09:36:19', '2018-07-05 09:36:19'), +(4, 'default', 'Patient Registration', 'Information on patient\'s registrars, and date.', 1, '2018-07-05 09:37:39', '2018-07-05 09:37:39'), +(5, 'default', 'Patient SS', 'Patients\' SS and postal codes', 1, '2018-07-05 09:40:59', '2018-07-05 09:40:59'); + +-- -------------------------------------------------------- + +-- +-- Dumping data for table `system_features` +-- + +INSERT INTO `system_features` (`id`, `name`, `description`, `user`, `created_at`, `updated_at`) VALUES +(1, 'Clients', 'Reports related to clients', 'default', '2018-07-02 04:43:04', '2018-07-02 04:43:04'), +(2, 'Financial', 'Reports related to finance and payments.', 'default', '2018-07-02 08:20:40', '2018-07-02 08:20:40'), +(3, 'Visits', 'Reports concerning patients and other visits.', 'default', '2018-07-04 23:00:00', '2018-07-04 23:00:00'), +(4, 'Procedures', 'Procedure statistics, and other pending orders', 'default', '2018-07-04 23:00:00', '2018-07-04 23:00:00'), +(5, 'Insurance', 'Reports related to patients\' insurance, and other related issues.', 'default', '2018-07-04 23:00:00', '2018-07-04 23:00:00'), +(6, 'Inventory', 'Reports related to inventory at various level in the system.', 'default', '2018-07-04 23:00:00', '2018-07-04 23:00:00'); diff --git a/Modules/ReportGenerator/Database/Migrations/2018_04_30_182051_create_system_features_table.php b/Modules/ReportGenerator/Database/Migrations/2018_04_30_182051_create_system_features_table.php new file mode 100644 index 0000000..0742e23 --- /dev/null +++ b/Modules/ReportGenerator/Database/Migrations/2018_04_30_182051_create_system_features_table.php @@ -0,0 +1,44 @@ + + * Copyright 2018 Tigpezeghe Rodrige K. + */ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +class CreateSystemFeaturesTable extends Migration +{ + /** + * Run the migrations. + * + * @author Tigpezeghe Rodrige K. (2018) + * + * @return void + */ + public function up() + { + Schema::connection('mysql_report_generator')->create('system_features', function (Blueprint $table) { + $table->increments('id')->comment = "This will identify each system feature with a unique integer."; + $table->string('name')->comment = "The name of the system feature."; + $table->text('description')->comment = "This describes the system feature briefly."; + $table->string('user', 255)->default('default')->comment = "The user who created the feature. This will be 'default' for features that come with the module."; + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('system_features'); + } +} diff --git a/Modules/ReportGenerator/Database/Migrations/2018_05_22_153827_create_draggable_components_table.php b/Modules/ReportGenerator/Database/Migrations/2018_05_22_153827_create_draggable_components_table.php new file mode 100644 index 0000000..00b2818 --- /dev/null +++ b/Modules/ReportGenerator/Database/Migrations/2018_05_22_153827_create_draggable_components_table.php @@ -0,0 +1,53 @@ + + * Copyright 2018 Tigpezeghe Rodrige K. + */ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +class CreateDraggableComponentsTable extends Migration +{ + /** + * Run the migrations. + * + * @author Tigpezeghe Rodrige K. (2018) + * + * @return void + */ + public function up() + { + Schema::connection('mysql_report_generator')->create('draggable_components', function (Blueprint $table) { + $table->increments('id')->comment = "This will identify each component with a unique integer."; + $table->string('option_id', 255)->comment = "All draggable components have an ID."; + $table->boolean('is_default')->default(1)->comment = "0 -> False, 1 -> True."; + $table->string('user', 255)->default('default')->comment = "The user who created the component. This will be 'default' for components that come with the module."; + $table->string('title', 255)->comment = "This is the text on the component that end users see."; + $table->integer('order', 0)->comment = "The order in which components appear in the list."; + $table->boolean('active')->default(1)->comment = "0 -> False, 1 -> True whether the component should be active or not."; + $table->string('note', 255)->comment = "This stores the fields that the component relates to in the database."; + $table->boolean('toggle_sort')->default(0)->comment = "0 -> False (Descending), 1 -> True (Ascending)."; + $table->boolean('toggle_display')->default(0)->comment = "0 -> False, 1 -> True. Display field if checked (1), and no if unchecked (0)."; + + $table->timestamps(); + + // $table->foreign('userID')->references('id')->on('users')->onDelete('cascade'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('draggable_components'); + } +} diff --git a/Modules/ReportGenerator/Database/Migrations/2018_05_25_203256_create_report_formats_table.php b/Modules/ReportGenerator/Database/Migrations/2018_05_25_203256_create_report_formats_table.php new file mode 100644 index 0000000..0397105 --- /dev/null +++ b/Modules/ReportGenerator/Database/Migrations/2018_05_25_203256_create_report_formats_table.php @@ -0,0 +1,49 @@ + + * Copyright 2018 Tigpezeghe Rodrige K. + */ +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +class CreateReportFormatsTable extends Migration +{ + /** + * Run the migrations. + * + * @author Tigpezeghe Rodrige K. (2018) + * + * @return void + */ + public function up() + { + Schema::connection('mysql_report_generator')->create('report_formats', function (Blueprint $table) { + $table->increments('id')->comment = "This will identify each component with a unique integer."; + $table->string('user', 255)->default('default')->comment = "The user who created the report format. This will be 'default' for components that come with the module."; + $table->string('title', 255)->comment = "This is the report name e.g Patient List."; + $table->text('description')->comment = "This describes the report format briefly."; + //$table->string('option_ids')->comment = "This stores the option ids of components that constitute this report format"; + $table->integer('system_feature_id')->unsigned()->comment = "The system feature under which the report belongs."; + $table->foreign('system_feature_id')->references('id')->on('system_features')->onDelete('cascade'); + //$table->string('draggable_components_id', 1000)->comment = "This stores the id of all the components that belong to this report format"; + + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('report_formats'); + } +} diff --git a/Modules/ReportGenerator/Database/Migrations/2018_06_04_083903_create_draggable_component_report_format_table.php b/Modules/ReportGenerator/Database/Migrations/2018_06_04_083903_create_draggable_component_report_format_table.php new file mode 100644 index 0000000..446bdd2 --- /dev/null +++ b/Modules/ReportGenerator/Database/Migrations/2018_06_04_083903_create_draggable_component_report_format_table.php @@ -0,0 +1,45 @@ + + * Copyright 2018 Tigpezeghe Rodrige K. + */ + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +class CreateDraggableComponentReportFormatTable extends Migration +{ + /** + * Run the migrations. + * + * @author Tigpezeghe Rodrige K. (2018) + * + * @return void + */ + public function up() + { + Schema::connection('mysql_report_generator')->create('draggable_component_report_format', function (Blueprint $table) { + $table->increments('id')->comment = "Primary key."; + $table->integer('draggable_component_id')->unsigned()->comment = "Used to access the draggable_components."; + $table->foreign('draggable_component_id')->references('id')->on('draggable_components')->onDelete('cascade'); + $table->integer('report_format_id')->unsigned()->comment = "Used to access the report_formats."; + $table->foreign('report_format_id')->references('id')->on('report_formats')->onDelete('cascade'); + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('draggable_component_report_format'); + } +} diff --git a/Modules/ReportGenerator/Database/Seeders/DraggableComponentTableSeeder.php b/Modules/ReportGenerator/Database/Seeders/DraggableComponentTableSeeder.php new file mode 100644 index 0000000..486d0b4 --- /dev/null +++ b/Modules/ReportGenerator/Database/Seeders/DraggableComponentTableSeeder.php @@ -0,0 +1,25 @@ + + * */ + +namespace Modules\ReportGenerator\Database\Seeders; + +use Illuminate\Database\Seeder; +use Illuminate\Database\Eloquent\Model; + +class DraggableComponentTableSeeder extends Seeder +{ + /** + * Run the database seeds. + * + * @return void + */ + public function run() + { + Model::unguard(); + factory("../../". Entities\DraggableComponent::class, 25)->create(); + // $this->call("OthersTableSeeder"); + } +} diff --git a/Modules/ReportGenerator/Database/Seeders/ReportFormatTableSeeder.php b/Modules/ReportGenerator/Database/Seeders/ReportFormatTableSeeder.php new file mode 100644 index 0000000..23e8e50 --- /dev/null +++ b/Modules/ReportGenerator/Database/Seeders/ReportFormatTableSeeder.php @@ -0,0 +1,25 @@ + + * */ + +//namespace Modules\ReportGenerator\Database\Seeders; + +use Illuminate\Database\Seeder; +use Illuminate\Database\Eloquent\Model; + +class ReportFormatTableSeeder extends Seeder +{ + /** + * Run the database seeds. + * + * @return void + */ + public function run() + { + Model::unguard(); + factory(Modules\ReportGenerator\Entities\ReportFormat::class, 25)->create(); + // $this->call("OthersTableSeeder"); + } +} diff --git a/Modules/ReportGenerator/Database/Seeders/ReportGeneratorDatabaseSeeder.php b/Modules/ReportGenerator/Database/Seeders/ReportGeneratorDatabaseSeeder.php index db21959..0bbf967 100644 --- a/Modules/ReportGenerator/Database/Seeders/ReportGeneratorDatabaseSeeder.php +++ b/Modules/ReportGenerator/Database/Seeders/ReportGeneratorDatabaseSeeder.php @@ -15,7 +15,8 @@ class ReportGeneratorDatabaseSeeder extends Seeder public function run() { Model::unguard(); - + $this->call(DraggableComponentTableSeeder::class); + $this->call(ReportFormatTableSeeder::class); // $this->call("OthersTableSeeder"); } } diff --git a/Modules/ReportGenerator/Database/factories/DraggableComponentFactory.php b/Modules/ReportGenerator/Database/factories/DraggableComponentFactory.php new file mode 100644 index 0000000..0054de4 --- /dev/null +++ b/Modules/ReportGenerator/Database/factories/DraggableComponentFactory.php @@ -0,0 +1,29 @@ + +| +*/ + +use Faker\Generator as Faker; + +$factory->define(Model::class, function (Faker $faker) { + +$booleanValue = array(true, false); + + return [ + 'option_id' => str_random(10)->unique(), + 'is_default' => $booleanValue[array_rand($booleanValue, 1)], + 'user' => $faker->name, + 'title' => $faker->sentence($nbWords = 3, $variableNbWords = true), + 'order' => $faker->number(2), + 'active' => $booleanValue[array_rand($booleanValue, 1)], + 'notes' => $faker->words($nb = 3, $asText = false), + 'toggle_sort' => $booleanValue[array_rand($booleanValue, 1)], + 'toggle_display' => $booleanValue[array_rand($booleanValue, 1)], + ]; +}); diff --git a/Modules/ReportGenerator/Database/factories/ReportFormatFactory.php b/Modules/ReportGenerator/Database/factories/ReportFormatFactory.php new file mode 100644 index 0000000..117f85e --- /dev/null +++ b/Modules/ReportGenerator/Database/factories/ReportFormatFactory.php @@ -0,0 +1,26 @@ + +| +*/ + +use Faker\Generator as Faker; + +$factory->define(Model::class, function (Faker $faker) { + + // Get all draggable_components_ids in draggable_components table + $draggable_components_ids = Entities\DraggableComponent::all()->pluck('id')->toArray(); + + return [ + 'user' => $faker->name, + 'title' => $faker->sentence($nbWords = 3, $variableNbWords = true), + 'system_feature' => $faker->sentence($nbWords = 3, $variableNbWords = true), + 'description' => $faker->text($maxNbChars = 100), + 'draggable_components_id' => $faker->randomElement($draggable_components_ids), + ]; +}); diff --git a/Modules/ReportGenerator/Entities/DraggableComponent.php b/Modules/ReportGenerator/Entities/DraggableComponent.php new file mode 100644 index 0000000..e12199c --- /dev/null +++ b/Modules/ReportGenerator/Entities/DraggableComponent.php @@ -0,0 +1,47 @@ + +| Copyright 2018 Tigpezeghe Rodrige K. +| +*/ + +namespace Modules\ReportGenerator\Entities; + +use Illuminate\Database\Eloquent\Model; + +class DraggableComponent extends Model +{ + protected $fillable = ['is_default', 'user', 'title', 'order', 'active', 'notes', 'toggle_sort', 'toggle_display']; + + /** + * Convert notes column from jsona(as specified in migration file) to array. + * + * @var string + */ + protected $casts = [ + 'notes' => 'array' + ]; + + /** + * The database connection name for DraggableComponent model. + * TODO + * @var string + */ + protected $connection = 'mysql_report_generator'; + + /** + * The report formats that belong to the Draggable component. + * + * @return Response + */ + public function report_formats() + { + return $this->belongsToMany('Modules\ReportGenerator\Entities\ReportFormat')->withTimestamps(); + } +} diff --git a/Modules/ReportGenerator/Entities/ReportFormat.php b/Modules/ReportGenerator/Entities/ReportFormat.php new file mode 100644 index 0000000..c279918 --- /dev/null +++ b/Modules/ReportGenerator/Entities/ReportFormat.php @@ -0,0 +1,58 @@ + +| Copyright 2018 Tigpezeghe Rodrige K. +| +*/ + +namespace Modules\ReportGenerator\Entities; + +use Illuminate\Database\Eloquent\Model; + +class ReportFormat extends Model +{ + protected $fillable = ['user', 'title', 'system_feature_id', 'description', 'draggable_components_id']; + + /** + * Convert draggable_components_id column from jsona(as specified in migration file) to array. + * + * @var string + */ + protected $casts = [ + 'draggable_components_id' => 'array' + ]; + + /** + * The database connection name for ReportFormat model. + * TODO + * @var string + */ + protected $connection = 'mysql_report_generator'; + + /** + * The draggable components that belong to the Report Format. + * + * @return Response + */ + public function draggable_components() + { + return $this->belongsToMany('Modules\ReportGenerator\Entities\DraggableComponent')->withTimestamps(); + } + + /** + * The system feature that this report format belongs to. + * + * @return Response + */ + public function system_feature() + { + return $this->belongsTo('Modules\ReportGenerator\Entities\SystemFeature'); + } + +} diff --git a/Modules/ReportGenerator/Entities/SystemFeature.php b/Modules/ReportGenerator/Entities/SystemFeature.php new file mode 100644 index 0000000..a7fe974 --- /dev/null +++ b/Modules/ReportGenerator/Entities/SystemFeature.php @@ -0,0 +1,46 @@ + +| Copyright 2018 Tigpezeghe Rodrige K. +| +*/ + +namespace Modules\ReportGenerator\Entities; + +use Illuminate\Database\Eloquent\Model; + +class SystemFeature extends Model +{ + protected $fillable = ['name', 'description']; + + /** + * Convert draggable_components_id column from jsona(as specified in migration file) to array. + * + * @var string + */ + protected $casts = []; + + /** + * The database connection name for ReportFormat model. + * TODO + * @var string + */ + protected $connection = 'mysql_report_generator'; + + /** + * The report formats under this system feature. + * + * @return Response + */ + public function report_formats() + { + return $this->hasMany('Modules\ReportGenerator\Entities\ReportFormat'); + } + +} diff --git a/Modules/ReportGenerator/Http/Controllers/PdfController.php b/Modules/ReportGenerator/Http/Controllers/PdfController.php new file mode 100644 index 0000000..b934544 --- /dev/null +++ b/Modules/ReportGenerator/Http/Controllers/PdfController.php @@ -0,0 +1,73 @@ +column_names); + return view('reportgenerator::index'); + } + + /** + * Show the form for creating a new resource. + * @return Response + */ + public function create() + { + return view('reportgenerator::create'); + } + + /** + * Store a newly created resource in storage. + * @param Request $request + * @return Response + */ + public function store(Request $request) + { + } + + /** + * Show the specified resource. + * @return Response + */ + public function show() + { + return view('reportgenerator::show'); + } + + /** + * Show the form for editing the specified resource. + * @return Response + */ + public function edit() + { + return view('reportgenerator::edit'); + } + + /** + * Update the specified resource in storage. + * @param Request $request + * @return Response + */ + public function update(Request $request) + { + } + + /** + * Remove the specified resource from storage. + * @return Response + */ + public function destroy() + { + } +} diff --git a/Modules/ReportGenerator/Http/Controllers/ReportFormatController.php b/Modules/ReportGenerator/Http/Controllers/ReportFormatController.php new file mode 100644 index 0000000..b447ccb --- /dev/null +++ b/Modules/ReportGenerator/Http/Controllers/ReportFormatController.php @@ -0,0 +1,167 @@ + +| Copyright 2018 Tigpezeghe Rodrige K. +| +*/ + +namespace Modules\ReportGenerator\Http\Controllers; + +use Illuminate\Http\Request; +use Illuminate\Http\Response; +use Illuminate\Routing\Controller; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Validator; +use Illuminate\Foundation\Validation\ValidatesRequests; + +use Modules\ReportGenerator\Entities\ReportFormat as ReportFormat; +use Modules\ReportGenerator\Entities\SystemFeature as SystemFeature; +use Modules\ReportGenerator\Entities\DraggableComponent as DraggableComponent; + +class ReportFormatController extends Controller +{ + /** + * Display a listing of the resource, report formats. + * @return Response + */ + public function index() + { + return view('reportgenerator::report_formats')->with([ + 'report_formats' => ReportFormat::all(), + 'system_features' => SystemFeature::all(), + ]); + } + + /** + * Show the form for creating a new resource. + * @return Response + */ + public function create() + { + return view('reportgenerator::create'); + } + + /** + * Store a newly created resource in storage. + * + * @param Request $request + * + * @return Response + */ + public function store(Request $request) + { + $validate = Validator::make($request->all(), [ // Validate the input from new report format form + 'title' => 'required|max:255', + 'description' => 'required|max:255', + 'system_feature_id' => 'required' + ]); + + if($validate->fails()){ // Fire error if validation fails + return back()->withErrors($validate); + } + + // Save the report format + $report_format = ReportFormat::create([ + 'title' => $request->title, + 'description' => $request->description, + 'system_feature_id' => $request->system_feature_id + ]); + + // Save the draggable components in the join table (Report format and draggable_components table) + $new_report_format = ReportFormat::findOrFail($report_format->id); // Get the last inserted report format id + $draggable_component_ids = []; // Store the ids of the draggable components + $option_ids = unserialize($request->option_ids); + + foreach ($option_ids as $key => $option_id) { // foreach option id, + $draggable_component_ids[] = DraggableComponent::where('option_id', $option_id)->first()->id; // get the id of the corresponding draggable component + } + + // Populate the draggable_component_report_format join table + $new_report_format->draggable_components()->attach($draggable_component_ids); + + if(!$report_format){ // If for some reason report format isn't created, fire error message + return back()->with('failure', 'An error occured while saving report format. Fill all fields!!!'); + } + + return back()->with('success', 'Successfully created new report format '.$request->title); + } + + /** + * Show the specified resource. + * @return Response + */ + public function show() + { + return view('reportgenerator::show'); + } + + /** + * Show the form for editing the specified resource. + * @return Response + */ + public function edit() + { + return view('reportgenerator::edit'); + } + + /** + * Update the specified resource in storage. + * + * @param Request $request + * + * @return Response + * + * TODO: Restrict users from deleting default report formats. + */ + public function update(Request $request) + { + $validate = Validator::make($request->all(), [ // Validate the input from new report format form + 'title' => 'required|max:255', + 'description' => 'required|max:255' + ]); + + if($validate->fails()){ // Fire error if validation fails + return back()->withErrors($validate); + } + + $report_format = ReportFormat::find($request->id); + + $report_format->title = $request->title; + $report_format->description = $request->description; + $report_format->system_feature_id = $request->system_feature_id; + $report_format->save(); + + if(!$report_format){ // If for some reason system feature isn't created, fire error message + return back()->with('failure', 'An error occured while saving report format. Fill all fields!!!'); + } + + return back()->with('success', 'Successfully updated report format '.$request->title); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * + * @return Response + * + * TODO: Restrict users from deleting default report formats + */ + public function destroy(Request $request) + { + $report_format = ReportFormat::find($request->id); + $report_format->delete(); + + if(!$report_format){ // If for some reason system feature isn't created, fire error message + return back()->with('failure', 'An error occured while deleting report format. Try again!!!'); + } + + return back()->with('success', 'Deleted report format, '.$report_format->title); + } +} diff --git a/Modules/ReportGenerator/Http/Controllers/ReportGeneratorController.php b/Modules/ReportGenerator/Http/Controllers/ReportGeneratorController.php index f0363fc..52ff33f 100644 --- a/Modules/ReportGenerator/Http/Controllers/ReportGeneratorController.php +++ b/Modules/ReportGenerator/Http/Controllers/ReportGeneratorController.php @@ -1,22 +1,138 @@ +| Copyright 2018 Tigpezeghe Rodrige K. +| +*/ namespace Modules\ReportGenerator\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Routing\Controller; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Validator; +use Illuminate\Foundation\Validation\ValidatesRequests; + +use Modules\ReportGenerator\Entities\ReportFormat as ReportFormat; +use Modules\ReportGenerator\Entities\SystemFeature as SystemFeature; +use Modules\ReportGenerator\Entities\DraggableComponent as DraggableComponent; class ReportGeneratorController extends Controller { + use ValidatesRequests; + /** * Display a listing of the resource. * @return Response */ public function index() { - return view('reportgenerator::index'); + $report_formats = ReportFormat::all(); + $system_features = SystemFeature::all(); + $draggable_components = DraggableComponent::all(); + return view('reportgenerator::index')->with([ + 'report_formats' => $report_formats, + 'system_features' => $system_features, + 'draggable_components' => $draggable_components + ]); + } + + /** + * This function gets the selected components and sends them to them + * to the showReport() function to get the data and show the report. + * @param Request $request : holds selected components + * @return Response $protocol_host : holds protocol and host + * $option_ids : holds option_ids of selected components + */ + public function getComponents(Request $request) + { + $option_ids = $request->ids; // returns an array + + // Get protocol and host to redirect users. + $protocol_host = 'http://' . $_SERVER['HTTP_HOST']; + if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') + $protocol_host = 'https://' . $_SERVER['HTTP_HOST']; + + $option_ids = serialize($option_ids); + return response()->json([ + 'option_ids' => $option_ids, + 'success' => 'Received Option IDs', + 'redirecturl' => $protocol_host.'/reportgenerator/report/'.$option_ids + ]); + } + + /** + * Use option_ids from getComponents() above, + * get data and show the generated report. + * @param Array $option_ids : selected draggable_components + * @param Boolean $hide: hide or show 'Save report format' button + * @return Response $data : holds retrieved data + */ + public function showReport($option_ids, $hide = False) + { + $option_ids = unserialize($option_ids); + $notes = []; // store the notes for each dragged component. + $column_list = []; // store an array of lists of columns for each note in an array. + for ($i = 0; $i < count($option_ids); $i++) { // foreach $option_id + $notes[$i] = DraggableComponent::where('option_id', $option_ids[$i])->first(); // get the notes for each component + $column_list[$i] = explode(':', $notes[$i]->note); // split the each 'note string' and store in $column_list[] + } + + $data = []; // store the retrieved data + $column_names = []; // store the column_names + foreach ($column_list as $columns) { // $columns has the list of columns for each component. + $table_name = $columns[0]; // get table name to which each column list points to. + for($i = 1; $i < count($columns); $i++) { // foreach list of columns + $data[] = DB::connection('mysql_libreehr') // get the data, and append to $data[] + ->table($table_name) + ->select($columns[$i]) + ->get()->toArray(); + //$data = collect($data); + $column_names[] = $columns[$i]; + } + } + + // These are used in menu and the select field in the form to add new report format + $report_formats = ReportFormat::all(); + $system_features = SystemFeature::all(); + + return view('reportgenerator::report')->with([ + 'data' => $data, + 'hide' => $hide, + 'column_names' => $column_names, + 'report_formats' => $report_formats, + 'system_features' => $system_features, + 'option_ids' => serialize($option_ids) + ]); } + /** + * Get option_ids for report from selected report_format + * @param: Request $report_format_id + * @return: showReport($option_ids) + */ + public function view($report_format_id) + { + $draggable_components = ReportFormat::find($report_format_id)->draggable_components()->get(); + + $option_ids = []; + foreach ($draggable_components as $draggable_component) { // Get the option_ids of each $draggable_component + $option_ids[] = $draggable_component->option_id; + } + + $option_ids = serialize($option_ids); // serialize option_ids in preparation for showReport method + + return ReportGeneratorController::showReport($option_ids, True); // call showReport method above + + } + /** * Show the form for creating a new resource. * @return Response diff --git a/Modules/ReportGenerator/Http/Controllers/SystemFeatureController.php b/Modules/ReportGenerator/Http/Controllers/SystemFeatureController.php new file mode 100644 index 0000000..9933723 --- /dev/null +++ b/Modules/ReportGenerator/Http/Controllers/SystemFeatureController.php @@ -0,0 +1,149 @@ + +| Copyright 2018 Tigpezeghe Rodrige K. +| +*/ + +namespace Modules\ReportGenerator\Http\Controllers; + +use Illuminate\Http\Request; +use Illuminate\Http\Response; +use Illuminate\Routing\Controller; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Validator; +use Illuminate\Foundation\Validation\ValidatesRequests; + +use Modules\ReportGenerator\Entities\ReportFormat as ReportFormat; +use Modules\ReportGenerator\Entities\SystemFeature as SystemFeature; +use Modules\ReportGenerator\Entities\DraggableComponent as DraggableComponent; + +class SystemFeatureController extends Controller +{ + /** + * Show all system features. + * @return Response + */ + public function index() + { + return view('reportgenerator::system_features')->with('system_features', SystemFeature::all()); + } + + /** + * Show the form for creating a new resource. + * @return Response + */ + public function create() + { + return view('reportgenerator::create'); + } + + /** + * Store a newly created resource in storage. + * @param Request $request + * @return Response + */ + public function store(Request $request) + { + $validate = Validator::make($request->all(), [ // Validate the input from new system feature form + 'feature_name' => 'required|max:255', + 'description' => 'required|max:255' + ]); + + if($validate->fails()){ // Fire error if validation fails + return back()->withErrors($validate); + } + + $system_feature = new SystemFeature; + + $system_feature->name = $request->feature_name; + $system_feature->description = $request->description; + + $system_feature->save(); // Save new system feature + + if(!$system_feature){ // If for some reason system feature isn't created, fire error message + return back()->with('failure', 'An error occured while saving system feature. Fill all fields!!!'); + } + + return back()->with('success', 'Successfully created new system feature '.$request->feature_name); + } + + /** + * Show the specified resource. + * @return Response + */ + public function show() + { + return view('reportgenerator::show'); + } + + /** + * Show the form for editing the specified resource. + * @return Response + */ + public function edit() + { + return view('reportgenerator::edit'); + } + + /** + * Update the specified resource in storage. + * + * @param Request $request + * + * @return Response + * + * TODO: Restrict users from deleting default system features. + */ + public function update(Request $request) + { + $validate = Validator::make($request->all(), [ // Validate the input from new system feature form + 'feature_name' => 'required|max:255', + 'description' => 'required|max:255' + ]); + + if($validate->fails()){ // Fire error if validation fails + return back()->withErrors($validate); + } + + $system_feature = SystemFeature::find($request->id); + + $system_feature->name = $request->feature_name; + $system_feature->description = $request->description; + $system_feature->save(); + + if(!$system_feature){ // If for some reason system feature isn't created, fire error message + return back()->with('failure', 'An error occured while saving system feature. Fill all fields!!!'); + } + + return back()->with('success', 'Successfully updated system feature '.$request->feature_name); + } + + /** + * Remove the specified resource from storage. + * + * @param int $id + * + * @return Response + * + * TODO: Restrict users from deleting default system features. + */ + public function destroy(Request $request) + { + $system_feature = SystemFeature::find($request->id); + $system_feature->delete(); + + if(!$system_feature){ // If for some reason system feature isn't created, fire error message + return back()->with('failure', 'An error occured while deleting system feature. Try again!!!'); + } + + return back()->with('success', 'Deleted system feature, '.$system_feature->name); + } + +} diff --git a/Modules/ReportGenerator/Http/routes.php b/Modules/ReportGenerator/Http/routes.php index a3d07fd..12c57ed 100644 --- a/Modules/ReportGenerator/Http/routes.php +++ b/Modules/ReportGenerator/Http/routes.php @@ -2,5 +2,37 @@ Route::group(['middleware' => 'web', 'prefix' => 'reportgenerator', 'namespace' => 'Modules\ReportGenerator\Http\Controllers'], function() { + Route::get('/pdf_report', 'PdfController@index'); + Route::get('/', 'ReportGeneratorController@index'); + + Route::get('/generate', 'ReportGeneratorController@getComponents'); // get all option_ids for selected components and call the route below + + Route::get('/report/{option_ids}', 'ReportGeneratorController@showReport')->name('showReport'); // show report from generated report page + + Route::get('/report_format/view/{report_format_id}', 'ReportGeneratorController@view'); // show report from report_format page + + /*** System Feature routes ***/ + Route::resource('system_feature', 'SystemFeatureController'); + /* + Route::get('/system_feature', 'SystemFeatureController@index'); // show all system features + + Route::post('/system_feature', 'SystemFeatureController@store'); // create new system feature + + Route::patch('/system_feature/{id}/{feature_name}/{description}', 'SystemFeatureController@update'); // update system feature + + Route::delete('/system_feature/{id}', 'SystemFeatureController@destroy'); // delete system feature + */ + + /*** Report Format routes ***/ + Route::resource('report_format', 'ReportFormatController'); + /* + Route::get('/report_format', 'ReportFormatController@index'); // show all report formats + + Route::post('/report_format', 'ReportFormatController@store'); // create new report format + + Route::put('/report_format/{id}', 'ReportFormatController@update'); // update report format + + Route::delete('/report_format/{id}', 'ReportFormatController@destroy'); // delete report format + */ }); diff --git a/Modules/ReportGenerator/Resources/views/index.blade.php b/Modules/ReportGenerator/Resources/views/index.blade.php index 6ccdb5e..c8b172a 100644 --- a/Modules/ReportGenerator/Resources/views/index.blade.php +++ b/Modules/ReportGenerator/Resources/views/index.blade.php @@ -1,89 +1,27 @@ @extends('reportgenerator::layouts.master') +@section('title', 'Report Generator') + @section('content') -  
+
-
+
-
-
Drop columns here -
-
-
-
-

Why am I stil empty?

+
+
+
Drop columns here +
-
+
+
+

Why am I still empty?

+
+
    +
    +
    @@ -96,31 +34,14 @@

    Frequently used columns

    -
    -

    I am one

    -

    I am two

    -

    I am three

    -

    I am four

    -
    -
    -

    I am five

    -

    I am six

    -

    I am seven

    -

    I am eight

    -
    -
    -

    All columns that concern reports

    -
    -

    I am one

    -

    I am two

    -

    I am three

    -

    I am four

    -
    -
    -

    I am five

    -

    I am six

    -

    I am seven

    -

    I am eight

    +
    + @foreach ($draggable_components as $draggable_component) +
    +

    + {{ $draggable_component->title }} +

    +
    + @endforeach
    @@ -155,32 +76,4 @@
    - - -@stop +@endsection diff --git a/Modules/ReportGenerator/Resources/views/layouts/master.blade.php b/Modules/ReportGenerator/Resources/views/layouts/master.blade.php index 5ce1aba..89baa04 100644 --- a/Modules/ReportGenerator/Resources/views/layouts/master.blade.php +++ b/Modules/ReportGenerator/Resources/views/layouts/master.blade.php @@ -1,12 +1,14 @@ - + + + - - Report Generator - LibreEHR + + @yield('title') - LibreHealthEHR @@ -27,7 +29,220 @@ + + @if(session('error')) + + @endif + @if(session('success')) + + @endif + @if($errors->any()) + + @endif + @yield('content') - + + + + + + + + + + + + + + + + diff --git a/Modules/ReportGenerator/Resources/views/report.blade.php b/Modules/ReportGenerator/Resources/views/report.blade.php new file mode 100644 index 0000000..38eb735 --- /dev/null +++ b/Modules/ReportGenerator/Resources/views/report.blade.php @@ -0,0 +1,113 @@ +@extends('reportgenerator::layouts.master') + +@section('title', 'Generated report') + +@section('content') + + +
    +
    + + + @foreach($data as $index => $datum) + + @endforeach + +
    + + + + @if($index == 0) + + @endif + + + + + + @foreach($datum as $key => $item) + + @if($index == 0) + + + + + @else + + + + @endif + @endforeach + + +
    #{{ $column_names[$index] }}
    {{ $key + 1 }}: + {{ empty($item[$column_names[$index]]) ? '---' : $item[$column_names[$index]] }} +
    + {{ empty($item[$column_names[$index]]) ? '---' : $item[$column_names[$index]] }} +
    +
    +
    + + + +@endsection diff --git a/Modules/ReportGenerator/Resources/views/report_formats.blade.php b/Modules/ReportGenerator/Resources/views/report_formats.blade.php new file mode 100644 index 0000000..648f25f --- /dev/null +++ b/Modules/ReportGenerator/Resources/views/report_formats.blade.php @@ -0,0 +1,34 @@ +@extends('reportgenerator::layouts.master') + +@section('title', 'Report Formats') + +@section('content') +   + + + + + + + + + + + + @foreach($report_formats as $report_format) + + + + + + + + + @endforeach + +
    #TitleDescriptionSystem FeatureActions
    {{ $report_format->id }}{{ $report_format->title }}{{ $report_format->description }}{{ $report_format->system_feature->name }} + View + Edit + Delete +
    +@endsection diff --git a/Modules/ReportGenerator/Resources/views/system_features.blade.php b/Modules/ReportGenerator/Resources/views/system_features.blade.php new file mode 100644 index 0000000..8bd4c89 --- /dev/null +++ b/Modules/ReportGenerator/Resources/views/system_features.blade.php @@ -0,0 +1,30 @@ +@extends('reportgenerator::layouts.master') + +@section('title', 'System Features') + +@section('content') +   + + + + + + + + + + + @foreach($system_features as $system_feature) + + + + + + + @endforeach + +
    #NameDescriptionActions
    {{ $system_feature->id }}{{ $system_feature->name }}{{ $system_feature->description }} + Edit + Delete +
    +@endsection diff --git a/Modules/ReportGenerator/install.txt b/Modules/ReportGenerator/install.txt new file mode 100644 index 0000000..3adbba0 --- /dev/null +++ b/Modules/ReportGenerator/install.txt @@ -0,0 +1,6 @@ +Under constant updates + +1. Create your own .env file from the .env.example fill +2. Edit the database variables as for your report generator database connection. +3. Create a new database with the database name you specified in DB_REPORT_GENERATOR_DATABASE +4. Run php artisan module:seed ReportGenerator diff --git a/README.md b/README.md index d41d5fb..6275395 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,117 @@ Code contributions are very welcome! We encourage newcomers to browse the [issue # Installation -For detailed, step-by-step instructions, refer to [Installation Instructions](/Documentation/instructions.txt) +##Laravel Installation : + +For installation purpose, official docs at https://laravel.com/docs/5.4/installation followed. +Below are brief instructions to follow for unix based systems. + +##Dependencies: + +1. PHP 7.0+ +2. OpenSSL PHP Extension +3. PDO PHP Extension +4. Mbstring PHP Extension +5. Composer + +##Install Laravel: + +Run `composer global require "laravel/installer"` + +The command above will install laravel via Laravel Installer. In order to have global access, we need to export its path. +So for this, follow below instructions : + +1. Open your shell. (In my case bash shell) +2. open .bashrc +3. Add **export PATH="$PATH:$HOME/.config/composer/vendor/bin"** at the end of file. +4. Run source ~/.bashrc + + +##Instructions: + +1. Repository setup + * Fork the Repository at https://github.com/LibreHealthIO/lh-ehr-laravel-port.git + * Clone your fork of the Repository from your GitHub account at https://github.com/your_username/lh-ehr-laravel-port.git + - Command to clone fork: `git clone https://github.com/your_username/lh-ehr-laravel-port.git` + * Add your upstream and origin remotes + - command to add upstream --> `git remote add upstream https://github.com/LibreHealthIO/lh-ehr-laravel-port.git` + - command to add origin --> `git remote add origin https://github.com/your_username/lh-ehr-laravel-port.git` + +2. Ensure to have the following dependencies + * PHP 7.0 (7.0.* is required for LibreEHR) + * OpenSSL PHP Extension + * PDO PHP Extension + * Mbstring PHP Extension + * composer + +3. Installing Composer + * Run `sudo apt update` in the terminal. + * Run `sudo apt install curl php7.0-cli php7.0-mbstring git unzip` + * `cd~` + * `curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer` + * Test the installation by running `composer` in the terminal. + * Ensure that your home/'username'/.config/ folder is writtable. + +3. Run the command below to install Laravel globally via Laravel Installer + `composer global require "laravel/installer"` + +4. Now we have to add global access + * Open .bashrc by running this command `sudo gedit .bashrc`. Feel free to use anything other than gedit. You'll be prompted to enter your password. + * Add this line at the end of the file and save it + **PATH="$PATH:$HOME/.config/composer/vendor/bin"** + * Run this command after saving the .bashrc file + `source ~/.bashrc` + +5. Navigate to lh-ehr-laravel-port directory + `cd lh-ehr-laravel-port` + +6. Add your .env file by running this command: `cp .env.example .env` + +7. Add your .env file to .gitignore file. _It is already there, just check!_ + +8. Generate key for your application by running the command below + `php artisan key:generate` + Observe that the key is inserted in your .env file. + +9. Edit your database name, username and password in your .env file + DB_DATABASE = your_db_name + DB_USERNAME = your_username + DB_PASSWORD = your_password + + _For Report Generator's database_ + DB_REPORT_GENERATOR_DATABASE=homestead + DB_REPORT_GENERATOR_USERNAME=homestead + DB_REPORT_GENERATOR_PASSWORD=secret + + _For Main LibreEHR database_ + DB_LIBREEHR_DATABASE=homestead + DB_LIBREEHR_USERNAME=homestead + DB_LIBREEHR_PASSWORD=secret + +10. Now, you can create the database by running + `php artisan make:database` _Subsequently, this will create both databases automatically._ + + For now you have to create two databases manually. These databases should have the same + names as those specified in **DB_DATABASE** and **DB_REPORT_GENERATOR_DATABASE** + +11. Create tables by running + `php artisan module:migrate ReportGenerator` + + In case you want to do a refresh(rollback) of the database, use + `php artisan module:migrate-refresh ReportGenerator` OR + `php artisan module:migrate-rollback ReportGenerator` + +12. You can seed the database width + `php artisan db:seed` _This shouldn't work for now._ + If seeding fails, then use the [librereportgenerator.sql](Documentation/librereportgenerator.sql) file in this directory to import sample data. + +13. Start the application by running the command below in the terminal: + `php artisan serve` + +14. Head over to your browser and access [localhost:8000](http://localhost:8000) or 127.0.0.1:8000 + +15. You can also check your database at [phpMyAdmin](http://localhost/phpmyadmin/) + # License diff --git a/app/Console/Commands/CreateDatabase.php b/app/Console/Commands/CreateDatabase.php index 314de4d..af51264 100755 --- a/app/Console/Commands/CreateDatabase.php +++ b/app/Console/Commands/CreateDatabase.php @@ -8,16 +8,17 @@ use PDOException; /** - * This will create a command to create database. + * This will create a command to create databases. + * * @author Priyanshu Sinha + * Copyright 2018 Tigpezeghe Rodrige K. */ - class CreateDatabase extends Command { /** * The name and signature of the console command. - * + * * @var string */ protected $signature = 'make:database'; @@ -27,7 +28,7 @@ class CreateDatabase extends Command * * @var string */ - protected $description = 'Use this command to create database. Note that it will create the database configired in .env file. Self made command'; + protected $description = 'Use this command to create database. Note that it will create the database configured in .env file. Self made command'; /** * Create a new command instance. @@ -39,67 +40,75 @@ public function __construct() parent::__construct(); } - /** * Function to create PDO connection and return it. - * @param host name - * @param port number - * @param database user - * @param database password + * @param db_name Database name + * @param db_host Database hostname + * @param db_port Database port number + * @param db_username Database username + * @param db_password Database user's password * @return PDO connection. */ - private function getPDO($host, $port, $user_name, $db_password) + private function getPDO($db_host, $db_port, $db_username, $db_password) { - try - { - $connection = new PDO(sprintf('mysql:host = %s;port=%d', $host, $port), $user_name, $db_password); - $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - return $connection; - } - catch(PDOException $ex) - { - $this->error(sprintf('Oops! Some Error Occured... %s', $ex->getMessage())); - } + try { + $connection = new PDO(sprintf('mysql:host = %s;port=%d', $db_host, $db_port), $db_username, $db_password); + $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + return $connection; + } catch(PDOException $exception) { + $this->error(sprintf('Oops! Some Error Occured... %s', $exception->getMessage())); + } } /** - * Function to create databse. If database name is not specified in .env file, it will display the messasge and exits.Then it checks if database already exists + * Function to create databases. If database name is not specified in .env file, + * it will display the messasge and exits.Then it checks if database already exists + * If not, it will create database for it. It's used to create 2 dbs in handle method. + * @param db_name Database name + * @param db_host Database hostname + * @param db_port Database port number + * @param db_username Database username + * @param db_password Database user's password + * @return void + * @author 2018 Tigpezeghe Rodrige K. + */ + private function createDB($db_name, $db_host, $db_port, $db_username, $db_password) + { + /* LibreLaravel database creation logic. */ + if(!$db_name) { + $this->info('Database name is not specified in .env file. Please check that both database names are specified.'); + } else { + $pdo_instance = $this->getPDO($db_host, $db_port, $db_username, $db_password); + $check_db_exists = $pdo_instance->prepare('select count(*) from INFORMATION_SCHEMA.SCHEMATA where SCHEMA_NAME = :dbname'); + $check_db_exists->bindParam(':dbname', $db_name, PDO::PARAM_STR, 12); + $check_db_exists->execute(); + $check_db_exists->setFetchMode(PDO::FETCH_ASSOC); + /*If database exist it will return 1 else 0 in $check_db_exists variable. */ + if(!$check_db_exists->fetchColumn()) { + $pdo_instance->exec(sprintf('CREATE DATABASE IF NOT EXISTS %s;', $db_name)); + $this->info(sprintf('Created Database %s Successfully. Run migrations to install tables.', $db_name)); + } else { + $this->info(sprintf('Database %s already exists. Migrate the tables.', $db_name)); + } + } + } + + /** + * Function to create databases. If database name is not specified in .env file, it will display the messasge and exits.Then it checks if database already exists * If not then it will create database for it. * @param None - * @return void + * @return void */ - public function handle() { - /* Take the database configuration from .env file. */ - $databaseName = env('DB_DATABASE', false); - $databaseHost = env('DB_HOST'); - $databasePort = env('DB_PORT'); - $databaseUser = env('DB_USERNAME'); - $databasePassword = env('DB_PASSWORD'); + /** librelaravel database creation logic. + * @TODO: Uncomment the line below when EHR is in full Laravel mode. + * That is, when the EHR has been completely ported to Laravel. + */ + //$this->createDB(env('DB_DATABASE'), env('DB_HOST'), env('DB_PORT'), env('DB_USERNAME'), env('DB_PASSWORD')); - /*Database creation logic.*/ - if(!$databaseName) - { - $this->info('No database name specified in .env file. Please check it.'); - } - else - { - $pdoInstance = $this->getPDO($databaseHost, $databasePort, $databaseUser, $databasePassword); - $checkDBExists = $pdoInstance->prepare('select count(*) from INFORMATION_SCHEMA.SCHEMATA where SCHEMA_NAME = :dbname'); - $checkDBExists->bindParam(':dbname', $databaseName, PDO::PARAM_STR, 12); - $checkDBExists->execute(); - $checkDBExists->setFetchMode(PDO::FETCH_ASSOC); - /*If database exist it will return 1 else 0*/ - if(!$checkDBExists->fetchColumn()) - { - $pdoInstance->exec(sprintf('CREATE DATABASE IF NOT EXISTS %s;', $databaseName)); - $this->info(sprintf('Created Database %s Successfully. Run migrations to install tables.', $databaseName)); - } - else - { - $this->info(sprintf('Database Already Created. Migrate the tables.')); - } - } + /* librereportgenerator database creation logic. */ + $this->createDB(env('DB_REPORT_GENERATOR_DATABASE'), env('DB_REPORT_GENERATOR_HOST'), env('DB_REPORT_GENERATOR_PORT'), env('DB_REPORT_GENERATOR_USERNAME'), env('DB_REPORT_GENERATOR_PASSWORD')); } + } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 35471f6..7021981 100755 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use Illuminate\Support\Facades\Schema; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -13,7 +14,7 @@ class AppServiceProvider extends ServiceProvider */ public function boot() { - // + Schema::defaultStringLength(191); } /** diff --git a/composer.lock b/composer.lock index 6eb62fa..74561a7 100644 --- a/composer.lock +++ b/composer.lock @@ -370,16 +370,16 @@ }, { "name": "laravel/tinker", - "version": "v1.0.6", + "version": "v1.0.7", "source": { "type": "git", "url": "https://github.com/laravel/tinker.git", - "reference": "b22fe905fcefdffae76b011e27c7ac09e07e052b" + "reference": "e3086ee8cb1f54a39ae8dcb72d1c37d10128997d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/b22fe905fcefdffae76b011e27c7ac09e07e052b", - "reference": "b22fe905fcefdffae76b011e27c7ac09e07e052b", + "url": "https://api.github.com/repos/laravel/tinker/zipball/e3086ee8cb1f54a39ae8dcb72d1c37d10128997d", + "reference": "e3086ee8cb1f54a39ae8dcb72d1c37d10128997d", "shasum": "" }, "require": { @@ -429,20 +429,20 @@ "laravel", "psysh" ], - "time": "2018-04-16T12:10:37+00:00" + "time": "2018-05-17T13:42:07+00:00" }, { "name": "league/flysystem", - "version": "1.0.44", + "version": "1.0.45", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "168dbe519737221dc87d17385cde33073881fd02" + "reference": "a99f94e63b512d75f851b181afcdf0ee9ebef7e6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/168dbe519737221dc87d17385cde33073881fd02", - "reference": "168dbe519737221dc87d17385cde33073881fd02", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a99f94e63b512d75f851b181afcdf0ee9ebef7e6", + "reference": "a99f94e63b512d75f851b181afcdf0ee9ebef7e6", "shasum": "" }, "require": { @@ -513,7 +513,7 @@ "sftp", "storage" ], - "time": "2018-04-06T09:58:14+00:00" + "time": "2018-05-07T08:44:23+00:00" }, { "name": "monolog/monolog", @@ -639,16 +639,16 @@ }, { "name": "nesbot/carbon", - "version": "1.27.0", + "version": "1.29.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "ef81c39b67200dcd7401c24363dcac05ac3a4fe9" + "reference": "b1cc4493fafb1b1402d50474fe6305e0558c6829" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/ef81c39b67200dcd7401c24363dcac05ac3a4fe9", - "reference": "ef81c39b67200dcd7401c24363dcac05ac3a4fe9", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/b1cc4493fafb1b1402d50474fe6305e0558c6829", + "reference": "b1cc4493fafb1b1402d50474fe6305e0558c6829", "shasum": "" }, "require": { @@ -683,7 +683,7 @@ "datetime", "time" ], - "time": "2018-04-23T09:02:57+00:00" + "time": "2018-05-24T13:09:20+00:00" }, { "name": "nikic/php-parser", @@ -902,16 +902,16 @@ }, { "name": "psy/psysh", - "version": "v0.9.3", + "version": "v0.9.4", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "79c280013cf0b30fa23f3ba8bd3649218075adf4" + "reference": "4d969a0e08e1e05e7207c07cb4207017ecc9a331" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/79c280013cf0b30fa23f3ba8bd3649218075adf4", - "reference": "79c280013cf0b30fa23f3ba8bd3649218075adf4", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/4d969a0e08e1e05e7207c07cb4207017ecc9a331", + "reference": "4d969a0e08e1e05e7207c07cb4207017ecc9a331", "shasum": "" }, "require": { @@ -923,9 +923,9 @@ "symfony/var-dumper": "~2.7|~3.0|~4.0" }, "require-dev": { + "bamarni/composer-bin-plugin": "^1.2", "hoa/console": "~2.15|~3.16", - "phpunit/phpunit": "~4.8.35|~5.0|~6.0|~7.0", - "symfony/finder": "~2.1|~3.0|~4.0" + "phpunit/phpunit": "~4.8.35|~5.0|~6.0|~7.0" }, "suggest": { "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", @@ -970,7 +970,7 @@ "interactive", "shell" ], - "time": "2018-04-18T12:32:50+00:00" + "time": "2018-05-22T06:48:07+00:00" }, { "name": "ramsey/uuid", @@ -1108,16 +1108,16 @@ }, { "name": "symfony/console", - "version": "v3.4.9", + "version": "v3.4.11", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "5b1fdfa8eb93464bcc36c34da39cedffef822cdf" + "reference": "36f83f642443c46f3cf751d4d2ee5d047d757a27" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/5b1fdfa8eb93464bcc36c34da39cedffef822cdf", - "reference": "5b1fdfa8eb93464bcc36c34da39cedffef822cdf", + "url": "https://api.github.com/repos/symfony/console/zipball/36f83f642443c46f3cf751d4d2ee5d047d757a27", + "reference": "36f83f642443c46f3cf751d4d2ee5d047d757a27", "shasum": "" }, "require": { @@ -1173,20 +1173,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-04-30T01:22:56+00:00" + "time": "2018-05-16T08:49:21+00:00" }, { "name": "symfony/css-selector", - "version": "v3.4.9", + "version": "v3.4.11", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "519a80d7c1d95c6cc0b67f686d15fe27c6910de0" + "reference": "d2ce52290b648ae33b5301d09bc14ee378612914" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/519a80d7c1d95c6cc0b67f686d15fe27c6910de0", - "reference": "519a80d7c1d95c6cc0b67f686d15fe27c6910de0", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/d2ce52290b648ae33b5301d09bc14ee378612914", + "reference": "d2ce52290b648ae33b5301d09bc14ee378612914", "shasum": "" }, "require": { @@ -1226,20 +1226,20 @@ ], "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", - "time": "2018-03-19T22:32:39+00:00" + "time": "2018-05-16T12:49:49+00:00" }, { "name": "symfony/debug", - "version": "v3.4.9", + "version": "v3.4.11", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "1b95888cfd996484527cb41e8952d9a5eaf7454f" + "reference": "b28fd73fefbac341f673f5efd707d539d6a19f68" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/1b95888cfd996484527cb41e8952d9a5eaf7454f", - "reference": "1b95888cfd996484527cb41e8952d9a5eaf7454f", + "url": "https://api.github.com/repos/symfony/debug/zipball/b28fd73fefbac341f673f5efd707d539d6a19f68", + "reference": "b28fd73fefbac341f673f5efd707d539d6a19f68", "shasum": "" }, "require": { @@ -1282,11 +1282,11 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2018-04-30T16:53:52+00:00" + "time": "2018-05-16T14:03:39+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v3.4.9", + "version": "v3.4.11", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -1349,16 +1349,16 @@ }, { "name": "symfony/finder", - "version": "v3.4.9", + "version": "v3.4.11", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "bd14efe8b1fabc4de82bf50dce62f05f9a102433" + "reference": "472a92f3df8b247b49ae364275fb32943b9656c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/bd14efe8b1fabc4de82bf50dce62f05f9a102433", - "reference": "bd14efe8b1fabc4de82bf50dce62f05f9a102433", + "url": "https://api.github.com/repos/symfony/finder/zipball/472a92f3df8b247b49ae364275fb32943b9656c6", + "reference": "472a92f3df8b247b49ae364275fb32943b9656c6", "shasum": "" }, "require": { @@ -1394,20 +1394,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-04-04T05:07:11+00:00" + "time": "2018-05-16T08:49:21+00:00" }, { "name": "symfony/http-foundation", - "version": "v3.4.9", + "version": "v3.4.11", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "edc43b1a50402bb06b5111eb86b275c87a93e373" + "reference": "a7b5fc605d1c215cea1122359044b1e682eb70c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/edc43b1a50402bb06b5111eb86b275c87a93e373", - "reference": "edc43b1a50402bb06b5111eb86b275c87a93e373", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/a7b5fc605d1c215cea1122359044b1e682eb70c0", + "reference": "a7b5fc605d1c215cea1122359044b1e682eb70c0", "shasum": "" }, "require": { @@ -1448,20 +1448,20 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2018-04-30T01:05:13+00:00" + "time": "2018-05-25T11:07:31+00:00" }, { "name": "symfony/http-kernel", - "version": "v3.4.9", + "version": "v3.4.11", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "280fcedbcb3dabcc467a9c1734054af61928fe4f" + "reference": "3dac45df55ee0c5134c457a730cd68e2a2ce0445" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/280fcedbcb3dabcc467a9c1734054af61928fe4f", - "reference": "280fcedbcb3dabcc467a9c1734054af61928fe4f", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/3dac45df55ee0c5134c457a730cd68e2a2ce0445", + "reference": "3dac45df55ee0c5134c457a730cd68e2a2ce0445", "shasum": "" }, "require": { @@ -1469,7 +1469,8 @@ "psr/log": "~1.0", "symfony/debug": "~2.8|~3.0|~4.0", "symfony/event-dispatcher": "~2.8|~3.0|~4.0", - "symfony/http-foundation": "^3.4.4|^4.0.4" + "symfony/http-foundation": "^3.4.4|^4.0.4", + "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/config": "<2.8", @@ -1536,7 +1537,62 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2018-04-30T19:27:02+00:00" + "time": "2018-05-25T13:16:28+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2018-04-30T19:57:29+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -1658,16 +1714,16 @@ }, { "name": "symfony/process", - "version": "v3.4.9", + "version": "v3.4.11", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "4b7d64e852886319e93ddfdecff0d744ab87658b" + "reference": "4cbf2db9abcb01486a21b7a059e03a62fae63187" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/4b7d64e852886319e93ddfdecff0d744ab87658b", - "reference": "4b7d64e852886319e93ddfdecff0d744ab87658b", + "url": "https://api.github.com/repos/symfony/process/zipball/4cbf2db9abcb01486a21b7a059e03a62fae63187", + "reference": "4cbf2db9abcb01486a21b7a059e03a62fae63187", "shasum": "" }, "require": { @@ -1703,20 +1759,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-04-03T05:22:50+00:00" + "time": "2018-05-16T08:49:21+00:00" }, { "name": "symfony/routing", - "version": "v3.4.9", + "version": "v3.4.11", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "9deb375986f5d1f37283d8386716d26985a0f4b6" + "reference": "e382da877f5304aabc12ec3073eec430670c8296" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/9deb375986f5d1f37283d8386716d26985a0f4b6", - "reference": "9deb375986f5d1f37283d8386716d26985a0f4b6", + "url": "https://api.github.com/repos/symfony/routing/zipball/e382da877f5304aabc12ec3073eec430670c8296", + "reference": "e382da877f5304aabc12ec3073eec430670c8296", "shasum": "" }, "require": { @@ -1781,20 +1837,20 @@ "uri", "url" ], - "time": "2018-04-12T09:01:03+00:00" + "time": "2018-05-16T12:49:49+00:00" }, { "name": "symfony/translation", - "version": "v3.4.9", + "version": "v3.4.11", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "d4af50f46cd8171fd5c1cdebdb9a8bbcd8078c6c" + "reference": "7047f725e35eab768137c677f8c38e4a2a8e38fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/d4af50f46cd8171fd5c1cdebdb9a8bbcd8078c6c", - "reference": "d4af50f46cd8171fd5c1cdebdb9a8bbcd8078c6c", + "url": "https://api.github.com/repos/symfony/translation/zipball/7047f725e35eab768137c677f8c38e4a2a8e38fb", + "reference": "7047f725e35eab768137c677f8c38e4a2a8e38fb", "shasum": "" }, "require": { @@ -1849,11 +1905,11 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2018-04-30T01:22:56+00:00" + "time": "2018-05-21T10:06:52+00:00" }, { "name": "symfony/var-dumper", - "version": "v3.4.9", + "version": "v3.4.11", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", @@ -3398,20 +3454,21 @@ }, { "name": "symfony/yaml", - "version": "v3.4.9", + "version": "v3.4.11", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "033cfa61ef06ee0847e056e530201842b6e926c3" + "reference": "c5010cc1692ce1fa328b1fb666961eb3d4a85bb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/033cfa61ef06ee0847e056e530201842b6e926c3", - "reference": "033cfa61ef06ee0847e056e530201842b6e926c3", + "url": "https://api.github.com/repos/symfony/yaml/zipball/c5010cc1692ce1fa328b1fb666961eb3d4a85bb0", + "reference": "c5010cc1692ce1fa328b1fb666961eb3d4a85bb0", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/console": "<3.4" @@ -3452,7 +3509,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2018-04-08T08:21:29+00:00" + "time": "2018-05-03T23:18:14+00:00" }, { "name": "webmozart/assert", diff --git a/config/database.php b/config/database.php index cab5d06..11afc85 100644 --- a/config/database.php +++ b/config/database.php @@ -39,6 +39,7 @@ 'prefix' => '', ], + # Primary database connection 'mysql' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), @@ -54,6 +55,38 @@ 'engine' => null, ], + # ReportGenerator database connection + 'mysql_report_generator' => [ + 'driver' => 'mysql', + 'host' => env('DB_REPORT_GENERATOR_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_REPORT_GENERATOR_DATABASE', 'forge'), + 'username' => env('DB_REPORT_GENERATOR_USERNAME', 'forge'), + 'password' => env('DB_REPORT_GENERATOR_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => 'utf8mb4', + 'collation' => 'utf8mb4_unicode_ci', + 'prefix' => '', + 'strict' => true, + 'engine' => null, + ], + + # LibreHealthEHR database connection + 'mysql_libreehr' => [ + 'driver' => 'mysql', + 'host' => env('DB_LIBREEHR_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_LIBREEHR_DATABASE', 'forge'), + 'username' => env('DB_LIBREEHR_USERNAME', 'forge'), + 'password' => env('DB_LIBREEHR_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => 'utf8mb4', + 'collation' => 'utf8mb4_unicode_ci', + 'prefix' => '', + 'strict' => true, + 'engine' => null, + ], + 'pgsql' => [ 'driver' => 'pgsql', 'host' => env('DB_HOST', '127.0.0.1'), diff --git a/database/factories/PatientDataFactory.php b/database/factories/PatientDataFactory.php index cca90da..3eb91dd 100755 --- a/database/factories/PatientDataFactory.php +++ b/database/factories/PatientDataFactory.php @@ -5,7 +5,7 @@ | Patient Data Factory |-------------------------------------------------------------------------- | -| Use this to generate fake data for patient_datas table. +| Use this to generate fake data for patient_datas table. | Further used in PatientDataTableSeeder.phpr.php. | @author Priyanshu Sinha | @@ -18,7 +18,7 @@ $industry = array('Law Firm', 'Engineering Firm', 'Construction Firm', 'College'); //Add if any new industry is added in UI return [ 'pid' => $faker->unique()->randomNumber($nbDigits = 4, $strict = false), - 'title' => $faker->title($gender = null|'mail'|'female'), + 'title' => $faker->title($gender = null|'male'|'female'), 'occupation' => $occupation[array_rand($occupation, 1)], 'industry' => $industry[array_rand($industry, 1)], 'addressId' => factory(App\Address::class)->create()->id, diff --git a/database/migrations/2018_05_18_085927_create_list_options_table.php b/database/migrations/2018_05_18_085927_create_list_options_table.php new file mode 100644 index 0000000..391ba70 --- /dev/null +++ b/database/migrations/2018_05_18_085927_create_list_options_table.php @@ -0,0 +1,49 @@ + (2018) + * @return void + */ + public function up() + { + Schema::create('list_options', function (Blueprint $table) { + $table->increments('id')->comment = "Primary Key. Autoincrement."; + $table->string('list_id', 31)->comment = "List Id."; + $table->string('option_id', 31)->comment = "Id for list item."; + $table->string('title', 255)->comment = "The title of the component."; + $table->integer('seq', 0)->comment = "The order in which the components appear in the list."; + $table->boolean('is_default')->default(0)->comment = "0 -> False, 1 -> True."; + $table->float('option_value', 8, 2)->default(0)->comment = ""; + $table->string('mapping', 31)->comment = ""; + $table->string('notes', 255)->comment = "This stores the meaning or usefulness of the component."; + $table->string('codes', 255)->comment = ""; + $table->boolean('toggle_setting_1')->default(0)->comment = "0 -> False, 1 -> True."; + $table->boolean('toggle_setting_2')->default(0)->comment = "0 -> False, 1 -> True."; + $table->boolean('activity')->default(1)->comment = "0 -> False, 1 -> True whether the component should be active or not."; + $table->string('subtype', 31)->comment = ""; + + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('list_options'); + } +} diff --git a/public/assets/css/master.css b/public/assets/css/master.css index f7fbd22..e016e8a 100644 --- a/public/assets/css/master.css +++ b/public/assets/css/master.css @@ -1,3 +1,15 @@ +/* +|-------------------------------------------------------------------------- +| Report generator master CSS file. +|-------------------------------------------------------------------------- +| +| This is the main CSS file for the report generator. +| Basically, most of styling of the module is done here. +| @author: Tigpezeghe Rodrige K. +| +| Copyright 2018 Tigpezeghe Rodrige K. +| +*/ #second { height: 250px; } @@ -6,7 +18,7 @@ text-align: center; } -#draggable{ +.draggable{ max-width: 24.5%; height: 50px; border: 1px solid lightgrey; @@ -19,3 +31,28 @@ margin-top: -7px; margin-bottom: -7px; } +#draggable-column { + /* overflow: auto; */ + height: 500px; +} + +/* Wrap and break the draggable components' titles. */ +.wordwrap { + padding: 3px; + width: 130px; + word-break: break-all; + word-wrap: break-word; + overflow: hidden; +} + +/* Wrap and break the cells' data in generated report. */ +.table-wordwrap { + max-width: 250px !important; + word-break: break-all; + word-wrap: break-word; + overflow: hidden; +} + +thead { + background-color:#ccc !important +} diff --git a/public/assets/js/master.js b/public/assets/js/master.js index 77a314e..e0b3aa5 100644 --- a/public/assets/js/master.js +++ b/public/assets/js/master.js @@ -1,18 +1,183 @@ -$( function(){ - $('.col-sm-3').draggable({ - addClasses: true - }); +/* +|-------------------------------------------------------------------------- +| Report generator master Javascript (JQuery) file. +|-------------------------------------------------------------------------- +| +| This is the main JS file for the report generator. +| Basically, all Javascript work for the module is here. +| @author: Tigpezeghe Rodrige K. +| +| Copyright 2018 Tigpezeghe Rodrige K. +| +*/ +var IDs = []; // array to store the IDs of dropped components. + +$(function() { + $('.col-sm-2').draggable({ + revert: 'invalid', + addClasses: true + }); + + var addClasses = $('.col-sm-2').draggable("option", "addClasses"); + + $('#second').droppable({ + drop: function(event, ui) { // when a component is dropped + var title = $(ui.draggable).find("p").attr("title"); + var id = (ui.draggable).attr("id"); + $(this) + .addClass('ui-state-highlight') // 1. add this jquery class + .css('background-color', '#fd7e14') // 2. change 'dropbox' background color + .find('p') // 3. get the text in the 'dropbox' + .html("Dropped " + title) // 4. replace it with name of dropped component + .html(); + if(!IDs.includes(id)){ // Display component's title only if it hasn't already been dropped + $('#selected-list').append('

    ' + title + '

    '); // add the title of the dropped component at the bottom of the drop box + } else { + alert("ALERT: You can't drop a component more than once!!!") + } + //ui.draggable.draggable( 'option', 'revert', true ); + $(ui.draggable).addClass('ui-state-highlight'); + console.log('Dragged: ' + title); + IDs.push((ui.draggable).attr("id")); // Push the id of the dropped component to the IDs array + }, + out: function(event, ui) { // when an accepted draggable component is dragged out of the drop box (droppable) + var title = $(ui.draggable).find("p").attr("title"); + var id = (ui.draggable).attr("id"); + $(this) + .removeClass('ui-state-highlight') + //.css('background-color', 'white') + .find('p') + .html("Removed " + title) + .html(); + $(ui.draggable).removeClass('ui-state-highlight'); + console.log('Removed: ' + title); + IDs.splice( IDs.indexOf(id), 1 ); // Delete draggable component when it's removed from drop box + $('#removed-' + id).remove(); // Delete the title of the removed component at the bottom of the drop box + if(jQuery.isEmptyObject(IDs)){ // Change color of drop box to white when all dragged components are removed + $(this).css('background-color', 'white'); + } + } + }); + /* this will prevent drop on section + $( ".container" ).droppable({ + drop: function( event, ui ) { + ui.draggable.draggable( 'option', 'revert', true ); + } + });*/ +}); + +/* This function gets the IDs of all (unique) dropped components and displays them. + * @params: array: IDs + * @return: Display these IDs + */ +function generate(IDs) { + var option_ids = IDs.filter(function(item, i, IDs) { + return i == IDs.indexOf(item); + }); + console.log(option_ids); + $.ajaxSetup({ + headers: { + 'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content') + } + }); + $.ajax({ + url: 'reportgenerator/generate', + type: 'get', + data: { ids: option_ids }, + dataType: 'json', + success: function(response){ + console.log(response); + //alert("You've successfully sent the unique ids"); + jQuery('.alert').show(); + jQuery('.alert').html(response.option_ids); + window.location.href = response.redirecturl; // your action should return an object having [redirecturl] property + }, + error: function (httpRequest, textStatus, errorThrown) { // detailed error messsage + alert("Error: " + textStatus + " " + errorThrown + " " + httpRequest); + } + }); +} + +/* This function prints the report. + * @params: DOM element: report_div + * @return: Boolean: True + */ +function printReport(report_div) { + var mywindow = window.open('', 'PRINT', 'height=400,width=600'); + + mywindow.document.write('' + document.title + ''); + mywindow.document.write(''); + mywindow.document.write('

    ' + document.title + '

    '); + mywindow.document.write(document.getElementById(report_div).innerHTML); + mywindow.document.write(''); + + //mywindow.document.write(''); + + mywindow.document.close(); // necessary for IE >= 10 + mywindow.focus(); // necessary for IE >= 10*/ + + setTimeout(function() { // This is for large documents + mywindow.close(); + }, 10); - var addClasses = $('.col-sm-3').draggable("option", "addClasses"); - $('#second').droppable({ - drop: function(event, ui){ - $(this) - .addClass('ui-state-highlight') - .find('p') - .html("Dropped " + $(ui.draggable).attr("id")); - $(ui.draggable).addClass('ui-state-highlight'); - //$(ui.draggable).draggable('disable'); - console.log('Dragged: ' + $(ui.draggable).attr("id")); + mywindow.print(); + mywindow.close(); + + return true; +} + +$(document).ready(function() { + /*** generate report from dropped components ***/ + $('#generate-button').click(function(e) { + e.preventDefault(); + if (jQuery.isEmptyObject(IDs)) { // check if the user has dropped any component before trying to generate a report + alert("Cannot generate a blank report! You must add at least one component."); + } else { + generate(IDs); // Call the generate function above when the generate button is clicked } }); + + /*** Edit system feature ***/ + $('#edit-system-feature').on('show.bs.modal', function(e){ + $('#edit-system-feature #feature_name').val($(e.relatedTarget).data('feature_name')); + $('#edit-system-feature #description').val($(e.relatedTarget).data('description')); + $('#edit-system-feature-form').submit(function(){ + var id = $('#edit-system-feature #id').val($(e.relatedTarget).data('id')); + $("#edit-system-feature-form").attr("action", "system_feature/" + id); + }); + }); + + /*** Delete system feature ***/ + $('#delete-system-feature').on('show.bs.modal', function(e){ + $('#delete-system-feature #feature_name').text($(e.relatedTarget).data('feature_name')); + $('#delete-system-feature-form').submit(function(){ + var id = $('#delete-system-feature #id').val($(e.relatedTarget).data('id')); + $("#delete-system-feature-form").attr("action", "system_feature/" + id); + }); + }); + + /*** Edit report format ***/ + $('#edit-report-format').on('show.bs.modal', function(e){ + $('#edit-report-format #title').val($(e.relatedTarget).data('title')); + $('#edit-report-format #description').val($(e.relatedTarget).data('description')); + $('#edit-report-format #system_feature_id').select($(e.relatedTarget).data('system_feature_id')); + $('#edit-report-format-form').submit(function(){ + var id = $('#edit-report-format #id').val($(e.relatedTarget).data('id')); + $("#edit-report-format-form").attr("action", "report_format/" + id); + }); + }); + + /*** Delete report format ***/ + $('#delete-report-format').on('show.bs.modal', function(e){ + $('#delete-report-format #title').text($(e.relatedTarget).data('title')); + $('#delete-report-format-form').submit(function(){ + var id = $('#delete-report-format #id').val($(e.relatedTarget).data('id')); + $("#delete-report-format-form").attr("action", "report_format/" + id); + }); + }); + + /*** Hide alert messsage after 30 seconds ***/ + setTimeout(function(){ + $("#alert").hide(); + }, 10000); });