-
Notifications
You must be signed in to change notification settings - Fork 105
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
6337: Feat: merge ODK central work r=jmcameron a=jniles This PR adds in [ODK Central](https://docs.getodk.org/central-install/) functionality to the BHIMA server. Here is what the ODK administration interface looks like: ![image](https://user-images.githubusercontent.com/896472/150951277-34cf068b-9eca-4363-a485-ad135ad18df1.png) You'll need to set your own username/password and ODK Central URL to test it out. This installation is very bare-bones. The way this works is somewhat documented in #6235 (comment). This PR is plucked from work done by `@jniles` and `@mbayopanda` in `sprint-prosani`. Closes #6235. Closes #6302. Closes #6322. --- **TESTING** (based on session with `@jniles` ) - Use bhima test (rebuild db, etc) - Go to Administration > ODK Settings - Enter the ODK Central login credentials in the left-most panel (ODK Integration Settings) - In the middle panel, click on - Synchronize enterprise settings - Synchronize users - Synchronize forms - Go to Adminstration > User Management - In the action menu for Superuser, click on the [ODK QR Code] link to display the QR code (leave it up on your screen) - On your mobile phone - If you have not installed ODK Collect, do that - In ODK Collect, click on the [Configure with QR code] button on the entry screen. This should bring up the "Test Enterprise" page - Click on [Get Blank Form]. It should show that it has downloaded a form - On the bottom right of the page, click on the [Get Selected] button. This downloads the form and sends you back to the "Test Enterprise" page. - Click on [Fill Blank Form] and select the form. This should start filling out the form. - Fill out the form - For Nombre des articles, enter 1 - For the barcode, first go to Bhima (Stock Lots) and display the barcode for lot VITAMIN-A. Then scan that barcode with your phone. When you click next, it should show the lot you selected. - Finish the form ([X] Mark form as finalize, press [Save Form and Exit]) - Back on the "Test Enterprise" page, click [Send Finalized Form]. Select the form you just completed and press [Send Selected] on the bottom right of the page. - Back on Bhima go to Administration > ODK Settings - Click on: Synchronize Submissions [Sync] - Go to Stock > Stock Movements and verify that you have a new stock entry in Depot Tertiaire Co-authored-by: Jonathan Niles <jonathanwniles@gmail.com>
- Loading branch information
Showing
25 changed files
with
1,088 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"ODK" : { | ||
"CONFIG_SETTINGS" : "ODK Central Configuration", | ||
"NO_CONFIGURATION_SET" : "There is no ODK Central configuration set up. To get started, add a username, password, and the ODK Central URL.", | ||
"IMPORTED_SUCCESSFULLY" : "Records successfully imported", | ||
"LOAD_FOSA_DATA" : "Load data of FOSA", | ||
"NO_RECORD_FOUND" : "No record found", | ||
"ODK_ADMIN_PASSWORD" : "ODK Central Admin Password", | ||
"ODK_ADMIN_USER" : "ODK Central Admin Email", | ||
"ODK_CENTRAL_URL" : "ODK Central Server URL", | ||
"ODK_INTEGRATION_SETTINGS" : "ODK Integration Settings", | ||
"PROJECT_DETAILS" : "Project Details", | ||
"PROJECT_FORMS" : "Number of Forms", | ||
"PROJECT_ID" : "Project ID", | ||
"PROJECT_NAME" : "Project Name", | ||
"QRCODE" : "ODK QR Code", | ||
"SHOW_QRCODE" : "Show QR Code", | ||
"SYNC_ENTERPRISE" : "Synchronize enterprise settings", | ||
"SYNC_FORMS" : "Synchronize forms", | ||
"SYNC_SETTINGS" : "Synchronization Settings", | ||
"SYNC_SUBMISSIONS" : "Synchronize submissions", | ||
"SYNC_USERS" : "Synchronize users", | ||
"TOTAL_APP_USERS" : "Number of App Users", | ||
"TOTAL_FOUND" : "Total records found" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"ODK" : { | ||
"CONFIG_SETTINGS" : "ODK Central Configuration", | ||
"NO_CONFIGURATION_SET" : "Aucune configuration ODK Central n'est configurée. Pour commencer, ajoutez un nom d'utilisateur, un mot de passe et l'URL d'ODK Central.", | ||
"IMPORTED_SUCCESSFULLY" : "Données importées avec succès", | ||
"LOAD_FOSA_DATA" : "Chargement des données des FOSA", | ||
"NO_RECORD_FOUND" : "Aucun enregistrement trouvé", | ||
"ODK_ADMIN_PASSWORD" : "Mot de passe de l'administrateur", | ||
"ODK_ADMIN_USER" : "Adressse mail de l'administrateur", | ||
"ODK_CENTRAL_URL" : "URL du serveur ODK Central", | ||
"ODK_INTEGRATION_SETTINGS" : "Paramètres d'intégration ODK", | ||
"PROJECT_DETAILS" : "Détails du projet", | ||
"PROJECT_FORMS" : "Nombre de formulaire", | ||
"PROJECT_ID" : "ID Projet", | ||
"PROJECT_NAME" : "Nom du projet", | ||
"QRCODE" : "ODK QR Code", | ||
"SHOW_QRCODE" : "Afficher QR Code", | ||
"SYNC_ENTERPRISE" : "Synchroniser les paramètres d'entreprise", | ||
"SYNC_FORMS" : "Synchroniser les formulaires", | ||
"SYNC_SETTINGS" : "Synchroniser les paramètres", | ||
"SYNC_SUBMISSIONS" : "Synchroniser les soumissions des formulaires", | ||
"SYNC_USERS" : "Synchroniser les utilisateurs", | ||
"TOTAL_APP_USERS" : "Nombre des utilisateurs mobiles", | ||
"TOTAL_FOUND" : "Total des enregistrements trouvés" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
<div class="flex-header"> | ||
<div class="bhima-title"> | ||
<ol class="headercrumb"> | ||
<li class="static" translate>TREE.ADMIN</li> | ||
<li class="title" translate>TREE.ODK_SETTINGS</li> | ||
</ol> | ||
</div> | ||
</div> | ||
|
||
<div class="flex-content"> | ||
<div class="container-fluid"> | ||
<div class="col-xs-12 col-md-6 col-lg-4"> | ||
<form | ||
name="ODKSettingsForm" | ||
bh-submit="ODKSettingsCtrl.submit(ODKSettingsForm)" | ||
ng-model-options="{ updateOn: 'blur' }" novalidate> | ||
<div class="panel panel-primary"> | ||
<div class="panel-heading"> | ||
<i class="fa fa-server"></i> | ||
<span translate>ODK.ODK_INTEGRATION_SETTINGS</span> | ||
</div> | ||
<div class="panel-body"> | ||
<div class="form-group" ng-class="{ 'has-error' : ODKSettingsForm.$submitted && ODKSettingsForm.odk_central_url.$invalid }"> | ||
<label class="control-label" translate>ODK.ODK_CENTRAL_URL</label> | ||
<input | ||
type="text" | ||
class="form-control" | ||
name="odk_central_url" | ||
ng-model="ODKSettingsCtrl.settings.odk_central_url" | ||
autocomplete="off"> | ||
<div class="help-block" ng-messages="ODKSettingsForm.odk_central_url.$error" ng-show="ODKSettingsForm.$submitted"> | ||
<div ng-messages-include="modules/templates/messages.tmpl.html"></div> | ||
</div> | ||
</div> | ||
|
||
<div class="form-group" ng-class="{ 'has-error' : ODKSettingsForm.$submitted && ODKSettingsForm.odk_admin_user.$invalid }"> | ||
<label class="control-label" translate>ODK.ODK_ADMIN_USER</label> | ||
<input | ||
type="email" | ||
class="form-control" | ||
name="odk_admin_user" | ||
ng-model="ODKSettingsCtrl.settings.odk_admin_user" | ||
autocomplete="off" | ||
ng-required="!!ODKSettingsCtrl.settings.odk_central_url"> | ||
<div class="help-block" ng-messages="ODKSettingsForm.odk_admin_user.$error" ng-show="ODKSettingsForm.$submitted"> | ||
<div ng-messages-include="modules/templates/messages.tmpl.html"></div> | ||
</div> | ||
</div> | ||
|
||
<div class="form-group" ng-class="{ 'has-error' : ODKSettingsForm.$submitted && ODKSettingsForm.odk_admin_password.$invalid }"> | ||
<label class="control-label" translate>ODK.ODK_ADMIN_PASSWORD</label> | ||
<input | ||
type="password" | ||
class="form-control" | ||
name="odk_admin_password" | ||
ng-model="ODKSettingsCtrl.settings.odk_admin_password" | ||
autocomplete="off" | ||
ng-required="!!ODKSettingsCtrl.settings.odk_admin_user"> | ||
<div class="help-block" ng-messages="ODKSettingsForm.odk_admin_password.$error" ng-show="ODKSettingsForm.$submitted"> | ||
<div ng-messages-include="modules/templates/messages.tmpl.html"></div> | ||
</div> | ||
</div> | ||
</div> | ||
<div class="panel-footer text-right"> | ||
<bh-loading-button loading-state="ODKSettingsForm.$loading"> | ||
<span translate>FORM.BUTTONS.UPDATE</span> | ||
</bh-loading-button> | ||
</div> | ||
</div> | ||
</div> | ||
</form> | ||
|
||
|
||
<div class="col-xs-12 col-md-6 col-lg-4"> | ||
<div class="panel panel-danger"> | ||
<div class="panel-heading"> | ||
<i class="fa fa-cloud-upload"></i> | ||
<span translate>ODK.SYNC_SETTINGS</span> | ||
</div> | ||
|
||
<div class="panel-body"> | ||
<fieldset ng-disabled="ODKSettingsCtrl.loading"> | ||
<div class="form-group"> | ||
<label class="control-label" translate>ODK.SYNC_ENTERPRISE</label> | ||
<button type="button" class="btn btn-default btn-xs pull-right" ng-click="ODKSettingsCtrl.syncEnterprise()" translate>FORM.BUTTONS.SYNC</button> | ||
</div> | ||
|
||
<hr> | ||
|
||
<div class="form-group"> | ||
<label class="control-label" translate>ODK.SYNC_USERS</label> | ||
<button type="button" class="btn btn-default btn-xs pull-right" ng-click="ODKSettingsCtrl.syncAppUsers()" translate>FORM.BUTTONS.SYNC</button> | ||
</div> | ||
|
||
|
||
<hr> | ||
|
||
<div class="form-group"> | ||
<label class="control-label" translate>ODK.SYNC_FORMS</label> | ||
<button type="button" class="btn btn-default btn-xs pull-right" ng-click="ODKSettingsCtrl.syncForms()" translate>FORM.BUTTONS.SYNC</button> | ||
</div> | ||
|
||
<hr> | ||
|
||
<div class="form-group"> | ||
<label class="control-label" translate>ODK.SYNC_SUBMISSIONS</label> | ||
<button type="button" class="btn btn-default btn-xs pull-right" ng-click="ODKSettingsCtrl.syncSubmissions()" translate>FORM.BUTTONS.SYNC</button> | ||
</div> | ||
</fieldset> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<div class="col-xs-12 col-md-6 col-lg-4"> | ||
<div class="panel panel-success"> | ||
<div class="panel-heading"> | ||
<i class="fa fa-cogs"></i> | ||
<span translate>ODK.CONFIG_SETTINGS</span> | ||
</div> | ||
|
||
<div class="panel-body"> | ||
<div ng-show="ODKSettingsCtrl.loading" class="text-center"> | ||
<loading-indicator></loading-indicator> | ||
</div> | ||
|
||
<dl ng-hide="ODKSettingsCtrl.loading && ODKSettingsCtrl.hasODKConfiguration"> | ||
<dt translate>ODK.PROJECT_DETAILS</dt> | ||
<dd><span translate>ODK.PROJECT_NAME</span>: {{ODKSettingsCtrl.project.name}} </dd> | ||
<dd><span translate>ODK.PROJECT_ID</span>: {{ODKSettingsCtrl.project.id}} </dd> | ||
<dd><span translate>ODK.PROJECT_FORMS</span>: {{ODKSettingsCtrl.project.forms}} </dd> | ||
<dd><span translate>FORM.LABELS.CREATED</span>: {{ODKSettingsCtrl.project.createdAt | date}} </dd> | ||
<dd><span translate>ODK.TOTAL_APP_USERS</span>: {{ODKSettingsCtrl.appUsers.length | number}} </dd> | ||
</dl> | ||
|
||
<p ng-if="!ODKSettingsCtrl.loading && !ODKSettingsCtrl.hasODKConfiguration" translate> | ||
ODK.NO_CONFIGURATION_SET | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
angular.module('bhima.controllers') | ||
.controller('ODKSettingsController', ODKSettingsController); | ||
|
||
ODKSettingsController.$inject = [ | ||
'ODKSettingsService', 'util', 'NotifyService', 'SessionService', '$state', '$q', | ||
]; | ||
|
||
/** | ||
* ODK Settings Controller | ||
* | ||
* Provides configuration parameters for the link to ODK. | ||
*/ | ||
function ODKSettingsController( | ||
ODKSettings, util, Notify, Session, $state, $q, | ||
) { | ||
const vm = this; | ||
|
||
vm.enterprise = Session.enterprise; | ||
vm.settings = { }; | ||
|
||
vm.loading = false; | ||
|
||
function refreshSettings() { | ||
const settingsPromise = ODKSettings.read() | ||
.then(settings => { | ||
vm.hasODKConfiguration = settings.length > 0; | ||
if (vm.hasODKConfiguration) { | ||
[vm.settings] = settings; | ||
} | ||
}); | ||
|
||
const projectPromise = ODKSettings.getProjectSettings() | ||
.then(project => { | ||
vm.project = project; | ||
}); | ||
|
||
const appUsersPromise = ODKSettings.getAppUsers() | ||
.then(appUsers => { | ||
vm.appUsers = appUsers; | ||
}); | ||
|
||
vm.loading = true; | ||
$q.all([settingsPromise, projectPromise, appUsersPromise]) | ||
.catch(Notify.handleError) | ||
.finally(() => { vm.loading = false; }); | ||
} | ||
|
||
// bind methods | ||
vm.submit = submit; | ||
vm.syncEnterprise = () => { | ||
vm.loading = true; | ||
ODKSettings.syncEnterprise() | ||
.then(() => Notify.success('FORM.INFO.UPDATE_SUCCESS')) | ||
.then(() => refreshSettings()) | ||
.catch(Notify.handleError) | ||
.finally(() => { vm.loading = false; }); | ||
}; | ||
|
||
vm.syncAppUsers = () => { | ||
vm.loading = true; | ||
|
||
ODKSettings.syncAppUsers() | ||
.then(() => Notify.success('FORM.INFO.UPDATE_SUCCESS')) | ||
.then(() => refreshSettings()) | ||
.catch(Notify.handleError) | ||
.finally(() => { vm.loading = false; }); | ||
}; | ||
|
||
vm.syncForms = () => { | ||
vm.loading = true; | ||
ODKSettings.syncForms() | ||
.then(() => Notify.success('FORM.INFO.UPDATE_SUCCESS')) | ||
.then(() => refreshSettings()) | ||
.catch(Notify.handleError) | ||
.finally(() => { vm.loading = false; }); | ||
}; | ||
|
||
vm.syncSubmissions = () => { | ||
vm.loading = true; | ||
ODKSettings.syncSubmissions() | ||
.then(() => Notify.success('FORM.INFO.UPDATE_SUCCESS')) | ||
.then(() => refreshSettings()) | ||
.catch(Notify.handleError) | ||
.finally(() => { vm.loading = false; }); | ||
}; | ||
|
||
// fired on startup | ||
function startup() { | ||
refreshSettings(); | ||
} | ||
|
||
// form submission | ||
function submit(form) { | ||
vm.loading = true; | ||
if (form.$invalid) { | ||
Notify.danger('FORM.ERRORS.HAS_ERRORS'); | ||
return 0; | ||
} | ||
|
||
// make sure only fresh data is sent to the server. | ||
if (form.$pristine) { | ||
Notify.warn('FORM.WARNINGS.NO_CHANGES'); | ||
return 0; | ||
} | ||
|
||
const changes = angular.copy(vm.settings); | ||
|
||
return ODKSettings.create(changes) | ||
.then(() => Notify.success('FORM.INFO.UPDATE_SUCCESS')) | ||
.then(() => refreshSettings()) | ||
.catch(Notify.handleError) | ||
.finally(() => { vm.loading = false; }); | ||
} | ||
|
||
startup(); | ||
} |
Oops, something went wrong.