From 2ede6b7abb1b9c63f922cb40f893168b91368466 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Wed, 3 Dec 2025 17:35:40 -0500 Subject: [PATCH 01/12] Implement flags domain --- README.md | 6 + .../api/loaders/LoadersOrderTest.java | 3 + api-2.4/pom.xml | 7 + .../patientflags/DisplayPointListParser.java | 45 ++++++ .../api/patientflags/FlagsCsvParser.java | 51 ++++++ .../api/patientflags/FlagsLineProcessor.java | 111 +++++++++++++ .../api/patientflags/FlagsLoader.java | 18 +++ .../api/patientflags/PrioritiesCsvParser.java | 60 +++++++ .../api/patientflags/PrioritiesLoader.java | 18 +++ .../patientflags/PriorityLineProcessor.java | 40 +++++ .../api/patientflags/TagLineProcessor.java | 65 ++++++++ .../api/patientflags/TagListParser.java | 44 ++++++ .../api/patientflags/TagsCsvParser.java | 60 +++++++ .../api/patientflags/TagsLoader.java | 18 +++ ...ontextSensitive_2_4_patientflags_test.java | 41 +++++ .../FlagsLoaderIntegrationTest.java | 146 ++++++++++++++++++ .../PrioritiesLoaderIntegrationTest.java | 89 +++++++++++ .../TagsLoaderIntegrationTest.java | 95 ++++++++++++ .../src/test/resources/test-hibernate.cfg.xml | 6 + .../flagpriorities/priorities.csv | 6 + .../configuration/flags/flags.csv | 5 + .../configuration/flagtags/tags.csv | 6 + .../openmrs/module/initializer/Domain.java | 3 + pom.xml | 1 + readme/flagpriorities.md | 39 +++++ readme/flags.md | 53 +++++++ readme/flagtags.md | 39 +++++ 27 files changed, 1075 insertions(+) create mode 100644 api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java create mode 100644 api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java create mode 100644 api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java create mode 100644 api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java create mode 100644 api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java create mode 100644 api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoader.java create mode 100644 api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java create mode 100644 api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java create mode 100644 api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java create mode 100644 api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java create mode 100644 api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java create mode 100644 api-2.4/src/test/java/org/openmrs/module/initializer/api/DomainBaseModuleContextSensitive_2_4_patientflags_test.java create mode 100644 api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java create mode 100644 api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java create mode 100644 api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java create mode 100644 api-2.4/src/test/resources/testAppDataDir/configuration/flagpriorities/priorities.csv create mode 100644 api-2.4/src/test/resources/testAppDataDir/configuration/flags/flags.csv create mode 100644 api-2.4/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv create mode 100644 readme/flagpriorities.md create mode 100644 readme/flags.md create mode 100644 readme/flagtags.md diff --git a/README.md b/README.md index f64ee800..5cb8d70f 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,9 @@ configuration/ ├── orderfrequencies/ ├── ordertypes/ ├── paymentmodes/ + ├── flags/ + ├── flagpriorities/ + ├── flagtags/ ├── patientidentifiertypes/ ├── personattributetypes/ ├── privileges/ @@ -137,6 +140,9 @@ This is the list of currently supported domains in their loading order: 1. [Billable Services (CSV files)](readme/billableservices.md) 1. [Cash Points (CSV files)](readme/cashpoints.md) 1. [Payment Modes (CSV files)](readme/paymentmodes.md) +1. [Flags (CSV files)](readme/flags.md) +1. [Flag Priorities (CSV files)](readme/flagpriorities.md) +1. [Flag Tags (CSV files)](readme/flagtags.md) 1. [Concept Sets and Answers (CSV files)](readme/conceptsets.md) 1. [Concept Reference Ranges (CSV files)](readme/conceptreferencerange.md) 1. [Programs (CSV files)](readme/prog.md) diff --git a/api-2.3/src/test/java/org/openmrs/module/initializer/api/loaders/LoadersOrderTest.java b/api-2.3/src/test/java/org/openmrs/module/initializer/api/loaders/LoadersOrderTest.java index dbe682a2..aa0e1a65 100644 --- a/api-2.3/src/test/java/org/openmrs/module/initializer/api/loaders/LoadersOrderTest.java +++ b/api-2.3/src/test/java/org/openmrs/module/initializer/api/loaders/LoadersOrderTest.java @@ -74,6 +74,9 @@ protected boolean matchesSafely(List loaders, Description mismatchDescri exclude.add(Domain.BILLABLE_SERVICES.getName()); exclude.add(Domain.CASH_POINTS.getName()); exclude.add(Domain.CONCEPT_REFERENCE_RANGE.getName()); + exclude.add(Domain.FLAGS.getName()); + exclude.add(Domain.FLAG_PRIORITIES.getName()); + exclude.add(Domain.FLAG_TAGS.getName()); boolean result = true; Set loaderDomains = loaders.stream().map(Loader::getDomainName).collect(Collectors.toSet()); diff --git a/api-2.4/pom.xml b/api-2.4/pom.xml index c41605e9..f5dc4480 100644 --- a/api-2.4/pom.xml +++ b/api-2.4/pom.xml @@ -87,6 +87,13 @@ provided + + org.openmrs.module + patientflags-api + ${patientflagsVersion} + provided + + org.openmrs.module stockmanagement-api diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java new file mode 100644 index 00000000..9e98c3fd --- /dev/null +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java @@ -0,0 +1,45 @@ +package org.openmrs.module.initializer.api.patientflags; + +import org.apache.commons.lang3.StringUtils; +import org.openmrs.annotation.OpenmrsProfile; +import org.openmrs.module.patientflags.DisplayPoint; +import org.openmrs.module.patientflags.api.FlagService; +import org.openmrs.module.initializer.api.utils.ListParser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +/** + * Parses a list of DisplayPoint identifiers (UUID or name) and fetches the corresponding + * DisplayPoint entities. + */ +@OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) +public class DisplayPointListParser extends ListParser { + + private FlagService flagService; + + @Autowired + public DisplayPointListParser(@Qualifier("flagService") FlagService flagService) { + this.flagService = flagService; + } + + @Override + protected DisplayPoint fetch(String id) { + if (StringUtils.isBlank(id)) { + return null; + } + + // Try UUID first + DisplayPoint displayPoint = flagService.getDisplayPointByUuid(id); + if (displayPoint != null) { + return displayPoint; + } + + // Try name + displayPoint = flagService.getDisplayPoint(id); + if (displayPoint != null) { + return displayPoint; + } + + return null; + } +} diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java new file mode 100644 index 00000000..ae07ef60 --- /dev/null +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java @@ -0,0 +1,51 @@ +package org.openmrs.module.initializer.api.patientflags; + +import org.apache.commons.lang3.StringUtils; +import org.openmrs.annotation.OpenmrsProfile; +import org.openmrs.module.patientflags.Flag; +import org.openmrs.module.patientflags.api.FlagService; +import org.openmrs.module.initializer.Domain; +import org.openmrs.module.initializer.api.BaseLineProcessor; +import org.openmrs.module.initializer.api.CsvLine; +import org.openmrs.module.initializer.api.CsvParser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +/** + * Parses CSV files for Flag entities. + */ +@OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) +public class FlagsCsvParser extends CsvParser> { + + private final FlagService flagService; + + @Autowired + public FlagsCsvParser(@Qualifier("flagService") FlagService flagService, FlagsLineProcessor processor) { + super(processor); + this.flagService = flagService; + } + + @Override + public Domain getDomain() { + return Domain.FLAGS; + } + + @Override + public Flag bootstrap(CsvLine line) throws IllegalArgumentException { + String uuid = line.getUuid(); + Flag flag = flagService.getFlagByUuid(uuid); + if (flag == null) { + flag = new Flag(); + if (StringUtils.isNotBlank(uuid)) { + flag.setUuid(uuid); + } + } + return flag; + } + + @Override + public Flag save(Flag instance) { + flagService.saveFlag(instance); + return instance; + } +} diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java new file mode 100644 index 00000000..8e0a589d --- /dev/null +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java @@ -0,0 +1,111 @@ +package org.openmrs.module.initializer.api.patientflags; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.openmrs.annotation.OpenmrsProfile; +import org.openmrs.module.patientflags.Flag; +import org.openmrs.module.patientflags.Priority; +import org.openmrs.module.patientflags.Tag; +import org.openmrs.module.patientflags.api.FlagService; +import org.openmrs.module.initializer.api.BaseLineProcessor; +import org.openmrs.module.initializer.api.CsvLine; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +/** + * Processes CSV lines for Flag entities. + */ +@OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) +public class FlagsLineProcessor extends BaseLineProcessor { + + protected static final String HEADER_CRITERIA = "criteria"; + + protected static final String HEADER_EVALUATOR = "evaluator"; + + protected static final String HEADER_MESSAGE = "message"; + + protected static final String HEADER_PRIORITY = "priority"; + + protected static final String HEADER_ENABLED = "enabled"; + + protected static final String HEADER_TAGS = "tags"; + + private FlagService flagService; + + private TagListParser tagListParser; + + @Autowired + public FlagsLineProcessor(@Qualifier("flagService") FlagService flagService, TagListParser tagListParser) { + this.flagService = flagService; + this.tagListParser = tagListParser; + } + + @Override + public Flag fill(Flag flag, CsvLine line) throws IllegalArgumentException { + flag.setName(line.get(HEADER_NAME, true)); + flag.setDescription(line.get(HEADER_DESC)); + + // Required fields + flag.setCriteria(line.get(HEADER_CRITERIA, true)); + flag.setEvaluator(line.get(HEADER_EVALUATOR, true)); + flag.setMessage(line.get(HEADER_MESSAGE, true)); + + // Optional priority + String priorityId = line.getString(HEADER_PRIORITY, ""); + if (StringUtils.isNotBlank(priorityId)) { + Priority priority = fetchPriority(priorityId); + if (priority == null) { + throw new IllegalArgumentException( + "The priority referenced by '" + priorityId + "' does not point to any known priority."); + } + flag.setPriority(priority); + } else { + flag.setPriority(null); + } + + // Optional enabled flag (defaults to true if not specified) + String enabledStr = line.getString(HEADER_ENABLED, ""); + if (StringUtils.isNotBlank(enabledStr)) { + flag.setEnabled(Boolean.parseBoolean(enabledStr.trim())); + } else { + flag.setEnabled(true); // Default to enabled + } + + // Optional tags + String tagsStr = line.getString(HEADER_TAGS, ""); + if (StringUtils.isNotBlank(tagsStr)) { + Set tags = new HashSet(tagListParser.parseList(tagsStr)); + flag.setTags(tags); + } else if (flag.getTags() != null) { + // Clear tags if not specified (only if tags were previously set) + flag.getTags().clear(); + } + + return flag; + } + + /** + * Fetches a Priority by UUID or name. + */ + private Priority fetchPriority(String id) { + if (StringUtils.isBlank(id)) { + return null; + } + + // Try UUID first + Priority priority = flagService.getPriorityByUuid(id); + if (priority != null) { + return priority; + } + + // Try name + priority = flagService.getPriorityByName(id); + if (priority != null) { + return priority; + } + + return null; + } +} diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java new file mode 100644 index 00000000..8c581222 --- /dev/null +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java @@ -0,0 +1,18 @@ +package org.openmrs.module.initializer.api.patientflags; + +import org.openmrs.annotation.OpenmrsProfile; +import org.openmrs.module.patientflags.Flag; +import org.openmrs.module.initializer.api.loaders.BaseCsvLoader; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * Loads Flags from CSV files. + */ +@OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) +public class FlagsLoader extends BaseCsvLoader { + + @Autowired + public void setParser(FlagsCsvParser parser) { + this.parser = parser; + } +} diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java new file mode 100644 index 00000000..a4cece9f --- /dev/null +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java @@ -0,0 +1,60 @@ +package org.openmrs.module.initializer.api.patientflags; + +import org.apache.commons.lang3.StringUtils; +import org.openmrs.annotation.OpenmrsProfile; +import org.openmrs.module.patientflags.Priority; +import org.openmrs.module.patientflags.api.FlagService; +import org.openmrs.module.initializer.Domain; +import org.openmrs.module.initializer.api.BaseLineProcessor; +import org.openmrs.module.initializer.api.CsvLine; +import org.openmrs.module.initializer.api.CsvParser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +/** + * Parses CSV files for Priority entities. + */ +@OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) +public class PrioritiesCsvParser extends CsvParser> { + + private final FlagService flagService; + + @Autowired + public PrioritiesCsvParser(@Qualifier("flagService") FlagService flagService, PriorityLineProcessor processor) { + super(processor); + this.flagService = flagService; + } + + @Override + public Domain getDomain() { + return Domain.FLAG_PRIORITIES; + } + + @Override + public Priority bootstrap(CsvLine line) throws IllegalArgumentException { + String uuid = line.getUuid(); + Priority priority = flagService.getPriorityByUuid(uuid); + + if (priority == null && StringUtils.isEmpty(uuid)) { + String name = line.getName(); + if (StringUtils.isNotBlank(name)) { + priority = flagService.getPriorityByName(name); + } + } + + if (priority == null) { + priority = new Priority(); + if (StringUtils.isNotBlank(uuid)) { + priority.setUuid(uuid); + } + } + + return priority; + } + + @Override + public Priority save(Priority instance) { + flagService.savePriority(instance); + return instance; + } +} diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoader.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoader.java new file mode 100644 index 00000000..25633485 --- /dev/null +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoader.java @@ -0,0 +1,18 @@ +package org.openmrs.module.initializer.api.patientflags; + +import org.openmrs.annotation.OpenmrsProfile; +import org.openmrs.module.patientflags.Priority; +import org.openmrs.module.initializer.api.loaders.BaseCsvLoader; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * Loads Priorities from CSV files. + */ +@OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) +public class PrioritiesLoader extends BaseCsvLoader { + + @Autowired + public void setParser(PrioritiesCsvParser parser) { + this.parser = parser; + } +} diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java new file mode 100644 index 00000000..110c763b --- /dev/null +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java @@ -0,0 +1,40 @@ +package org.openmrs.module.initializer.api.patientflags; + +import org.apache.commons.lang3.StringUtils; +import org.openmrs.annotation.OpenmrsProfile; +import org.openmrs.module.patientflags.Priority; +import org.openmrs.module.initializer.api.BaseLineProcessor; +import org.openmrs.module.initializer.api.CsvLine; + +/** + * Processes CSV lines for Priority entities. + */ +@OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) +public class PriorityLineProcessor extends BaseLineProcessor { + + protected static final String HEADER_STYLE = "style"; + + protected static final String HEADER_RANK = "rank"; + + @Override + public Priority fill(Priority priority, CsvLine line) throws IllegalArgumentException { + priority.setName(line.get(HEADER_NAME, true)); + priority.setDescription(line.get(HEADER_DESC)); + + // Required style + priority.setStyle(line.get(HEADER_STYLE, true)); + + // Required rank + String rankStr = line.get(HEADER_RANK, true); + if (StringUtils.isNotBlank(rankStr)) { + try { + priority.setRank(Integer.parseInt(rankStr.trim())); + } + catch (NumberFormatException e) { + throw new IllegalArgumentException("The rank value '" + rankStr + "' could not be parsed as an integer."); + } + } + + return priority; + } +} diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java new file mode 100644 index 00000000..50066986 --- /dev/null +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java @@ -0,0 +1,65 @@ +package org.openmrs.module.initializer.api.patientflags; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.openmrs.Role; +import org.openmrs.annotation.OpenmrsProfile; +import org.openmrs.api.UserService; +import org.openmrs.module.patientflags.DisplayPoint; +import org.openmrs.module.patientflags.Tag; +import org.openmrs.module.initializer.api.BaseLineProcessor; +import org.openmrs.module.initializer.api.CsvLine; +import org.openmrs.module.initializer.api.utils.RoleListParser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +/** + * Processes CSV lines for Tag entities. + */ +@OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) +public class TagLineProcessor extends BaseLineProcessor { + + protected static final String HEADER_ROLES = "roles"; + + protected static final String HEADER_DISPLAY_POINTS = "display points"; + + private RoleListParser roleListParser; + + private DisplayPointListParser displayPointListParser; + + @Autowired + public TagLineProcessor(RoleListParser roleListParser, DisplayPointListParser displayPointListParser) { + this.roleListParser = roleListParser; + this.displayPointListParser = displayPointListParser; + } + + @Override + public Tag fill(Tag tag, CsvLine line) throws IllegalArgumentException { + tag.setName(line.get(HEADER_NAME, true)); + tag.setDescription(line.get(HEADER_DESC)); + + // Optional roles + String rolesStr = line.getString(HEADER_ROLES, ""); + if (StringUtils.isNotBlank(rolesStr)) { + Set roles = new HashSet(roleListParser.parseList(rolesStr)); + tag.setRoles(roles); + } else if (tag.getRoles() != null) { + // Clear roles if not specified (only if roles were previously set) + tag.getRoles().clear(); + } + + // Optional display points + String displayPointsStr = line.getString(HEADER_DISPLAY_POINTS, ""); + if (StringUtils.isNotBlank(displayPointsStr)) { + Set displayPoints = new HashSet(displayPointListParser.parseList(displayPointsStr)); + tag.setDisplayPoints(displayPoints); + } else if (tag.getDisplayPoints() != null) { + // Clear display points if not specified (only if display points were previously set) + tag.getDisplayPoints().clear(); + } + + return tag; + } +} diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java new file mode 100644 index 00000000..003c9713 --- /dev/null +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java @@ -0,0 +1,44 @@ +package org.openmrs.module.initializer.api.patientflags; + +import org.apache.commons.lang3.StringUtils; +import org.openmrs.annotation.OpenmrsProfile; +import org.openmrs.module.patientflags.Tag; +import org.openmrs.module.patientflags.api.FlagService; +import org.openmrs.module.initializer.api.utils.ListParser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +/** + * Parses a list of Tag identifiers (UUID or name) and fetches the corresponding Tag entities. + */ +@OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) +public class TagListParser extends ListParser { + + private FlagService flagService; + + @Autowired + public TagListParser(@Qualifier("flagService") FlagService flagService) { + this.flagService = flagService; + } + + @Override + protected Tag fetch(String id) { + if (StringUtils.isBlank(id)) { + return null; + } + + // Try UUID first + Tag tag = flagService.getTagByUuid(id); + if (tag != null) { + return tag; + } + + // Try name + tag = flagService.getTag(id); + if (tag != null) { + return tag; + } + + return null; + } +} diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java new file mode 100644 index 00000000..57890fff --- /dev/null +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java @@ -0,0 +1,60 @@ +package org.openmrs.module.initializer.api.patientflags; + +import org.apache.commons.lang3.StringUtils; +import org.openmrs.annotation.OpenmrsProfile; +import org.openmrs.module.patientflags.Tag; +import org.openmrs.module.patientflags.api.FlagService; +import org.openmrs.module.initializer.Domain; +import org.openmrs.module.initializer.api.BaseLineProcessor; +import org.openmrs.module.initializer.api.CsvLine; +import org.openmrs.module.initializer.api.CsvParser; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +/** + * Parses CSV files for Tag entities. + */ +@OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) +public class TagsCsvParser extends CsvParser> { + + private final FlagService flagService; + + @Autowired + public TagsCsvParser(@Qualifier("flagService") FlagService flagService, TagLineProcessor processor) { + super(processor); + this.flagService = flagService; + } + + @Override + public Domain getDomain() { + return Domain.FLAG_TAGS; + } + + @Override + public Tag bootstrap(CsvLine line) throws IllegalArgumentException { + String uuid = line.getUuid(); + Tag tag = flagService.getTagByUuid(uuid); + + if (tag == null && StringUtils.isEmpty(uuid)) { + String name = line.getName(); + if (StringUtils.isNotBlank(name)) { + tag = flagService.getTag(name); + } + } + + if (tag == null) { + tag = new Tag(); + if (StringUtils.isNotBlank(uuid)) { + tag.setUuid(uuid); + } + } + + return tag; + } + + @Override + public Tag save(Tag instance) { + flagService.saveTag(instance); + return instance; + } +} diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java new file mode 100644 index 00000000..84e28a01 --- /dev/null +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java @@ -0,0 +1,18 @@ +package org.openmrs.module.initializer.api.patientflags; + +import org.openmrs.annotation.OpenmrsProfile; +import org.openmrs.module.patientflags.Tag; +import org.openmrs.module.initializer.api.loaders.BaseCsvLoader; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * Loads Tags from CSV files. + */ +@OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) +public class TagsLoader extends BaseCsvLoader { + + @Autowired + public void setParser(TagsCsvParser parser) { + this.parser = parser; + } +} diff --git a/api-2.4/src/test/java/org/openmrs/module/initializer/api/DomainBaseModuleContextSensitive_2_4_patientflags_test.java b/api-2.4/src/test/java/org/openmrs/module/initializer/api/DomainBaseModuleContextSensitive_2_4_patientflags_test.java new file mode 100644 index 00000000..c448d792 --- /dev/null +++ b/api-2.4/src/test/java/org/openmrs/module/initializer/api/DomainBaseModuleContextSensitive_2_4_patientflags_test.java @@ -0,0 +1,41 @@ +/** + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at http://mozilla.org/MPL/2.0/. OpenMRS is also distributed under + * the terms of the Healthcare Disclaimer located at http://openmrs.org/license. + * + * Copyright (C) OpenMRS Inc. OpenMRS is a registered trademark and the OpenMRS + * graphic logo is a trademark of OpenMRS Inc. + */ +package org.openmrs.module.initializer.api; + +import org.openmrs.module.Module; +import org.openmrs.module.ModuleFactory; +import org.openmrs.module.initializer.DomainBaseModuleContextSensitiveTest; + +import java.io.File; + +/** + * This allows to perform Spring context sensitive tests when patientflags module is a dependency. + */ +public abstract class DomainBaseModuleContextSensitive_2_4_patientflags_test extends DomainBaseModuleContextSensitiveTest { + + public DomainBaseModuleContextSensitive_2_4_patientflags_test() { + super(); + { + Module mod = new Module("", "patientflags", "", "", "", "3.0.0"); + mod.setFile(new File("")); + ModuleFactory.getStartedModulesMap().put(mod.getModuleId(), mod); + } + } + + @Override + public void updateSearchIndex() { + // to prevent Data Filter's 'Illegal Record Access' + } + + @Override + public void revertContextMocks() { + + } +} diff --git a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java b/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java new file mode 100644 index 00000000..b9d9580c --- /dev/null +++ b/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java @@ -0,0 +1,146 @@ +package org.openmrs.module.initializer.api.patientflags; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.patientflags.Flag; +import org.openmrs.module.patientflags.Priority; +import org.openmrs.module.patientflags.Tag; +import org.openmrs.module.patientflags.api.FlagService; +import org.openmrs.module.initializer.api.DomainBaseModuleContextSensitive_2_4_patientflags_test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +public class FlagsLoaderIntegrationTest extends DomainBaseModuleContextSensitive_2_4_patientflags_test { + + @Autowired + @Qualifier("flagService") + private FlagService flagService; + + @Autowired + private FlagsLoader loader; + + @Before + public void setup() throws Exception { + executeDataSet("testdata/test-concepts-2.4.xml"); + + // Set up prerequisites: Priorities and Tags that flags will reference + + // Create priorities + Priority highPriority = new Priority(); + highPriority.setUuid("526bf278-ba81-4436-b867-c2f6641d060a"); + highPriority.setName("High Priority"); + highPriority.setStyle("color:red"); + highPriority.setRank(1); + highPriority.setRetired(false); + flagService.savePriority(highPriority); + + Priority mediumPriority = new Priority(); + mediumPriority.setUuid("627bf278-ba81-4436-b867-c2f6641d060b"); + mediumPriority.setName("Medium Priority"); + mediumPriority.setStyle("color:orange"); + mediumPriority.setRank(2); + mediumPriority.setRetired(false); + flagService.savePriority(mediumPriority); + + Priority lowPriority = new Priority(); + lowPriority.setUuid("728bf278-ba81-4436-b867-c2f6641d060c"); + lowPriority.setName("Low Priority"); + lowPriority.setStyle("color:yellow"); + lowPriority.setRank(3); + lowPriority.setRetired(false); + flagService.savePriority(lowPriority); + + // Create tags + Tag hivTag = new Tag(); + hivTag.setUuid("526bf278-ba81-4436-b867-c2f6641d060a"); + hivTag.setName("HIV"); + hivTag.setRetired(false); + flagService.saveTag(hivTag); + + Tag clinicalTag = new Tag(); + clinicalTag.setUuid("627bf278-ba81-4436-b867-c2f6641d060b"); + clinicalTag.setName("Clinical"); + clinicalTag.setRetired(false); + flagService.saveTag(clinicalTag); + + Tag urgentTag = new Tag(); + urgentTag.setUuid("728bf278-ba81-4436-b867-c2f6641d060c"); + urgentTag.setName("Urgent"); + urgentTag.setRetired(false); + flagService.saveTag(urgentTag); + + { + // To be edited - create a flag that will be updated + Flag flag = new Flag(); + flag.setUuid("f279d252-g6ge-5ffd-ce4f-744cef2d0717"); + flag.setName("Test Flag"); + flag.setCriteria("SELECT patient_id FROM patient WHERE patient_id = 99"); + flag.setEvaluator("org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator"); + flag.setMessage("Old test message"); + flag.setPriority(lowPriority); + flag.setEnabled(false); + flag.setRetired(false); + flagService.saveFlag(flag); + } + + { + // To be retired + Flag flag = new Flag(); + flag.setUuid("g38ae363-h7hf-6gge-df5g-855dfg3e1828"); + flag.setName("Retired Flag"); + flag.setCriteria("SELECT patient_id FROM patient WHERE patient_id = 3"); + flag.setEvaluator("org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator"); + flag.setMessage("Retired message"); + flag.setPriority(lowPriority); + flag.setEnabled(true); + flag.setRetired(false); + flagService.saveFlag(flag); + } + } + + @Test + public void load_shouldLoadFlagsAccordingToCsvFiles() { + // Replay + loader.load(); + + // Verify creation + { + Flag flag = flagService.getFlagByUuid("e168c141-f5fd-4eec-bd3e-633bed1c9606"); + assertNotNull(flag); + assertEquals("HIV Positive", flag.getName()); + assertEquals("SELECT patient_id FROM patient WHERE patient_id = 2", flag.getCriteria()); + assertEquals("org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator", flag.getEvaluator()); + assertEquals("patientflags.message.hivPositive", flag.getMessage()); + assertNotNull(flag.getPriority()); + assertEquals("High Priority", flag.getPriority().getName()); + assertTrue(flag.getEnabled()); + assertNotNull(flag.getTags()); + assertEquals(2, flag.getTags().size()); // Should have HIV and Clinical tags + assertEquals("Flag for HIV positive patients", flag.getDescription()); + } + + // Verify edition + { + Flag flag = flagService.getFlagByUuid("f279d252-g6ge-5ffd-ce4f-744cef2d0717"); + assertNotNull(flag); + assertEquals("Test Flag", flag.getName()); + assertEquals("SELECT patient_id FROM patient WHERE patient_id = 1", flag.getCriteria()); // Updated + assertEquals("Test message", flag.getMessage()); // Updated + assertNotNull(flag.getPriority()); + assertEquals("Medium Priority", flag.getPriority().getName()); // Updated + assertTrue(flag.getEnabled()); // Updated from false + assertNotNull(flag.getTags()); + assertEquals(1, flag.getTags().size()); // Should have Clinical tag + } + + // Verify retirement + { + Flag flag = flagService.getFlagByUuid("g38ae363-h7hf-6gge-df5g-855dfg3e1828"); + assertTrue(flag.getRetired()); + } + } +} diff --git a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java b/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java new file mode 100644 index 00000000..df86c8ad --- /dev/null +++ b/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java @@ -0,0 +1,89 @@ +package org.openmrs.module.initializer.api.patientflags; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; +import org.openmrs.module.patientflags.Priority; +import org.openmrs.module.patientflags.api.FlagService; +import org.openmrs.module.initializer.api.DomainBaseModuleContextSensitive_2_4_patientflags_test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +public class PrioritiesLoaderIntegrationTest extends DomainBaseModuleContextSensitive_2_4_patientflags_test { + + @Autowired + @Qualifier("flagService") + private FlagService flagService; + + @Autowired + private PrioritiesLoader loader; + + @Before + public void setup() throws Exception { + executeDataSet("testdata/test-concepts-2.4.xml"); + + { + // To be edited + Priority priority = new Priority(); + priority.setUuid("526bf278-ba81-4436-b867-c2f6641d060a"); + priority.setName("High Priority"); + priority.setStyle("color:blue"); + priority.setRank(10); + priority.setRetired(false); + flagService.savePriority(priority); + } + + { + // To be retired + Priority priority = new Priority(); + priority.setUuid("829bf278-ba81-4436-b867-c2f6641d060d"); + priority.setName("Very Low Priority"); + priority.setStyle("color:gray"); + priority.setRank(4); + priority.setRetired(false); + flagService.savePriority(priority); + } + } + + @Test + public void load_shouldLoadPrioritiesAccordingToCsvFiles() { + // Replay + loader.load(); + + // Verify creation + { + Priority priority = flagService.getPriorityByUuid("627bf278-ba81-4436-b867-c2f6641d060b"); + assertNotNull(priority); + assertEquals("Medium Priority", priority.getName()); + assertEquals("color:orange", priority.getStyle()); + assertEquals(Integer.valueOf(2), priority.getRank()); + assertEquals("Medium priority flags", priority.getDescription()); + } + + { + Priority priority = flagService.getPriorityByUuid("728bf278-ba81-4436-b867-c2f6641d060c"); + assertNotNull(priority); + assertEquals("Low Priority", priority.getName()); + assertEquals("color:yellow", priority.getStyle()); + assertEquals(Integer.valueOf(3), priority.getRank()); + } + + // Verify edition + { + Priority priority = flagService.getPriorityByUuid("526bf278-ba81-4436-b867-c2f6641d060a"); + assertNotNull(priority); + assertEquals("High Priority", priority.getName()); + assertEquals("color:red", priority.getStyle()); // Updated from blue + assertEquals(Integer.valueOf(1), priority.getRank()); // Updated from 10 + } + + // Verify retirement + { + Priority priority = flagService.getPriorityByUuid("829bf278-ba81-4436-b867-c2f6641d060d"); + assertTrue(priority.getRetired()); + } + } +} diff --git a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java b/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java new file mode 100644 index 00000000..d19340dd --- /dev/null +++ b/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java @@ -0,0 +1,95 @@ +package org.openmrs.module.initializer.api.patientflags; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Before; +import org.junit.Test; +import org.openmrs.Role; +import org.openmrs.api.UserService; +import org.openmrs.module.patientflags.Tag; +import org.openmrs.module.patientflags.api.FlagService; +import org.openmrs.module.initializer.api.DomainBaseModuleContextSensitive_2_4_patientflags_test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +public class TagsLoaderIntegrationTest extends DomainBaseModuleContextSensitive_2_4_patientflags_test { + + @Autowired + @Qualifier("flagService") + private FlagService flagService; + + @Autowired + @Qualifier("userService") + private UserService userService; + + @Autowired + private TagsLoader loader; + + @Before + public void setup() throws Exception { + executeDataSet("testdata/test-concepts-2.4.xml"); + + // Create roles for testing + Role clinicianRole = new Role("Clinician", "Clinician role"); + userService.saveRole(clinicianRole); + + Role nurseRole = new Role("Nurse", "Nurse role"); + userService.saveRole(nurseRole); + + { + // To be edited + Tag tag = new Tag(); + tag.setUuid("526bf278-ba81-4436-b867-c2f6641d060a"); + tag.setName("HIV"); + tag.setRetired(false); + flagService.saveTag(tag); + } + + { + // To be retired + Tag tag = new Tag(); + tag.setUuid("829bf278-ba81-4436-b867-c2f6641d060d"); + tag.setName("Deprecated"); + tag.setRetired(false); + flagService.saveTag(tag); + } + } + + @Test + public void load_shouldLoadTagsAccordingToCsvFiles() { + // Replay + loader.load(); + + // Verify creation + { + Tag tag = flagService.getTagByUuid("627bf278-ba81-4436-b867-c2f6641d060b"); + assertNotNull(tag); + assertEquals("Clinical", tag.getName()); + assertEquals("General clinical flags", tag.getDescription()); + assertNotNull(tag.getRoles()); + assertEquals(2, tag.getRoles().size()); // Should have Clinician and Nurse roles + } + + { + Tag tag = flagService.getTagByUuid("728bf278-ba81-4436-b867-c2f6641d060c"); + assertNotNull(tag); + assertEquals("Urgent", tag.getName()); + } + + // Verify edition + { + Tag tag = flagService.getTagByUuid("526bf278-ba81-4436-b867-c2f6641d060a"); + assertNotNull(tag); + assertEquals("HIV", tag.getName()); + assertEquals("Tags for HIV-related flags", tag.getDescription()); + } + + // Verify retirement + { + Tag tag = flagService.getTagByUuid("829bf278-ba81-4436-b867-c2f6641d060d"); + assertTrue(tag.getRetired()); + } + } +} diff --git a/api-2.4/src/test/resources/test-hibernate.cfg.xml b/api-2.4/src/test/resources/test-hibernate.cfg.xml index e8d4e48f..a99efab0 100644 --- a/api-2.4/src/test/resources/test-hibernate.cfg.xml +++ b/api-2.4/src/test/resources/test-hibernate.cfg.xml @@ -9,5 +9,11 @@ + + + + + + diff --git a/api-2.4/src/test/resources/testAppDataDir/configuration/flagpriorities/priorities.csv b/api-2.4/src/test/resources/testAppDataDir/configuration/flagpriorities/priorities.csv new file mode 100644 index 00000000..48d71c47 --- /dev/null +++ b/api-2.4/src/test/resources/testAppDataDir/configuration/flagpriorities/priorities.csv @@ -0,0 +1,6 @@ +uuid,Void/Retire,name,style,rank,description +526bf278-ba81-4436-b867-c2f6641d060a,,High Priority,color:red,1,High priority flags +627bf278-ba81-4436-b867-c2f6641d060b,,Medium Priority,color:orange,2,Medium priority flags +728bf278-ba81-4436-b867-c2f6641d060c,,Low Priority,color:yellow,3,Low priority flags +829bf278-ba81-4436-b867-c2f6641d060d,true,Very Low Priority,color:gray,4,Very low priority flags + diff --git a/api-2.4/src/test/resources/testAppDataDir/configuration/flags/flags.csv b/api-2.4/src/test/resources/testAppDataDir/configuration/flags/flags.csv new file mode 100644 index 00000000..f7929d86 --- /dev/null +++ b/api-2.4/src/test/resources/testAppDataDir/configuration/flags/flags.csv @@ -0,0 +1,5 @@ +uuid,Void/Retire,name,criteria,evaluator,message,priority,enabled,tags,description +e168c141-f5fd-4eec-bd3e-633bed1c9606,,HIV Positive,SELECT patient_id FROM patient WHERE patient_id = 2,org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator,patientflags.message.hivPositive,High Priority,true,HIV;Clinical,Flag for HIV positive patients +f279d252-g6ge-5ffd-ce4f-744cef2d0717,,Test Flag,SELECT patient_id FROM patient WHERE patient_id = 1,org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator,Test message,Medium Priority,true,Clinical,Test flag for unit testing +g38ae363-h7hf-6gge-df5g-855dfg3e1828,true,Retired Flag,SELECT patient_id FROM patient WHERE patient_id = 3,org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator,Retired message,Low Priority,true,Urgent,This flag should be retired + diff --git a/api-2.4/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv b/api-2.4/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv new file mode 100644 index 00000000..ed6b9977 --- /dev/null +++ b/api-2.4/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv @@ -0,0 +1,6 @@ +uuid,Void/Retire,name,roles,display points,description +526bf278-ba81-4436-b867-c2f6641d060a,,HIV,,Patient Summary,Tags for HIV-related flags +627bf278-ba81-4436-b867-c2f6641d060b,,Clinical,Clinician;Nurse,Patient Summary;Patient Dashboard,General clinical flags +728bf278-ba81-4436-b867-c2f6641d060c,,Urgent,,,Urgent flags +829bf278-ba81-4436-b867-c2f6641d060d,true,Deprecated,,,Deprecated flags + diff --git a/api/src/main/java/org/openmrs/module/initializer/Domain.java b/api/src/main/java/org/openmrs/module/initializer/Domain.java index af0af6d4..0f95cfc1 100644 --- a/api/src/main/java/org/openmrs/module/initializer/Domain.java +++ b/api/src/main/java/org/openmrs/module/initializer/Domain.java @@ -30,6 +30,9 @@ public enum Domain { BILLABLE_SERVICES, PAYMENT_MODES, CASH_POINTS, + FLAG_PRIORITIES, + FLAG_TAGS, + FLAGS, PROGRAMS, PROGRAM_WORKFLOWS, PROGRAM_WORKFLOW_STATES, diff --git a/pom.xml b/pom.xml index 334818c0..9cdb107b 100644 --- a/pom.xml +++ b/pom.xml @@ -77,6 +77,7 @@ 1.6.0 1.1.0 2.0.2 + 3.0.9-SNAPSHOT 1.0.0 diff --git a/readme/flagpriorities.md b/readme/flagpriorities.md new file mode 100644 index 00000000..58b3fe09 --- /dev/null +++ b/readme/flagpriorities.md @@ -0,0 +1,39 @@ +## Domain 'flagpriorities' +The **Flag Priorities** subfolder contains CSV import files for saving Priority entities which are used to determine the visual styling and importance level of patient flags. Below is a possible example of its content: + +```bash +flagpriorities/ + ├──priorities.csv + └── ... +``` +Here are the possible headers with a sample data set: + +| Uuid | name | style | rank | description | +|--------------------------------------|-------------|----------------|----------------|----------------| +| 526bf278-ba81-4436-b867-c2f6641d060a | High Priority | color:red | 1 | High priority flags | +| 627bf278-ba81-4436-b867-c2f6641d060b | Medium Priority | color:orange | 2 | Medium priority flags | + +Let's review the headers as below + +###### Header `UUID` *(optional)* +This unique identifier represents the different priorities. + +###### Header `Name` *(required)* +This is the descriptive name of the priority. + +###### Header `Style` *(required)* +This is the CSS style string applied to flags with this priority (e.g., "color:red", "background-color:yellow"). + +###### Header `Rank` *(required)* +This is an integer value representing the priority rank. Lower numbers indicate higher priority. + +###### Header `Description` *(optional)* +A description of the priority. + +#### Requirements +* The [patientflags module](https://github.com/openmrs/openmrs-module-patientflags) version 3.0 or higher must be installed +* The OpenMRS version must be 2.2 or higher + +#### Further examples: +Please look at the test configuration folder for sample import files for all domains, see [here](../api-2.4/src/test/resources/testAppDataDir/configuration). + diff --git a/readme/flags.md b/readme/flags.md new file mode 100644 index 00000000..fa056296 --- /dev/null +++ b/readme/flags.md @@ -0,0 +1,53 @@ +## Domain 'flags' +The **Flags** subfolder contains CSV import files for saving Patient Flags which are used to mark patients with specific conditions or criteria. Below is a possible example of its content: + +```bash +flags/ + ├──flags.csv + └── ... +``` +Here are the possible headers with a sample data set: + +| Uuid | name | criteria | evaluator | message | priority | enabled | tags | description | +|--------------------------------------|-------------|-----------------------------|----------------|----------------|----------------|----------------|----------------|----------------| +| 526bf278-ba81-4436-b867-c2f6641d060a | HIV Positive | SELECT patient_id FROM patient WHERE ... | org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator | patientflags.message.hivPositive | High Priority | true | HIV;Clinical | Flag for HIV positive patients | + +Let's review the headers as below + +###### Header `UUID` *(optional)* +This unique identifier represents the different flags. + +###### Header `Name` *(required)* +This is the descriptive name of the flag. + +###### Header `Criteria` *(required)* +This is the criteria expression used to determine whether a flag should be triggered for a patient. The format depends on the evaluator type being used. + +###### Header `Evaluator` *(required)* +This is the fully qualified class name of the FlagEvaluator implementation to use when evaluating the flag. Examples: +- `org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator` - for SQL-based flags +- `org.openmrs.module.patientflags.evaluator.GroovyFlagEvaluator` - for Groovy script-based flags +- `org.openmrs.module.drools.patientflags.DroolsFlagEvaluator` - for Drools session-based flags + +###### Header `Message` *(required)* +This is the message key (from message properties) or the actual message text to display when the flag is triggered. + +###### Header `Priority` *(optional)* +This references a Priority entity by UUID or name. The priority determines the visual styling and importance level of the flag. + +###### Header `Enabled` *(optional)* +Whether the flag is enabled (true/false). Defaults to `true` if not specified. + +###### Header `Tags` *(optional)* +A semi-colon separated list of Tag identifiers (UUID or name) associated with the flag. Tags can be used to categorize and filter flags. + +###### Header `Description` *(optional)* +A description of the flag. + +#### Requirements +* The [patientflags module](https://github.com/openmrs/openmrs-module-patientflags) version 3.0 or higher must be installed +* The OpenMRS version must be 2.2 or higher + +#### Further examples: +Please look at the test configuration folder for sample import files for all domains, see [here](../api-2.4/src/test/resources/testAppDataDir/configuration). + diff --git a/readme/flagtags.md b/readme/flagtags.md new file mode 100644 index 00000000..38894307 --- /dev/null +++ b/readme/flagtags.md @@ -0,0 +1,39 @@ +## Domain 'flagtags' +The **Flag Tags** subfolder contains CSV import files for saving Tag entities which are used to categorize and filter patient flags. Below is a possible example of its content: + +```bash +flagtags/ + ├──tags.csv + └── ... +``` +Here are the possible headers with a sample data set: + +| Uuid | name | roles | display points | description | +|--------------------------------------|-------------|----------------|----------------|----------------| +| 526bf278-ba81-4436-b867-c2f6641d060a | HIV | Clinician;Nurse | Patient Summary | Tags for HIV-related flags | +| 627bf278-ba81-4436-b867-c2f6641d060b | Clinical | | Patient Summary;Patient Dashboard | General clinical flags | + +Let's review the headers as below + +###### Header `UUID` *(optional)* +This unique identifier represents the different tags. + +###### Header `Name` *(required)* +This is the descriptive name of the tag. + +###### Header `Roles` *(optional)* +A semi-colon separated list of Role identifiers (UUID or name). Flags associated with this tag will be visible to users with these roles. + +###### Header `Display Points` *(optional)* +A semi-colon separated list of DisplayPoint identifiers (UUID or name). Flags associated with this tag will be displayed at these display points. + +###### Header `Description` *(optional)* +A description of the tag. + +#### Requirements +* The [patientflags module](https://github.com/openmrs/openmrs-module-patientflags) version 3.0 or higher must be installed +* The OpenMRS version must be 2.2 or higher + +#### Further examples: +Please look at the test configuration folder for sample import files for all domains, see [here](../api-2.4/src/test/resources/testAppDataDir/configuration). + From 569dac0bdbb05dd82b7f6c065bf46abaeb2f5ac1 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Fri, 5 Dec 2025 15:22:25 -0500 Subject: [PATCH 02/12] Add @Component to everything --- .../api/patientflags/DisplayPointListParser.java | 2 ++ .../initializer/api/patientflags/FlagsCsvParser.java | 5 ++++- .../api/patientflags/FlagsLineProcessor.java | 5 ++++- .../initializer/api/patientflags/FlagsLoader.java | 2 ++ .../api/patientflags/PrioritiesCsvParser.java | 5 ++++- .../api/patientflags/PrioritiesLoader.java | 2 ++ .../api/patientflags/PriorityLineProcessor.java | 2 ++ .../api/patientflags/TagLineProcessor.java | 5 ++++- .../initializer/api/patientflags/TagListParser.java | 2 ++ .../initializer/api/patientflags/TagsCsvParser.java | 5 ++++- .../initializer/api/patientflags/TagsLoader.java | 2 ++ .../api/patientflags/TagsLoaderIntegrationTest.java | 12 ++++++++++++ .../testAppDataDir/configuration/flagtags/tags.csv | 1 - 13 files changed, 44 insertions(+), 6 deletions(-) diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java index 9e98c3fd..a81da500 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java @@ -7,11 +7,13 @@ import org.openmrs.module.initializer.api.utils.ListParser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; /** * Parses a list of DisplayPoint identifiers (UUID or name) and fetches the corresponding * DisplayPoint entities. */ +@Component("initializer.displayPointListParser") @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class DisplayPointListParser extends ListParser { diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java index ae07ef60..c8b4d178 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java @@ -10,17 +10,20 @@ import org.openmrs.module.initializer.api.CsvParser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; /** * Parses CSV files for Flag entities. */ +@Component @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class FlagsCsvParser extends CsvParser> { private final FlagService flagService; @Autowired - public FlagsCsvParser(@Qualifier("flagService") FlagService flagService, FlagsLineProcessor processor) { + public FlagsCsvParser(@Qualifier("flagService") FlagService flagService, + @Qualifier("initializer.flagsLineProcessor") FlagsLineProcessor processor) { super(processor); this.flagService = flagService; } diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java index 8e0a589d..573285ac 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java @@ -13,10 +13,12 @@ import org.openmrs.module.initializer.api.CsvLine; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; /** * Processes CSV lines for Flag entities. */ +@Component("initializer.flagsLineProcessor") @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class FlagsLineProcessor extends BaseLineProcessor { @@ -37,7 +39,8 @@ public class FlagsLineProcessor extends BaseLineProcessor { private TagListParser tagListParser; @Autowired - public FlagsLineProcessor(@Qualifier("flagService") FlagService flagService, TagListParser tagListParser) { + public FlagsLineProcessor(@Qualifier("flagService") FlagService flagService, + @Qualifier("initializer.tagListParser") TagListParser tagListParser) { this.flagService = flagService; this.tagListParser = tagListParser; } diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java index 8c581222..f471ca02 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java @@ -4,10 +4,12 @@ import org.openmrs.module.patientflags.Flag; import org.openmrs.module.initializer.api.loaders.BaseCsvLoader; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; /** * Loads Flags from CSV files. */ +@Component @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class FlagsLoader extends BaseCsvLoader { diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java index a4cece9f..7baad3bd 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java @@ -10,17 +10,20 @@ import org.openmrs.module.initializer.api.CsvParser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; /** * Parses CSV files for Priority entities. */ +@Component @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class PrioritiesCsvParser extends CsvParser> { private final FlagService flagService; @Autowired - public PrioritiesCsvParser(@Qualifier("flagService") FlagService flagService, PriorityLineProcessor processor) { + public PrioritiesCsvParser(@Qualifier("flagService") FlagService flagService, + @Qualifier("initializer.priorityLineProcessor") PriorityLineProcessor processor) { super(processor); this.flagService = flagService; } diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoader.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoader.java index 25633485..6f47eecf 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoader.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoader.java @@ -4,10 +4,12 @@ import org.openmrs.module.patientflags.Priority; import org.openmrs.module.initializer.api.loaders.BaseCsvLoader; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; /** * Loads Priorities from CSV files. */ +@Component @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class PrioritiesLoader extends BaseCsvLoader { diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java index 110c763b..0751d1c3 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java @@ -5,10 +5,12 @@ import org.openmrs.module.patientflags.Priority; import org.openmrs.module.initializer.api.BaseLineProcessor; import org.openmrs.module.initializer.api.CsvLine; +import org.springframework.stereotype.Component; /** * Processes CSV lines for Priority entities. */ +@Component("initializer.priorityLineProcessor") @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class PriorityLineProcessor extends BaseLineProcessor { diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java index 50066986..bda5d850 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java @@ -14,10 +14,12 @@ import org.openmrs.module.initializer.api.utils.RoleListParser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; /** * Processes CSV lines for Tag entities. */ +@Component("initializer.tagLineProcessor") @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class TagLineProcessor extends BaseLineProcessor { @@ -30,7 +32,8 @@ public class TagLineProcessor extends BaseLineProcessor { private DisplayPointListParser displayPointListParser; @Autowired - public TagLineProcessor(RoleListParser roleListParser, DisplayPointListParser displayPointListParser) { + public TagLineProcessor(RoleListParser roleListParser, + @Qualifier("initializer.displayPointListParser") DisplayPointListParser displayPointListParser) { this.roleListParser = roleListParser; this.displayPointListParser = displayPointListParser; } diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java index 003c9713..e0a27f88 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java @@ -7,10 +7,12 @@ import org.openmrs.module.initializer.api.utils.ListParser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; /** * Parses a list of Tag identifiers (UUID or name) and fetches the corresponding Tag entities. */ +@Component("initializer.tagListParser") @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class TagListParser extends ListParser { diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java index 57890fff..70334065 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java @@ -10,17 +10,20 @@ import org.openmrs.module.initializer.api.CsvParser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; /** * Parses CSV files for Tag entities. */ +@Component @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class TagsCsvParser extends CsvParser> { private final FlagService flagService; @Autowired - public TagsCsvParser(@Qualifier("flagService") FlagService flagService, TagLineProcessor processor) { + public TagsCsvParser(@Qualifier("flagService") FlagService flagService, + @Qualifier("initializer.tagLineProcessor") TagLineProcessor processor) { super(processor); this.flagService = flagService; } diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java index 84e28a01..f16f402c 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java @@ -4,10 +4,12 @@ import org.openmrs.module.patientflags.Tag; import org.openmrs.module.initializer.api.loaders.BaseCsvLoader; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; /** * Loads Tags from CSV files. */ +@Component @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class TagsLoader extends BaseCsvLoader { diff --git a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java b/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java index d19340dd..1f005b2d 100644 --- a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java +++ b/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java @@ -8,6 +8,7 @@ import org.junit.Test; import org.openmrs.Role; import org.openmrs.api.UserService; +import org.openmrs.module.patientflags.DisplayPoint; import org.openmrs.module.patientflags.Tag; import org.openmrs.module.patientflags.api.FlagService; import org.openmrs.module.initializer.api.DomainBaseModuleContextSensitive_2_4_patientflags_test; @@ -38,6 +39,17 @@ public void setup() throws Exception { Role nurseRole = new Role("Nurse", "Nurse role"); userService.saveRole(nurseRole); + // Create display points for testing + DisplayPoint patientSummary = new DisplayPoint("Patient Summary"); + patientSummary.setUuid("a1b2c3d4-e5f6-7890-abcd-ef1234567890"); + patientSummary.setRetired(false); + flagService.saveDisplayPoint(patientSummary); + + DisplayPoint patientDashboard = new DisplayPoint("Patient Dashboard"); + patientDashboard.setUuid("b2c3d4e5-f6a7-8901-bcde-f12345678901"); + patientDashboard.setRetired(false); + flagService.saveDisplayPoint(patientDashboard); + { // To be edited Tag tag = new Tag(); diff --git a/api-2.4/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv b/api-2.4/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv index ed6b9977..9ecd06f0 100644 --- a/api-2.4/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv +++ b/api-2.4/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv @@ -3,4 +3,3 @@ uuid,Void/Retire,name,roles,display points,description 627bf278-ba81-4436-b867-c2f6641d060b,,Clinical,Clinician;Nurse,Patient Summary;Patient Dashboard,General clinical flags 728bf278-ba81-4436-b867-c2f6641d060c,,Urgent,,,Urgent flags 829bf278-ba81-4436-b867-c2f6641d060d,true,Deprecated,,,Deprecated flags - From 826773d872ed94c975babb18ce36c75d91c20e03 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Fri, 5 Dec 2025 15:41:10 -0500 Subject: [PATCH 03/12] Add patientflags to more POMs --- api-2.5/pom.xml | 7 +++++++ api-2.7/pom.xml | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/api-2.5/pom.xml b/api-2.5/pom.xml index 37584a8c..5b8d183d 100644 --- a/api-2.5/pom.xml +++ b/api-2.5/pom.xml @@ -101,6 +101,13 @@ provided + + org.openmrs.module + patientflags-api + ${patientflagsVersion} + test + + diff --git a/api-2.7/pom.xml b/api-2.7/pom.xml index e3466913..a9de41eb 100644 --- a/api-2.7/pom.xml +++ b/api-2.7/pom.xml @@ -79,6 +79,13 @@ provided + + org.openmrs.module + patientflags-api + ${patientflagsVersion} + test + + From 798d5585ba851ec8a4890de2228f1026898b7142 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Fri, 5 Dec 2025 18:43:25 -0500 Subject: [PATCH 04/12] Get tests working; work around non-nullable Priority style --- .../patientflags/PriorityLineProcessor.java | 21 +++++++++++-------- .../FlagsLoaderIntegrationTest.java | 11 +++++----- .../PrioritiesLoaderIntegrationTest.java | 10 ++++----- .../flagpriorities/priorities.csv | 7 +++---- .../configuration/flags/flags.csv | 7 +++---- .../configuration/flagtags/tags.csv | 2 +- readme/flagpriorities.md | 6 +++--- readme/flags.md | 2 +- readme/flagtags.md | 6 +++--- 9 files changed, 37 insertions(+), 35 deletions(-) diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java index 0751d1c3..831c78fb 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java @@ -23,18 +23,21 @@ public Priority fill(Priority priority, CsvLine line) throws IllegalArgumentExce priority.setName(line.get(HEADER_NAME, true)); priority.setDescription(line.get(HEADER_DESC)); - // Required style - priority.setStyle(line.get(HEADER_STYLE, true)); + // Optional style + String styleStr = line.getString(HEADER_STYLE, ""); + if (StringUtils.isBlank(styleStr)) { + priority.setStyle("/**/"); // field is non-nullable but is not used; set to empty comment + } else { + priority.setStyle(styleStr.trim()); + } // Required rank String rankStr = line.get(HEADER_RANK, true); - if (StringUtils.isNotBlank(rankStr)) { - try { - priority.setRank(Integer.parseInt(rankStr.trim())); - } - catch (NumberFormatException e) { - throw new IllegalArgumentException("The rank value '" + rankStr + "' could not be parsed as an integer."); - } + try { + priority.setRank(Integer.parseInt(rankStr.trim())); + } + catch (NumberFormatException e) { + throw new IllegalArgumentException("The rank value '" + rankStr + "' could not be parsed as an integer."); } return priority; diff --git a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java b/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java index b9d9580c..28b8df74 100644 --- a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java +++ b/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java @@ -78,7 +78,8 @@ public void setup() throws Exception { Flag flag = new Flag(); flag.setUuid("f279d252-g6ge-5ffd-ce4f-744cef2d0717"); flag.setName("Test Flag"); - flag.setCriteria("SELECT patient_id FROM patient WHERE patient_id = 99"); + + flag.setCriteria("SELECT a.patient_id FROM allergy a where a.allergen_type = 'CATS'"); flag.setEvaluator("org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator"); flag.setMessage("Old test message"); flag.setPriority(lowPriority); @@ -92,7 +93,7 @@ public void setup() throws Exception { Flag flag = new Flag(); flag.setUuid("g38ae363-h7hf-6gge-df5g-855dfg3e1828"); flag.setName("Retired Flag"); - flag.setCriteria("SELECT patient_id FROM patient WHERE patient_id = 3"); + flag.setCriteria("SELECT a.patient_id FROM allergy a where a.allergen_type = 'DOGS'"); flag.setEvaluator("org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator"); flag.setMessage("Retired message"); flag.setPriority(lowPriority); @@ -112,7 +113,7 @@ public void load_shouldLoadFlagsAccordingToCsvFiles() { Flag flag = flagService.getFlagByUuid("e168c141-f5fd-4eec-bd3e-633bed1c9606"); assertNotNull(flag); assertEquals("HIV Positive", flag.getName()); - assertEquals("SELECT patient_id FROM patient WHERE patient_id = 2", flag.getCriteria()); + assertEquals("SELECT c.patient_id FROM condition c where c.condition_name = 'HIV'", flag.getCriteria()); assertEquals("org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator", flag.getEvaluator()); assertEquals("patientflags.message.hivPositive", flag.getMessage()); assertNotNull(flag.getPriority()); @@ -123,12 +124,12 @@ public void load_shouldLoadFlagsAccordingToCsvFiles() { assertEquals("Flag for HIV positive patients", flag.getDescription()); } - // Verify edition + // Verify editing { Flag flag = flagService.getFlagByUuid("f279d252-g6ge-5ffd-ce4f-744cef2d0717"); assertNotNull(flag); assertEquals("Test Flag", flag.getName()); - assertEquals("SELECT patient_id FROM patient WHERE patient_id = 1", flag.getCriteria()); // Updated + assertEquals("SELECT a.patient_id FROM allergy a where a.allergen_type = 'DRUG'", flag.getCriteria()); // Updated assertEquals("Test message", flag.getMessage()); // Updated assertNotNull(flag.getPriority()); assertEquals("Medium Priority", flag.getPriority().getName()); // Updated diff --git a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java b/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java index df86c8ad..df987a7a 100644 --- a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java +++ b/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java @@ -53,12 +53,12 @@ public void load_shouldLoadPrioritiesAccordingToCsvFiles() { // Replay loader.load(); - // Verify creation + // Verify creation with blank style (null, legacy field not used in OpenMRS 3+) { Priority priority = flagService.getPriorityByUuid("627bf278-ba81-4436-b867-c2f6641d060b"); assertNotNull(priority); assertEquals("Medium Priority", priority.getName()); - assertEquals("color:orange", priority.getStyle()); + assertEquals("/**/", priority.getStyle()); // Blank style stored as null assertEquals(Integer.valueOf(2), priority.getRank()); assertEquals("Medium priority flags", priority.getDescription()); } @@ -67,11 +67,11 @@ public void load_shouldLoadPrioritiesAccordingToCsvFiles() { Priority priority = flagService.getPriorityByUuid("728bf278-ba81-4436-b867-c2f6641d060c"); assertNotNull(priority); assertEquals("Low Priority", priority.getName()); - assertEquals("color:yellow", priority.getStyle()); + assertEquals("/**/", priority.getStyle()); // Blank style stored as null assertEquals(Integer.valueOf(3), priority.getRank()); } - // Verify edition + // Verify editing { Priority priority = flagService.getPriorityByUuid("526bf278-ba81-4436-b867-c2f6641d060a"); assertNotNull(priority); @@ -80,7 +80,7 @@ public void load_shouldLoadPrioritiesAccordingToCsvFiles() { assertEquals(Integer.valueOf(1), priority.getRank()); // Updated from 10 } - // Verify retirement + // Verify retirement (style set to placeholder from CSV) { Priority priority = flagService.getPriorityByUuid("829bf278-ba81-4436-b867-c2f6641d060d"); assertTrue(priority.getRetired()); diff --git a/api-2.4/src/test/resources/testAppDataDir/configuration/flagpriorities/priorities.csv b/api-2.4/src/test/resources/testAppDataDir/configuration/flagpriorities/priorities.csv index 48d71c47..8b00108d 100644 --- a/api-2.4/src/test/resources/testAppDataDir/configuration/flagpriorities/priorities.csv +++ b/api-2.4/src/test/resources/testAppDataDir/configuration/flagpriorities/priorities.csv @@ -1,6 +1,5 @@ uuid,Void/Retire,name,style,rank,description 526bf278-ba81-4436-b867-c2f6641d060a,,High Priority,color:red,1,High priority flags -627bf278-ba81-4436-b867-c2f6641d060b,,Medium Priority,color:orange,2,Medium priority flags -728bf278-ba81-4436-b867-c2f6641d060c,,Low Priority,color:yellow,3,Low priority flags -829bf278-ba81-4436-b867-c2f6641d060d,true,Very Low Priority,color:gray,4,Very low priority flags - +627bf278-ba81-4436-b867-c2f6641d060b,,Medium Priority,,2,Medium priority flags +728bf278-ba81-4436-b867-c2f6641d060c,,Low Priority,,3,Low priority flags +829bf278-ba81-4436-b867-c2f6641d060d,true,Very Low Priority,,4, \ No newline at end of file diff --git a/api-2.4/src/test/resources/testAppDataDir/configuration/flags/flags.csv b/api-2.4/src/test/resources/testAppDataDir/configuration/flags/flags.csv index f7929d86..a3238360 100644 --- a/api-2.4/src/test/resources/testAppDataDir/configuration/flags/flags.csv +++ b/api-2.4/src/test/resources/testAppDataDir/configuration/flags/flags.csv @@ -1,5 +1,4 @@ uuid,Void/Retire,name,criteria,evaluator,message,priority,enabled,tags,description -e168c141-f5fd-4eec-bd3e-633bed1c9606,,HIV Positive,SELECT patient_id FROM patient WHERE patient_id = 2,org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator,patientflags.message.hivPositive,High Priority,true,HIV;Clinical,Flag for HIV positive patients -f279d252-g6ge-5ffd-ce4f-744cef2d0717,,Test Flag,SELECT patient_id FROM patient WHERE patient_id = 1,org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator,Test message,Medium Priority,true,Clinical,Test flag for unit testing -g38ae363-h7hf-6gge-df5g-855dfg3e1828,true,Retired Flag,SELECT patient_id FROM patient WHERE patient_id = 3,org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator,Retired message,Low Priority,true,Urgent,This flag should be retired - +e168c141-f5fd-4eec-bd3e-633bed1c9606,,HIV Positive,SELECT c.patient_id FROM condition c where c.condition_name = 'HIV',org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator,patientflags.message.hivPositive,High Priority,true,HIV;Clinical,Flag for HIV positive patients +f279d252-g6ge-5ffd-ce4f-744cef2d0717,,Test Flag,SELECT a.patient_id FROM allergy a where a.allergen_type = 'DRUG',org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator,Test message,Medium Priority,true,Clinical,Test flag for unit testing +g38ae363-h7hf-6gge-df5g-855dfg3e1828,true,Retired Flag,SELECT a.patient_id FROM allergy a where a.allergen_type = 'DOGS',org.openmrs.module.patientflags.evaluator.SqlFlagEvaluator,Retired message,Low Priority,true,Urgent,This flag should be retired \ No newline at end of file diff --git a/api-2.4/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv b/api-2.4/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv index 9ecd06f0..735d7123 100644 --- a/api-2.4/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv +++ b/api-2.4/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv @@ -2,4 +2,4 @@ uuid,Void/Retire,name,roles,display points,description 526bf278-ba81-4436-b867-c2f6641d060a,,HIV,,Patient Summary,Tags for HIV-related flags 627bf278-ba81-4436-b867-c2f6641d060b,,Clinical,Clinician;Nurse,Patient Summary;Patient Dashboard,General clinical flags 728bf278-ba81-4436-b867-c2f6641d060c,,Urgent,,,Urgent flags -829bf278-ba81-4436-b867-c2f6641d060d,true,Deprecated,,,Deprecated flags +829bf278-ba81-4436-b867-c2f6641d060d,true,Deprecated,,,Deprecated flags \ No newline at end of file diff --git a/readme/flagpriorities.md b/readme/flagpriorities.md index 58b3fe09..6160a100 100644 --- a/readme/flagpriorities.md +++ b/readme/flagpriorities.md @@ -21,15 +21,15 @@ This unique identifier represents the different priorities. ###### Header `Name` *(required)* This is the descriptive name of the priority. -###### Header `Style` *(required)* -This is the CSS style string applied to flags with this priority (e.g., "color:red", "background-color:yellow"). - ###### Header `Rank` *(required)* This is an integer value representing the priority rank. Lower numbers indicate higher priority. ###### Header `Description` *(optional)* A description of the priority. +###### Header `Style` *(optional)* +LEGACY: Only used for RefApp 2.x. This is the CSS style string applied to flags with this priority (e.g., "color:red", "background-color:yellow"). In OpenMRS 3+, this is configured on the frontend. + #### Requirements * The [patientflags module](https://github.com/openmrs/openmrs-module-patientflags) version 3.0 or higher must be installed * The OpenMRS version must be 2.2 or higher diff --git a/readme/flags.md b/readme/flags.md index fa056296..5792345a 100644 --- a/readme/flags.md +++ b/readme/flags.md @@ -39,7 +39,7 @@ This references a Priority entity by UUID or name. The priority determines the v Whether the flag is enabled (true/false). Defaults to `true` if not specified. ###### Header `Tags` *(optional)* -A semi-colon separated list of Tag identifiers (UUID or name) associated with the flag. Tags can be used to categorize and filter flags. +A semi-colon separated list of Tag identifiers (UUID or name) associated with the flag. Tags are used to determine where flags are displayed in the UI. ###### Header `Description` *(optional)* A description of the flag. diff --git a/readme/flagtags.md b/readme/flagtags.md index 38894307..3c408fe7 100644 --- a/readme/flagtags.md +++ b/readme/flagtags.md @@ -24,12 +24,12 @@ This is the descriptive name of the tag. ###### Header `Roles` *(optional)* A semi-colon separated list of Role identifiers (UUID or name). Flags associated with this tag will be visible to users with these roles. -###### Header `Display Points` *(optional)* -A semi-colon separated list of DisplayPoint identifiers (UUID or name). Flags associated with this tag will be displayed at these display points. - ###### Header `Description` *(optional)* A description of the tag. +###### Header `Display Points` *(optional)* +LEGACY: Only used for RefApp 2.x. A semi-colon separated list of DisplayPoint identifiers (UUID or name). Flags associated with this tag will be displayed at these display points in RefApp 2.x. In OpenMRS 3+, this is configured on the frontend. + #### Requirements * The [patientflags module](https://github.com/openmrs/openmrs-module-patientflags) version 3.0 or higher must be installed * The OpenMRS version must be 2.2 or higher From c93076b687d3aded98446020204c8e2fbd17af45 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Mon, 8 Dec 2025 14:13:25 -0500 Subject: [PATCH 05/12] Add patientflags to aware_of_module --- omod/src/main/resources/config.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/omod/src/main/resources/config.xml b/omod/src/main/resources/config.xml index 11c574cb..c32e444e 100644 --- a/omod/src/main/resources/config.xml +++ b/omod/src/main/resources/config.xml @@ -76,6 +76,9 @@ org.openmrs.module.billing + + org.openmrs.module.patientflags + From 080b0e79d70c2e29f132511b2c9b55f9de81b2d5 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Tue, 20 Jan 2026 09:03:59 -0500 Subject: [PATCH 06/12] README: add flags module compatibility & changelog line --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 5cb8d70f..7928f6f4 100644 --- a/README.md +++ b/README.md @@ -186,6 +186,7 @@ mvn clean package * Bahmni I.e Apps 1.1.0 (*compatible*) * Billing 1.1.0 (*compatible*) * Data Filter 1.0.0 (*compatible*) +* Flags 3.0.8 (*compatible*) * HTML Form Entry 4.0.0 (*compatible*) * ID Gen 4.3 (*compatible*) * Metadata Sharing 1.2.2 (*compatible*) @@ -221,6 +222,9 @@ See the [documentation on Initializer's logging properties](readme/rtprops.md#lo ## Releases notes +#### Version 2.11.0 +* Added support for patient flags (flags, flagpriorities, flagtags) domains + #### Version 2.10.0 * Support enhanced methods for loading htmlforms when running htmlformentry 5.5.0+ * Support loading drug ingredients within the drug domain, for compatible OpenMRS versions From d31a140a8b2570a18b31f3bab7293c8f8cc38bde Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Tue, 20 Jan 2026 09:13:03 -0500 Subject: [PATCH 07/12] Fix component names --- .../api/patientflags/DisplayPointListParser.java | 2 +- .../initializer/api/patientflags/FlagsCsvParser.java | 2 +- .../initializer/api/patientflags/FlagsLineProcessor.java | 2 +- .../module/initializer/api/patientflags/FlagsLoader.java | 2 +- .../initializer/api/patientflags/PrioritiesCsvParser.java | 4 ++-- .../initializer/api/patientflags/PrioritiesLoader.java | 2 +- .../api/patientflags/PriorityLineProcessor.java | 2 +- .../initializer/api/patientflags/TagLineProcessor.java | 8 ++++---- .../initializer/api/patientflags/TagListParser.java | 2 +- .../initializer/api/patientflags/TagsCsvParser.java | 4 ++-- .../module/initializer/api/patientflags/TagsLoader.java | 2 +- 11 files changed, 16 insertions(+), 16 deletions(-) diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java index a81da500..28d0c52f 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java @@ -13,7 +13,7 @@ * Parses a list of DisplayPoint identifiers (UUID or name) and fetches the corresponding * DisplayPoint entities. */ -@Component("initializer.displayPointListParser") +@Component("initializer.flagDisplayPointListParser") @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class DisplayPointListParser extends ListParser { diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java index c8b4d178..a596d41c 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java @@ -15,7 +15,7 @@ /** * Parses CSV files for Flag entities. */ -@Component +@Component("initializer.flagFlagsCsvParser") @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class FlagsCsvParser extends CsvParser> { diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java index 573285ac..4f4a207f 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java @@ -40,7 +40,7 @@ public class FlagsLineProcessor extends BaseLineProcessor { @Autowired public FlagsLineProcessor(@Qualifier("flagService") FlagService flagService, - @Qualifier("initializer.tagListParser") TagListParser tagListParser) { + @Qualifier("initializer.flagTagListParser") TagListParser tagListParser) { this.flagService = flagService; this.tagListParser = tagListParser; } diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java index f471ca02..592f0973 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java @@ -9,7 +9,7 @@ /** * Loads Flags from CSV files. */ -@Component +@Component("initializer.flagFlagsLoader") @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class FlagsLoader extends BaseCsvLoader { diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java index 7baad3bd..8c6b8e24 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java @@ -15,7 +15,7 @@ /** * Parses CSV files for Priority entities. */ -@Component +@Component("initializer.flagPrioritiesCsvParser") @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class PrioritiesCsvParser extends CsvParser> { @@ -23,7 +23,7 @@ public class PrioritiesCsvParser extends CsvParser { diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java index 831c78fb..0214a839 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java @@ -10,7 +10,7 @@ /** * Processes CSV lines for Priority entities. */ -@Component("initializer.priorityLineProcessor") +@Component("initializer.flagPriorityLineProcessor") @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class PriorityLineProcessor extends BaseLineProcessor { diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java index bda5d850..9d2c512a 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java @@ -19,7 +19,7 @@ /** * Processes CSV lines for Tag entities. */ -@Component("initializer.tagLineProcessor") +@Component("initializer.flagTagLineProcessor") @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class TagLineProcessor extends BaseLineProcessor { @@ -33,7 +33,7 @@ public class TagLineProcessor extends BaseLineProcessor { @Autowired public TagLineProcessor(RoleListParser roleListParser, - @Qualifier("initializer.displayPointListParser") DisplayPointListParser displayPointListParser) { + @Qualifier("initializer.flagDisplayPointListParser") DisplayPointListParser displayPointListParser) { this.roleListParser = roleListParser; this.displayPointListParser = displayPointListParser; } @@ -46,7 +46,7 @@ public Tag fill(Tag tag, CsvLine line) throws IllegalArgumentException { // Optional roles String rolesStr = line.getString(HEADER_ROLES, ""); if (StringUtils.isNotBlank(rolesStr)) { - Set roles = new HashSet(roleListParser.parseList(rolesStr)); + Set roles = new HashSet<>(roleListParser.parseList(rolesStr)); tag.setRoles(roles); } else if (tag.getRoles() != null) { // Clear roles if not specified (only if roles were previously set) @@ -56,7 +56,7 @@ public Tag fill(Tag tag, CsvLine line) throws IllegalArgumentException { // Optional display points String displayPointsStr = line.getString(HEADER_DISPLAY_POINTS, ""); if (StringUtils.isNotBlank(displayPointsStr)) { - Set displayPoints = new HashSet(displayPointListParser.parseList(displayPointsStr)); + Set displayPoints = new HashSet<>(displayPointListParser.parseList(displayPointsStr)); tag.setDisplayPoints(displayPoints); } else if (tag.getDisplayPoints() != null) { // Clear display points if not specified (only if display points were previously set) diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java index e0a27f88..2179cef4 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java @@ -12,7 +12,7 @@ /** * Parses a list of Tag identifiers (UUID or name) and fetches the corresponding Tag entities. */ -@Component("initializer.tagListParser") +@Component("initializer.flagTagListParser") @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class TagListParser extends ListParser { diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java index 70334065..64a0b9e0 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java @@ -15,7 +15,7 @@ /** * Parses CSV files for Tag entities. */ -@Component +@Component("initializer.flagTagsCsvParser") @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class TagsCsvParser extends CsvParser> { @@ -23,7 +23,7 @@ public class TagsCsvParser extends CsvParser> { @Autowired public TagsCsvParser(@Qualifier("flagService") FlagService flagService, - @Qualifier("initializer.tagLineProcessor") TagLineProcessor processor) { + @Qualifier("initializer.flagTagLineProcessor") TagLineProcessor processor) { super(processor); this.flagService = flagService; } diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java index f16f402c..efb56cba 100644 --- a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java +++ b/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java @@ -9,7 +9,7 @@ /** * Loads Tags from CSV files. */ -@Component +@Component("initializer.flagTagsLoader") @OpenmrsProfile(modules = { "patientflags:3.* - 9.*" }) public class TagsLoader extends BaseCsvLoader { From 9e80d04345d3abce15d8cfa38bd190f9c0593731 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Tue, 20 Jan 2026 10:25:15 -0500 Subject: [PATCH 08/12] Move flags from api-2.4/ to api/ --- api-2.4/pom.xml | 9 +-------- api/pom.xml | 6 ++++++ .../api/patientflags/DisplayPointListParser.java | 0 .../initializer/api/patientflags/FlagsCsvParser.java | 0 .../initializer/api/patientflags/FlagsLineProcessor.java | 0 .../module/initializer/api/patientflags/FlagsLoader.java | 0 .../api/patientflags/PrioritiesCsvParser.java | 0 .../initializer/api/patientflags/PrioritiesLoader.java | 0 .../api/patientflags/PriorityLineProcessor.java | 0 .../initializer/api/patientflags/TagLineProcessor.java | 0 .../initializer/api/patientflags/TagListParser.java | 0 .../initializer/api/patientflags/TagsCsvParser.java | 0 .../module/initializer/api/patientflags/TagsLoader.java | 0 ...mainBaseModuleContextSensitive_patientflags_test.java | 4 ++-- .../api/patientflags/FlagsLoaderIntegrationTest.java | 6 +++--- .../patientflags/PrioritiesLoaderIntegrationTest.java | 6 +++--- .../api/patientflags/TagsLoaderIntegrationTest.java | 6 +++--- api/src/test/resources/test-hibernate.cfg.xml | 6 ++++++ .../configuration/flagpriorities/priorities.csv | 0 .../testAppDataDir/configuration/flags/flags.csv | 0 .../testAppDataDir/configuration/flagtags/tags.csv | 0 21 files changed, 24 insertions(+), 19 deletions(-) rename {api-2.4 => api}/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java (100%) rename {api-2.4 => api}/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java (100%) rename {api-2.4 => api}/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java (100%) rename {api-2.4 => api}/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java (100%) rename {api-2.4 => api}/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java (100%) rename {api-2.4 => api}/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoader.java (100%) rename {api-2.4 => api}/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java (100%) rename {api-2.4 => api}/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java (100%) rename {api-2.4 => api}/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java (100%) rename {api-2.4 => api}/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java (100%) rename {api-2.4 => api}/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java (100%) rename api-2.4/src/test/java/org/openmrs/module/initializer/api/DomainBaseModuleContextSensitive_2_4_patientflags_test.java => api/src/test/java/org/openmrs/module/initializer/api/DomainBaseModuleContextSensitive_patientflags_test.java (85%) rename {api-2.4 => api}/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java (97%) rename {api-2.4 => api}/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java (95%) rename {api-2.4 => api}/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java (96%) rename {api-2.4 => api}/src/test/resources/testAppDataDir/configuration/flagpriorities/priorities.csv (100%) rename {api-2.4 => api}/src/test/resources/testAppDataDir/configuration/flags/flags.csv (100%) rename {api-2.4 => api}/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv (100%) diff --git a/api-2.4/pom.xml b/api-2.4/pom.xml index f5dc4480..2189d238 100644 --- a/api-2.4/pom.xml +++ b/api-2.4/pom.xml @@ -86,14 +86,7 @@ ${billingVersion} provided - - - org.openmrs.module - patientflags-api - ${patientflagsVersion} - provided - - + org.openmrs.module stockmanagement-api diff --git a/api/pom.xml b/api/pom.xml index f519ffc2..16f7f9ec 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -36,6 +36,12 @@ org.openmrs.module openconceptlab-api + + org.openmrs.module + patientflags-api + ${patientflagsVersion} + provided + diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java b/api/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java similarity index 100% rename from api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java rename to api/src/main/java/org/openmrs/module/initializer/api/patientflags/DisplayPointListParser.java diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java b/api/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java similarity index 100% rename from api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java rename to api/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java b/api/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java similarity index 100% rename from api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java rename to api/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLineProcessor.java diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java b/api/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java similarity index 100% rename from api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java rename to api/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsLoader.java diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java b/api/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java similarity index 100% rename from api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java rename to api/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesCsvParser.java diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoader.java b/api/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoader.java similarity index 100% rename from api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoader.java rename to api/src/main/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoader.java diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java b/api/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java similarity index 100% rename from api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java rename to api/src/main/java/org/openmrs/module/initializer/api/patientflags/PriorityLineProcessor.java diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java b/api/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java similarity index 100% rename from api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java rename to api/src/main/java/org/openmrs/module/initializer/api/patientflags/TagLineProcessor.java diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java b/api/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java similarity index 100% rename from api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java rename to api/src/main/java/org/openmrs/module/initializer/api/patientflags/TagListParser.java diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java b/api/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java similarity index 100% rename from api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java rename to api/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsCsvParser.java diff --git a/api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java b/api/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java similarity index 100% rename from api-2.4/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java rename to api/src/main/java/org/openmrs/module/initializer/api/patientflags/TagsLoader.java diff --git a/api-2.4/src/test/java/org/openmrs/module/initializer/api/DomainBaseModuleContextSensitive_2_4_patientflags_test.java b/api/src/test/java/org/openmrs/module/initializer/api/DomainBaseModuleContextSensitive_patientflags_test.java similarity index 85% rename from api-2.4/src/test/java/org/openmrs/module/initializer/api/DomainBaseModuleContextSensitive_2_4_patientflags_test.java rename to api/src/test/java/org/openmrs/module/initializer/api/DomainBaseModuleContextSensitive_patientflags_test.java index c448d792..3ccbfe8f 100644 --- a/api-2.4/src/test/java/org/openmrs/module/initializer/api/DomainBaseModuleContextSensitive_2_4_patientflags_test.java +++ b/api/src/test/java/org/openmrs/module/initializer/api/DomainBaseModuleContextSensitive_patientflags_test.java @@ -18,9 +18,9 @@ /** * This allows to perform Spring context sensitive tests when patientflags module is a dependency. */ -public abstract class DomainBaseModuleContextSensitive_2_4_patientflags_test extends DomainBaseModuleContextSensitiveTest { +public abstract class DomainBaseModuleContextSensitive_patientflags_test extends DomainBaseModuleContextSensitiveTest { - public DomainBaseModuleContextSensitive_2_4_patientflags_test() { + public DomainBaseModuleContextSensitive_patientflags_test() { super(); { Module mod = new Module("", "patientflags", "", "", "", "3.0.0"); diff --git a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java b/api/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java similarity index 97% rename from api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java rename to api/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java index 28b8df74..067f9b70 100644 --- a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java +++ b/api/src/test/java/org/openmrs/module/initializer/api/patientflags/FlagsLoaderIntegrationTest.java @@ -10,11 +10,11 @@ import org.openmrs.module.patientflags.Priority; import org.openmrs.module.patientflags.Tag; import org.openmrs.module.patientflags.api.FlagService; -import org.openmrs.module.initializer.api.DomainBaseModuleContextSensitive_2_4_patientflags_test; +import org.openmrs.module.initializer.api.DomainBaseModuleContextSensitive_patientflags_test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -public class FlagsLoaderIntegrationTest extends DomainBaseModuleContextSensitive_2_4_patientflags_test { +public class FlagsLoaderIntegrationTest extends DomainBaseModuleContextSensitive_patientflags_test { @Autowired @Qualifier("flagService") @@ -25,7 +25,7 @@ public class FlagsLoaderIntegrationTest extends DomainBaseModuleContextSensitive @Before public void setup() throws Exception { - executeDataSet("testdata/test-concepts-2.4.xml"); + executeDataSet("testdata/test-concepts.xml"); // Set up prerequisites: Priorities and Tags that flags will reference diff --git a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java b/api/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java similarity index 95% rename from api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java rename to api/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java index df987a7a..83b8c2d4 100644 --- a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java +++ b/api/src/test/java/org/openmrs/module/initializer/api/patientflags/PrioritiesLoaderIntegrationTest.java @@ -8,11 +8,11 @@ import org.junit.Test; import org.openmrs.module.patientflags.Priority; import org.openmrs.module.patientflags.api.FlagService; -import org.openmrs.module.initializer.api.DomainBaseModuleContextSensitive_2_4_patientflags_test; +import org.openmrs.module.initializer.api.DomainBaseModuleContextSensitive_patientflags_test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -public class PrioritiesLoaderIntegrationTest extends DomainBaseModuleContextSensitive_2_4_patientflags_test { +public class PrioritiesLoaderIntegrationTest extends DomainBaseModuleContextSensitive_patientflags_test { @Autowired @Qualifier("flagService") @@ -23,7 +23,7 @@ public class PrioritiesLoaderIntegrationTest extends DomainBaseModuleContextSens @Before public void setup() throws Exception { - executeDataSet("testdata/test-concepts-2.4.xml"); + executeDataSet("testdata/test-concepts.xml"); { // To be edited diff --git a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java b/api/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java similarity index 96% rename from api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java rename to api/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java index 1f005b2d..74804a3c 100644 --- a/api-2.4/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java +++ b/api/src/test/java/org/openmrs/module/initializer/api/patientflags/TagsLoaderIntegrationTest.java @@ -11,11 +11,11 @@ import org.openmrs.module.patientflags.DisplayPoint; import org.openmrs.module.patientflags.Tag; import org.openmrs.module.patientflags.api.FlagService; -import org.openmrs.module.initializer.api.DomainBaseModuleContextSensitive_2_4_patientflags_test; +import org.openmrs.module.initializer.api.DomainBaseModuleContextSensitive_patientflags_test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; -public class TagsLoaderIntegrationTest extends DomainBaseModuleContextSensitive_2_4_patientflags_test { +public class TagsLoaderIntegrationTest extends DomainBaseModuleContextSensitive_patientflags_test { @Autowired @Qualifier("flagService") @@ -30,7 +30,7 @@ public class TagsLoaderIntegrationTest extends DomainBaseModuleContextSensitive_ @Before public void setup() throws Exception { - executeDataSet("testdata/test-concepts-2.4.xml"); + executeDataSet("testdata/test-concepts.xml"); // Create roles for testing Role clinicianRole = new Role("Clinician", "Clinician role"); diff --git a/api/src/test/resources/test-hibernate.cfg.xml b/api/src/test/resources/test-hibernate.cfg.xml index 00f0e76b..f49a1d7a 100644 --- a/api/src/test/resources/test-hibernate.cfg.xml +++ b/api/src/test/resources/test-hibernate.cfg.xml @@ -34,6 +34,12 @@ + + + + + + diff --git a/api-2.4/src/test/resources/testAppDataDir/configuration/flagpriorities/priorities.csv b/api/src/test/resources/testAppDataDir/configuration/flagpriorities/priorities.csv similarity index 100% rename from api-2.4/src/test/resources/testAppDataDir/configuration/flagpriorities/priorities.csv rename to api/src/test/resources/testAppDataDir/configuration/flagpriorities/priorities.csv diff --git a/api-2.4/src/test/resources/testAppDataDir/configuration/flags/flags.csv b/api/src/test/resources/testAppDataDir/configuration/flags/flags.csv similarity index 100% rename from api-2.4/src/test/resources/testAppDataDir/configuration/flags/flags.csv rename to api/src/test/resources/testAppDataDir/configuration/flags/flags.csv diff --git a/api-2.4/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv b/api/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv similarity index 100% rename from api-2.4/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv rename to api/src/test/resources/testAppDataDir/configuration/flagtags/tags.csv From 79441895de7ce77233bf16704cf2ef7fdf14ef37 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Tue, 20 Jan 2026 10:31:41 -0500 Subject: [PATCH 09/12] Check for blank UUID before trying to load flag --- .../module/initializer/api/patientflags/FlagsCsvParser.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/api/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java b/api/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java index a596d41c..584b177d 100644 --- a/api/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java +++ b/api/src/main/java/org/openmrs/module/initializer/api/patientflags/FlagsCsvParser.java @@ -36,7 +36,10 @@ public Domain getDomain() { @Override public Flag bootstrap(CsvLine line) throws IllegalArgumentException { String uuid = line.getUuid(); - Flag flag = flagService.getFlagByUuid(uuid); + Flag flag = null; + if (uuid != null && uuid != "") { + flag = flagService.getFlagByUuid(uuid); + } if (flag == null) { flag = new Flag(); if (StringUtils.isNotBlank(uuid)) { From 307f572e483d5f5631916e390731ad606f20fe60 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Mon, 26 Jan 2026 10:11:46 -0500 Subject: [PATCH 10/12] Clean up merge, clean up extra POM references --- api-2.5/pom.xml | 7 ------- api-2.7/pom.xml | 5 ----- api/pom.xml | 6 ------ pom.xml | 7 +++++++ 4 files changed, 7 insertions(+), 18 deletions(-) diff --git a/api-2.5/pom.xml b/api-2.5/pom.xml index 23cd6ce2..58a3eb2c 100644 --- a/api-2.5/pom.xml +++ b/api-2.5/pom.xml @@ -101,13 +101,6 @@ provided - - org.openmrs.module - patientflags-api - ${patientflagsVersion} - test - - diff --git a/api-2.7/pom.xml b/api-2.7/pom.xml index 3342fd07..551fc389 100644 --- a/api-2.7/pom.xml +++ b/api-2.7/pom.xml @@ -82,11 +82,6 @@ org.openmrs.module - patientflags-api - ${patientflagsVersion} - test - - billing-api ${billing2Version} provided diff --git a/api/pom.xml b/api/pom.xml index 8964fc06..8a2002e8 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -36,12 +36,6 @@ org.openmrs.module openconceptlab-api - - org.openmrs.module - patientflags-api - ${patientflagsVersion} - provided - diff --git a/pom.xml b/pom.xml index 083f01f4..5723f37f 100644 --- a/pom.xml +++ b/pom.xml @@ -206,6 +206,13 @@ provided + + org.openmrs.module + patientflags-api + ${patientflagsVersion} + provided + + org.openmrs.module idgen-api From 0758495ae83b557aad67a716fa77b7efd56d260f Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Tue, 3 Feb 2026 10:26:02 -0500 Subject: [PATCH 11/12] Fix Flags version compatibility in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c6accee..e06c1a76 100644 --- a/README.md +++ b/README.md @@ -187,7 +187,7 @@ mvn clean package * Bahmni I.e Apps 1.1.0 (*compatible*) * Billing 1.1.0 (*compatible*) * Data Filter 1.0.0 (*compatible*) -* Flags 3.0.8 (*compatible*) +* Flags 3.0.9 (*compatible*) * HTML Form Entry 4.0.0 (*compatible*) * ID Gen 4.3 (*compatible*) * Metadata Sharing 1.2.2 (*compatible*) From d408a9e22b66c52db762373b1a6eb4e9927c4d16 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Tue, 3 Feb 2026 16:28:16 -0500 Subject: [PATCH 12/12] Use release version of patientflags 3.0.9 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5723f37f..93704093 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ 1.6.0 1.1.0 2.0.2 - 3.0.9-SNAPSHOT + 3.0.9 1.0.0