diff --git a/README.md b/README.md
index 674b18452..b976212a7 100644
--- a/README.md
+++ b/README.md
@@ -134,6 +134,7 @@ This is the list of currently supported domains in their loading order:
1. [Bahmni Appointment Specialities (CSV files)](readme/appointmentspecialities.md)
1. [Bahmni Appointment Service Definitions (CSV files)](readme/appointmentservices.md#domain-appointmentservicedefinitions)
1. [Bahmni Appointment Service Types (CSV files)](readme/appointmentservices.md#domain-appointmentservicetypes)
+1. [Queues (CSV files)](readme/queues.md#domain-queues)
1. [Data Filter Entity-Basis Mappings (CSV files)](readme/datafiltermappings.md)
1. [Metadata Sets (CSV files)](readme/mdm.md#domain-metadatasets)
1. [Metadata Set Members (CSV files)](readme/mdm.md#domain-metadatasetmembers)
@@ -188,6 +189,7 @@ See the [documentation on Initializer's logging properties](readme/rtprops.md#lo
## Releases notes
#### Version 2.7.0
+* Added support for Queues
#### Version 2.6.0
* Added support for Cohort Attribute types
diff --git a/api-2.3/pom.xml b/api-2.3/pom.xml
index 51f5d3a04..e3b88098f 100644
--- a/api-2.3/pom.xml
+++ b/api-2.3/pom.xml
@@ -66,6 +66,13 @@
org.openmrs.module
openconceptlab-api
+
+
+ org.openmrs.module
+ queue-api
+ ${queueVersion}
+ provided
+
diff --git a/api-2.3/src/main/java/org/openmrs/module/initializer/api/queues/QueueCsvParser.java b/api-2.3/src/main/java/org/openmrs/module/initializer/api/queues/QueueCsvParser.java
new file mode 100644
index 000000000..aa0d2989c
--- /dev/null
+++ b/api-2.3/src/main/java/org/openmrs/module/initializer/api/queues/QueueCsvParser.java
@@ -0,0 +1,44 @@
+package org.openmrs.module.initializer.api.queues;
+
+import org.apache.commons.lang3.StringUtils;
+import org.openmrs.annotation.OpenmrsProfile;
+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.openmrs.module.queue.api.QueueService;
+import org.openmrs.module.queue.model.Queue;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+
+@OpenmrsProfile(modules = { "queue:*" })
+public class QueueCsvParser extends CsvParser> {
+
+ private final QueueService queueService;
+
+ @Autowired
+ public QueueCsvParser(@Qualifier("queue.QueueService") QueueService queueService, QueueLineProcessor processor) {
+ super(processor);
+ this.queueService = queueService;
+ }
+
+ @Override
+ public Domain getDomain() {
+ return Domain.QUEUES;
+ }
+
+ @Override
+ public Queue bootstrap(CsvLine line) throws IllegalArgumentException {
+ String uuid = line.getUuid();
+ Queue queue = queueService.getQueueByUuid(uuid).orElse(new Queue());
+ if (StringUtils.isNotBlank(uuid)) {
+ queue.setUuid(uuid);
+ }
+ return queue;
+ }
+
+ @Override
+ public Queue save(Queue instance) {
+ return queueService.createQueue(instance);
+ }
+}
diff --git a/api-2.3/src/main/java/org/openmrs/module/initializer/api/queues/QueueLineProcessor.java b/api-2.3/src/main/java/org/openmrs/module/initializer/api/queues/QueueLineProcessor.java
new file mode 100644
index 000000000..d675ceecd
--- /dev/null
+++ b/api-2.3/src/main/java/org/openmrs/module/initializer/api/queues/QueueLineProcessor.java
@@ -0,0 +1,58 @@
+package org.openmrs.module.initializer.api.queues;
+
+import org.apache.commons.lang3.StringUtils;
+import org.openmrs.annotation.OpenmrsProfile;
+import org.openmrs.api.ConceptService;
+import org.openmrs.api.LocationService;
+import org.openmrs.module.initializer.api.BaseLineProcessor;
+import org.openmrs.module.initializer.api.CsvLine;
+import org.openmrs.module.initializer.api.utils.Utils;
+import org.openmrs.module.queue.model.Queue;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+
+/**
+ * This is the first level line processor for a Queue
+ */
+@OpenmrsProfile(modules = { "queue:*" })
+public class QueueLineProcessor extends BaseLineProcessor {
+
+ protected static String HEADER_SERVICE = "service";
+
+ protected static String HEADER_LOCATION = "location";
+
+ private final ConceptService conceptService;
+
+ private final LocationService locationService;
+
+ @Autowired
+ public QueueLineProcessor(@Qualifier("conceptService") ConceptService conceptService,
+ @Qualifier("locationService") LocationService locationService) {
+ super();
+ this.conceptService = conceptService;
+ this.locationService = locationService;
+ }
+
+ @Override
+ public Queue fill(Queue queue, CsvLine line) throws IllegalArgumentException {
+ queue.setName(line.get(HEADER_NAME, true));
+ queue.setDescription(line.getString(HEADER_DESC));
+ if (line.containsHeader(HEADER_SERVICE)) {
+ String service = line.getString(HEADER_SERVICE);
+ if (StringUtils.isNotBlank(service)) {
+ queue.setService(Utils.fetchConcept(service, conceptService));
+ } else {
+ queue.setService(null);
+ }
+ }
+ if (line.containsHeader(HEADER_LOCATION)) {
+ String location = line.getString(HEADER_LOCATION);
+ if (StringUtils.isNotBlank(location)) {
+ queue.setLocation(Utils.fetchLocation(location, locationService));
+ } else {
+ queue.setLocation(null);
+ }
+ }
+ return queue;
+ }
+}
diff --git a/api-2.3/src/main/java/org/openmrs/module/initializer/api/queues/QueueLoader.java b/api-2.3/src/main/java/org/openmrs/module/initializer/api/queues/QueueLoader.java
new file mode 100644
index 000000000..5c01970c2
--- /dev/null
+++ b/api-2.3/src/main/java/org/openmrs/module/initializer/api/queues/QueueLoader.java
@@ -0,0 +1,15 @@
+package org.openmrs.module.initializer.api.queues;
+
+import org.openmrs.annotation.OpenmrsProfile;
+import org.openmrs.module.initializer.api.loaders.BaseCsvLoader;
+import org.openmrs.module.queue.model.Queue;
+import org.springframework.beans.factory.annotation.Autowired;
+
+@OpenmrsProfile(modules = { "queue:*" })
+public class QueueLoader extends BaseCsvLoader {
+
+ @Autowired
+ public void setParser(QueueCsvParser parser) {
+ this.parser = parser;
+ }
+}
diff --git a/api-2.3/src/test/java/org/openmrs/module/initializer/DomainBaseModuleContextSensitive_2_3_Test.java b/api-2.3/src/test/java/org/openmrs/module/initializer/DomainBaseModuleContextSensitive_2_3_Test.java
index cc58c3dd3..19f3f997d 100644
--- a/api-2.3/src/test/java/org/openmrs/module/initializer/DomainBaseModuleContextSensitive_2_3_Test.java
+++ b/api-2.3/src/test/java/org/openmrs/module/initializer/DomainBaseModuleContextSensitive_2_3_Test.java
@@ -9,12 +9,26 @@
*/
package org.openmrs.module.initializer;
+import org.openmrs.module.Module;
+import org.openmrs.module.ModuleFactory;
+
+import java.io.File;
+
/**
* This allows to perform Spring context sensitive tests when Data Filter API is a dependency. In
* that case it is necessary for each context sensitive test to update the search index.
*/
public abstract class DomainBaseModuleContextSensitive_2_3_Test extends DomainBaseModuleContextSensitiveTest {
+ public DomainBaseModuleContextSensitive_2_3_Test() {
+ super();
+ {
+ Module mod = new Module("", "queue", "", "", "", "1.0.0");
+ mod.setFile(new File(""));
+ ModuleFactory.getStartedModulesMap().put(mod.getModuleId(), mod);
+ }
+ }
+
@Override
public void updateSearchIndex() {
// to prevent Data Filter's 'Illegal Record Access'
diff --git a/api-2.3/src/test/java/org/openmrs/module/initializer/api/queues/QueueLoaderIntegrationTest.java b/api-2.3/src/test/java/org/openmrs/module/initializer/api/queues/QueueLoaderIntegrationTest.java
new file mode 100644
index 000000000..b8eed537d
--- /dev/null
+++ b/api-2.3/src/test/java/org/openmrs/module/initializer/api/queues/QueueLoaderIntegrationTest.java
@@ -0,0 +1,69 @@
+/**
+ * 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.queues;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.openmrs.module.initializer.DomainBaseModuleContextSensitive_2_3_Test;
+import org.openmrs.module.queue.api.QueueService;
+import org.openmrs.module.queue.model.Queue;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+
+public class QueueLoaderIntegrationTest extends DomainBaseModuleContextSensitive_2_3_Test {
+
+ @Autowired
+ @Qualifier("queue.QueueService")
+ private QueueService queueService;
+
+ @Autowired
+ private QueueLoader loader;
+
+ @Before
+ public void setup() throws Exception {
+ executeDataSet("testdata/test-queues.xml");
+ }
+
+ @Test
+ public void load_shouldLoadAccordingToCsvFiles() throws Exception {
+
+ // Initial Queue
+ {
+ Queue queue = queueService.getQueueByUuid("2a0e0eee-6888-11ee-ab8d-0242ac120002").orElse(null);
+ Assert.assertNotNull(queue);
+ Assert.assertEquals("Initial Queue", queue.getName());
+ Assert.assertEquals("", queue.getDescription());
+ Assert.assertEquals(2001, queue.getService().getConceptId().intValue());
+ Assert.assertEquals(1, queue.getLocation().getLocationId().intValue());
+ }
+
+ loader.load();
+
+ // Revised Queue
+ {
+ Queue queue = queueService.getQueueByUuid("2a0e0eee-6888-11ee-ab8d-0242ac120002").orElse(null);
+ Assert.assertNotNull(queue);
+ Assert.assertEquals("Revised Queue", queue.getName());
+ Assert.assertEquals("Revised Description", queue.getDescription());
+ Assert.assertEquals(2002, queue.getService().getConceptId().intValue());
+ Assert.assertEquals(2, queue.getLocation().getLocationId().intValue());
+ }
+ // New Queue
+ {
+ Queue queue = queueService.getQueueByUuid("288db1cc-688a-11ee-ab8d-0242ac120002").orElse(null);
+ Assert.assertNotNull(queue);
+ Assert.assertEquals("New Queue", queue.getName());
+ Assert.assertEquals("New Description", queue.getDescription());
+ Assert.assertEquals(2001, queue.getService().getConceptId().intValue());
+ Assert.assertEquals(3, queue.getLocation().getLocationId().intValue());
+ }
+ }
+}
diff --git a/api-2.3/src/test/resources/testAppDataDir/configuration/queues/queues.csv b/api-2.3/src/test/resources/testAppDataDir/configuration/queues/queues.csv
new file mode 100644
index 000000000..9df55879c
--- /dev/null
+++ b/api-2.3/src/test/resources/testAppDataDir/configuration/queues/queues.csv
@@ -0,0 +1,3 @@
+Uuid,Void/Retire,Name,Description,Service,Location
+2a0e0eee-6888-11ee-ab8d-0242ac120002,,Revised Queue,Revised Description,68b910bd-298c-4ecf-a632-661ae2f446op,Xanadu
+288db1cc-688a-11ee-ab8d-0242ac120002,,New Queue,New Description,Triage,167ce20c-4785-4285-9119-d197268f7f4a
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 c4ae103ca..9f7ac0d3a 100644
--- a/api/src/main/java/org/openmrs/module/initializer/Domain.java
+++ b/api/src/main/java/org/openmrs/module/initializer/Domain.java
@@ -37,6 +37,7 @@ public enum Domain {
APPOINTMENT_SPECIALITIES,
APPOINTMENT_SERVICE_DEFINITIONS,
APPOINTMENT_SERVICE_TYPES,
+ QUEUES,
DATAFILTER_MAPPINGS,
METADATA_SETS,
METADATA_SET_MEMBERS,
diff --git a/api/src/test/resources/testdata/test-queues.xml b/api/src/test/resources/testdata/test-queues.xml
new file mode 100644
index 000000000..37016feb0
--- /dev/null
+++ b/api/src/test/resources/testdata/test-queues.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/omod/src/main/resources/config.xml b/omod/src/main/resources/config.xml
index 0577189fe..c1ed69e08 100644
--- a/omod/src/main/resources/config.xml
+++ b/omod/src/main/resources/config.xml
@@ -56,6 +56,9 @@
org.openmrs.module.fhir2
+
+ org.openmrs.module.queue
+
diff --git a/pom.xml b/pom.xml
index 2477acc22..37ae77927 100644
--- a/pom.xml
+++ b/pom.xml
@@ -71,6 +71,7 @@
1.0.0
+ 1.0.0-SNAPSHOT
1.19.0
diff --git a/readme/queues.md b/readme/queues.md
new file mode 100644
index 000000000..d8559b8d3
--- /dev/null
+++ b/readme/queues.md
@@ -0,0 +1,36 @@
+## Domain 'queues'
+The **queues** subfolder contains CSV import files for saving queues in bulk. This is a possible example of its content:
+```bash
+queues/
+ ├──queues.csv
+ └── ...
+```
+There is currently only one format for the queue CSV line, here are the possible headers with a sample data set:
+
+|Uuid |Void/Retire |Name | Description | Service | Location | _order:1000 |
+| - | - | - | - | - |
+|32176576-1652-4835-8736-826eb0237482|| Clinical Consultation Queue | Consult Queue || Outpatient Service| Outpatient Clinic|
+
+Headers that start with an underscore such as `_order:1000` are metadata headers. The values in the columns under those headers are never read by the CSV parser.
+
+Let's review some important headers.
+
+###### Header `Name` *(mandatory)*
+This is _not_ a localized header.
+
The name is _not_ a secondary identifier to access a queue type. UUID must be provided for each Queue.
+
+###### Header `Description`
+A description is optional and will populate the Queue description
+
+###### Header `Service`
+This is a reference (UUID, same as mapping or name) to an existing Concept that defines the service associated with this Queue
+
+###### Header `Location`
+This is a reference (UUID or name) to an existing Location that defines the Location associated with this Queue
+
+#### Requirements
+* The [queue module](https://github.com/openmrs/openmrs-module-queue) must be installed
+* The OpenMRS version must be 2.3 or higher
+
+#### Further examples:
+Please look at the test configuration folder for sample import files for all domains, see [here](../api/src/test/resources/testAppDataDir/configuration).
diff --git a/validator/pom.xml b/validator/pom.xml
index ed78a858b..8ba3b2029 100644
--- a/validator/pom.xml
+++ b/validator/pom.xml
@@ -350,6 +350,14 @@
runtime
jar
+
+
+ org.openmrs.module
+ queue-api
+ ${queueVersion}
+ runtime
+ jar
+
org.testcontainers