Skip to content

Commit

Permalink
Recovery OP-312 telemetry module (#876)
Browse files Browse the repository at this point in the history
* Telemetry updates
added Telemetry popup + configuration
renamed SmsSender class to SmsDaemon

* resolved conflict

* OP-153 Fix lots quantities on multiple discharges

* sync + little changes

* - added headers

* added freegeoip remote service configuration + changed package name fro
data collector module

* corrections based on Alessandro's suggestions

* corrections based on Alessandro's suggestions

* restored old variable name (reason: in the future we will do a
refactoring)

* new db single connection config + ipinfo config

* fixed some bugs

- now telemetry is based on the following rules: if active = null =>
show telemetry popup, if active = true => start telemetry daemon, if
active = false => do nothing (we should add a menu item in order to
allow user to access to the popup?)
- if TELEMETRYENABLED is yes then start telemetry daemon always (with
SINGLEUSER equals to yes or no)

* implementation telemetry module completed

+ added also simulated message sending (when DEBUG=yes)

* added property to enable/disable telemetry module

* Added Telemetry menu item in the Settings menu

+ managed the case when telemetry module is disabled from
settings.properties (could be used for other OH modules): we will not
show the menu item in the Settings menu

* OP-149 Set default duration (30min) and date check on visits. (#877)

* Set default duration (30min) and date check on visits.

Also clean and improve code

* Fix for multiple visit save

* Fix as per comments review

* Fix therapy changes

and also refactor constants

* Fix spacing

* Fix edit therapy (not insert)

Fix also duration calculation

* Fix window position after re-pack

* Add remove visit button in worksheet

* Enable visits management for admitted patients

* Fixes by comments review

* Avoid automatic saving and have changes all buffered before save

* Fix visit automatic save in worksheet

* Fix layout

* Fix deletion on second day list

* reload data from DB upon new visits

* Fix MessageDialog calls

* Organize imports

* Fix bundle

* Small workaround to avoid cursor jumps among new items in the same day

TODO:
- better arrays management (to highlight also unsaved)
- improve events handling (to avoid selection flickering)

* Add validation for visits buffered to save

* Avoid Worksheet operativity when there are visit changes pending

* Fixes by comments review

* Sync Swing quantity controllers

* Avoid Worksheet operativity when there are therapies changes pending

* Avoid therapies in the past and improved bundles

* Chore: remove duplicate semi-colon (#878)

* Chore: remove duplicate code in both branches of if (#879)

* Chore: remove what looks like an octal value for int array (#880)

* run always telemetry daemon + confirmation dialog with summary

- run always telemetry daemon - (except if settings.properties disables
it)

- added dialog with the content of the tlemetry message that will be
sent to https://www.informaticisenzafrontiere.org/

- corrected what Alessandro asked to change

Co-authored-by: Alessandro Domanico <[email protected]>
Co-authored-by: David B Malkovsky <[email protected]>
  • Loading branch information
3 people committed Sep 16, 2022
1 parent d4b69fd commit a256aa4
Show file tree
Hide file tree
Showing 13 changed files with 611 additions and 98 deletions.
9 changes: 9 additions & 0 deletions bundle/language_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,7 @@ angal.menu.btn.printing
angal.menu.btn.smsmanager = SMS Manager
angal.menu.btn.statistics = Statistics
angal.menu.btn.supplier = Supplier
angal.menu.btn.telemetry = Telemetry
angal.menu.btn.types = Types
angal.menu.btn.users = Users & Groups
angal.menu.btn.usersusers = Users
Expand Down Expand Up @@ -965,6 +966,14 @@ angal.menu.printing
angal.menu.smsmanager = SMS Manager
angal.menu.statistics = Statistics
angal.menu.supplier = Supplier
angal.telemetry.title = Help us improve Open Hospital
angal.telemetry.about = Collect anonymous usage data and send them to informaticisenzafrontiere.org
angal.telemetry.info = Open Hospital is the first of a set of software products that Informatici Senza Frontiere has developed to support the information management and the activities of hospitals and health centers in the simplest manner possible, by providing tools for the hospital administrative operations (like registering patients, manage laboratory analysis and pharmaceutical stocks) and to produce detailed statistics and reports.
angal.telemetry.body = Please choose what you want to share (and what not) with our organization:
angal.telemetry.confirmation.dialog.message = Are you sure that you want to send these informations?
angal.telemetry.button.label.confirm = Confirm
angal.telemetry.button.label.ask.later = Ask me later
angal.telemetry.button.label.ask.never = Disable and never ask again
angal.menu.types = Types
angal.menu.users = Users
angal.menu.usersusers = Users
Expand Down
71 changes: 38 additions & 33 deletions bundle/language_es.properties

Large diffs are not rendered by default.

35 changes: 20 additions & 15 deletions bundle/language_fr.properties

Large diffs are not rendered by default.

76 changes: 41 additions & 35 deletions bundle/language_it.properties

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions bundle/language_pt.properties
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ angal.menu.btn.printing = Im
angal.menu.btn.smsmanager = Gerente de SMS
angal.menu.btn.statistics = Estatísticas
angal.menu.btn.supplier = Fornecedor
angal.menu.btn.telemetry = Telemetria
angal.menu.btn.types = Tipos de
angal.menu.btn.users = Usuários
angal.menu.btn.usersusers = Usuários
Expand Down Expand Up @@ -367,6 +368,7 @@ angal.menu.printing = Im
angal.menu.smsmanager = Gerente de SMS
angal.menu.statistics = Estatísticas
angal.menu.supplier = Fornecedor
angal.menu.telemetry = Telemetria
angal.menu.types = Tipos de
angal.menu.users = Usuários
angal.menu.usersusers = Usuários
Expand Down
2 changes: 2 additions & 0 deletions bundle/language_sw.properties
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ angal.menu.btn.printing = Uc
angal.menu.btn.smsmanager = Ujumbe wa Msimamizi
angal.menu.btn.statistics = Takwimu
angal.menu.btn.supplier = Muuzaji
angal.menu.btn.telemetry = Telemetry
angal.menu.btn.types = Aina
angal.menu.btn.users = Watumiaji
angal.menu.btn.usersusers = Watumiaji
Expand Down Expand Up @@ -320,6 +321,7 @@ angal.menu.printing = Uc
angal.menu.smsmanager = Ujumbe wa Msimamizi
angal.menu.statistics = Takwimu
angal.menu.supplier = Muuzaji
angal.menu.telemetry = Telemetry
angal.menu.types = Aina
angal.menu.users = Watumiaji
angal.menu.usersusers = Watumiaji
Expand Down
1 change: 1 addition & 0 deletions rsc/ipinfo.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
freegeoip-remote-service.ribbon.base-url=https://freegeoip.app:443
3 changes: 2 additions & 1 deletion rsc/settings.properties.dist
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ ALLOWPRINTOPENEDBILL=yes
ALLOWMULTIPLEOPENEDBILL=yes
PATIENTBILLGROUPED=PatientBillGrouped
PATIENTBILLSTATEMENT=PatientBillStatement
TELEMETRYENABLED=no
DEBUG=no
USERSLISTLOGIN=no
STRONGPASSWORD=yes
STRONGLENGTH=10
STRONGLENGTH=10
6 changes: 6 additions & 0 deletions rsc/telemetry.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# enables/disables daemon - valid values: true | false
telemetry.daemon.enabled=true
# number of second to check if it should send a message
telemetry.daemon.thread.loop.seconds=10
# remote data collector server base url
telemetry-gateway-service.base-url=http://localhost:8080
93 changes: 81 additions & 12 deletions src/main/java/org/isf/menu/gui/MainMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.Box;
Expand All @@ -58,6 +60,12 @@
import org.isf.menu.model.UserGroup;
import org.isf.menu.model.UserMenuItem;
import org.isf.sms.service.SmsSender;
import org.isf.telemetry.constants.TelemetryConst;
import org.isf.telemetry.daemon.TelemetryDaemon;
import org.isf.telemetry.gui.TelemetryGUI;
import org.isf.telemetry.gui.TelemetryGUI.TelemetryListener;
import org.isf.telemetry.manager.TelemetryManager;
import org.isf.telemetry.model.Telemetry;
import org.isf.utils.exception.OHServiceException;
import org.isf.utils.exception.gui.OHServiceExceptionUtil;
import org.isf.utils.jobjects.ModalJFrame;
Expand All @@ -69,12 +77,16 @@
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

public class MainMenu extends JFrame implements ActionListener, Login.LoginListener, SubMenu.CommandListener {
public class MainMenu extends JFrame
implements ActionListener, Login.LoginListener, SubMenu.CommandListener, TelemetryListener {

private static final long serialVersionUID = 7620582079916035164L;
public static final String ADMIN_STR = "admin";
private boolean flag_Xmpp;
private boolean flag_Sms;
private Thread telemetryThread;
// used to understand if a module is enabled
private Map<String, Boolean> activableModules;

private static final Logger LOGGER = LoggerFactory.getLogger(MainMenu.class);

Expand Down Expand Up @@ -134,7 +146,8 @@ public int getMinButtonSize() {
public MainMenu() {
myFrame = this;
GeneralData.initialize();
Locale.setDefault(new Locale(GeneralData.LANGUAGE)); //for all fixed options YES_NO_CANCEL in dialogs
this.activableModules = retrieveActivatedModulesMap();
Locale.setDefault(new Locale(GeneralData.LANGUAGE)); // for all fixed options YES_NO_CANCEL in dialogs
singleUser = GeneralData.getGeneralData().getSINGLEUSER();
MessageBundle.getBundle();
try {
Expand All @@ -145,11 +158,13 @@ public MainMenu() {
}
flag_Xmpp = GeneralData.XMPPMODULEENABLED;
flag_Sms = GeneralData.SMSENABLED;

// start connection with SMS service
if (flag_Sms) {
Thread thread = new Thread(new SmsSender());
thread.start();
}

} catch (Exception e) {
singleUser = true; // default for property not found
internalPharmacies = false; // default for property not found
Expand All @@ -165,13 +180,16 @@ public MainMenu() {
// get an user
LOGGER.info("Logging: Multi User mode.");
new Login(this);

if (null == myUser) {
// Login failed
actionExit(2);
}
}

if (GeneralData.TELEMETRYENABLED) {
runTelemetry();
}

// get menu items
try {
myMenu = manager.getMenu(myUser);
Expand All @@ -190,16 +208,18 @@ public MainMenu() {
}
new CommunicationFrame();
/*
* Interaction communication= new Interaction();
* communication.incomingChat(); communication.receiveFile();
* Interaction communication= new Interaction(); communication.incomingChat();
* communication.receiveFile();
*/
} catch (XMPPException e) {
String message = e.getMessage();
if (message.contains("SASL authentication DIGEST-MD5 failed")) {
if (ADMIN_STR.equals(myUser.getUserName())) {
LOGGER.error("Cannot use \"admin\" user, please consider creating another user under the admin group.");
LOGGER.error(
"Cannot use \"admin\" user, please consider creating another user under the admin group.");
} else {
LOGGER.error("Passwords do not match, please drop the XMPP user and login to OH again with the same user.");
LOGGER.error(
"Passwords do not match, please drop the XMPP user and login to OH again with the same user.");
}
} else if (message.contains("XMPPError connecting")) {
LOGGER.error("No XMPP Server seems to be running: set XMPPMODULEENABLED = false");
Expand Down Expand Up @@ -258,7 +278,8 @@ public MainMenu() {
if (!internalPharmacies) {
List<UserMenuItem> junkMenu = new ArrayList<>();
for (UserMenuItem umi : myMenu) {
if ("MEDICALSWARD".equalsIgnoreCase(umi.getCode()) || "MEDICALSWARD".equalsIgnoreCase(umi.getMySubmenu())) {
if ("MEDICALSWARD".equalsIgnoreCase(umi.getCode())
|| "MEDICALSWARD".equalsIgnoreCase(umi.getMySubmenu())) {
junkMenu.add(umi);
}
}
Expand All @@ -270,7 +291,9 @@ public MainMenu() {
// remove disabled buttons
List<UserMenuItem> junkMenu = new ArrayList<>();
for (UserMenuItem umi : myMenu) {
if (!umi.isActive()) {
// if is not active or it is a module that is not enabled (there is no point in
// showing a menu item)
if (!umi.isActive() || isMenuItemNotEnabled(umi.getCode())) {
junkMenu.add(umi);
}
}
Expand All @@ -297,21 +320,54 @@ public MainMenu() {
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setAlwaysOnTop(GeneralData.MAINMENUALWAYSONTOP);
myFrame.addWindowListener(new WindowAdapter() {

@Override
public void windowClosing(WindowEvent e) {
actionExit(0);
}
});

setVisible(true);

}

private HashMap<String, Boolean> retrieveActivatedModulesMap() {
return new HashMap<String, Boolean>() {

private static final long serialVersionUID = 1L;
{
put(TelemetryConst.MENU_ID, Boolean.valueOf(GeneralData.TELEMETRYENABLED));
}
};
}

private boolean isMenuItemNotEnabled(String menuCode) {
return this.activableModules.containsKey(menuCode) && !activableModules.get(menuCode).booleanValue();
}

private void runTelemetry() {
TelemetryManager telemetryManager = Context.getApplicationContext().getBean(TelemetryManager.class);
Telemetry settings = telemetryManager.retrieveSettings();
// active = null => show popup
// active = true => start daemon
// active = false => do nothing
if (settings == null || settings.getActive() == null) {
// show telemetry popup
new TelemetryGUI(this);
}

// start telemetry daemon
Thread thread = new Thread(new TelemetryDaemon());
thread.start();
}

private void actionExit(int status) {
if (2 == status) {
LOGGER.info("Login failed.");
}
String newLine = System.lineSeparator();
LOGGER.info("{}{}====================={} Open Hospital closed {}====================={}", newLine, newLine, newLine, newLine, newLine);
LOGGER.info("{}{}====================={} Open Hospital closed {}====================={}", newLine, newLine,
newLine, newLine, newLine);
System.exit(status);
}

Expand Down Expand Up @@ -351,7 +407,8 @@ private void launchApp(String itemMenuCode) {
}
}
} catch (InstantiationException | ClassNotFoundException | IllegalAccessException ie) {
LOGGER.error("Error instantiating menu item: '{}' with class '{}'.", u.getCode(), u.getMyClass());
LOGGER.error("Error instantiating menu item: '{}' with class '{}'.", u.getCode(),
u.getMyClass());
}
break;
}
Expand Down Expand Up @@ -466,5 +523,17 @@ private String truncate(String string, int size) {
public static User getUser() {
return myUser;
}


@Override
public void telemetryInserted(AWTEvent e) {
if (e.getSource() instanceof Telemetry) {
Telemetry telemetry = (Telemetry) e.getSource();
LOGGER.info("Telemetry: \"{}\" telemetry inserted.", telemetry);
if (null != this.telemetryThread) {
this.telemetryThread = new Thread(new TelemetryDaemon());
this.telemetryThread.start();
}
}

}
}
56 changes: 56 additions & 0 deletions src/main/java/org/isf/telemetry/gui/CheckBoxWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Open Hospital (www.open-hospital.org)
* Copyright © 2006-2021 Informatici Senza Frontiere ([email protected])
*
* Open Hospital is a free and open source software for healthcare data management.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* https://www.gnu.org/licenses/gpl-3.0-standalone.html
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.isf.telemetry.gui;

import javax.swing.JCheckBox;

public class CheckBoxWrapper {

private String id;
private Integer order;
private JCheckBox checkbox;

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public Integer getOrder() {
return order;
}

public void setOrder(Integer order) {
this.order = order;
}

public JCheckBox getCheckbox() {
return checkbox;
}

public void setCheckbox(JCheckBox checkbox) {
this.checkbox = checkbox;
}

}
Loading

0 comments on commit a256aa4

Please sign in to comment.