You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by GitBox <gi...@apache.org> on 2018/04/23 18:26:59 UTC

[GitHub] Izakey closed pull request #5: Document the Office API

Izakey closed pull request #5: Document the Office API
URL: https://github.com/apache/fineract-cn-office/pull/5
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/service/build.gradle b/service/build.gradle
index 5a3f9b8..adb216d 100644
--- a/service/build.gradle
+++ b/service/build.gradle
@@ -26,6 +26,7 @@ buildscript {
 
     dependencies {
         classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
+        classpath("org.asciidoctor:asciidoctor-gradle-plugin:1.5.3")
     }
 }
 
@@ -37,6 +38,7 @@ plugins {
 apply from: '../shared.gradle'
 
 apply plugin: 'spring-boot'
+apply plugin: 'org.asciidoctor.convert'
 
 springBoot {
     executable = true
@@ -58,6 +60,23 @@ dependencies {
             [group: 'org.apache.fineract.cn', name: 'mariadb', version: versions.frameworkmariadb],
             [group: 'org.apache.fineract.cn', name: 'command', version: versions.frameworkcommand],
     )
+    testCompile(
+            [group: 'org.apache.fineract.cn.office', name: 'api', version: project.version],
+            [group: 'org.apache.fineract.cn', name: 'api', version: versions.frameworkapi],
+            [group: 'org.apache.fineract.cn', name: 'test', version: versions.frameworktest],
+            [group: 'org.apache.fineract.cn.anubis', name: 'test', version: versions.frameworkanubis],
+            [group: 'org.springframework.restdocs', name: 'spring-restdocs-mockmvc'],
+            [group: 'org.springframework.boot', name: 'spring-boot-starter-test'],
+            [group: 'junit', name: 'junit', version: '4.12']
+    )
+}
+
+asciidoctor {
+    sourceDir 'src/doc/asciidoc/'
+    outputDir 'src/doc/html5'
+    options backend: "html", doctype: "book"
+    attributes "source-highlighter": "highlightjs", \
+                'snippets': file('src/doc/generated-snippets/')
 }
 
 publishToMavenLocal.dependsOn bootRepackage
diff --git a/service/src/doc/asciidoc/api-docs.adoc b/service/src/doc/asciidoc/api-docs.adoc
new file mode 100644
index 0000000..aeef42d
--- /dev/null
+++ b/service/src/doc/asciidoc/api-docs.adoc
@@ -0,0 +1,201 @@
+== Apache Fineract CN Office Management API Documentation ==
+
+== Offices ==
+
+==== Create An Office ====
+
+.curl-request
+include::{snippets}/test-office/should-create-office/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-office/should-create-office/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-office/should-create-office/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-office/should-create-office/httpie-request.adoc[]
+
+==== Get An Office ====
+
+.curl-request
+include::{snippets}/test-office/should-indicate-office-has-external-references/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-office/should-indicate-office-has-external-references/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-office/should-indicate-office-has-external-references/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-office/should-indicate-office-has-external-references/httpie-request.adoc[]
+
+==== Get An Office's Address ====
+
+.curl-request
+include::{snippets}/test-office/should-get-address-of-office/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-office/should-get-address-of-office/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-office/should-get-address-of-office/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-office/should-get-address-of-office/httpie-request.adoc[]
+
+==== Update An Office's Address ====
+
+.curl-request
+include::{snippets}/test-office/should-set-address-of-office/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-office/should-set-address-of-office/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-office/should-set-address-of-office/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-office/should-set-address-of-office/httpie-request.adoc[]
+
+==== Update An Office ====
+
+.curl-request
+include::{snippets}/test-office/should-update-office/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-office/should-update-office/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-office/should-update-office/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-office/should-update-office/httpie-request.adoc[]
+
+==== Delete An Office's Address ====
+
+.curl-request
+include::{snippets}/test-office/should-delete-address-of-office/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-office/should-delete-address-of-office/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-office/should-delete-address-of-office/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-office/should-delete-address-of-office/httpie-request.adoc[]
+
+==== Add A Branch To An Office ====
+
+.curl-request
+include::{snippets}/test-office/should-add-branch/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-office/should-add-branch/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-office/should-add-branch/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-office/should-add-branch/httpie-request.adoc[]
+
+== Employees ==
+
+==== Create An Employee ====
+
+.curl-request
+include::{snippets}/test-employee/should-create-employee/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-employee/should-create-employee/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-employee/should-create-employee/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-employee/should-create-employee/httpie-request.adoc[]
+
+==== Update An Employee ====
+
+.curl-request
+include::{snippets}/test-employee/should-update-employee/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-employee/should-update-employee/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-employee/should-update-employee/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-employee/should-update-employee/httpie-request.adoc[]
+
+==== Get Employees ====
+
+.curl-request
+include::{snippets}/test-employee/should-find-all-employees/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-employee/should-find-all-employees/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-employee/should-find-all-employees/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-employee/should-find-all-employees/httpie-request.adoc[]
+
+==== Get An Office's Employees ====
+
+.curl-request
+include::{snippets}/test-employee/should-find-employees-by-office/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-employee/should-find-employees-by-office/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-employee/should-find-employees-by-office/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-employee/should-find-employees-by-office/httpie-request.adoc[]
+
+==== Update Employee's Contact Details ====
+
+.curl-request
+include::{snippets}/test-employee/should-set-contact-detail-of-employee/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-employee/should-set-contact-detail-of-employee/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-employee/should-set-contact-detail-of-employee/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-employee/should-set-contact-detail-of-employee/httpie-request.adoc[]
+
+==== Delete Employee's Contact Details ====
+
+.curl-request
+include::{snippets}/test-employee/should-delete-contact-detail-of-employee/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-employee/should-delete-contact-detail-of-employee/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-employee/should-delete-contact-detail-of-employee/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-employee/should-delete-contact-detail-of-employee/httpie-request.adoc[]
+
+==== Delete An Employee ====
+
+.curl-request
+include::{snippets}/test-employee/should-delete-employee/curl-request.adoc[]
+
+.http-request
+include::{snippets}/test-employee/should-delete-employee/http-request.adoc[]
+
+.http-response
+include::{snippets}/test-employee/should-delete-employee/http-response.adoc[]
+
+.httpie-request
+include::{snippets}/test-employee/should-delete-employee/httpie-request.adoc[]
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-create-employee/curl-request.adoc b/service/src/doc/generated-snippets/test-employee/should-create-employee/curl-request.adoc
new file mode 100644
index 0000000..32f20ea
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-create-employee/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/office/v1/employees' -i -X POST -H 'Content-Type: application/json' -d 'pmOnIEX1BHG2Zj3CI45It135RjS30UMZ'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-create-employee/http-request.adoc b/service/src/doc/generated-snippets/test-employee/should-create-employee/http-request.adoc
new file mode 100644
index 0000000..2fb0327
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-create-employee/http-request.adoc
@@ -0,0 +1,9 @@
+[source,http,options="nowrap"]
+----
+POST /office/v1/employees HTTP/1.1
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+pmOnIEX1BHG2Zj3CI45It135RjS30UMZ
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-create-employee/http-response.adoc b/service/src/doc/generated-snippets/test-employee/should-create-employee/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-create-employee/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-create-employee/httpie-request.adoc b/service/src/doc/generated-snippets/test-employee/should-create-employee/httpie-request.adoc
new file mode 100644
index 0000000..5678721
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-create-employee/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ echo 'pmOnIEX1BHG2Zj3CI45It135RjS30UMZ' | http POST 'http://localhost:8080/office/v1/employees' 'Content-Type:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-delete-contact-detail-of-employee/curl-request.adoc b/service/src/doc/generated-snippets/test-employee/should-delete-contact-detail-of-employee/curl-request.adoc
new file mode 100644
index 0000000..9d5ae4d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-delete-contact-detail-of-employee/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/office/v1/employees/GNhkajYzqKNwN4QCRkuPbCl5ZhME0LfO/contacts' -i -X DELETE -H 'Content-Type: image/png'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-delete-contact-detail-of-employee/http-request.adoc b/service/src/doc/generated-snippets/test-employee/should-delete-contact-detail-of-employee/http-request.adoc
new file mode 100644
index 0000000..1fe8351
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-delete-contact-detail-of-employee/http-request.adoc
@@ -0,0 +1,7 @@
+[source,http,options="nowrap"]
+----
+DELETE /office/v1/employees/GNhkajYzqKNwN4QCRkuPbCl5ZhME0LfO/contacts HTTP/1.1
+Content-Type: image/png
+Host: localhost:8080
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-delete-contact-detail-of-employee/http-response.adoc b/service/src/doc/generated-snippets/test-employee/should-delete-contact-detail-of-employee/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-delete-contact-detail-of-employee/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-delete-contact-detail-of-employee/httpie-request.adoc b/service/src/doc/generated-snippets/test-employee/should-delete-contact-detail-of-employee/httpie-request.adoc
new file mode 100644
index 0000000..d961296
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-delete-contact-detail-of-employee/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ http DELETE 'http://localhost:8080/office/v1/employees/GNhkajYzqKNwN4QCRkuPbCl5ZhME0LfO/contacts' 'Content-Type:image/png'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-delete-employee/curl-request.adoc b/service/src/doc/generated-snippets/test-employee/should-delete-employee/curl-request.adoc
new file mode 100644
index 0000000..4c3c2f8
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-delete-employee/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/office/v1/employees/FBea9IQEOII3aaR7xv7jBQCN6dEFrqqY' -i -X DELETE -H 'Accept: */*' -H 'Content-Type: application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-delete-employee/http-request.adoc b/service/src/doc/generated-snippets/test-employee/should-delete-employee/http-request.adoc
new file mode 100644
index 0000000..7f87f9a
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-delete-employee/http-request.adoc
@@ -0,0 +1,8 @@
+[source,http,options="nowrap"]
+----
+DELETE /office/v1/employees/FBea9IQEOII3aaR7xv7jBQCN6dEFrqqY HTTP/1.1
+Accept: */*
+Content-Type: application/json
+Host: localhost:8080
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-delete-employee/http-response.adoc b/service/src/doc/generated-snippets/test-employee/should-delete-employee/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-delete-employee/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-delete-employee/httpie-request.adoc b/service/src/doc/generated-snippets/test-employee/should-delete-employee/httpie-request.adoc
new file mode 100644
index 0000000..8b97126
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-delete-employee/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ http DELETE 'http://localhost:8080/office/v1/employees/FBea9IQEOII3aaR7xv7jBQCN6dEFrqqY' 'Accept:*/*' 'Content-Type:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-find-all-employees/curl-request.adoc b/service/src/doc/generated-snippets/test-employee/should-find-all-employees/curl-request.adoc
new file mode 100644
index 0000000..15d0dfe
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-find-all-employees/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/office/v1/employees' -i -H 'Accept: */*'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-find-all-employees/http-request.adoc b/service/src/doc/generated-snippets/test-employee/should-find-all-employees/http-request.adoc
new file mode 100644
index 0000000..b6b410d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-find-all-employees/http-request.adoc
@@ -0,0 +1,7 @@
+[source,http,options="nowrap"]
+----
+GET /office/v1/employees HTTP/1.1
+Accept: */*
+Host: localhost:8080
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-find-all-employees/http-response.adoc b/service/src/doc/generated-snippets/test-employee/should-find-all-employees/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-find-all-employees/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-find-all-employees/httpie-request.adoc b/service/src/doc/generated-snippets/test-employee/should-find-all-employees/httpie-request.adoc
new file mode 100644
index 0000000..78a5d99
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-find-all-employees/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ http GET 'http://localhost:8080/office/v1/employees' 'Accept:*/*'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-find-employees-by-office/curl-request.adoc b/service/src/doc/generated-snippets/test-employee/should-find-employees-by-office/curl-request.adoc
new file mode 100644
index 0000000..15d0dfe
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-find-employees-by-office/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/office/v1/employees' -i -H 'Accept: */*'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-find-employees-by-office/http-request.adoc b/service/src/doc/generated-snippets/test-employee/should-find-employees-by-office/http-request.adoc
new file mode 100644
index 0000000..b6b410d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-find-employees-by-office/http-request.adoc
@@ -0,0 +1,7 @@
+[source,http,options="nowrap"]
+----
+GET /office/v1/employees HTTP/1.1
+Accept: */*
+Host: localhost:8080
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-find-employees-by-office/http-response.adoc b/service/src/doc/generated-snippets/test-employee/should-find-employees-by-office/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-find-employees-by-office/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-find-employees-by-office/httpie-request.adoc b/service/src/doc/generated-snippets/test-employee/should-find-employees-by-office/httpie-request.adoc
new file mode 100644
index 0000000..78a5d99
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-find-employees-by-office/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ http GET 'http://localhost:8080/office/v1/employees' 'Accept:*/*'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-set-contact-detail-of-employee/curl-request.adoc b/service/src/doc/generated-snippets/test-employee/should-set-contact-detail-of-employee/curl-request.adoc
new file mode 100644
index 0000000..9558705
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-set-contact-detail-of-employee/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/office/v1/employees/nqnRpYG4QlyLKtPVrJQDz2mEak2cncBL/contacts' -i -X PUT -H 'Accept: */*' -H 'Content-Type: application/json' -d 'nqnRpYG4QlyLKtPVrJQDz2mEak2cncBL'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-set-contact-detail-of-employee/http-request.adoc b/service/src/doc/generated-snippets/test-employee/should-set-contact-detail-of-employee/http-request.adoc
new file mode 100644
index 0000000..9ecb0f4
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-set-contact-detail-of-employee/http-request.adoc
@@ -0,0 +1,10 @@
+[source,http,options="nowrap"]
+----
+PUT /office/v1/employees/nqnRpYG4QlyLKtPVrJQDz2mEak2cncBL/contacts HTTP/1.1
+Accept: */*
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+nqnRpYG4QlyLKtPVrJQDz2mEak2cncBL
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-set-contact-detail-of-employee/http-response.adoc b/service/src/doc/generated-snippets/test-employee/should-set-contact-detail-of-employee/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-set-contact-detail-of-employee/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-set-contact-detail-of-employee/httpie-request.adoc b/service/src/doc/generated-snippets/test-employee/should-set-contact-detail-of-employee/httpie-request.adoc
new file mode 100644
index 0000000..16206ab
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-set-contact-detail-of-employee/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ echo 'nqnRpYG4QlyLKtPVrJQDz2mEak2cncBL' | http PUT 'http://localhost:8080/office/v1/employees/nqnRpYG4QlyLKtPVrJQDz2mEak2cncBL/contacts' 'Accept:*/*' 'Content-Type:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-update-employee/curl-request.adoc b/service/src/doc/generated-snippets/test-employee/should-update-employee/curl-request.adoc
new file mode 100644
index 0000000..d50308b
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-update-employee/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/office/v1/employees/Z3Qm799gURp8x3jigLf5OAxGfVHDchnp' -i -X PUT -H 'Content-Type: application/json' -d 'Z3Qm799gURp8x3jigLf5OAxGfVHDchnp'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-update-employee/http-request.adoc b/service/src/doc/generated-snippets/test-employee/should-update-employee/http-request.adoc
new file mode 100644
index 0000000..2e893d2
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-update-employee/http-request.adoc
@@ -0,0 +1,9 @@
+[source,http,options="nowrap"]
+----
+PUT /office/v1/employees/Z3Qm799gURp8x3jigLf5OAxGfVHDchnp HTTP/1.1
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+Z3Qm799gURp8x3jigLf5OAxGfVHDchnp
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-update-employee/http-response.adoc b/service/src/doc/generated-snippets/test-employee/should-update-employee/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-update-employee/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-employee/should-update-employee/httpie-request.adoc b/service/src/doc/generated-snippets/test-employee/should-update-employee/httpie-request.adoc
new file mode 100644
index 0000000..c87388c
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-employee/should-update-employee/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ echo 'Z3Qm799gURp8x3jigLf5OAxGfVHDchnp' | http PUT 'http://localhost:8080/office/v1/employees/Z3Qm799gURp8x3jigLf5OAxGfVHDchnp' 'Content-Type:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-add-branch/curl-request.adoc b/service/src/doc/generated-snippets/test-office/should-add-branch/curl-request.adoc
new file mode 100644
index 0000000..25b2d24
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-add-branch/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/office/v1/offices/6j0iKMH44oA1OfJVaHTCLAeutUDVfltO' -i -X PUT -H 'Content-Type: application/json' -d '6j0iKMH44oA1OfJVaHTCLAeutUDVfltO'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-add-branch/http-request.adoc b/service/src/doc/generated-snippets/test-office/should-add-branch/http-request.adoc
new file mode 100644
index 0000000..37a7ada
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-add-branch/http-request.adoc
@@ -0,0 +1,9 @@
+[source,http,options="nowrap"]
+----
+PUT /office/v1/offices/6j0iKMH44oA1OfJVaHTCLAeutUDVfltO HTTP/1.1
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+6j0iKMH44oA1OfJVaHTCLAeutUDVfltO
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-add-branch/http-response.adoc b/service/src/doc/generated-snippets/test-office/should-add-branch/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-add-branch/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-add-branch/httpie-request.adoc b/service/src/doc/generated-snippets/test-office/should-add-branch/httpie-request.adoc
new file mode 100644
index 0000000..57c4097
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-add-branch/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ echo '6j0iKMH44oA1OfJVaHTCLAeutUDVfltO' | http PUT 'http://localhost:8080/office/v1/offices/6j0iKMH44oA1OfJVaHTCLAeutUDVfltO' 'Content-Type:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-create-office/curl-request.adoc b/service/src/doc/generated-snippets/test-office/should-create-office/curl-request.adoc
new file mode 100644
index 0000000..ca94d34
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-create-office/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/office/v1/offices' -i -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -d 'hna7lb2PicYbSK9hkemc7Ta8kBW6e43v'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-create-office/http-request.adoc b/service/src/doc/generated-snippets/test-office/should-create-office/http-request.adoc
new file mode 100644
index 0000000..b14605e
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-create-office/http-request.adoc
@@ -0,0 +1,10 @@
+[source,http,options="nowrap"]
+----
+POST /office/v1/offices HTTP/1.1
+Content-Type: application/json
+Accept: application/json
+Host: localhost:8080
+Content-Length: 32
+
+hna7lb2PicYbSK9hkemc7Ta8kBW6e43v
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-create-office/http-response.adoc b/service/src/doc/generated-snippets/test-office/should-create-office/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-create-office/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-create-office/httpie-request.adoc b/service/src/doc/generated-snippets/test-office/should-create-office/httpie-request.adoc
new file mode 100644
index 0000000..b72f09e
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-create-office/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ echo 'hna7lb2PicYbSK9hkemc7Ta8kBW6e43v' | http POST 'http://localhost:8080/office/v1/offices' 'Content-Type:application/json' 'Accept:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-delete-address-of-office/curl-request.adoc b/service/src/doc/generated-snippets/test-office/should-delete-address-of-office/curl-request.adoc
new file mode 100644
index 0000000..c8e4676
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-delete-address-of-office/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/office/v1/offices/l8jKQP4SFczwVTEnYRANZrSfcD2TI1Wj/address' -i -X DELETE -H 'Content-Type: */*'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-delete-address-of-office/http-request.adoc b/service/src/doc/generated-snippets/test-office/should-delete-address-of-office/http-request.adoc
new file mode 100644
index 0000000..3ff9002
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-delete-address-of-office/http-request.adoc
@@ -0,0 +1,7 @@
+[source,http,options="nowrap"]
+----
+DELETE /office/v1/offices/l8jKQP4SFczwVTEnYRANZrSfcD2TI1Wj/address HTTP/1.1
+Content-Type: */*
+Host: localhost:8080
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-delete-address-of-office/http-response.adoc b/service/src/doc/generated-snippets/test-office/should-delete-address-of-office/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-delete-address-of-office/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-delete-address-of-office/httpie-request.adoc b/service/src/doc/generated-snippets/test-office/should-delete-address-of-office/httpie-request.adoc
new file mode 100644
index 0000000..0f5b207
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-delete-address-of-office/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ http DELETE 'http://localhost:8080/office/v1/offices/l8jKQP4SFczwVTEnYRANZrSfcD2TI1Wj/address' 'Content-Type:*/*'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-get-address-of-office/curl-request.adoc b/service/src/doc/generated-snippets/test-office/should-get-address-of-office/curl-request.adoc
new file mode 100644
index 0000000..93e6363
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-get-address-of-office/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/office/v1/offices/mgi4uXODB0fWCrxet6gdfgFUt4sFvQBv/address' -i -H 'Accept: */*' -H 'Content-Type: application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-get-address-of-office/http-request.adoc b/service/src/doc/generated-snippets/test-office/should-get-address-of-office/http-request.adoc
new file mode 100644
index 0000000..31d2825
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-get-address-of-office/http-request.adoc
@@ -0,0 +1,8 @@
+[source,http,options="nowrap"]
+----
+GET /office/v1/offices/mgi4uXODB0fWCrxet6gdfgFUt4sFvQBv/address HTTP/1.1
+Accept: */*
+Content-Type: application/json
+Host: localhost:8080
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-get-address-of-office/http-response.adoc b/service/src/doc/generated-snippets/test-office/should-get-address-of-office/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-get-address-of-office/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-get-address-of-office/httpie-request.adoc b/service/src/doc/generated-snippets/test-office/should-get-address-of-office/httpie-request.adoc
new file mode 100644
index 0000000..9344461
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-get-address-of-office/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ http GET 'http://localhost:8080/office/v1/offices/mgi4uXODB0fWCrxet6gdfgFUt4sFvQBv/address' 'Accept:*/*' 'Content-Type:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-indicate-office-has-external-references/curl-request.adoc b/service/src/doc/generated-snippets/test-office/should-indicate-office-has-external-references/curl-request.adoc
new file mode 100644
index 0000000..5f51f50
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-indicate-office-has-external-references/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/office/v1/offices/BgAjPgBZZWfbEj8GH89Za5k5Z8NPCrzh/references' -i -X PUT -H 'Content-Type: application/json' -H 'Accept: application/json' -d 'BgAjPgBZZWfbEj8GH89Za5k5Z8NPCrzh'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-indicate-office-has-external-references/http-request.adoc b/service/src/doc/generated-snippets/test-office/should-indicate-office-has-external-references/http-request.adoc
new file mode 100644
index 0000000..c10a29f
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-indicate-office-has-external-references/http-request.adoc
@@ -0,0 +1,10 @@
+[source,http,options="nowrap"]
+----
+PUT /office/v1/offices/BgAjPgBZZWfbEj8GH89Za5k5Z8NPCrzh/references HTTP/1.1
+Content-Type: application/json
+Accept: application/json
+Host: localhost:8080
+Content-Length: 32
+
+BgAjPgBZZWfbEj8GH89Za5k5Z8NPCrzh
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-indicate-office-has-external-references/http-response.adoc b/service/src/doc/generated-snippets/test-office/should-indicate-office-has-external-references/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-indicate-office-has-external-references/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-indicate-office-has-external-references/httpie-request.adoc b/service/src/doc/generated-snippets/test-office/should-indicate-office-has-external-references/httpie-request.adoc
new file mode 100644
index 0000000..b963e2a
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-indicate-office-has-external-references/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ echo 'BgAjPgBZZWfbEj8GH89Za5k5Z8NPCrzh' | http PUT 'http://localhost:8080/office/v1/offices/BgAjPgBZZWfbEj8GH89Za5k5Z8NPCrzh/references' 'Content-Type:application/json' 'Accept:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-set-address-of-office/curl-request.adoc b/service/src/doc/generated-snippets/test-office/should-set-address-of-office/curl-request.adoc
new file mode 100644
index 0000000..25a4466
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-set-address-of-office/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/office/v1/offices/N8EbAON507KYq2T7FCNOPIiOfQQRA4TB/address' -i -X PUT -H 'Content-Type: application/json' -H 'Accept: application/json' -d 'N8EbAON507KYq2T7FCNOPIiOfQQRA4TB'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-set-address-of-office/http-request.adoc b/service/src/doc/generated-snippets/test-office/should-set-address-of-office/http-request.adoc
new file mode 100644
index 0000000..538c4ba
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-set-address-of-office/http-request.adoc
@@ -0,0 +1,10 @@
+[source,http,options="nowrap"]
+----
+PUT /office/v1/offices/N8EbAON507KYq2T7FCNOPIiOfQQRA4TB/address HTTP/1.1
+Content-Type: application/json
+Accept: application/json
+Host: localhost:8080
+Content-Length: 32
+
+N8EbAON507KYq2T7FCNOPIiOfQQRA4TB
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-set-address-of-office/http-response.adoc b/service/src/doc/generated-snippets/test-office/should-set-address-of-office/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-set-address-of-office/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-set-address-of-office/httpie-request.adoc b/service/src/doc/generated-snippets/test-office/should-set-address-of-office/httpie-request.adoc
new file mode 100644
index 0000000..7a26f5e
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-set-address-of-office/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ echo 'N8EbAON507KYq2T7FCNOPIiOfQQRA4TB' | http PUT 'http://localhost:8080/office/v1/offices/N8EbAON507KYq2T7FCNOPIiOfQQRA4TB/address' 'Content-Type:application/json' 'Accept:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-update-office/curl-request.adoc b/service/src/doc/generated-snippets/test-office/should-update-office/curl-request.adoc
new file mode 100644
index 0000000..7894613
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-update-office/curl-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ curl 'http://localhost:8080/office/v1/offices/KaenTLcYkYksdhUG4KSkYMTpeWOwAxd7' -i -X PUT -H 'Content-Type: application/json' -d 'vVvt8iN1Q8kaCeHvZnJpR59oDXKjWkt8'
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-update-office/http-request.adoc b/service/src/doc/generated-snippets/test-office/should-update-office/http-request.adoc
new file mode 100644
index 0000000..0afbb65
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-update-office/http-request.adoc
@@ -0,0 +1,9 @@
+[source,http,options="nowrap"]
+----
+PUT /office/v1/offices/KaenTLcYkYksdhUG4KSkYMTpeWOwAxd7 HTTP/1.1
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+vVvt8iN1Q8kaCeHvZnJpR59oDXKjWkt8
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-update-office/http-response.adoc b/service/src/doc/generated-snippets/test-office/should-update-office/http-response.adoc
new file mode 100644
index 0000000..f3b256d
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-update-office/http-response.adoc
@@ -0,0 +1,5 @@
+[source,http,options="nowrap"]
+----
+HTTP/1.1 404 Not Found
+
+----
\ No newline at end of file
diff --git a/service/src/doc/generated-snippets/test-office/should-update-office/httpie-request.adoc b/service/src/doc/generated-snippets/test-office/should-update-office/httpie-request.adoc
new file mode 100644
index 0000000..3292a15
--- /dev/null
+++ b/service/src/doc/generated-snippets/test-office/should-update-office/httpie-request.adoc
@@ -0,0 +1,4 @@
+[source,bash]
+----
+$ echo 'vVvt8iN1Q8kaCeHvZnJpR59oDXKjWkt8' | http PUT 'http://localhost:8080/office/v1/offices/KaenTLcYkYksdhUG4KSkYMTpeWOwAxd7' 'Content-Type:application/json'
+----
\ No newline at end of file
diff --git a/service/src/doc/html5/html5/api-docs.html b/service/src/doc/html5/html5/api-docs.html
new file mode 100644
index 0000000..fb33b70
--- /dev/null
+++ b/service/src/doc/html5/html5/api-docs.html
@@ -0,0 +1,886 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<meta name="generator" content="Asciidoctor 1.5.3">
+<title>Apache Fineract CN Office Management API Documentation</title>
+<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
+<style>
+/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
+/* Remove comment around @import statement below when using as a custom stylesheet */
+/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
+article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
+audio,canvas,video{display:inline-block}
+audio:not([controls]){display:none;height:0}
+[hidden],template{display:none}
+script{display:none!important}
+html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
+body{margin:0}
+a{background:transparent}
+a:focus{outline:thin dotted}
+a:active,a:hover{outline:0}
+h1{font-size:2em;margin:.67em 0}
+abbr[title]{border-bottom:1px dotted}
+b,strong{font-weight:bold}
+dfn{font-style:italic}
+hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
+mark{background:#ff0;color:#000}
+code,kbd,pre,samp{font-family:monospace;font-size:1em}
+pre{white-space:pre-wrap}
+q{quotes:"\201C" "\201D" "\2018" "\2019"}
+small{font-size:80%}
+sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
+sup{top:-.5em}
+sub{bottom:-.25em}
+img{border:0}
+svg:not(:root){overflow:hidden}
+figure{margin:0}
+fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
+legend{border:0;padding:0}
+button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
+button,input{line-height:normal}
+button,select{text-transform:none}
+button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
+button[disabled],html input[disabled]{cursor:default}
+input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
+input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
+input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
+button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
+textarea{overflow:auto;vertical-align:top}
+table{border-collapse:collapse;border-spacing:0}
+*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
+html,body{font-size:100%}
+body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto}
+a:hover{cursor:pointer}
+img,object,embed{max-width:100%;height:auto}
+object,embed{height:100%}
+img{-ms-interpolation-mode:bicubic}
+.left{float:left!important}
+.right{float:right!important}
+.text-left{text-align:left!important}
+.text-right{text-align:right!important}
+.text-center{text-align:center!important}
+.text-justify{text-align:justify!important}
+.hide{display:none}
+body{-webkit-font-smoothing:antialiased}
+img,object,svg{display:inline-block;vertical-align:middle}
+textarea{height:auto;min-height:50px}
+select{width:100%}
+.center{margin-left:auto;margin-right:auto}
+.spread{width:100%}
+p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}
+.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
+div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
+a{color:#2156a5;text-decoration:underline;line-height:inherit}
+a:hover,a:focus{color:#1d4b8f}
+a img{border:none}
+p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
+p aside{font-size:.875em;line-height:1.35;font-style:italic}
+h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
+h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
+h1{font-size:2.125em}
+h2{font-size:1.6875em}
+h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
+h4,h5{font-size:1.125em}
+h6{font-size:1em}
+hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
+em,i{font-style:italic;line-height:inherit}
+strong,b{font-weight:bold;line-height:inherit}
+small{font-size:60%;line-height:inherit}
+code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
+ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
+ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em}
+ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
+ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
+ul.square{list-style-type:square}
+ul.circle{list-style-type:circle}
+ul.disc{list-style-type:disc}
+ul.no-bullet{list-style:none}
+ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
+dl dt{margin-bottom:.3125em;font-weight:bold}
+dl dd{margin-bottom:1.25em}
+abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
+abbr{text-transform:none}
+blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
+blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
+blockquote cite:before{content:"\2014 \0020"}
+blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
+blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
+@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
+h1{font-size:2.75em}
+h2{font-size:2.3125em}
+h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
+h4{font-size:1.4375em}}
+table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
+table thead,table tfoot{background:#f7f8f7;font-weight:bold}
+table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
+table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
+table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
+table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
+body{tab-size:4}
+h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
+h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
+.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}
+.clearfix:after,.float-group:after{clear:both}
+*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
+pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
+.keyseq{color:rgba(51,51,51,.8)}
+kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
+.keyseq kbd:first-child{margin-left:0}
+.keyseq kbd:last-child{margin-right:0}
+.menuseq,.menu{color:rgba(0,0,0,.8)}
+b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}
+b.button:before{content:"[";padding:0 3px 0 2px}
+b.button:after{content:"]";padding:0 2px 0 3px}
+p a>code:hover{color:rgba(0,0,0,.9)}
+#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
+#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}
+#header:after,#content:after,#footnotes:after,#footer:after{clear:both}
+#content{margin-top:1.25em}
+#content:before{content:none}
+#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
+#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}
+#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}
+#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
+#header .details span:first-child{margin-left:-.125em}
+#header .details span.email a{color:rgba(0,0,0,.85)}
+#header .details br{display:none}
+#header .details br+span:before{content:"\00a0\2013\00a0"}
+#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
+#header .details br+span#revremark:before{content:"\00a0|\00a0"}
+#header #revnumber{text-transform:capitalize}
+#header #revnumber:after{content:"\00a0"}
+#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
+#toc{border-bottom:1px solid #efefed;padding-bottom:.5em}
+#toc>ul{margin-left:.125em}
+#toc ul.sectlevel0>li>a{font-style:italic}
+#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
+#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
+#toc li{line-height:1.3334;margin-top:.3334em}
+#toc a{text-decoration:none}
+#toc a:active{text-decoration:underline}
+#toctitle{color:#7a2518;font-size:1.2em}
+@media only screen and (min-width:768px){#toctitle{font-size:1.375em}
+body.toc2{padding-left:15em;padding-right:0}
+#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
+#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
+#toc.toc2>ul{font-size:.9em;margin-bottom:0}
+#toc.toc2 ul ul{margin-left:0;padding-left:1em}
+#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
+body.toc2.toc-right{padding-left:0;padding-right:15em}
+body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}
+@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
+#toc.toc2{width:20em}
+#toc.toc2 #toctitle{font-size:1.375em}
+#toc.toc2>ul{font-size:.95em}
+#toc.toc2 ul ul{padding-left:1.25em}
+body.toc2.toc-right{padding-left:0;padding-right:20em}}
+#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
+#content #toc>:first-child{margin-top:0}
+#content #toc>:last-child{margin-bottom:0}
+#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
+#footer-text{color:rgba(255,255,255,.8);line-height:1.44}
+.sect1{padding-bottom:.625em}
+@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}
+.sect1+.sect1{border-top:1px solid #efefed}
+#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
+#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
+#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
+#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
+#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
+.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
+.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
+table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}
+.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}
+table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}
+.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
+.admonitionblock>table td.icon{text-align:center;width:80px}
+.admonitionblock>table td.icon img{max-width:none}
+.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
+.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}
+.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
+.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
+.exampleblock>.content>:first-child{margin-top:0}
+.exampleblock>.content>:last-child{margin-bottom:0}
+.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
+.sidebarblock>:first-child{margin-top:0}
+.sidebarblock>:last-child{margin-bottom:0}
+.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
+.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
+.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
+.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
+.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}
+.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}
+@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
+@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
+.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
+.listingblock pre.highlightjs{padding:0}
+.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
+.listingblock pre.prettyprint{border-width:0}
+.listingblock>.content{position:relative}
+.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
+.listingblock:hover code[data-lang]:before{display:block}
+.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}
+.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}
+table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
+table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
+table.pyhltable td.code{padding-left:.75em;padding-right:0}
+pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}
+pre.pygments .lineno{display:inline-block;margin-right:.25em}
+table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
+.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
+.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
+.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
+.quoteblock blockquote{margin:0;padding:0;border:0}
+.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
+.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
+.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}
+.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}
+.quoteblock .quoteblock blockquote{padding:0 0 0 .75em}
+.quoteblock .quoteblock blockquote:before{display:none}
+.verseblock{margin:0 1em 1.25em 1em}
+.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
+.verseblock pre strong{font-weight:400}
+.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
+.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
+.quoteblock .attribution br,.verseblock .attribution br{display:none}
+.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
+.quoteblock.abstract{margin:0 0 1.25em 0;display:block}
+.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}
+.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}
+table.tableblock{max-width:100%;border-collapse:separate}
+table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}
+table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
+table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}
+table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}
+table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0}
+table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0}
+table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0}
+table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0}
+table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0}
+table.frame-all{border-width:1px}
+table.frame-sides{border-width:0 1px}
+table.frame-topbot{border-width:1px 0}
+th.halign-left,td.halign-left{text-align:left}
+th.halign-right,td.halign-right{text-align:right}
+th.halign-center,td.halign-center{text-align:center}
+th.valign-top,td.valign-top{vertical-align:top}
+th.valign-bottom,td.valign-bottom{vertical-align:bottom}
+th.valign-middle,td.valign-middle{vertical-align:middle}
+table thead th,table tfoot th{font-weight:bold}
+tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
+tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
+p.tableblock>code:only-child{background:none;padding:0}
+p.tableblock{font-size:1em}
+td>div.verse{white-space:pre}
+ol{margin-left:1.75em}
+ul li ol{margin-left:1.5em}
+dl dd{margin-left:1.125em}
+dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
+ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
+ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none}
+ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em}
+ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:.85em}
+ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px}
+ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}
+ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}
+ul.inline>li>*{display:block}
+.unstyled dl dt{font-weight:400;font-style:normal}
+ol.arabic{list-style-type:decimal}
+ol.decimal{list-style-type:decimal-leading-zero}
+ol.loweralpha{list-style-type:lower-alpha}
+ol.upperalpha{list-style-type:upper-alpha}
+ol.lowerroman{list-style-type:lower-roman}
+ol.upperroman{list-style-type:upper-roman}
+ol.lowergreek{list-style-type:lower-greek}
+.hdlist>table,.colist>table{border:0;background:none}
+.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
+td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
+td.hdlist1{font-weight:bold;padding-bottom:1.25em}
+.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
+.colist>table tr>td:first-of-type{padding:0 .75em;line-height:1}
+.colist>table tr>td:last-of-type{padding:.25em 0}
+.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
+.imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0}
+.imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em}
+.imageblock>.title{margin-bottom:0}
+.imageblock.thumb,.imageblock.th{border-width:6px}
+.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
+.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
+.image.left{margin-right:.625em}
+.image.right{margin-left:.625em}
+a.image{text-decoration:none;display:inline-block}
+a.image object{pointer-events:none}
+sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
+sup.footnote a,sup.footnoteref a{text-decoration:none}
+sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
+#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
+#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}
+#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}
+#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}
+#footnotes .footnote:last-of-type{margin-bottom:0}
+#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
+.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
+.gist .file-data>table td.line-data{width:99%}
+div.unbreakable{page-break-inside:avoid}
+.big{font-size:larger}
+.small{font-size:smaller}
+.underline{text-decoration:underline}
+.overline{text-decoration:overline}
+.line-through{text-decoration:line-through}
+.aqua{color:#00bfbf}
+.aqua-background{background-color:#00fafa}
+.black{color:#000}
+.black-background{background-color:#000}
+.blue{color:#0000bf}
+.blue-background{background-color:#0000fa}
+.fuchsia{color:#bf00bf}
+.fuchsia-background{background-color:#fa00fa}
+.gray{color:#606060}
+.gray-background{background-color:#7d7d7d}
+.green{color:#006000}
+.green-background{background-color:#007d00}
+.lime{color:#00bf00}
+.lime-background{background-color:#00fa00}
+.maroon{color:#600000}
+.maroon-background{background-color:#7d0000}
+.navy{color:#000060}
+.navy-background{background-color:#00007d}
+.olive{color:#606000}
+.olive-background{background-color:#7d7d00}
+.purple{color:#600060}
+.purple-background{background-color:#7d007d}
+.red{color:#bf0000}
+.red-background{background-color:#fa0000}
+.silver{color:#909090}
+.silver-background{background-color:#bcbcbc}
+.teal{color:#006060}
+.teal-background{background-color:#007d7d}
+.white{color:#bfbfbf}
+.white-background{background-color:#fafafa}
+.yellow{color:#bfbf00}
+.yellow-background{background-color:#fafa00}
+span.icon>.fa{cursor:default}
+.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
+.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}
+.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
+.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}
+.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}
+.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}
+.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
+.conum[data-value] *{color:#fff!important}
+.conum[data-value]+b{display:none}
+.conum[data-value]:after{content:attr(data-value)}
+pre .conum[data-value]{position:relative;top:-.125em}
+b.conum *{color:inherit!important}
+.conum:not([data-value]):empty{display:none}
+dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
+h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
+p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
+p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
+p{margin-bottom:1.25rem}
+.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
+.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
+.print-only{display:none!important}
+@media print{@page{margin:1.25cm .75cm}
+*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
+a{color:inherit!important;text-decoration:underline!important}
+a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
+a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
+abbr[title]:after{content:" (" attr(title) ")"}
+pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
+thead{display:table-header-group}
+svg{max-width:100%}
+p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
+h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
+#toc,.sidebarblock,.exampleblock>.content{background:none!important}
+#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}
+.sect1{padding-bottom:0!important}
+.sect1+.sect1{border:0!important}
+#header>h1:first-child{margin-top:1.25rem}
+body.book #header{text-align:center}
+body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}
+body.book #header .details{border:0!important;display:block;padding:0!important}
+body.book #header .details span:first-child{margin-left:0!important}
+body.book #header .details br{display:block}
+body.book #header .details br+span:before{content:none!important}
+body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
+body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
+.listingblock code[data-lang]:before{display:block}
+#footer{background:none!important;padding:0 .9375em}
+#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}
+.hide-on-print{display:none!important}
+.print-only{display:block!important}
+.hide-for-print{display:none!important}
+.show-for-print{display:inherit!important}}
+</style>
+</head>
+<body class="book">
+<div id="header">
+</div>
+<div id="content">
+<div class="sect1">
+<h2 id="_apache_fineract_cn_office_management_api_documentation">Apache Fineract CN Office Management API Documentation</h2>
+<div class="sectionbody">
+
+</div>
+</div>
+<div class="sect1">
+<h2 id="_offices">Offices</h2>
+<div class="sectionbody">
+<div class="sect3">
+<h4 id="_create_an_office">Create An Office</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/office/v1/offices' -i -X POST -H 'Content-Type: application/json' -H 'Accept: application/json' -d 'hna7lb2PicYbSK9hkemc7Ta8kBW6e43v'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">POST /office/v1/offices HTTP/1.1
+Content-Type: application/json
+Accept: application/json
+Host: localhost:8080
+Content-Length: 32
+
+hna7lb2PicYbSK9hkemc7Ta8kBW6e43v</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'hna7lb2PicYbSK9hkemc7Ta8kBW6e43v' | http POST 'http://localhost:8080/office/v1/offices' 'Content-Type:application/json' 'Accept:application/json'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_get_an_office">Get An Office</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/office/v1/offices/BgAjPgBZZWfbEj8GH89Za5k5Z8NPCrzh/references' -i -X PUT -H 'Content-Type: application/json' -H 'Accept: application/json' -d 'BgAjPgBZZWfbEj8GH89Za5k5Z8NPCrzh'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">PUT /office/v1/offices/BgAjPgBZZWfbEj8GH89Za5k5Z8NPCrzh/references HTTP/1.1
+Content-Type: application/json
+Accept: application/json
+Host: localhost:8080
+Content-Length: 32
+
+BgAjPgBZZWfbEj8GH89Za5k5Z8NPCrzh</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'BgAjPgBZZWfbEj8GH89Za5k5Z8NPCrzh' | http PUT 'http://localhost:8080/office/v1/offices/BgAjPgBZZWfbEj8GH89Za5k5Z8NPCrzh/references' 'Content-Type:application/json' 'Accept:application/json'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_get_an_office_s_address">Get An Office&#8217;s Address</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/office/v1/offices/mgi4uXODB0fWCrxet6gdfgFUt4sFvQBv/address' -i -H 'Accept: */*' -H 'Content-Type: application/json'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">GET /office/v1/offices/mgi4uXODB0fWCrxet6gdfgFUt4sFvQBv/address HTTP/1.1
+Accept: */*
+Content-Type: application/json
+Host: localhost:8080</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ http GET 'http://localhost:8080/office/v1/offices/mgi4uXODB0fWCrxet6gdfgFUt4sFvQBv/address' 'Accept:*/*' 'Content-Type:application/json'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_update_an_office_s_address">Update An Office&#8217;s Address</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/office/v1/offices/N8EbAON507KYq2T7FCNOPIiOfQQRA4TB/address' -i -X PUT -H 'Content-Type: application/json' -H 'Accept: application/json' -d 'N8EbAON507KYq2T7FCNOPIiOfQQRA4TB'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">PUT /office/v1/offices/N8EbAON507KYq2T7FCNOPIiOfQQRA4TB/address HTTP/1.1
+Content-Type: application/json
+Accept: application/json
+Host: localhost:8080
+Content-Length: 32
+
+N8EbAON507KYq2T7FCNOPIiOfQQRA4TB</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'N8EbAON507KYq2T7FCNOPIiOfQQRA4TB' | http PUT 'http://localhost:8080/office/v1/offices/N8EbAON507KYq2T7FCNOPIiOfQQRA4TB/address' 'Content-Type:application/json' 'Accept:application/json'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_update_an_office">Update An Office</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/office/v1/offices/KaenTLcYkYksdhUG4KSkYMTpeWOwAxd7' -i -X PUT -H 'Content-Type: application/json' -d 'vVvt8iN1Q8kaCeHvZnJpR59oDXKjWkt8'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">PUT /office/v1/offices/KaenTLcYkYksdhUG4KSkYMTpeWOwAxd7 HTTP/1.1
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+vVvt8iN1Q8kaCeHvZnJpR59oDXKjWkt8</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'vVvt8iN1Q8kaCeHvZnJpR59oDXKjWkt8' | http PUT 'http://localhost:8080/office/v1/offices/KaenTLcYkYksdhUG4KSkYMTpeWOwAxd7' 'Content-Type:application/json'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_delete_an_office_s_address">Delete An Office&#8217;s Address</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/office/v1/offices/l8jKQP4SFczwVTEnYRANZrSfcD2TI1Wj/address' -i -X DELETE -H 'Content-Type: */*'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">DELETE /office/v1/offices/l8jKQP4SFczwVTEnYRANZrSfcD2TI1Wj/address HTTP/1.1
+Content-Type: */*
+Host: localhost:8080</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ http DELETE 'http://localhost:8080/office/v1/offices/l8jKQP4SFczwVTEnYRANZrSfcD2TI1Wj/address' 'Content-Type:*/*'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_add_a_branch_to_an_office">Add A Branch To An Office</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/office/v1/offices/6j0iKMH44oA1OfJVaHTCLAeutUDVfltO' -i -X PUT -H 'Content-Type: application/json' -d '6j0iKMH44oA1OfJVaHTCLAeutUDVfltO'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">PUT /office/v1/offices/6j0iKMH44oA1OfJVaHTCLAeutUDVfltO HTTP/1.1
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+6j0iKMH44oA1OfJVaHTCLAeutUDVfltO</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo '6j0iKMH44oA1OfJVaHTCLAeutUDVfltO' | http PUT 'http://localhost:8080/office/v1/offices/6j0iKMH44oA1OfJVaHTCLAeutUDVfltO' 'Content-Type:application/json'</code></pre>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="_employees">Employees</h2>
+<div class="sectionbody">
+<div class="sect3">
+<h4 id="_create_an_employee">Create An Employee</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/office/v1/employees' -i -X POST -H 'Content-Type: application/json' -d 'pmOnIEX1BHG2Zj3CI45It135RjS30UMZ'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">POST /office/v1/employees HTTP/1.1
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+pmOnIEX1BHG2Zj3CI45It135RjS30UMZ</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'pmOnIEX1BHG2Zj3CI45It135RjS30UMZ' | http POST 'http://localhost:8080/office/v1/employees' 'Content-Type:application/json'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_update_an_employee">Update An Employee</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/office/v1/employees/Z3Qm799gURp8x3jigLf5OAxGfVHDchnp' -i -X PUT -H 'Content-Type: application/json' -d 'Z3Qm799gURp8x3jigLf5OAxGfVHDchnp'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">PUT /office/v1/employees/Z3Qm799gURp8x3jigLf5OAxGfVHDchnp HTTP/1.1
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+Z3Qm799gURp8x3jigLf5OAxGfVHDchnp</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'Z3Qm799gURp8x3jigLf5OAxGfVHDchnp' | http PUT 'http://localhost:8080/office/v1/employees/Z3Qm799gURp8x3jigLf5OAxGfVHDchnp' 'Content-Type:application/json'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_get_employees">Get Employees</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/office/v1/employees' -i -H 'Accept: */*'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">GET /office/v1/employees HTTP/1.1
+Accept: */*
+Host: localhost:8080</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ http GET 'http://localhost:8080/office/v1/employees' 'Accept:*/*'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_get_an_office_s_employees">Get An Office&#8217;s Employees</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/office/v1/employees' -i -H 'Accept: */*'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">GET /office/v1/employees HTTP/1.1
+Accept: */*
+Host: localhost:8080</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ http GET 'http://localhost:8080/office/v1/employees' 'Accept:*/*'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_update_employee_s_contact_details">Update Employee&#8217;s Contact Details</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/office/v1/employees/nqnRpYG4QlyLKtPVrJQDz2mEak2cncBL/contacts' -i -X PUT -H 'Accept: */*' -H 'Content-Type: application/json' -d 'nqnRpYG4QlyLKtPVrJQDz2mEak2cncBL'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">PUT /office/v1/employees/nqnRpYG4QlyLKtPVrJQDz2mEak2cncBL/contacts HTTP/1.1
+Accept: */*
+Content-Type: application/json
+Host: localhost:8080
+Content-Length: 32
+
+nqnRpYG4QlyLKtPVrJQDz2mEak2cncBL</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ echo 'nqnRpYG4QlyLKtPVrJQDz2mEak2cncBL' | http PUT 'http://localhost:8080/office/v1/employees/nqnRpYG4QlyLKtPVrJQDz2mEak2cncBL/contacts' 'Accept:*/*' 'Content-Type:application/json'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_delete_employee_s_contact_details">Delete Employee&#8217;s Contact Details</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/office/v1/employees/GNhkajYzqKNwN4QCRkuPbCl5ZhME0LfO/contacts' -i -X DELETE -H 'Content-Type: image/png'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">DELETE /office/v1/employees/GNhkajYzqKNwN4QCRkuPbCl5ZhME0LfO/contacts HTTP/1.1
+Content-Type: image/png
+Host: localhost:8080</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ http DELETE 'http://localhost:8080/office/v1/employees/GNhkajYzqKNwN4QCRkuPbCl5ZhME0LfO/contacts' 'Content-Type:image/png'</code></pre>
+</div>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_delete_an_employee">Delete An Employee</h4>
+<div class="listingblock">
+<div class="title">curl-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ curl 'http://localhost:8080/office/v1/employees/FBea9IQEOII3aaR7xv7jBQCN6dEFrqqY' -i -X DELETE -H 'Accept: */*' -H 'Content-Type: application/json'</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-request</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">DELETE /office/v1/employees/FBea9IQEOII3aaR7xv7jBQCN6dEFrqqY HTTP/1.1
+Accept: */*
+Content-Type: application/json
+Host: localhost:8080</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">http-response</div>
+<div class="content">
+<pre class="highlightjs highlight nowrap"><code class="language-http" data-lang="http">HTTP/1.1 404 Not Found</code></pre>
+</div>
+</div>
+<div class="listingblock">
+<div class="title">httpie-request</div>
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-bash" data-lang="bash">$ http DELETE 'http://localhost:8080/office/v1/employees/FBea9IQEOII3aaR7xv7jBQCN6dEFrqqY' 'Accept:*/*' 'Content-Type:application/json'</code></pre>
+</div>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div id="footer">
+<div id="footer-text">
+Last updated 2018-04-16 16:56:31 +01:00
+</div>
+</div>
+<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/styles/github.min.css">
+<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.9.1/highlight.min.js"></script>
+<script>hljs.initHighlighting()</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/service/src/test/java/org/apache/fineract/cn/office/TestEmployee.java b/service/src/test/java/org/apache/fineract/cn/office/TestEmployee.java
new file mode 100644
index 0000000..0c2fbce
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/office/TestEmployee.java
@@ -0,0 +1,483 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.cn.office;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.fineract.cn.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
+import org.apache.fineract.cn.api.context.AutoUserContext;
+import org.apache.fineract.cn.office.api.v1.EventConstants;
+import org.apache.fineract.cn.office.api.v1.client.AlreadyExistsException;
+import org.apache.fineract.cn.office.api.v1.client.BadRequestException;
+import org.apache.fineract.cn.office.api.v1.client.NotFoundException;
+import org.apache.fineract.cn.office.api.v1.client.OrganizationManager;
+import org.apache.fineract.cn.office.api.v1.domain.ContactDetail;
+import org.apache.fineract.cn.office.api.v1.domain.Employee;
+import org.apache.fineract.cn.office.api.v1.domain.EmployeePage;
+import org.apache.fineract.cn.office.api.v1.domain.Office;
+import org.apache.fineract.cn.office.rest.config.OfficeRestConfiguration;
+import org.apache.fineract.cn.office.util.EmployeeFactory;
+import org.apache.fineract.cn.office.util.OfficeFactory;
+import org.apache.fineract.cn.test.env.TestEnvironment;
+import org.apache.fineract.cn.test.fixture.TenantDataStoreContextTestRule;
+import org.apache.fineract.cn.test.fixture.cassandra.CassandraInitializer;
+import org.apache.fineract.cn.test.fixture.mariadb.MariaDBInitializer;
+import org.apache.fineract.cn.test.listener.EnableEventRecording;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.junit.*;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.netflix.feign.EnableFeignClients;
+import org.springframework.cloud.netflix.ribbon.RibbonClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.http.MediaType;
+import org.springframework.restdocs.JUnitRestDocumentation;
+import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.put;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
+public class TestEmployee {
+
+  @Rule
+  public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("src/doc/generated-snippets/test-employee");
+
+  @Autowired
+  private WebApplicationContext context;
+
+  private MockMvc mockMvc;
+
+  final String path = "/office/v1";
+
+  @Before
+  public void setUp(){
+
+    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
+            .apply(documentationConfiguration(this.restDocumentation))
+            .alwaysDo(document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
+            .build();
+  }
+
+  private static final String APP_NAME = "office-v1";
+  private static final String TEST_USER = "thutmosis";
+
+  private final static TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
+  private final static CassandraInitializer cassandraInitializer = new CassandraInitializer();
+  private final static MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
+  private final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
+
+  @ClassRule
+  public static TestRule orderClassRules = RuleChain
+          .outerRule(testEnvironment)
+          .around(cassandraInitializer)
+          .around(mariaDBInitializer)
+          .around(tenantDataStoreContext);
+
+  @Rule
+  public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
+          = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
+
+  @Autowired
+  private OrganizationManager organizationManager;
+
+  @Autowired
+  private EventRecorder eventRecorder;
+
+  private AutoUserContext userContext;
+
+  @Before
+  public void prepareTest() {
+    userContext = tenantApplicationSecurityEnvironment.createAutoUserContext(TestEmployee.TEST_USER);
+  }
+
+  @After
+  public void cleanupTest() {
+    userContext.close();
+  }
+
+  public boolean waitForInitialize() {
+    try {
+      return this.eventRecorder.wait(EventConstants.INITIALIZE, EventConstants.INITIALIZE);
+    } catch (final InterruptedException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  @Test
+  public void shouldCreateEmployee() throws Exception {
+    final Employee employee = EmployeeFactory.createRandomEmployee();
+    {
+      this.organizationManager.createEmployee(employee);
+      final boolean found = this.eventRecorder.wait(EventConstants.OPERATION_POST_EMPLOYEE, employee.getIdentifier());
+      Assert.assertTrue(found);
+    }
+
+    final Employee savedEmployee = this.organizationManager.findEmployee(employee.getIdentifier());
+
+    Assert.assertNotNull(savedEmployee);
+    Assert.assertEquals(employee.getIdentifier(), savedEmployee.getIdentifier());
+    Assert.assertEquals(employee.getGivenName(), savedEmployee.getGivenName());
+    Assert.assertEquals(employee.getMiddleName(), savedEmployee.getMiddleName());
+    Assert.assertEquals(employee.getSurname(), savedEmployee.getSurname());
+
+    this.organizationManager.deleteEmployee(employee.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_EMPLOYEE, employee.getIdentifier());
+
+    this.mockMvc.perform(post(path + "/employees")
+            .contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(savedEmployee.getIdentifier()))
+            .andExpect(status().isNotFound());
+  }
+
+  @Test
+  public void shouldNotCreateEmployeeAlreadyExists() throws Exception {
+    final Employee employee = EmployeeFactory.createRandomEmployee();
+    this.organizationManager.createEmployee(employee);
+
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_EMPLOYEE, employee.getIdentifier());
+
+    try {
+      this.organizationManager.createEmployee(employee);
+      Assert.fail();
+    } catch (final AlreadyExistsException ex) {
+      // do nothing, expected
+    }
+
+    this.organizationManager.deleteEmployee(employee.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_EMPLOYEE, employee.getIdentifier());
+  }
+
+  @Test
+  public void shouldFindEmployeesByOffice() throws Exception {
+    final Office office = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(office);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, office.getIdentifier());
+
+    final Employee employee = EmployeeFactory.createRandomEmployee();
+    employee.setAssignedOffice(office.getIdentifier());
+    this.organizationManager.createEmployee(employee);
+
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_EMPLOYEE, employee.getIdentifier());
+
+    final EmployeePage employeePage = this.organizationManager.fetchEmployees(null, office.getIdentifier(), 0, 20, null, null);
+    Assert.assertEquals(Long.valueOf(1L), employeePage.getTotalElements());
+    final Employee savedEmployee = employeePage.getEmployees().get(0);
+    Assert.assertEquals(employee.getIdentifier(), savedEmployee.getIdentifier());
+    Assert.assertEquals(employee.getGivenName(), savedEmployee.getGivenName());
+    Assert.assertEquals(employee.getMiddleName(), savedEmployee.getMiddleName());
+    Assert.assertEquals(employee.getSurname(), savedEmployee.getSurname());
+
+    this.organizationManager.deleteEmployee(employee.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_EMPLOYEE, employee.getIdentifier());
+    this.organizationManager.deleteOffice(office.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_OFFICE, office.getIdentifier());
+
+    try
+    {
+      this.mockMvc.perform(get(path + "/employees")
+              .accept(MediaType.ALL))
+              .andExpect(status().is4xxClientError());
+    } catch (Exception exception){ exception.printStackTrace(); }
+  }
+
+  @Test
+  public void shouldFindAllEmployees() throws Exception {
+    final Employee firstEmployee = EmployeeFactory.createRandomEmployee();
+    this.organizationManager.createEmployee(firstEmployee);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_EMPLOYEE, firstEmployee.getIdentifier());
+    final Employee secondEmployee = EmployeeFactory.createRandomEmployee();
+    this.organizationManager.createEmployee(secondEmployee);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_EMPLOYEE, secondEmployee.getIdentifier());
+
+    final EmployeePage employeePage = this.organizationManager.fetchEmployees(null, null, 0, 20, null, null);
+    Assert.assertEquals(Long.valueOf(2L), employeePage.getTotalElements());
+
+    this.organizationManager.deleteEmployee(firstEmployee.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_EMPLOYEE, firstEmployee.getIdentifier());
+    this.organizationManager.deleteEmployee(secondEmployee.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_EMPLOYEE, secondEmployee.getIdentifier());
+
+    try
+    {
+      this.mockMvc.perform(get(path + "/employees")
+              .accept(MediaType.ALL))
+              .andExpect(status().isNotFound());
+    } catch (Exception exception){ exception.printStackTrace(); }
+  }
+
+  @Test
+  public void shouldDeleteEmployee() throws Exception {
+    final Employee employee = EmployeeFactory.createRandomEmployee();
+    this.organizationManager.createEmployee(employee);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_EMPLOYEE, employee.getIdentifier());
+    Assert.assertNotNull(this.organizationManager.findEmployee(employee.getIdentifier()));
+
+    {
+      this.organizationManager.deleteEmployee(employee.getIdentifier());
+      final boolean found = this.eventRecorder.wait(EventConstants.OPERATION_DELETE_EMPLOYEE, employee.getIdentifier());
+      Assert.assertTrue(found);
+    }
+
+    try {
+      this.organizationManager.findEmployee(employee.getIdentifier());
+      Assert.fail();
+    } catch (final NotFoundException ex) {
+      // do nothing, expected
+    }
+
+    try
+    {
+      this.mockMvc.perform(delete(path + "/employees/" + employee.getIdentifier())
+              .accept(MediaType.ALL_VALUE)
+              .contentType(MediaType.APPLICATION_JSON_VALUE))
+              .andExpect(status().isNotFound());
+    } catch (Exception exception){ exception.printStackTrace(); }
+  }
+
+  @Test
+  public void shouldUpdateEmployee() throws Exception {
+    final Employee employee = EmployeeFactory.createRandomEmployee();
+    this.organizationManager.createEmployee(employee);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_EMPLOYEE, employee.getIdentifier());
+
+    final Office office = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(office);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, office.getIdentifier());
+
+    final Employee updatedEmployee = EmployeeFactory.createRandomEmployee();
+    updatedEmployee.setIdentifier(employee.getIdentifier());
+    updatedEmployee.setAssignedOffice(office.getIdentifier());
+
+    {
+      this.organizationManager.updateEmployee(employee.getIdentifier(), updatedEmployee);
+      final boolean found = this.eventRecorder.wait(EventConstants.OPERATION_PUT_EMPLOYEE, employee.getIdentifier());
+      Assert.assertTrue(found);
+    }
+
+    final Employee savedEmployee = this.organizationManager.findEmployee(employee.getIdentifier());
+    Assert.assertNotNull(savedEmployee);
+    Assert.assertEquals(updatedEmployee.getIdentifier(), savedEmployee.getIdentifier());
+    Assert.assertEquals(updatedEmployee.getGivenName(), savedEmployee.getGivenName());
+    Assert.assertEquals(updatedEmployee.getMiddleName(), savedEmployee.getMiddleName());
+    Assert.assertEquals(updatedEmployee.getSurname(), savedEmployee.getSurname());
+    Assert.assertEquals(updatedEmployee.getAssignedOffice(), savedEmployee.getAssignedOffice());
+
+    {
+      this.organizationManager.deleteEmployee(employee.getIdentifier());
+      final boolean found = this.eventRecorder.wait(EventConstants.OPERATION_DELETE_EMPLOYEE, employee.getIdentifier());
+      Assert.assertTrue(found);
+    }
+
+    this.mockMvc.perform(put(path + "/employees/" + savedEmployee.getIdentifier())
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(savedEmployee.getIdentifier()))
+            .andExpect(status().is4xxClientError());
+  }
+
+  @Test
+  public void shouldNotUpdateEmployeeCodeMismatch() throws Exception {
+    final Employee employee = EmployeeFactory.createRandomEmployee();
+    this.organizationManager.createEmployee(employee);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_EMPLOYEE, employee.getIdentifier());
+
+    final String originalCode = employee.getIdentifier();
+    employee.setIdentifier(RandomStringUtils.randomAlphanumeric(8));
+
+    try {
+      this.organizationManager.updateEmployee(originalCode, employee);
+      Assert.fail();
+    } catch (final BadRequestException ex) {
+      // do nothing, expected
+    }
+
+    this.organizationManager.deleteEmployee(originalCode);
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_EMPLOYEE, originalCode);
+  }
+
+  @Test
+  public void shouldNotUpdateEmployeeNotFound() throws Exception {
+    final Employee employee = EmployeeFactory.createRandomEmployee();
+    this.organizationManager.createEmployee(employee);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_EMPLOYEE, employee.getIdentifier());
+
+    try {
+      this.organizationManager.updateEmployee(RandomStringUtils.randomAlphanumeric(8), employee);
+      Assert.fail();
+    } catch (final NotFoundException ex) {
+      // do nothing, expected
+    }
+
+    this.organizationManager.deleteEmployee(employee.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_EMPLOYEE, employee.getIdentifier());
+  }
+
+  @Test
+  public void shouldSetContactDetailOfEmployee() throws Exception {
+    final Employee employee = EmployeeFactory.createRandomEmployee();
+    this.organizationManager.createEmployee(employee);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_EMPLOYEE, employee.getIdentifier());
+
+    final ContactDetail email = new ContactDetail();
+    email.setType(ContactDetail.Type.EMAIL.name());
+    email.setGroup(ContactDetail.Group.PRIVATE.name());
+    email.setValue("test@example.org");
+    email.setPreferenceLevel(1);
+
+    final ContactDetail phone = new ContactDetail();
+    phone.setType(ContactDetail.Type.PHONE.name());
+    phone.setGroup(ContactDetail.Group.PRIVATE.name());
+    phone.setValue("123456789");
+    phone.setPreferenceLevel(2);
+
+    {
+      this.organizationManager.setContactDetails(employee.getIdentifier(), Arrays.asList(email, phone));
+      final boolean found = this.eventRecorder.wait(EventConstants.OPERATION_PUT_CONTACT_DETAIL, employee.getIdentifier());
+      Assert.assertTrue(found);
+    }
+
+    final List<ContactDetail> savedContactDetails = this.organizationManager.fetchContactDetails(employee.getIdentifier());
+    Assert.assertNotNull(savedContactDetails);
+    Assert.assertEquals(2, savedContactDetails.size());
+
+    final ContactDetail savedEmail = savedContactDetails.get(0);
+    Assert.assertEquals(email.getType(), savedEmail.getType());
+    Assert.assertEquals(email.getGroup(), savedEmail.getGroup());
+    Assert.assertEquals(email.getValue(), savedEmail.getValue());
+    Assert.assertEquals(email.getPreferenceLevel(), savedEmail.getPreferenceLevel());
+
+    final ContactDetail savedPhone = savedContactDetails.get(1);
+    Assert.assertEquals(phone.getType(), savedPhone.getType());
+    Assert.assertEquals(phone.getGroup(), savedPhone.getGroup());
+    Assert.assertEquals(phone.getValue(), savedPhone.getValue());
+    Assert.assertEquals(phone.getPreferenceLevel(), savedPhone.getPreferenceLevel());
+
+    {
+      this.organizationManager.deleteEmployee(employee.getIdentifier());
+      final boolean found = this.eventRecorder.wait(EventConstants.OPERATION_DELETE_EMPLOYEE, employee.getIdentifier());
+      Assert.assertTrue(found);
+    }
+
+    this.mockMvc.perform(put(path + "/employees/" + employee.getIdentifier() + "/contacts")
+            .accept(MediaType.ALL_VALUE)
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(employee.getIdentifier()))
+            .andExpect(status().is4xxClientError());
+  }
+
+  @Test
+  public void shouldNotSetContactDetailEmployeeNotFound() throws Exception {
+    final ContactDetail contactDetail = new ContactDetail();
+    contactDetail.setType(ContactDetail.Type.EMAIL.name());
+    contactDetail.setGroup(ContactDetail.Group.BUSINESS.name());
+    contactDetail.setValue("employee@example.com");
+
+    try {
+      this.organizationManager.setContactDetails(RandomStringUtils.randomAlphanumeric(8), Collections.singletonList(contactDetail));
+      Assert.fail();
+    } catch (final NotFoundException ex) {
+      // do nothing, expected
+    }
+  }
+
+  @Test
+  public void shouldDeleteContactDetailOfEmployee() throws Exception {
+    final Employee employee = EmployeeFactory.createRandomEmployee();
+    this.organizationManager.createEmployee(employee);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_EMPLOYEE, employee.getIdentifier());
+
+    final ContactDetail email = new ContactDetail();
+    email.setType(ContactDetail.Type.EMAIL.name());
+    email.setGroup(ContactDetail.Group.PRIVATE.name());
+    email.setValue("test@example.org");
+    email.setPreferenceLevel(1);
+
+    final ContactDetail phone = new ContactDetail();
+    phone.setType(ContactDetail.Type.PHONE.name());
+    phone.setGroup(ContactDetail.Group.PRIVATE.name());
+    phone.setValue("123456789");
+    phone.setPreferenceLevel(2);
+
+    {
+      this.organizationManager.setContactDetails(employee.getIdentifier(), Arrays.asList(email, phone));
+      final boolean found = this.eventRecorder.wait(EventConstants.OPERATION_PUT_CONTACT_DETAIL, employee.getIdentifier());
+      Assert.assertTrue(found);
+    }
+
+    Assert.assertNotNull(this.organizationManager.fetchContactDetails(employee.getIdentifier()));
+
+    {
+      this.organizationManager.deleteContactDetails(employee.getIdentifier());
+      final boolean found = this.eventRecorder.wait(EventConstants.OPERATION_DELETE_CONTACT_DETAIL, employee.getIdentifier());
+      Assert.assertTrue(found);
+    }
+
+    Assert.assertTrue(this.organizationManager.fetchContactDetails(employee.getIdentifier()).isEmpty());
+
+    this.organizationManager.deleteEmployee(employee.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_EMPLOYEE, employee.getIdentifier());
+
+    this.mockMvc.perform(delete(path + "/employees/" + employee.getIdentifier() + "/contacts")
+            .contentType(MediaType.IMAGE_PNG_VALUE))
+            .andExpect(status().isNotFound());
+  }
+
+  @Configuration
+  @ComponentScan(
+          basePackages = "org.apache.fineract.cn.office.listener"
+  )
+  @EnableFeignClients(basePackages = {"org.apache.fineract.cn.office.api.v1.client"})
+  @RibbonClient(name = APP_NAME)
+  @EnableEventRecording(maxWait = 5000L)
+  @Import({OfficeRestConfiguration.class})
+  public static class TestConfiguration {
+    public TestConfiguration() {
+      super();
+    }
+
+    @Bean
+    public Logger logger() {
+      return LoggerFactory.getLogger("office-test-logger");
+    }
+  }
+}
diff --git a/service/src/test/java/org/apache/fineract/cn/office/TestOffice.java b/service/src/test/java/org/apache/fineract/cn/office/TestOffice.java
new file mode 100644
index 0000000..cd4aa5d
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/office/TestOffice.java
@@ -0,0 +1,488 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.cn.office;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.fineract.cn.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
+import org.apache.fineract.cn.api.context.AutoUserContext;
+import org.apache.fineract.cn.office.api.v1.EventConstants;
+import org.apache.fineract.cn.office.api.v1.client.*;
+import org.apache.fineract.cn.office.api.v1.domain.*;
+import org.apache.fineract.cn.office.rest.config.OfficeRestConfiguration;
+import org.apache.fineract.cn.office.util.AddressFactory;
+import org.apache.fineract.cn.office.util.EmployeeFactory;
+import org.apache.fineract.cn.office.util.OfficeFactory;
+import org.apache.fineract.cn.test.env.TestEnvironment;
+import org.apache.fineract.cn.test.fixture.TenantDataStoreContextTestRule;
+import org.apache.fineract.cn.test.fixture.cassandra.CassandraInitializer;
+import org.apache.fineract.cn.test.fixture.mariadb.MariaDBInitializer;
+import org.apache.fineract.cn.test.listener.EnableEventRecording;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.junit.*;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.netflix.feign.EnableFeignClients;
+import org.springframework.cloud.netflix.ribbon.RibbonClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.http.MediaType;
+import org.springframework.restdocs.JUnitRestDocumentation;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
+
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
+import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.put;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
+public class TestOffice {
+
+  @Rule
+  public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("src/doc/generated-snippets/test-office");
+
+  @Autowired
+  private WebApplicationContext context;
+
+  private MockMvc mockMvc;
+
+  final String path = "/office/v1";
+
+  @Before
+  public void setUp(){
+
+    this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context)
+            .apply(documentationConfiguration(this.restDocumentation))
+            .alwaysDo(document("{method-name}", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint())))
+            .build();
+  }
+
+  private static final String APP_NAME = "office-v1";
+  private static final String TEST_USER = "thutmosis";
+
+  private final static TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
+  private final static CassandraInitializer cassandraInitializer = new CassandraInitializer();
+  private final static MariaDBInitializer mariaDBInitializer = new MariaDBInitializer();
+  private final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
+
+  @ClassRule
+  public static TestRule orderClassRules = RuleChain
+          .outerRule(testEnvironment)
+          .around(cassandraInitializer)
+          .around(mariaDBInitializer)
+          .around(tenantDataStoreContext);
+
+  @Rule
+  public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
+          = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
+
+  @Autowired
+  private OrganizationManager organizationManager;
+
+  @Autowired
+  private EventRecorder eventRecorder;
+
+  private AutoUserContext userContext;
+
+  @Before
+  public void prepareTest() {
+    userContext = tenantApplicationSecurityEnvironment.createAutoUserContext(TestOffice.TEST_USER);
+  }
+
+  @After
+  public void cleanupTest() {
+    userContext.close();
+  }
+
+  public boolean waitForInitialize() {
+    try {
+      return this.eventRecorder.wait(EventConstants.INITIALIZE, EventConstants.INITIALIZE);
+    } catch (final InterruptedException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  @Test
+  public void shouldCreateOffice() throws Exception {
+    final Office office = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(office);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, office.getIdentifier());
+
+    final Office savedOffice = this.organizationManager.findOfficeByIdentifier(office.getIdentifier());
+    Assert.assertNotNull(savedOffice);
+    Assert.assertEquals(office.getIdentifier(), savedOffice.getIdentifier());
+    Assert.assertEquals(office.getName(), savedOffice.getName());
+    Assert.assertEquals(office.getDescription(), savedOffice.getDescription());
+
+    this.organizationManager.deleteOffice(office.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_OFFICE, office.getIdentifier());
+
+    this.mockMvc.perform(post(path + "/offices").contentType(MediaType.APPLICATION_JSON_VALUE)
+            .content(savedOffice.getIdentifier()).accept(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isNotFound());
+  }
+
+  @Test
+  public void shouldNotCreateOfficeDuplicate() throws Exception {
+    final Office office = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(office);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, office.getIdentifier());
+    try {
+      this.organizationManager.createOffice(office);
+      Assert.fail();
+    } catch (final AlreadyExistsException ex) {
+      // do nothing, expected
+    }
+
+    this.organizationManager.deleteOffice(office.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_OFFICE, office.getIdentifier());
+  }
+
+  @Test
+  public void shouldUpdateOffice() throws Exception {
+    final Office office = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(office);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, office.getIdentifier());
+
+    final String modifiedOfficeName = RandomStringUtils.randomAlphanumeric(32);
+    office.setName(modifiedOfficeName);
+
+    this.organizationManager.updateOffice(office.getIdentifier(), office);
+    this.eventRecorder.wait(EventConstants.OPERATION_PUT_OFFICE, office.getIdentifier());
+
+    final Office changedOffice = this.organizationManager.findOfficeByIdentifier(office.getIdentifier());
+    Assert.assertEquals(modifiedOfficeName, changedOffice.getName());
+
+    this.organizationManager.deleteOffice(office.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_OFFICE, office.getIdentifier());
+
+    this.mockMvc.perform(put(path + "/offices/" + changedOffice.getIdentifier())
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(changedOffice.getName()))
+            .andExpect(status().is4xxClientError());
+  }
+
+  @Test
+  public void shouldNotUpdateOfficeIdentifierMismatch() throws Exception {
+    final Office office = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(office);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, office.getIdentifier());
+
+    final String originalIdentifier = office.getIdentifier();
+    office.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
+
+    try {
+      this.organizationManager.updateOffice(originalIdentifier, office);
+      Assert.fail();
+    } catch (final BadRequestException ex) {
+      // do nothing, expected
+    }
+    this.organizationManager.deleteOffice(originalIdentifier);
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_OFFICE, office.getIdentifier());
+  }
+
+  @Test
+  public void shouldAddBranch() throws Exception {
+    final Office office = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(office);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, office.getIdentifier());
+
+    final Office branch = OfficeFactory.createRandomOffice();
+    this.organizationManager.addBranch(office.getIdentifier(), branch);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, branch.getIdentifier());
+
+    final OfficePage officePage = this.organizationManager.getBranches(office.getIdentifier(), 0, 10, null, null);
+    Assert.assertEquals(Long.valueOf(1L), officePage.getTotalElements());
+
+    final Office savedBranch = officePage.getOffices().get(0);
+    Assert.assertEquals(branch.getIdentifier(), savedBranch.getIdentifier());
+
+    this.organizationManager.deleteOffice(branch.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_OFFICE, branch.getIdentifier());
+    this.organizationManager.deleteOffice(office.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_OFFICE, office.getIdentifier());
+
+    this.mockMvc.perform(put(path + "/offices/" + branch.getIdentifier())
+            .contentType(MediaType.APPLICATION_JSON)
+            .content(branch.getIdentifier()))
+            .andExpect(status().is4xxClientError());
+  }
+
+  @Test
+  public void shouldNotAddBranchParentNotFound() throws Exception {
+    try {
+      final Office branch = OfficeFactory.createRandomOffice();
+      this.organizationManager.addBranch(RandomStringUtils.randomAlphanumeric(32), branch);
+      Assert.fail();
+    } catch (final NotFoundException ex) {
+      // do nothing, expected
+    }
+  }
+
+  @Test
+  public void shouldNotAddBranchDuplicate() throws Exception {
+    final Office office = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(office);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, office.getIdentifier());
+    try {
+      this.organizationManager.addBranch(office.getIdentifier(), office);
+      Assert.fail();
+    } catch (final AlreadyExistsException ex) {
+      // do nothing, expected
+    }
+
+    this.organizationManager.deleteOffice(office.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_OFFICE, office.getIdentifier());
+  }
+
+  @Test
+  public void shouldSetAddressOfOffice() throws Exception {
+    final Office office = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(office);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, office.getIdentifier());
+
+    final Address address = AddressFactory.createRandomAddress();
+    this.organizationManager.setAddressForOffice(office.getIdentifier(), address);
+    this.eventRecorder.wait(EventConstants.OPERATION_PUT_ADDRESS, office.getIdentifier());
+
+    final Address savedAddress = this.organizationManager.getAddressOfOffice(office.getIdentifier());
+    Assert.assertNotNull(savedAddress);
+    Assert.assertEquals(address.getStreet(), savedAddress.getStreet());
+    Assert.assertEquals(address.getCity(), savedAddress.getCity());
+    Assert.assertEquals(address.getRegion(), savedAddress.getRegion());
+    Assert.assertEquals(address.getPostalCode(), savedAddress.getPostalCode());
+    Assert.assertEquals(address.getCountryCode(), savedAddress.getCountryCode());
+    Assert.assertEquals(address.getCountry(), savedAddress.getCountry());
+
+    this.organizationManager.deleteOffice(office.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_OFFICE, office.getIdentifier());
+
+    this.mockMvc.perform(put(path + "/offices/" + office.getIdentifier() + "/address")
+            .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON_VALUE)
+            .content(office.getIdentifier()))
+            .andExpect(status().is4xxClientError());
+  }
+
+  @Test
+  public void shouldGetAddressOfOffice() throws Exception {
+    final Office office = OfficeFactory.createRandomOffice();
+    final Address address = AddressFactory.createRandomAddress();
+    office.setAddress(address);
+    this.organizationManager.createOffice(office);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, office.getIdentifier());
+
+    final Address savedAddress = this.organizationManager.getAddressOfOffice(office.getIdentifier());
+    Assert.assertNotNull(savedAddress);
+    Assert.assertEquals(address.getStreet(), savedAddress.getStreet());
+    Assert.assertEquals(address.getCity(), savedAddress.getCity());
+    Assert.assertEquals(address.getRegion(), savedAddress.getRegion());
+    Assert.assertEquals(address.getPostalCode(), savedAddress.getPostalCode());
+    Assert.assertEquals(address.getCountryCode(), savedAddress.getCountryCode());
+    Assert.assertEquals(address.getCountry(), savedAddress.getCountry());
+
+    this.organizationManager.deleteOffice(office.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_OFFICE, office.getIdentifier());
+
+    this.mockMvc.perform(get(path + "/offices/" + office.getIdentifier() + "/address")
+            .accept(MediaType.ALL).contentType(MediaType.APPLICATION_JSON_VALUE))
+            .andExpect(status().isNotFound());
+  }
+
+  @Test
+  public void shouldDeleteAddressOfOffice() throws Exception {
+    final Office office = OfficeFactory.createRandomOffice();
+    final Address address = AddressFactory.createRandomAddress();
+    office.setAddress(address);
+    this.organizationManager.createOffice(office);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, office.getIdentifier());
+
+    final Address savedAddress = this.organizationManager.getAddressOfOffice(office.getIdentifier());
+    Assert.assertNotNull(savedAddress);
+
+    this.organizationManager.deleteAddressOfOffice(office.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_ADDRESS, office.getIdentifier());
+
+    Assert.assertNull(this.organizationManager.getAddressOfOffice(office.getIdentifier()));
+
+    this.organizationManager.deleteOffice(office.getIdentifier());
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_OFFICE, office.getIdentifier());
+
+    this.mockMvc.perform(delete(path + "/offices/" + office.getIdentifier() + "/address")
+            .contentType(MediaType.ALL_VALUE))
+            .andExpect(status().isNotFound());
+  }
+
+  @Test
+  public void shouldReturnParentOfBranch() throws Exception {
+    final Office parent = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(parent);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, parent.getIdentifier());
+
+    final Office branch = OfficeFactory.createRandomOffice();
+    this.organizationManager.addBranch(parent.getIdentifier(), branch);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, branch.getIdentifier());
+
+    final Office savedBranch = this.organizationManager.findOfficeByIdentifier(branch.getIdentifier());
+
+    Assert.assertEquals(parent.getIdentifier(), savedBranch.getParentIdentifier());
+  }
+
+  @Test(expected = NotFoundException.class)
+  public void shouldDeleteOffice() throws Exception{
+    final Office office = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(office);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, office.getIdentifier());
+
+    this.organizationManager.deleteOffice(office.getIdentifier());
+
+    this.eventRecorder.wait(EventConstants.OPERATION_DELETE_OFFICE, office.getIdentifier());
+
+    this.organizationManager.findOfficeByIdentifier(office.getIdentifier());
+
+    this.mockMvc.perform(delete(path + "/offices/" + office.getIdentifier())
+            .contentType(MediaType.ALL_VALUE))
+            .andExpect(status().isNotFound());
+  }
+
+  @Test(expected = ChildrenExistException.class)
+  public void shouldNotDeleteOfficeWithBranches() throws Exception {
+    final Office parent = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(parent);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, parent.getIdentifier());
+
+    final Office branch = OfficeFactory.createRandomOffice();
+    this.organizationManager.addBranch(parent.getIdentifier(), branch);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, branch.getIdentifier());
+
+    final Office fetchedParent = this.organizationManager.findOfficeByIdentifier(parent.getIdentifier());
+    Assert.assertTrue(fetchedParent.getExternalReferences());
+
+    this.organizationManager.deleteOffice(parent.getIdentifier());
+  }
+
+  @Test(expected = ChildrenExistException.class)
+  public void shouldNotDeleteOfficeWithEmployees() throws Exception {
+    final Office office = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(office);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, office.getIdentifier());
+
+    final Employee employee = EmployeeFactory.createRandomEmployee();
+    employee.setAssignedOffice(office.getIdentifier());
+    this.organizationManager.createEmployee(employee);
+    this.eventRecorder.wait(EventConstants.OPERATION_POST_EMPLOYEE, employee.getIdentifier());
+
+    final Office fetchedOffice = this.organizationManager.findOfficeByIdentifier(office.getIdentifier());
+    Assert.assertTrue(fetchedOffice.getExternalReferences());
+
+    this.organizationManager.deleteOffice(office.getIdentifier());
+  }
+
+  @Test(expected = ChildrenExistException.class)
+  public void shouldNotDeleteOfficeWithActiveExternalReference() throws Exception {
+    final Office randomOffice = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(randomOffice);
+    Assert.assertTrue(this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, randomOffice.getIdentifier()));
+
+    final ExternalReference externalReference = new ExternalReference();
+    externalReference.setType("anytype");
+    externalReference.setState(ExternalReference.State.ACTIVE.name());
+
+    this.organizationManager.addExternalReference(randomOffice.getIdentifier(), externalReference);
+    Assert.assertTrue(this.eventRecorder.wait(EventConstants.OPERATION_PUT_REFERENCE, randomOffice.getIdentifier()));
+
+    this.organizationManager.deleteOffice(randomOffice.getIdentifier());
+  }
+
+  @Test
+  public void shouldDeleteOfficeWithInactiveExternalReference() throws Exception {
+    final Office randomOffice = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(randomOffice);
+    Assert.assertTrue(this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, randomOffice.getIdentifier()));
+
+    final ExternalReference externalReference = new ExternalReference();
+    externalReference.setType("anytype");
+    externalReference.setState(ExternalReference.State.INACTIVE.name());
+
+    this.organizationManager.addExternalReference(randomOffice.getIdentifier(), externalReference);
+    Assert.assertTrue(this.eventRecorder.wait(EventConstants.OPERATION_PUT_REFERENCE, randomOffice.getIdentifier()));
+
+    final Office office = this.organizationManager.findOfficeByIdentifier(randomOffice.getIdentifier());
+    Assert.assertFalse(office.getExternalReferences());
+
+    this.organizationManager.deleteOffice(randomOffice.getIdentifier());
+    Assert.assertTrue(this.eventRecorder.wait(EventConstants.OPERATION_DELETE_OFFICE, randomOffice.getIdentifier()));
+  }
+
+  @Test
+  public void shouldIndicateOfficeHasExternalReferences() throws Exception {
+    final Office randomOffice = OfficeFactory.createRandomOffice();
+    this.organizationManager.createOffice(randomOffice);
+    Assert.assertTrue(this.eventRecorder.wait(EventConstants.OPERATION_POST_OFFICE, randomOffice.getIdentifier()));
+
+    final ExternalReference externalReference = new ExternalReference();
+    externalReference.setType("anytype");
+    externalReference.setState(ExternalReference.State.ACTIVE.name());
+
+    this.organizationManager.addExternalReference(randomOffice.getIdentifier(), externalReference);
+    Assert.assertTrue(this.eventRecorder.wait(EventConstants.OPERATION_PUT_REFERENCE, randomOffice.getIdentifier()));
+
+    final Office office = this.organizationManager.findOfficeByIdentifier(randomOffice.getIdentifier());
+    Assert.assertTrue(office.getExternalReferences());
+
+    this.mockMvc.perform(put(path + "/offices/" + office.getIdentifier() + "/references")
+            .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON_VALUE)
+            .content(office.getIdentifier()))
+            .andExpect(status().is4xxClientError());
+  }
+
+  @Configuration
+  @ComponentScan(
+          basePackages = "org.apache.fineract.cn.office.listener"
+  )
+  @EnableFeignClients(basePackages = {"org.apache.fineract.cn.office.api.v1.client"})
+  @RibbonClient(name = APP_NAME)
+  @EnableEventRecording(maxWait = 5000L)
+  @Import({OfficeRestConfiguration.class})
+  public static class TestConfiguration {
+    public TestConfiguration() {
+      super();
+    }
+
+    @Bean
+    public Logger logger() {
+      return LoggerFactory.getLogger("office-test-logger");
+    }
+  }
+}
diff --git a/service/src/test/java/org/apache/fineract/cn/office/listener/EmployeeEventListener.java b/service/src/test/java/org/apache/fineract/cn/office/listener/EmployeeEventListener.java
new file mode 100644
index 0000000..0d0afcf
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/office/listener/EmployeeEventListener.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.cn.office.listener;
+
+import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
+import org.apache.fineract.cn.office.api.v1.EventConstants;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.stereotype.Component;
+
+@Component
+public class EmployeeEventListener {
+
+  private final EventRecorder eventRecorder;
+
+  @Autowired
+  public EmployeeEventListener(final EventRecorder eventRecorder) {
+    super();
+    this.eventRecorder = eventRecorder;
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_POST_EMPLOYEE
+  )
+  public void onCreateEmployee(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                               final String eventPayload) throws Exception {
+    this.eventRecorder.event(tenant, EventConstants.OPERATION_POST_EMPLOYEE, eventPayload, String.class);
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_PUT_EMPLOYEE
+  )
+  public void onUpdateEmployee(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                               final String eventPayload) throws Exception {
+    this.eventRecorder.event(tenant, EventConstants.OPERATION_PUT_EMPLOYEE, eventPayload, String.class);
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_DELETE_EMPLOYEE
+  )
+  public void onDeleteEmployee(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                               final String eventPayload) throws Exception {
+    this.eventRecorder.event(tenant, EventConstants.OPERATION_DELETE_EMPLOYEE, eventPayload, String.class);
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_PUT_CONTACT_DETAIL
+  )
+  public void onSetContactDetail(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                                 final String eventPayload) throws Exception {
+    this.eventRecorder.event(tenant, EventConstants.OPERATION_PUT_CONTACT_DETAIL, eventPayload, String.class);
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_DELETE_CONTACT_DETAIL
+  )
+  public void onDeleteContactDetail(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                                    final String eventPayload) throws Exception {
+    this.eventRecorder.event(tenant, EventConstants.OPERATION_DELETE_CONTACT_DETAIL, eventPayload, String.class);
+  }
+}
diff --git a/service/src/test/java/org/apache/fineract/cn/office/listener/MigrationEventListener.java b/service/src/test/java/org/apache/fineract/cn/office/listener/MigrationEventListener.java
new file mode 100644
index 0000000..581c99a
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/office/listener/MigrationEventListener.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.cn.office.listener;
+
+import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
+import org.apache.fineract.cn.office.api.v1.EventConstants;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.stereotype.Component;
+
+@SuppressWarnings("unused")
+@Component
+public class MigrationEventListener {
+
+  private final EventRecorder eventRecorder;
+
+  @Autowired
+  public MigrationEventListener(final EventRecorder eventRecorder) {
+    super();
+    this.eventRecorder = eventRecorder;
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_INITIALIZE
+  )
+  public void onInitialized(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                            final String payload) {
+    this.eventRecorder.event(tenant, EventConstants.INITIALIZE, payload, String.class);
+  }
+}
diff --git a/service/src/test/java/org/apache/fineract/cn/office/listener/OfficeEventListener.java b/service/src/test/java/org/apache/fineract/cn/office/listener/OfficeEventListener.java
new file mode 100644
index 0000000..58d9810
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/office/listener/OfficeEventListener.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.cn.office.listener;
+
+import com.google.gson.Gson;
+import org.apache.fineract.cn.command.util.CommandConstants;
+import org.apache.fineract.cn.lang.config.TenantHeaderFilter;
+import org.apache.fineract.cn.office.api.v1.EventConstants;
+import org.apache.fineract.cn.test.listener.EventRecorder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.jms.annotation.JmsListener;
+import org.springframework.messaging.handler.annotation.Header;
+import org.springframework.stereotype.Component;
+
+@Component
+public class OfficeEventListener {
+
+  private final Gson gson;
+  private final EventRecorder eventRecorder;
+
+  @Autowired
+  public OfficeEventListener(@Qualifier(CommandConstants.SERIALIZER) final Gson gson,
+                             final EventRecorder eventRecorder) {
+    super();
+    this.gson = gson;
+    this.eventRecorder = eventRecorder;
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_POST_OFFICE
+  )
+  public void onCreateOffice(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                             final String payload)
+      throws Exception {
+    this.eventRecorder.event(tenant, EventConstants.OPERATION_POST_OFFICE, payload, String.class);
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_DELETE_OFFICE
+  )
+  public void onDeleteOffice(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                             final String payload)
+      throws Exception {
+    this.eventRecorder.event(tenant, EventConstants.OPERATION_DELETE_OFFICE, payload, String.class);
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_PUT_OFFICE
+  )
+  public void onUpdateOffice(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                             final String payload)
+      throws Exception {
+    this.eventRecorder.event(tenant, EventConstants.OPERATION_PUT_OFFICE, payload, String.class);
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_PUT_ADDRESS
+  )
+  public void onSetAddress(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                           final String payload)
+      throws Exception {
+    this.eventRecorder.event(tenant, EventConstants.OPERATION_PUT_ADDRESS, payload, String.class);
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_DELETE_ADDRESS
+  )
+  public void onDeleteAddress(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                              final String payload)
+      throws Exception {
+    this.eventRecorder.event(tenant, EventConstants.OPERATION_DELETE_ADDRESS, payload, String.class);
+  }
+
+  @JmsListener(
+      subscription = EventConstants.DESTINATION,
+      destination = EventConstants.DESTINATION,
+      selector = EventConstants.SELECTOR_PUT_REFERENCE
+  )
+  public void onPutAReference(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+                              final String payload)
+      throws Exception {
+    this.eventRecorder.event(tenant, EventConstants.OPERATION_PUT_REFERENCE, payload, String.class);
+  }
+}
diff --git a/service/src/test/java/org/apache/fineract/cn/office/util/AddressFactory.java b/service/src/test/java/org/apache/fineract/cn/office/util/AddressFactory.java
new file mode 100644
index 0000000..5da97b5
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/office/util/AddressFactory.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.cn.office.util;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.fineract.cn.office.api.v1.domain.Address;
+
+public class AddressFactory {
+
+  private AddressFactory() {
+    super();
+  }
+
+  public static Address createRandomAddress() {
+    final Address address = new Address();
+    address.setStreet(RandomStringUtils.randomAlphanumeric(16));
+    address.setCity(RandomStringUtils.randomAlphanumeric(16));
+    address.setRegion(RandomStringUtils.randomAlphanumeric(16));
+    address.setPostalCode(RandomStringUtils.randomAlphabetic(6));
+    address.setCountryCode(RandomStringUtils.randomAlphanumeric(2));
+    address.setCountry(RandomStringUtils.randomAlphanumeric(16));
+    return address;
+  }
+}
diff --git a/service/src/test/java/org/apache/fineract/cn/office/util/EmployeeFactory.java b/service/src/test/java/org/apache/fineract/cn/office/util/EmployeeFactory.java
new file mode 100644
index 0000000..9c35875
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/office/util/EmployeeFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.cn.office.util;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.fineract.cn.office.api.v1.domain.Employee;
+
+public class EmployeeFactory {
+
+  private EmployeeFactory() {
+    super();
+  }
+
+  public static Employee createRandomEmployee() {
+    final Employee employee = new Employee();
+    employee.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
+    employee.setGivenName(RandomStringUtils.randomAlphanumeric(256));
+    employee.setMiddleName(RandomStringUtils.randomAlphanumeric(256));
+    employee.setSurname(RandomStringUtils.randomAlphanumeric(256));
+    return employee;
+  }
+}
diff --git a/service/src/test/java/org/apache/fineract/cn/office/util/OfficeFactory.java b/service/src/test/java/org/apache/fineract/cn/office/util/OfficeFactory.java
new file mode 100644
index 0000000..7df1c6f
--- /dev/null
+++ b/service/src/test/java/org/apache/fineract/cn/office/util/OfficeFactory.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.cn.office.util;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.fineract.cn.office.api.v1.domain.Office;
+
+public class OfficeFactory {
+
+  private OfficeFactory() {
+    super();
+  }
+
+  public static Office createRandomOffice() {
+    final Office office = new Office();
+    office.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
+    office.setName(RandomStringUtils.randomAlphanumeric(256));
+    office.setDescription(RandomStringUtils.randomAlphanumeric(2048));
+    return office;
+  }
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services