You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by aw...@apache.org on 2019/06/03 19:02:50 UTC
[fineract-cn-payroll] 15/50: initial commit
This is an automated email from the ASF dual-hosted git repository.
awasum pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract-cn-payroll.git
commit 118dd1df0e001f35cdbc3889f07915c5b60491b3
Author: mgeiss <mg...@mifos.org>
AuthorDate: Mon Sep 18 16:36:23 2017 +0200
initial commit
---
.gitignore | 1 +
README.md | 47 +------
.../events => payroll/api/v1}/EventConstants.java | 16 ++-
.../api/v1/PermittableGroupIds.java | 6 +-
.../api/v1/client/CustomerNotFoundException.java} | 5 +-
.../PayrollConfigurationNotFoundException.java | 5 +-
.../PayrollDistributionValidationException.java | 5 +-
.../payroll/api/v1/client/PayrollManager.java | 96 ++++++++++++++
.../client/PayrollPaymentValidationException.java | 5 +-
.../payroll/api/v1/domain/PayrollAllocation.java | 62 +++++++++
.../api/v1/domain/PayrollCollectionHistory.java | 68 ++++++++++
.../api/v1/domain/PayrollCollectionSheet.java | 51 +++++++
.../api/v1/domain/PayrollConfiguration.java | 86 ++++++++++++
.../payroll/api/v1/domain/PayrollPayment.java | 63 +++++++++
.../payroll/api/v1/domain/PayrollPaymentPage.java | 61 +++++++++
.../template/api/v1/client/TemplateManager.java | 57 --------
.../io/mifos/template/api/v1/domain/Sample.java | 70 ----------
.../mifos/template/api/v1/domain/SampleTest.java | 55 --------
component-test/build.gradle | 4 +-
.../java/io/mifos/payroll/AbstractPayrollTest.java | 111 ++++++++++++++++
.../SuiteTestEnvironment.java | 4 +-
.../io/mifos/payroll/TestPayrollConfiguration.java | 118 +++++++++++++++++
.../io/mifos/payroll/TestPayrollDistribution.java | 101 ++++++++++++++
.../io/mifos/{template => payroll}/TestSuite.java | 6 +-
.../payroll/domain/DomainObjectGenerator.java | 46 +++++++
.../listener/MigrationEventListener.java | 4 +-
.../listener/PayrollConfigurationListener.java} | 24 ++--
.../listener/PayrollDistributionListener.java} | 22 ++--
.../main/java/io/mifos/template/TestSample.java | 130 ------------------
component-test/src/main/resources/logback-test.xml | 34 +++++
gradle/wrapper/gradle-wrapper.properties | 4 +-
service/build.gradle | 4 +-
.../service/PayrollApplication.java} | 8 +-
.../service/PayrollServiceConfiguration.java} | 23 ++--
.../service/ServiceConstants.java | 4 +-
.../command/DistributePayrollCommand.java} | 24 ++--
.../internal/command/MigrateServiceCommand.java} | 12 +-
.../command/PutPayrollConfigurationCommand.java | 38 ++++++
.../command/handler/MigrationAggregate.java | 26 ++--
.../handler/PayrollConfigurationAggregate.java | 99 ++++++++++++++
.../handler/PayrollDistributionAggregate.java | 96 ++++++++++++++
.../internal/mapper/PayrollAllocationMapper.java | 42 ++++++
.../mapper/PayrollConfigurationMapper.java | 39 ++++++
.../internal/mapper/PayrollPaymentMapper.java | 34 +++++
.../repository/PayrollAllocationEntity.java | 89 +++++++++++++
.../repository/PayrollAllocationRepository.java} | 14 +-
.../repository/PayrollCollectionEntity.java | 89 +++++++++++++
.../repository/PayrollCollectionRepository.java} | 9 +-
.../repository/PayrollConfigurationEntity.java | 111 ++++++++++++++++
.../PayrollConfigurationRepository.java} | 6 +-
.../internal/repository/PayrollPaymentEntity.java | 89 +++++++++++++
.../repository/PayrollPaymentRepository.java} | 11 +-
.../service/PayrollConfigurationService.java | 83 ++++++++++++
.../service/PayrollDistributionService.java | 100 ++++++++++++++
.../service/adaptor/AccountingAdaptor.java | 112 ++++++++++++++++
.../internal/service/adaptor/CustomerAdaptor.java | 51 +++++++
.../service/rest/MigrationRestController.java | 56 ++++++++
.../rest/PayrollConfigurationRestController.java | 113 ++++++++++++++++
.../rest/PayrollDistributionRestController.java | 146 +++++++++++++++++++++
.../payroll/service/rest/util/PageableBuilder.java | 41 ++++++
.../internal/command/handler/SampleAggregate.java | 65 ---------
.../service/internal/mapper/SampleMapper.java | 43 ------
.../internal/repository/SampleJpaEntity.java | 61 ---------
.../service/internal/service/SampleService.java | 45 -------
.../service/rest/SampleRestController.java | 112 ----------------
service/src/main/resources/application.yml | 2 +-
service/src/main/resources/bootstrap.yml | 2 +-
.../db/migrations/mariadb/V1__initial_setup.sql | 46 ++++++-
service/src/main/resources/logback.xml | 55 ++++++++
settings.gradle | 2 +-
shared.gradle | 4 +-
71 files changed, 2561 insertions(+), 812 deletions(-)
diff --git a/.gitignore b/.gitignore
index f9d7cba..1d62734 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
.idea
build/
target/
+out/
# Ignore Gradle GUI config
gradle-app.setting
diff --git a/README.md b/README.md
index 1839633..8636dff 100644
--- a/README.md
+++ b/README.md
@@ -1,49 +1,6 @@
-# Mifos I/O Template
+# Mifos I/O Payroll
-[![Join the chat at https://gitter.im/mifos-initiative/mifos.io](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mifos-initiative/mifos.io?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-
-This project provides a template layout for all Mifos I/O microservices.
-
-## Abstract
-Mifos I/O is an application framework for digital financial services, a system to support nationwide and cross-national financial transactions and help to level and speed the creation of an inclusive, interconnected digital economy for every nation in the world.
-
-## Steps needed to turn the template project into a real project
-
-1. Git clone template into {project name} folder
-
- git clone https://github.com/mifosio/template.git {project name}
-
-2. Delete _.git_
-
- rm -rf .git
-
-3. Open settings.gradle and replace value of _rootProject.name_ with {project name}
-
-4. Open root build.gradle and replace value of _version_ with 0.1.0-snapshot
-
-6. Create Gradle wrapper
-
- gradle wrapper
-
-6. Open all module specific build.gradle files (api, service, and component-test) and replace value of _group_ with io.mifos.{project name}
-
-7. Import project into IDE
-
-8. Rename all io.mifos.template packages to io.mifos.{project name}
-
-9. Open _SampleRestConfiguration_ and _SampleServiceConfiguration_, adjust @ComponentScan to reflect the new package name
-
-10. Open _application.yml_ and replace _server.contextPath_ with /{project name}/v1/*
-
-11. Open _bootstrap.yml_ and replace _spring.application.name_ with {project name}/v1/
-
-12. Open _SampleTest_ and replace constructor argument of TestEnvironment in line 80 with {project name}/v1/
-
-13. Run _SampleTest_
-
-14. Replace the contents of the README with text describing your new project.
-
-15. Happy coding! ; o)
+This project provides functionality to configure payroll allocations and distribute payroll payments for customers.
## Versioning
The version numbers follow the [Semantic Versioning](http://semver.org/) scheme.
diff --git a/api/src/main/java/io/mifos/template/api/v1/events/EventConstants.java b/api/src/main/java/io/mifos/payroll/api/v1/EventConstants.java
similarity index 67%
rename from api/src/main/java/io/mifos/template/api/v1/events/EventConstants.java
rename to api/src/main/java/io/mifos/payroll/api/v1/EventConstants.java
index 6207c03..72e925b 100644
--- a/api/src/main/java/io/mifos/template/api/v1/events/EventConstants.java
+++ b/api/src/main/java/io/mifos/payroll/api/v1/EventConstants.java
@@ -13,14 +13,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.api.v1.events;
+package io.mifos.payroll.api.v1;
@SuppressWarnings("unused")
public interface EventConstants {
- String DESTINATION = "template-v1";
+ String DESTINATION = "payroll-v1";
String SELECTOR_NAME = "action";
+
+ // Migration events
String INITIALIZE = "initialize";
+
+ // Payroll configuration events
+ String PUT_CONFIGURATION = "put-configuration";
+ String SELECTOR_PUT_CONFIGURATION = SELECTOR_NAME + " = '" + PUT_CONFIGURATION + "'";
+
+ // Payroll distribution events
+ String POST_DISTRIBUTION = "post-distribution";
+ String SELECTOR_POST_DISTRIBUTION = SELECTOR_NAME + " = '" + POST_DISTRIBUTION + "'";
+
+
String POST_SAMPLE = "post-sample";
String SELECTOR_INITIALIZE = SELECTOR_NAME + " = '" + INITIALIZE + "'";
String SELECTOR_POST_SAMPLE = SELECTOR_NAME + " = '" + POST_SAMPLE + "'";
diff --git a/api/src/main/java/io/mifos/template/api/v1/PermittableGroupIds.java b/api/src/main/java/io/mifos/payroll/api/v1/PermittableGroupIds.java
similarity index 82%
rename from api/src/main/java/io/mifos/template/api/v1/PermittableGroupIds.java
rename to api/src/main/java/io/mifos/payroll/api/v1/PermittableGroupIds.java
index 239e2ac..f925986 100644
--- a/api/src/main/java/io/mifos/template/api/v1/PermittableGroupIds.java
+++ b/api/src/main/java/io/mifos/payroll/api/v1/PermittableGroupIds.java
@@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.api.v1;
+package io.mifos.payroll.api.v1;
@SuppressWarnings("unused")
public interface PermittableGroupIds {
- String SAMPLE_MANAGEMENT = "template__v1__samples";
- String SELF_MANAGEMENT = "template__v1__self";
+ String CONFIGURATION = "payroll__v1__configuration";
+ String DISTRIBUTION = "payroll__v1__distribution";
}
diff --git a/api/src/main/java/io/mifos/template/api/v1/client/IamATeapotException.java b/api/src/main/java/io/mifos/payroll/api/v1/client/CustomerNotFoundException.java
similarity index 81%
rename from api/src/main/java/io/mifos/template/api/v1/client/IamATeapotException.java
rename to api/src/main/java/io/mifos/payroll/api/v1/client/CustomerNotFoundException.java
index ec4383c..ca8d1c8 100644
--- a/api/src/main/java/io/mifos/template/api/v1/client/IamATeapotException.java
+++ b/api/src/main/java/io/mifos/payroll/api/v1/client/CustomerNotFoundException.java
@@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.api.v1.client;
+package io.mifos.payroll.api.v1.client;
-@SuppressWarnings("WeakerAccess")
-public class IamATeapotException extends RuntimeException {
+public class CustomerNotFoundException extends RuntimeException {
}
diff --git a/service/src/main/java/io/mifos/template/service/ServiceConstants.java b/api/src/main/java/io/mifos/payroll/api/v1/client/PayrollConfigurationNotFoundException.java
similarity index 83%
copy from service/src/main/java/io/mifos/template/service/ServiceConstants.java
copy to api/src/main/java/io/mifos/payroll/api/v1/client/PayrollConfigurationNotFoundException.java
index e9e0623..0c39d16 100644
--- a/service/src/main/java/io/mifos/template/service/ServiceConstants.java
+++ b/api/src/main/java/io/mifos/payroll/api/v1/client/PayrollConfigurationNotFoundException.java
@@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.service;
+package io.mifos.payroll.api.v1.client;
-public interface ServiceConstants {
- String LOGGER_NAME = "rest-logger";
+public class PayrollConfigurationNotFoundException extends RuntimeException {
}
diff --git a/service/src/main/java/io/mifos/template/service/ServiceConstants.java b/api/src/main/java/io/mifos/payroll/api/v1/client/PayrollDistributionValidationException.java
similarity index 83%
copy from service/src/main/java/io/mifos/template/service/ServiceConstants.java
copy to api/src/main/java/io/mifos/payroll/api/v1/client/PayrollDistributionValidationException.java
index e9e0623..2f330f2 100644
--- a/service/src/main/java/io/mifos/template/service/ServiceConstants.java
+++ b/api/src/main/java/io/mifos/payroll/api/v1/client/PayrollDistributionValidationException.java
@@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.service;
+package io.mifos.payroll.api.v1.client;
-public interface ServiceConstants {
- String LOGGER_NAME = "rest-logger";
+public class PayrollDistributionValidationException extends RuntimeException {
}
diff --git a/api/src/main/java/io/mifos/payroll/api/v1/client/PayrollManager.java b/api/src/main/java/io/mifos/payroll/api/v1/client/PayrollManager.java
new file mode 100644
index 0000000..5c232c0
--- /dev/null
+++ b/api/src/main/java/io/mifos/payroll/api/v1/client/PayrollManager.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.api.v1.client;
+
+import io.mifos.core.api.annotation.ThrowsException;
+import io.mifos.core.api.annotation.ThrowsExceptions;
+import io.mifos.core.api.util.CustomFeignClientsConfiguration;
+import io.mifos.payroll.api.v1.domain.PayrollCollectionHistory;
+import io.mifos.payroll.api.v1.domain.PayrollCollectionSheet;
+import io.mifos.payroll.api.v1.domain.PayrollConfiguration;
+import io.mifos.payroll.api.v1.domain.PayrollPaymentPage;
+import org.springframework.cloud.netflix.feign.FeignClient;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.validation.Valid;
+import java.util.List;
+
+@SuppressWarnings("unused")
+@FeignClient(name="payroll-v1", path="/payroll/v1", configuration = CustomFeignClientsConfiguration.class)
+public interface PayrollManager {
+
+ @RequestMapping(
+ value = "/customers/{identifier}/payroll",
+ method = RequestMethod.PUT,
+ produces = MediaType.APPLICATION_JSON_VALUE,
+ consumes = MediaType.APPLICATION_JSON_VALUE
+ )
+ @ThrowsExceptions({
+ @ThrowsException(status = HttpStatus.NOT_FOUND, exception = CustomerNotFoundException.class),
+ @ThrowsException(status = HttpStatus.BAD_REQUEST, exception = PayrollDistributionValidationException.class)
+ })
+ void setPayrollConfiguration(@PathVariable(value = "identifier") final String customerIdentifier,
+ @RequestBody @Valid final PayrollConfiguration payrollConfiguration);
+
+ @RequestMapping(
+ value = "/customers/{identifier}/payroll",
+ method = RequestMethod.GET,
+ produces = MediaType.ALL_VALUE,
+ consumes = MediaType.APPLICATION_JSON_VALUE
+ )
+ @ThrowsExceptions({
+ @ThrowsException(status = HttpStatus.NOT_FOUND, exception = PayrollConfigurationNotFoundException.class)
+ })
+ PayrollConfiguration findPayrollConfiguration(@PathVariable(value = "identifier") final String customerIdentifier);
+
+ @RequestMapping(
+ value = "/distribution",
+ method = RequestMethod.POST,
+ produces = MediaType.APPLICATION_JSON_VALUE,
+ consumes = MediaType.APPLICATION_JSON_VALUE
+ )
+ @ThrowsExceptions({
+ @ThrowsException(status = HttpStatus.BAD_REQUEST, exception = PayrollPaymentValidationException.class)
+ })
+ void distribute(@RequestBody @Valid final PayrollCollectionSheet payrollCollectionSheet);
+
+ @RequestMapping(
+ value = "/distribution",
+ method = RequestMethod.GET,
+ produces = MediaType.ALL_VALUE,
+ consumes = MediaType.APPLICATION_JSON_VALUE
+ )
+ List<PayrollCollectionHistory> fetchDistributionHistory();
+
+ @RequestMapping(
+ value = "/distribution/{identifier}/payments",
+ method = RequestMethod.GET,
+ produces = MediaType.ALL_VALUE,
+ consumes = MediaType.APPLICATION_JSON_VALUE
+ )
+ PayrollPaymentPage fetchPayments(@PathVariable("identifier") final String identifier,
+ @RequestParam(value = "pageIndex", required = false) final Integer pageIndex,
+ @RequestParam(value = "size", required = false) final Integer size,
+ @RequestParam(value = "sortColumn", required = false) final String sortColumn,
+ @RequestParam(value = "sortDirection", required = false) final String sortDirection);
+
+}
diff --git a/service/src/main/java/io/mifos/template/service/ServiceConstants.java b/api/src/main/java/io/mifos/payroll/api/v1/client/PayrollPaymentValidationException.java
similarity index 84%
copy from service/src/main/java/io/mifos/template/service/ServiceConstants.java
copy to api/src/main/java/io/mifos/payroll/api/v1/client/PayrollPaymentValidationException.java
index e9e0623..90ee5e5 100644
--- a/service/src/main/java/io/mifos/template/service/ServiceConstants.java
+++ b/api/src/main/java/io/mifos/payroll/api/v1/client/PayrollPaymentValidationException.java
@@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.service;
+package io.mifos.payroll.api.v1.client;
-public interface ServiceConstants {
- String LOGGER_NAME = "rest-logger";
+public class PayrollPaymentValidationException extends RuntimeException {
}
diff --git a/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollAllocation.java b/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollAllocation.java
new file mode 100644
index 0000000..3a4d42c
--- /dev/null
+++ b/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollAllocation.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.api.v1.domain;
+
+import io.mifos.core.lang.validation.constraints.ValidIdentifier;
+
+import javax.validation.constraints.DecimalMax;
+import javax.validation.constraints.DecimalMin;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+public class PayrollAllocation {
+
+ @ValidIdentifier(maxLength = 34)
+ private String accountNumber;
+ @NotNull
+ @DecimalMin("0.001")
+ @DecimalMax("9999999999.99999")
+ private BigDecimal amount;
+ private Boolean proportional = Boolean.FALSE;
+
+ public PayrollAllocation() {
+ super();
+ }
+
+ public String getAccountNumber() {
+ return this.accountNumber;
+ }
+
+ public void setAccountNumber(final String accountNumber) {
+ this.accountNumber = accountNumber;
+ }
+
+ public BigDecimal getAmount() {
+ return this.amount;
+ }
+
+ public void setAmount(final BigDecimal amount) {
+ this.amount = amount;
+ }
+
+ public Boolean getProportional() {
+ return this.proportional;
+ }
+
+ public void setProportional(final Boolean proportional) {
+ this.proportional = proportional;
+ }
+}
diff --git a/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollCollectionHistory.java b/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollCollectionHistory.java
new file mode 100644
index 0000000..b0b5f77
--- /dev/null
+++ b/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollCollectionHistory.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.api.v1.domain;
+
+import io.mifos.core.lang.validation.constraints.ValidIdentifier;
+
+import javax.validation.constraints.NotNull;
+
+public class PayrollCollectionHistory {
+
+ @ValidIdentifier
+ private String identifier;
+ @ValidIdentifier(maxLength = 34)
+ private String sourceAccountNumber;
+ @ValidIdentifier
+ private String createdBy;
+ @NotNull
+ private String createdOn;
+
+ public PayrollCollectionHistory() {
+ super();
+ }
+
+ public String getIdentifier() {
+ return this.identifier;
+ }
+
+ public void setIdentifier(final String identifier) {
+ this.identifier = identifier;
+ }
+
+ public String getSourceAccountNumber() {
+ return this.sourceAccountNumber;
+ }
+
+ public void setSourceAccountNumber(final String sourceAccountNumber) {
+ this.sourceAccountNumber = sourceAccountNumber;
+ }
+
+ public String getCreatedBy() {
+ return this.createdBy;
+ }
+
+ public void setCreatedBy(final String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public String getCreatedOn() {
+ return this.createdOn;
+ }
+
+ public void setCreatedOn(final String createdOn) {
+ this.createdOn = createdOn;
+ }
+}
diff --git a/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollCollectionSheet.java b/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollCollectionSheet.java
new file mode 100644
index 0000000..99f2f78
--- /dev/null
+++ b/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollCollectionSheet.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.api.v1.domain;
+
+import io.mifos.core.lang.validation.constraints.ValidIdentifier;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+public class PayrollCollectionSheet {
+
+ @ValidIdentifier(maxLength = 34)
+ private String sourceAccountNumber;
+ @NotNull
+ @Valid
+ private List<PayrollPayment> payrollPayments;
+
+ public PayrollCollectionSheet() {
+ super();
+ }
+
+ public String getSourceAccountNumber() {
+ return this.sourceAccountNumber;
+ }
+
+ public void setSourceAccountNumber(final String sourceAccountNumber) {
+ this.sourceAccountNumber = sourceAccountNumber;
+ }
+
+ public List<PayrollPayment> getPayrollPayments() {
+ return this.payrollPayments;
+ }
+
+ public void setPayrollPayments(final List<PayrollPayment> payrollPayments) {
+ this.payrollPayments = payrollPayments;
+ }
+}
diff --git a/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollConfiguration.java b/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollConfiguration.java
new file mode 100644
index 0000000..5375a9a
--- /dev/null
+++ b/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollConfiguration.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.api.v1.domain;
+
+import io.mifos.core.lang.validation.constraints.ValidIdentifier;
+
+import javax.validation.Valid;
+import java.util.HashSet;
+import java.util.Set;
+
+public class PayrollConfiguration {
+
+ @ValidIdentifier(maxLength = 34)
+ private String mainAccountNumber;
+ @Valid
+ private Set<PayrollAllocation> payrollAllocations = new HashSet<>();
+ private String createdBy;
+ private String createdOn;
+ private String lastModifiedBy;
+ private String lastModifiedOn;
+
+ public PayrollConfiguration() {
+ super();
+ }
+
+ public String getMainAccountNumber() {
+ return this.mainAccountNumber;
+ }
+
+ public void setMainAccountNumber(final String mainAccountNumber) {
+ this.mainAccountNumber = mainAccountNumber;
+ }
+
+ public Set<PayrollAllocation> getPayrollAllocations() {
+ return this.payrollAllocations;
+ }
+
+ public void setPayrollAllocations(final Set<PayrollAllocation> payrollAllocations) {
+ this.payrollAllocations = payrollAllocations;
+ }
+
+ public String getCreatedBy() {
+ return this.createdBy;
+ }
+
+ public void setCreatedBy(final String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public String getCreatedOn() {
+ return this.createdOn;
+ }
+
+ public void setCreatedOn(final String createdOn) {
+ this.createdOn = createdOn;
+ }
+
+ public String getLastModifiedBy() {
+ return this.lastModifiedBy;
+ }
+
+ public void setLastModifiedBy(final String lastModifiedBy) {
+ this.lastModifiedBy = lastModifiedBy;
+ }
+
+ public String getLastModifiedOn() {
+ return this.lastModifiedOn;
+ }
+
+ public void setLastModifiedOn(final String lastModifiedOn) {
+ this.lastModifiedOn = lastModifiedOn;
+ }
+}
diff --git a/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollPayment.java b/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollPayment.java
new file mode 100644
index 0000000..50daa4b
--- /dev/null
+++ b/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollPayment.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.api.v1.domain;
+
+import io.mifos.core.lang.validation.constraints.ValidIdentifier;
+
+import javax.validation.constraints.DecimalMax;
+import javax.validation.constraints.DecimalMin;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+public class PayrollPayment {
+
+ @ValidIdentifier
+ private String customerIdentifier;
+ @NotNull
+ private String employer;
+ @NotNull
+ @DecimalMin("0.001")
+ @DecimalMax("9999999999.99999")
+ private BigDecimal salary;
+
+ public PayrollPayment() {
+ super();
+ }
+
+ public String getCustomerIdentifier() {
+ return this.customerIdentifier;
+ }
+
+ public void setCustomerIdentifier(final String customerIdentifier) {
+ this.customerIdentifier = customerIdentifier;
+ }
+
+ public String getEmployer() {
+ return this.employer;
+ }
+
+ public void setEmployer(final String employer) {
+ this.employer = employer;
+ }
+
+ public BigDecimal getSalary() {
+ return this.salary;
+ }
+
+ public void setSalary(final BigDecimal salary) {
+ this.salary = salary;
+ }
+}
diff --git a/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollPaymentPage.java b/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollPaymentPage.java
new file mode 100644
index 0000000..2e28399
--- /dev/null
+++ b/api/src/main/java/io/mifos/payroll/api/v1/domain/PayrollPaymentPage.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.api.v1.domain;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PayrollPaymentPage {
+
+ private List<PayrollPayment> payrollPayments;
+ private Integer totalPages;
+ private Long totalElements;
+
+ public PayrollPaymentPage() {
+ super();
+ }
+
+ public List<PayrollPayment> getPayrollPayments() {
+ return this.payrollPayments;
+ }
+
+ public void setPayrollPayments(final List<PayrollPayment> payrollPayments) {
+ this.payrollPayments = payrollPayments;
+ }
+
+ public Integer getTotalPages() {
+ return this.totalPages;
+ }
+
+ public void setTotalPages(final Integer totalPages) {
+ this.totalPages = totalPages;
+ }
+
+ public Long getTotalElements() {
+ return this.totalElements;
+ }
+
+ public void setTotalElements(final Long totalElements) {
+ this.totalElements = totalElements;
+ }
+
+ public void add(final PayrollPayment payrollPayment) {
+ if (this.payrollPayments == null) {
+ this.payrollPayments = new ArrayList<>();
+ }
+ this.payrollPayments.add(payrollPayment);
+ }
+}
diff --git a/api/src/main/java/io/mifos/template/api/v1/client/TemplateManager.java b/api/src/main/java/io/mifos/template/api/v1/client/TemplateManager.java
deleted file mode 100644
index 9914e36..0000000
--- a/api/src/main/java/io/mifos/template/api/v1/client/TemplateManager.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2017 The Mifos Initiative.
- *
- * Licensed 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 io.mifos.template.api.v1.client;
-
-import io.mifos.core.api.annotation.ThrowsException;
-import io.mifos.core.api.util.CustomFeignClientsConfiguration;
-import io.mifos.template.api.v1.domain.Sample;
-import org.springframework.cloud.netflix.feign.FeignClient;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-
-import java.util.List;
-
-@SuppressWarnings("unused")
-@FeignClient(value="template-v1", path="/template/v1", configuration = CustomFeignClientsConfiguration.class)
-public interface TemplateManager {
-
- @RequestMapping(
- value = "/sample",
- method = RequestMethod.GET,
- produces = MediaType.ALL_VALUE,
- consumes = MediaType.APPLICATION_JSON_VALUE
- )
- List<Sample> findAllEntities();
-
- @RequestMapping(
- value = "/sample/{identifier}",
- method = RequestMethod.GET,
- produces = MediaType.ALL_VALUE,
- consumes = MediaType.APPLICATION_JSON_VALUE)
- Sample getEntity(@PathVariable("identifier") final String identifier);
-
- @RequestMapping(
- value = "/sample",
- method = RequestMethod.POST,
- produces = MediaType.APPLICATION_JSON_VALUE,
- consumes = MediaType.APPLICATION_JSON_VALUE
- )
- @ThrowsException(status = HttpStatus.I_AM_A_TEAPOT, exception = IamATeapotException.class)
- void createEntity(final Sample sample);
-}
diff --git a/api/src/main/java/io/mifos/template/api/v1/domain/Sample.java b/api/src/main/java/io/mifos/template/api/v1/domain/Sample.java
deleted file mode 100644
index 6f25719..0000000
--- a/api/src/main/java/io/mifos/template/api/v1/domain/Sample.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2017 The Mifos Initiative.
- *
- * Licensed 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 io.mifos.template.api.v1.domain;
-
-import io.mifos.core.lang.validation.constraints.ValidIdentifier;
-import org.hibernate.validator.constraints.Length;
-
-import java.util.Objects;
-
-@SuppressWarnings({"WeakerAccess", "unused"})
-public class Sample {
- @ValidIdentifier
- private String identifier;
- @Length(max = 512)
- private String payload;
-
- public Sample() {
- super();
- }
-
- public static Sample create(final String identifier, final String payload) {
- final Sample sample = new Sample();
- sample.setIdentifier(identifier);
- sample.setPayload(payload);
- return sample;
- }
-
- public String getIdentifier() {
- return this.identifier;
- }
-
- public void setIdentifier(final String identifier) {
- this.identifier = identifier;
- }
-
- public String getPayload() {
- return payload;
- }
-
- public void setPayload(String payload) {
- this.payload = payload;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- Sample sample = (Sample) o;
- return Objects.equals(identifier, sample.identifier) &&
- Objects.equals(payload, sample.payload);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(identifier, payload);
- }
-}
diff --git a/api/src/test/java/io/mifos/template/api/v1/domain/SampleTest.java b/api/src/test/java/io/mifos/template/api/v1/domain/SampleTest.java
deleted file mode 100644
index acf33cb..0000000
--- a/api/src/test/java/io/mifos/template/api/v1/domain/SampleTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2017 The Mifos Initiative.
- *
- * Licensed 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 io.mifos.template.api.v1.domain;
-
-import io.mifos.core.test.domain.ValidationTest;
-import io.mifos.core.test.domain.ValidationTestCase;
-import org.apache.commons.lang.RandomStringUtils;
-import org.junit.runners.Parameterized;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
-public class SampleTest extends ValidationTest<Sample> {
-
- public SampleTest(ValidationTestCase<Sample> testCase) {
- super(testCase);
- }
-
- @Override
- protected Sample createValidTestSubject() {
- return Sample.create("xxxx", "yyy");
- }
-
- @Parameterized.Parameters
- public static Collection testCases() {
- final Collection<ValidationTestCase> ret = new ArrayList<>();
- ret.add(new ValidationTestCase<Sample>("basicCase")
- .adjustment(x -> {})
- .valid(true));
- ret.add(new ValidationTestCase<Sample>("nullIdentifier")
- .adjustment(x -> x.setIdentifier(null))
- .valid(false));
- ret.add(new ValidationTestCase<Sample>("tooShortIdentifier")
- .adjustment(x -> x.setIdentifier("z"))
- .valid(false));
- ret.add(new ValidationTestCase<Sample>("tooLongPayload")
- .adjustment(x -> x.setPayload(RandomStringUtils.randomAlphanumeric(513)))
- .valid(false));
- return ret;
- }
-
-}
\ No newline at end of file
diff --git a/component-test/build.gradle b/component-test/build.gradle
index 7818273..4e0cc53 100644
--- a/component-test/build.gradle
+++ b/component-test/build.gradle
@@ -19,8 +19,8 @@ apply from: '../shared.gradle'
dependencies {
compile(
- [group: 'io.mifos.template', name: 'api', version: project.version],
- [group: 'io.mifos.template', name: 'service', version: project.version],
+ [group: 'io.mifos.payroll', name: 'api', version: project.version],
+ [group: 'io.mifos.payroll', name: 'service', version: project.version],
[group: 'io.mifos.anubis', name: 'test', version: versions.frameworkanubis],
[group: 'io.mifos.core', name: 'api', version: versions.frameworkapi],
[group: 'io.mifos.core', name: 'test', version: versions.frameworktest],
diff --git a/component-test/src/main/java/io/mifos/payroll/AbstractPayrollTest.java b/component-test/src/main/java/io/mifos/payroll/AbstractPayrollTest.java
new file mode 100644
index 0000000..a995040
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/payroll/AbstractPayrollTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll;
+
+
+import io.mifos.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
+import io.mifos.core.api.context.AutoUserContext;
+import io.mifos.core.test.fixture.TenantDataStoreContextTestRule;
+import io.mifos.core.test.listener.EnableEventRecording;
+import io.mifos.core.test.listener.EventRecorder;
+import io.mifos.payroll.api.v1.EventConstants;
+import io.mifos.payroll.api.v1.client.PayrollManager;
+import io.mifos.payroll.service.PayrollServiceConfiguration;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+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.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(
+ webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
+ classes = {
+ AbstractPayrollTest.TestConfiguration.class
+ }
+)
+public class AbstractPayrollTest extends SuiteTestEnvironment {
+
+ @Configuration
+ @EnableEventRecording
+ @EnableFeignClients(basePackages = {
+ "io.mifos.payroll.api.v1.client"
+ })
+ @RibbonClient(name = SuiteTestEnvironment.APP_NAME)
+ @ComponentScan(
+ basePackages = {
+ "io.mifos.payroll.listener"
+ }
+ )
+ @Import({
+ PayrollServiceConfiguration.class
+ })
+ public static class TestConfiguration {
+ public TestConfiguration() {
+ super();
+ }
+ }
+
+ static final String TEST_USER = "mage";
+
+ @ClassRule
+ public final static TenantDataStoreContextTestRule tenantDataStoreContext =
+ TenantDataStoreContextTestRule.forRandomTenantName(SuiteTestEnvironment.cassandraInitializer,
+ SuiteTestEnvironment.mariaDBInitializer);
+
+ @Rule
+ public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
+ = new TenantApplicationSecurityEnvironmentTestRule(SuiteTestEnvironment.testEnvironment, this::waitForInitialize);
+
+ @Autowired
+ EventRecorder eventRecorder;
+
+ private AutoUserContext userContext;
+
+ @Autowired
+ PayrollManager testSubject;
+
+ public AbstractPayrollTest() {
+ super();
+ }
+
+ @Before
+ public void prepareTest() {
+ this.userContext = this.tenantApplicationSecurityEnvironment.createAutoUserContext(AbstractPayrollTest.TEST_USER);
+ }
+
+ @After
+ public void cleanupTest() {
+ userContext.close();
+ }
+
+ public boolean waitForInitialize() {
+ try {
+ return this.eventRecorder.wait(EventConstants.INITIALIZE, SuiteTestEnvironment.APP_VERSION);
+ } catch (final InterruptedException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+}
diff --git a/component-test/src/main/java/io/mifos/template/SuiteTestEnvironment.java b/component-test/src/main/java/io/mifos/payroll/SuiteTestEnvironment.java
similarity index 95%
rename from component-test/src/main/java/io/mifos/template/SuiteTestEnvironment.java
rename to component-test/src/main/java/io/mifos/payroll/SuiteTestEnvironment.java
index 923cf79..8341aec 100644
--- a/component-test/src/main/java/io/mifos/template/SuiteTestEnvironment.java
+++ b/component-test/src/main/java/io/mifos/payroll/SuiteTestEnvironment.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template;
+package io.mifos.payroll;
import io.mifos.core.test.env.TestEnvironment;
import io.mifos.core.test.fixture.cassandra.CassandraInitializer;
@@ -31,7 +31,7 @@ import org.junit.rules.TestRule;
*/
public class SuiteTestEnvironment {
static final String APP_VERSION = "1";
- static final String APP_NAME = "template-v" + APP_VERSION;
+ static final String APP_NAME = "payroll-v" + APP_VERSION;
static final TestEnvironment testEnvironment = new TestEnvironment(APP_NAME);
static final CassandraInitializer cassandraInitializer = new CassandraInitializer();
diff --git a/component-test/src/main/java/io/mifos/payroll/TestPayrollConfiguration.java b/component-test/src/main/java/io/mifos/payroll/TestPayrollConfiguration.java
new file mode 100644
index 0000000..f2db0c4
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/payroll/TestPayrollConfiguration.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll;
+
+import com.google.common.collect.Sets;
+import io.mifos.accounting.api.v1.domain.Account;
+import io.mifos.customer.api.v1.domain.Customer;
+import io.mifos.payroll.api.v1.EventConstants;
+import io.mifos.payroll.api.v1.domain.PayrollAllocation;
+import io.mifos.payroll.api.v1.domain.PayrollConfiguration;
+import io.mifos.payroll.domain.DomainObjectGenerator;
+import io.mifos.payroll.service.internal.service.adaptor.AccountingAdaptor;
+import io.mifos.payroll.service.internal.service.adaptor.CustomerAdaptor;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.springframework.boot.test.mock.mockito.MockBean;
+
+import java.math.BigDecimal;
+import java.util.Optional;
+
+public class TestPayrollConfiguration extends AbstractPayrollTest {
+
+ @MockBean
+ private CustomerAdaptor customerAdaptorSpy;
+ @MockBean
+ private AccountingAdaptor accountingAdaptorSpy;
+
+ public TestPayrollConfiguration() {
+ super();
+ }
+
+ @Test
+ public void shouldCreatePayrollDistribution() throws Exception {
+ final String customerIdentifier = RandomStringUtils.randomAlphanumeric(32);
+ final PayrollConfiguration payrollConfiguration = DomainObjectGenerator.getPayrollConfiguration();
+ this.prepareMocks(customerIdentifier, payrollConfiguration);
+
+ super.testSubject.setPayrollConfiguration(customerIdentifier, payrollConfiguration);
+ Assert.assertTrue(super.eventRecorder.wait(EventConstants.PUT_CONFIGURATION, customerIdentifier));
+ }
+
+ @Test
+ public void shouldUpdatePayrollDistribution() throws Exception {
+ final String customerIdentifier = RandomStringUtils.randomAlphanumeric(32);
+ final PayrollConfiguration payrollConfiguration = DomainObjectGenerator.getPayrollConfiguration();
+ this.prepareMocks(customerIdentifier, payrollConfiguration);
+
+ super.testSubject.setPayrollConfiguration(customerIdentifier, payrollConfiguration);
+ Assert.assertTrue(super.eventRecorder.wait(EventConstants.PUT_CONFIGURATION, customerIdentifier));
+
+ final PayrollAllocation newPayrollAllocation = new PayrollAllocation();
+ payrollConfiguration.setPayrollAllocations(Sets.newHashSet(newPayrollAllocation));
+ newPayrollAllocation.setAccountNumber(RandomStringUtils.randomAlphanumeric(34));
+ newPayrollAllocation.setAmount(BigDecimal.valueOf(15.00D));
+ newPayrollAllocation.setProportional(Boolean.FALSE);
+
+ Mockito
+ .doAnswer(invocation -> Optional.of(new Account()))
+ .when(this.accountingAdaptorSpy).findAccount(Matchers.eq(newPayrollAllocation.getAccountNumber()));
+
+ super.testSubject.setPayrollConfiguration(customerIdentifier, payrollConfiguration);
+ Assert.assertTrue(super.eventRecorder.wait(EventConstants.PUT_CONFIGURATION, customerIdentifier));
+
+ Thread.sleep(500L);
+
+ final PayrollConfiguration fetchedPayrollConfiguration =
+ super.testSubject.findPayrollConfiguration(customerIdentifier);
+
+ Assert.assertNotNull(fetchedPayrollConfiguration.getLastModifiedBy());
+ Assert.assertNotNull(fetchedPayrollConfiguration.getLastModifiedOn());
+ Assert.assertEquals(1, fetchedPayrollConfiguration.getPayrollAllocations().size());
+
+ final Optional<PayrollAllocation> optionalPayrollAllocation =
+ fetchedPayrollConfiguration.getPayrollAllocations().stream().findFirst();
+
+ Assert.assertTrue(optionalPayrollAllocation.isPresent());
+
+ this.comparePayrollAllocations(newPayrollAllocation, optionalPayrollAllocation.get());
+ }
+
+ private void prepareMocks(final String customerIdentifier, final PayrollConfiguration payrollConfiguration) {
+ Mockito
+ .doAnswer(invocation -> Optional.of(new Customer()))
+ .when(this.customerAdaptorSpy).findCustomer(Matchers.eq(customerIdentifier));
+
+ Mockito
+ .doAnswer(invocation -> Optional.of(new Account()))
+ .when(this.accountingAdaptorSpy).findAccount(Matchers.eq(payrollConfiguration.getMainAccountNumber()));
+
+ payrollConfiguration.getPayrollAllocations().forEach(payrollAllocation ->
+ Mockito
+ .doAnswer(invocation -> Optional.of(new Account()))
+ .when(this.accountingAdaptorSpy).findAccount(Matchers.eq(payrollAllocation.getAccountNumber()))
+ );
+ }
+
+ private void comparePayrollAllocations(final PayrollAllocation expected, final PayrollAllocation actual) {
+ Assert.assertEquals(expected.getAccountNumber(), actual.getAccountNumber());
+ Assert.assertTrue(expected.getAmount().compareTo(actual.getAmount()) == 0);
+ Assert.assertEquals(expected.getProportional(), actual.getProportional());
+ }
+}
diff --git a/component-test/src/main/java/io/mifos/payroll/TestPayrollDistribution.java b/component-test/src/main/java/io/mifos/payroll/TestPayrollDistribution.java
new file mode 100644
index 0000000..0bcae44
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/payroll/TestPayrollDistribution.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll;
+
+import com.google.common.collect.Lists;
+import io.mifos.accounting.api.v1.domain.Account;
+import io.mifos.customer.api.v1.domain.Customer;
+import io.mifos.payroll.api.v1.EventConstants;
+import io.mifos.payroll.api.v1.domain.PayrollCollectionHistory;
+import io.mifos.payroll.api.v1.domain.PayrollCollectionSheet;
+import io.mifos.payroll.api.v1.domain.PayrollConfiguration;
+import io.mifos.payroll.api.v1.domain.PayrollPayment;
+import io.mifos.payroll.api.v1.domain.PayrollPaymentPage;
+import io.mifos.payroll.domain.DomainObjectGenerator;
+import io.mifos.payroll.service.internal.service.adaptor.AccountingAdaptor;
+import io.mifos.payroll.service.internal.service.adaptor.CustomerAdaptor;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+import org.springframework.boot.test.mock.mockito.MockBean;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Optional;
+
+public class TestPayrollDistribution extends AbstractPayrollTest {
+
+ @MockBean
+ private CustomerAdaptor customerAdaptorSpy;
+ @MockBean
+ private AccountingAdaptor accountingAdaptorSpy;
+
+ public TestPayrollDistribution() {
+ super();
+ }
+
+ @Test
+ public void shouldDistributePayments() throws Exception {
+ final String customerIdentifier = RandomStringUtils.randomAlphanumeric(32);
+ final PayrollConfiguration payrollConfiguration = DomainObjectGenerator.getPayrollConfiguration();
+ this.prepareMocks(customerIdentifier, payrollConfiguration);
+
+ super.testSubject.setPayrollConfiguration(customerIdentifier, payrollConfiguration);
+ Assert.assertTrue(super.eventRecorder.wait(EventConstants.PUT_CONFIGURATION, customerIdentifier));
+
+ final PayrollCollectionSheet payrollCollectionSheet = new PayrollCollectionSheet();
+ payrollCollectionSheet.setSourceAccountNumber(RandomStringUtils.randomAlphanumeric(34));
+ final PayrollPayment payrollPayment = new PayrollPayment();
+ payrollPayment.setCustomerIdentifier(customerIdentifier);
+ payrollPayment.setEmployer("ACME, Inc.");
+ payrollPayment.setSalary(BigDecimal.valueOf(1234.56D));
+ payrollCollectionSheet.setPayrollPayments(Lists.newArrayList(payrollPayment));
+
+ Mockito
+ .doAnswer(invocation -> Optional.of(new Account()))
+ .when(this.accountingAdaptorSpy).findAccount(Matchers.eq(payrollCollectionSheet.getSourceAccountNumber()));
+
+ super.testSubject.distribute(payrollCollectionSheet);
+ Assert.assertTrue(super.eventRecorder.wait(EventConstants.POST_DISTRIBUTION, payrollCollectionSheet.getSourceAccountNumber()));
+
+ final List<PayrollCollectionHistory> payrollCollectionHistories = super.testSubject.fetchDistributionHistory();
+ Assert.assertEquals(1, payrollCollectionHistories.size());
+
+ final PayrollCollectionHistory payrollCollectionHistory = payrollCollectionHistories.get(0);
+ final PayrollPaymentPage payrollPaymentPage =
+ super.testSubject.fetchPayments(payrollCollectionHistory.getIdentifier(), 0, 10, null, null);
+ Assert.assertEquals(Long.valueOf(1L), payrollPaymentPage.getTotalElements());
+ }
+
+ private void prepareMocks(final String customerIdentifier, final PayrollConfiguration payrollConfiguration) {
+ Mockito
+ .doAnswer(invocation -> Optional.of(new Customer()))
+ .when(this.customerAdaptorSpy).findCustomer(Matchers.eq(customerIdentifier));
+
+ Mockito
+ .doAnswer(invocation -> Optional.of(new Account()))
+ .when(this.accountingAdaptorSpy).findAccount(Matchers.eq(payrollConfiguration.getMainAccountNumber()));
+
+ payrollConfiguration.getPayrollAllocations().forEach(payrollAllocation ->
+ Mockito
+ .doAnswer(invocation -> Optional.of(new Account()))
+ .when(this.accountingAdaptorSpy).findAccount(Matchers.eq(payrollAllocation.getAccountNumber()))
+ );
+ }
+
+}
diff --git a/component-test/src/main/java/io/mifos/template/TestSuite.java b/component-test/src/main/java/io/mifos/payroll/TestSuite.java
similarity index 84%
rename from component-test/src/main/java/io/mifos/template/TestSuite.java
rename to component-test/src/main/java/io/mifos/payroll/TestSuite.java
index 44ed340..09862e8 100644
--- a/component-test/src/main/java/io/mifos/template/TestSuite.java
+++ b/component-test/src/main/java/io/mifos/payroll/TestSuite.java
@@ -13,15 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template;
+package io.mifos.payroll;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
- TestSample.class,
- //TODO: when you create a new component test, add it here so you can run it with the suite.
+ TestPayrollConfiguration.class,
+ TestPayrollDistribution.class
})
public class TestSuite extends SuiteTestEnvironment {
}
diff --git a/component-test/src/main/java/io/mifos/payroll/domain/DomainObjectGenerator.java b/component-test/src/main/java/io/mifos/payroll/domain/DomainObjectGenerator.java
new file mode 100644
index 0000000..389cde2
--- /dev/null
+++ b/component-test/src/main/java/io/mifos/payroll/domain/DomainObjectGenerator.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.domain;
+
+import io.mifos.payroll.api.v1.domain.PayrollAllocation;
+import io.mifos.payroll.api.v1.domain.PayrollConfiguration;
+import org.apache.commons.lang3.RandomStringUtils;
+
+import java.math.BigDecimal;
+import java.util.HashSet;
+
+public class DomainObjectGenerator {
+
+ private DomainObjectGenerator() {
+ super();
+ }
+
+ public static PayrollConfiguration getPayrollConfiguration() {
+ final PayrollConfiguration payrollConfiguration = new PayrollConfiguration();
+ payrollConfiguration.setMainAccountNumber(RandomStringUtils.randomAlphanumeric(34));
+
+ final HashSet<PayrollAllocation> payrollAllocations = new HashSet<>();
+ payrollConfiguration.setPayrollAllocations(payrollAllocations);
+
+ final PayrollAllocation savingsAllocation = new PayrollAllocation();
+ payrollAllocations.add(savingsAllocation);
+ savingsAllocation.setAccountNumber(RandomStringUtils.randomAlphanumeric(34));
+ savingsAllocation.setAmount(BigDecimal.valueOf(5.00D));
+ savingsAllocation.setProportional(Boolean.TRUE);
+
+ return payrollConfiguration;
+ }
+}
diff --git a/component-test/src/main/java/io/mifos/template/listener/MigrationEventListener.java b/component-test/src/main/java/io/mifos/payroll/listener/MigrationEventListener.java
similarity index 94%
copy from component-test/src/main/java/io/mifos/template/listener/MigrationEventListener.java
copy to component-test/src/main/java/io/mifos/payroll/listener/MigrationEventListener.java
index 52be53b..b521aad 100644
--- a/component-test/src/main/java/io/mifos/template/listener/MigrationEventListener.java
+++ b/component-test/src/main/java/io/mifos/payroll/listener/MigrationEventListener.java
@@ -13,11 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.listener;
+package io.mifos.payroll.listener;
import io.mifos.core.lang.config.TenantHeaderFilter;
import io.mifos.core.test.listener.EventRecorder;
-import io.mifos.template.api.v1.events.EventConstants;
+import io.mifos.payroll.api.v1.EventConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.messaging.handler.annotation.Header;
diff --git a/component-test/src/main/java/io/mifos/template/listener/SampleEventListener.java b/component-test/src/main/java/io/mifos/payroll/listener/PayrollConfigurationListener.java
similarity index 57%
rename from component-test/src/main/java/io/mifos/template/listener/SampleEventListener.java
rename to component-test/src/main/java/io/mifos/payroll/listener/PayrollConfigurationListener.java
index b54a819..66e5719 100644
--- a/component-test/src/main/java/io/mifos/template/listener/SampleEventListener.java
+++ b/component-test/src/main/java/io/mifos/payroll/listener/PayrollConfigurationListener.java
@@ -13,35 +13,41 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.listener;
+package io.mifos.payroll.listener;
import io.mifos.core.lang.config.TenantHeaderFilter;
import io.mifos.core.test.listener.EventRecorder;
-import io.mifos.template.api.v1.events.EventConstants;
+import io.mifos.payroll.api.v1.EventConstants;
+import io.mifos.payroll.service.ServiceConstants;
+import org.slf4j.Logger;
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;
-@SuppressWarnings("unused")
@Component
-public class SampleEventListener {
+public class PayrollConfigurationListener {
+ private final Logger logger;
private final EventRecorder eventRecorder;
@Autowired
- public SampleEventListener(@SuppressWarnings("SpringJavaAutowiringInspection") final EventRecorder eventRecorder) {
+ public PayrollConfigurationListener(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+ final EventRecorder eventRecorder) {
super();
+ this.logger = logger;
this.eventRecorder = eventRecorder;
}
@JmsListener(
subscription = EventConstants.DESTINATION,
destination = EventConstants.DESTINATION,
- selector = EventConstants.SELECTOR_POST_SAMPLE
+ selector = EventConstants.SELECTOR_PUT_CONFIGURATION
)
- public void onCreateSample(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
- final String payload) {
- this.eventRecorder.event(tenant, EventConstants.POST_SAMPLE, payload, String.class);
+ public void onPutConfiguration(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+ final String payload) {
+ this.logger.info("Payment configuration for customer {} processed.", payload);
+ this.eventRecorder.event(tenant, EventConstants.PUT_CONFIGURATION, payload, String.class);
}
}
diff --git a/component-test/src/main/java/io/mifos/template/listener/MigrationEventListener.java b/component-test/src/main/java/io/mifos/payroll/listener/PayrollDistributionListener.java
similarity index 61%
rename from component-test/src/main/java/io/mifos/template/listener/MigrationEventListener.java
rename to component-test/src/main/java/io/mifos/payroll/listener/PayrollDistributionListener.java
index 52be53b..72edede 100644
--- a/component-test/src/main/java/io/mifos/template/listener/MigrationEventListener.java
+++ b/component-test/src/main/java/io/mifos/payroll/listener/PayrollDistributionListener.java
@@ -13,35 +13,41 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.listener;
+package io.mifos.payroll.listener;
import io.mifos.core.lang.config.TenantHeaderFilter;
import io.mifos.core.test.listener.EventRecorder;
-import io.mifos.template.api.v1.events.EventConstants;
+import io.mifos.payroll.api.v1.EventConstants;
+import io.mifos.payroll.service.ServiceConstants;
+import org.slf4j.Logger;
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;
-@SuppressWarnings("unused")
@Component
-public class MigrationEventListener {
+public class PayrollDistributionListener {
+ private final Logger logger;
private final EventRecorder eventRecorder;
@Autowired
- public MigrationEventListener(@SuppressWarnings("SpringJavaAutowiringInspection") final EventRecorder eventRecorder) {
+ public PayrollDistributionListener(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+ final EventRecorder eventRecorder) {
super();
+ this.logger = logger;
this.eventRecorder = eventRecorder;
}
@JmsListener(
subscription = EventConstants.DESTINATION,
destination = EventConstants.DESTINATION,
- selector = EventConstants.SELECTOR_INITIALIZE
+ selector = EventConstants.SELECTOR_POST_DISTRIBUTION
)
- public void onInitialization(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
+ public void onPostCollection(@Header(TenantHeaderFilter.TENANT_HEADER) final String tenant,
final String payload) {
- this.eventRecorder.event(tenant, EventConstants.INITIALIZE, payload, String.class);
+ this.logger.info("Payment distribution with source account {0} processed.", payload);
+ this.eventRecorder.event(tenant, EventConstants.POST_DISTRIBUTION, payload, String.class);
}
}
diff --git a/component-test/src/main/java/io/mifos/template/TestSample.java b/component-test/src/main/java/io/mifos/template/TestSample.java
deleted file mode 100644
index 92ae690..0000000
--- a/component-test/src/main/java/io/mifos/template/TestSample.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright 2017 The Mifos Initiative.
- *
- * Licensed 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 io.mifos.template;
-
-import io.mifos.anubis.test.v1.TenantApplicationSecurityEnvironmentTestRule;
-import io.mifos.core.api.context.AutoUserContext;
-import io.mifos.core.test.fixture.TenantDataStoreContextTestRule;
-import io.mifos.core.test.listener.EnableEventRecording;
-import io.mifos.core.test.listener.EventRecorder;
-import io.mifos.template.api.v1.events.EventConstants;
-import io.mifos.template.api.v1.client.TemplateManager;
-import io.mifos.template.api.v1.domain.Sample;
-import io.mifos.template.service.TemplateConfiguration;
-import org.apache.commons.lang3.RandomStringUtils;
-import org.junit.*;
-import org.junit.runner.RunWith;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-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.test.context.junit4.SpringRunner;
-
-import java.util.List;
-
-@RunWith(SpringRunner.class)
-@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
-public class TestSample extends SuiteTestEnvironment {
- private static final String LOGGER_NAME = "test-logger";
- private static final String TEST_USER = "homer";
-
-
- @Configuration
- @EnableEventRecording
- @EnableFeignClients(basePackages = {"io.mifos.template.api.v1.client"})
- @RibbonClient(name = APP_NAME)
- @Import({TemplateConfiguration.class})
- @ComponentScan("io.mifos.template.listener")
- public static class TestConfiguration {
- public TestConfiguration() {
- super();
- }
-
- @Bean(name = LOGGER_NAME)
- public Logger logger() {
- return LoggerFactory.getLogger(LOGGER_NAME);
- }
- }
-
- @ClassRule
- public final static TenantDataStoreContextTestRule tenantDataStoreContext = TenantDataStoreContextTestRule.forRandomTenantName(cassandraInitializer, mariaDBInitializer);
-
- @Rule
- public final TenantApplicationSecurityEnvironmentTestRule tenantApplicationSecurityEnvironment
- = new TenantApplicationSecurityEnvironmentTestRule(testEnvironment, this::waitForInitialize);
-
- private AutoUserContext userContext;
-
- @Autowired
- private TemplateManager testSubject;
-
- @Autowired
- private EventRecorder eventRecorder;
-
- @SuppressWarnings("WeakerAccess")
- @Autowired
- @Qualifier(LOGGER_NAME)
- Logger logger;
-
- public TestSample() {
- super();
- }
-
- @Before
- public void prepTest() {
- userContext = tenantApplicationSecurityEnvironment.createAutoUserContext(TestSample.TEST_USER);
- }
-
- @After
- public void cleanTest() {
- userContext.close();
- eventRecorder.clear();
- }
-
- public boolean waitForInitialize() {
- try {
- return this.eventRecorder.wait(EventConstants.INITIALIZE, APP_VERSION);
- } catch (final InterruptedException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Test
- public void shouldCreateSample() throws InterruptedException {
- logger.info("Running test shouldCreateSample.");
- final Sample sample = Sample.create(RandomStringUtils.randomAlphanumeric(8), RandomStringUtils.randomAlphanumeric(512));
- this.testSubject.createEntity(sample);
-
- Assert.assertTrue(this.eventRecorder.wait(EventConstants.POST_SAMPLE, sample.getIdentifier()));
-
- final Sample createdSample = this.testSubject.getEntity(sample.getIdentifier());
- Assert.assertEquals(sample, createdSample);
- }
-
- @Test
- public void shouldListSamples() {
- logger.info("Running test shouldListSamples.");
- final List<Sample> allEntities = this.testSubject.findAllEntities();
- Assert.assertNotNull(allEntities);
- }
-}
diff --git a/component-test/src/main/resources/logback-test.xml b/component-test/src/main/resources/logback-test.xml
new file mode 100644
index 0000000..222fc38
--- /dev/null
+++ b/component-test/src/main/resources/logback-test.xml
@@ -0,0 +1,34 @@
+<!--
+
+ Copyright 2017 The Mifos Initiative.
+
+ Licensed 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.
+
+-->
+<configuration>
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <logger name="org" level="OFF"/>
+ <logger name="org.hibernate" level="DEBUG"/>
+ <logger name="io" level="OFF"/>
+ <logger name="com" level="OFF"/>
+ <logger name="ch" level="OFF"/>
+
+ <root level="DEBUG">
+ <appender-ref ref="STDOUT"/>
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 2888922..61d11e0 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Fri Mar 17 17:54:20 CET 2017
+#Thu Sep 14 14:33:32 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-all.zip
diff --git a/service/build.gradle b/service/build.gradle
index a9b4de9..65e1431 100644
--- a/service/build.gradle
+++ b/service/build.gradle
@@ -30,7 +30,9 @@ dependencies {
[group: 'org.springframework.cloud', name: 'spring-cloud-starter-config'],
[group: 'org.springframework.cloud', name: 'spring-cloud-starter-eureka'],
[group: 'org.springframework.boot', name: 'spring-boot-starter-jetty'],
- [group: 'io.mifos.template', name: 'api', version: project.version],
+ [group: 'io.mifos.payroll', name: 'api', version: project.version],
+ [group: 'io.mifos.accounting', name: 'api', version: versions.frameworkaccounting],
+ [group: 'io.mifos.customer', name: 'api', version: versions.frameworkcustomer],
[group: 'io.mifos.anubis', name: 'library', version: versions.frameworkanubis],
[group: 'com.google.code.gson', name: 'gson'],
[group: 'io.mifos.core', name: 'lang', version: versions.frameworklang],
diff --git a/service/src/main/java/io/mifos/template/service/TemplateApplication.java b/service/src/main/java/io/mifos/payroll/service/PayrollApplication.java
similarity index 81%
rename from service/src/main/java/io/mifos/template/service/TemplateApplication.java
rename to service/src/main/java/io/mifos/payroll/service/PayrollApplication.java
index 7ca88f0..2fe3036 100644
--- a/service/src/main/java/io/mifos/template/service/TemplateApplication.java
+++ b/service/src/main/java/io/mifos/payroll/service/PayrollApplication.java
@@ -13,17 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.service;
+package io.mifos.payroll.service;
import org.springframework.boot.SpringApplication;
-public class TemplateApplication {
+public class PayrollApplication {
- public TemplateApplication() {
+ public PayrollApplication() {
super();
}
public static void main(String[] args) {
- SpringApplication.run(TemplateConfiguration.class, args);
+ SpringApplication.run(PayrollServiceConfiguration.class, args);
}
}
diff --git a/service/src/main/java/io/mifos/template/service/TemplateConfiguration.java b/service/src/main/java/io/mifos/payroll/service/PayrollServiceConfiguration.java
similarity index 76%
rename from service/src/main/java/io/mifos/template/service/TemplateConfiguration.java
rename to service/src/main/java/io/mifos/payroll/service/PayrollServiceConfiguration.java
index 33ee609..d9a00e4 100644
--- a/service/src/main/java/io/mifos/template/service/TemplateConfiguration.java
+++ b/service/src/main/java/io/mifos/payroll/service/PayrollServiceConfiguration.java
@@ -13,8 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.service;
+package io.mifos.payroll.service;
+import io.mifos.accounting.api.v1.client.LedgerManager;
import io.mifos.anubis.config.EnableAnubis;
import io.mifos.core.async.config.EnableAsync;
import io.mifos.core.cassandra.config.EnableCassandra;
@@ -22,10 +23,12 @@ import io.mifos.core.command.config.EnableCommandProcessing;
import io.mifos.core.lang.config.EnableServiceException;
import io.mifos.core.lang.config.EnableTenantContext;
import io.mifos.core.mariadb.config.EnableMariaDB;
+import io.mifos.customer.api.v1.client.CustomerManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@@ -44,18 +47,22 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
@EnableCommandProcessing
@EnableAnubis
@EnableServiceException
+@EnableFeignClients(clients = {
+ LedgerManager.class,
+ CustomerManager.class
+})
@ComponentScan({
- "io.mifos.template.service.rest",
- "io.mifos.template.service.internal.service",
- "io.mifos.template.service.internal.repository",
- "io.mifos.template.service.internal.command.handler"
+ "io.mifos.payroll.service.rest",
+ "io.mifos.payroll.service.internal.service",
+ "io.mifos.payroll.service.internal.repository",
+ "io.mifos.payroll.service.internal.command.handler"
})
@EnableJpaRepositories({
- "io.mifos.template.service.internal.repository"
+ "io.mifos.payroll.service.internal.repository"
})
-public class TemplateConfiguration extends WebMvcConfigurerAdapter {
+public class PayrollServiceConfiguration extends WebMvcConfigurerAdapter {
- public TemplateConfiguration() {
+ public PayrollServiceConfiguration() {
super();
}
diff --git a/service/src/main/java/io/mifos/template/service/ServiceConstants.java b/service/src/main/java/io/mifos/payroll/service/ServiceConstants.java
similarity index 89%
rename from service/src/main/java/io/mifos/template/service/ServiceConstants.java
rename to service/src/main/java/io/mifos/payroll/service/ServiceConstants.java
index e9e0623..a5cfc4f 100644
--- a/service/src/main/java/io/mifos/template/service/ServiceConstants.java
+++ b/service/src/main/java/io/mifos/payroll/service/ServiceConstants.java
@@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.service;
+package io.mifos.payroll.service;
public interface ServiceConstants {
- String LOGGER_NAME = "rest-logger";
+ String LOGGER_NAME = "payroll-logger";
}
diff --git a/service/src/main/java/io/mifos/template/service/internal/command/SampleCommand.java b/service/src/main/java/io/mifos/payroll/service/internal/command/DistributePayrollCommand.java
similarity index 57%
rename from service/src/main/java/io/mifos/template/service/internal/command/SampleCommand.java
rename to service/src/main/java/io/mifos/payroll/service/internal/command/DistributePayrollCommand.java
index 5957f1b..e3b4202 100644
--- a/service/src/main/java/io/mifos/template/service/internal/command/SampleCommand.java
+++ b/service/src/main/java/io/mifos/payroll/service/internal/command/DistributePayrollCommand.java
@@ -13,27 +13,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.service.internal.command;
+package io.mifos.payroll.service.internal.command;
-import io.mifos.template.api.v1.domain.Sample;
+import io.mifos.payroll.api.v1.domain.PayrollCollectionSheet;
-public class SampleCommand {
+public class DistributePayrollCommand {
+ private final PayrollCollectionSheet payrollCollectionSheet;
- private final Sample sample;
-
- public SampleCommand(final Sample sample) {
+ public DistributePayrollCommand(final PayrollCollectionSheet payrollCollectionSheet) {
super();
- this.sample = sample;
- }
-
- public Sample sample() {
- return this.sample;
+ this.payrollCollectionSheet = payrollCollectionSheet;
}
- @Override
- public String toString() {
- return "SampleCommand{" +
- "sample=" + sample.getIdentifier() +
- '}';
+ public PayrollCollectionSheet payrollCollectionSheet() {
+ return this.payrollCollectionSheet;
}
}
diff --git a/service/src/main/java/io/mifos/template/service/internal/command/InitializeServiceCommand.java b/service/src/main/java/io/mifos/payroll/service/internal/command/MigrateServiceCommand.java
similarity index 74%
rename from service/src/main/java/io/mifos/template/service/internal/command/InitializeServiceCommand.java
rename to service/src/main/java/io/mifos/payroll/service/internal/command/MigrateServiceCommand.java
index e02d2d0..4cacdc2 100644
--- a/service/src/main/java/io/mifos/template/service/internal/command/InitializeServiceCommand.java
+++ b/service/src/main/java/io/mifos/payroll/service/internal/command/MigrateServiceCommand.java
@@ -13,16 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.service.internal.command;
+package io.mifos.payroll.service.internal.command;
-public class InitializeServiceCommand {
-
- public InitializeServiceCommand() {
+public class MigrateServiceCommand {
+ public MigrateServiceCommand() {
super();
}
-
- @Override
- public String toString() {
- return "InitializeServiceCommand{}";
- }
}
diff --git a/service/src/main/java/io/mifos/payroll/service/internal/command/PutPayrollConfigurationCommand.java b/service/src/main/java/io/mifos/payroll/service/internal/command/PutPayrollConfigurationCommand.java
new file mode 100644
index 0000000..3507489
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/internal/command/PutPayrollConfigurationCommand.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.internal.command;
+
+import io.mifos.payroll.api.v1.domain.PayrollConfiguration;
+
+public class PutPayrollConfigurationCommand {
+ private final String customerIdentifier;
+ private final PayrollConfiguration payrollConfiguration;
+
+ public PutPayrollConfigurationCommand(final String customerIdentifier,
+ final PayrollConfiguration payrollConfiguration) {
+ super();
+ this.customerIdentifier = customerIdentifier;
+ this.payrollConfiguration = payrollConfiguration;
+ }
+
+ public String customerIdentifier() {
+ return this.customerIdentifier;
+ }
+
+ public PayrollConfiguration payrollConfiguration() {
+ return this.payrollConfiguration;
+ }
+}
diff --git a/service/src/main/java/io/mifos/template/service/internal/command/handler/MigrationAggregate.java b/service/src/main/java/io/mifos/payroll/service/internal/command/handler/MigrationAggregate.java
similarity index 64%
rename from service/src/main/java/io/mifos/template/service/internal/command/handler/MigrationAggregate.java
rename to service/src/main/java/io/mifos/payroll/service/internal/command/handler/MigrationAggregate.java
index 12ae643..4d9d2c8 100644
--- a/service/src/main/java/io/mifos/template/service/internal/command/handler/MigrationAggregate.java
+++ b/service/src/main/java/io/mifos/payroll/service/internal/command/handler/MigrationAggregate.java
@@ -13,52 +13,42 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.service.internal.command.handler;
+package io.mifos.payroll.service.internal.command.handler;
+import io.mifos.accounting.api.v1.EventConstants;
import io.mifos.core.command.annotation.Aggregate;
import io.mifos.core.command.annotation.CommandHandler;
-import io.mifos.core.command.annotation.CommandLogLevel;
import io.mifos.core.command.annotation.EventEmitter;
import io.mifos.core.lang.ApplicationName;
import io.mifos.core.mariadb.domain.FlywayFactoryBean;
-import io.mifos.template.api.v1.events.EventConstants;
-import io.mifos.template.service.ServiceConstants;
-import io.mifos.template.service.internal.command.InitializeServiceCommand;
-import org.slf4j.Logger;
+import io.mifos.payroll.service.internal.command.MigrateServiceCommand;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.annotation.Transactional;
import javax.sql.DataSource;
-@SuppressWarnings({
- "unused"
-})
@Aggregate
public class MigrationAggregate {
- private final Logger logger;
private final DataSource dataSource;
private final FlywayFactoryBean flywayFactoryBean;
private final ApplicationName applicationName;
@Autowired
- public MigrationAggregate(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
- final DataSource dataSource,
- final FlywayFactoryBean flywayFactoryBean,
+ public MigrationAggregate(@SuppressWarnings("SpringJavaAutowiringInspection") final DataSource dataSource,
+ @SuppressWarnings("SpringJavaAutowiringInspection") final FlywayFactoryBean flywayFactoryBean,
final ApplicationName applicationName) {
super();
- this.logger = logger;
this.dataSource = dataSource;
this.flywayFactoryBean = flywayFactoryBean;
this.applicationName = applicationName;
}
- @CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
+ @SuppressWarnings("unused")
@Transactional
+ @CommandHandler
@EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.INITIALIZE)
- public String initialize(final InitializeServiceCommand initializeServiceCommand) {
- this.logger.debug("Start service migration.");
+ public String initialize(final MigrateServiceCommand migrateServiceCommand) {
this.flywayFactoryBean.create(this.dataSource).migrate();
return this.applicationName.getVersionString();
}
diff --git a/service/src/main/java/io/mifos/payroll/service/internal/command/handler/PayrollConfigurationAggregate.java b/service/src/main/java/io/mifos/payroll/service/internal/command/handler/PayrollConfigurationAggregate.java
new file mode 100644
index 0000000..d71fe45
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/internal/command/handler/PayrollConfigurationAggregate.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.internal.command.handler;
+
+import io.mifos.core.api.util.UserContextHolder;
+import io.mifos.core.command.annotation.Aggregate;
+import io.mifos.core.command.annotation.CommandHandler;
+import io.mifos.core.command.annotation.EventEmitter;
+import io.mifos.payroll.api.v1.EventConstants;
+import io.mifos.payroll.api.v1.domain.PayrollConfiguration;
+import io.mifos.payroll.service.ServiceConstants;
+import io.mifos.payroll.service.internal.command.PutPayrollConfigurationCommand;
+import io.mifos.payroll.service.internal.mapper.PayrollAllocationMapper;
+import io.mifos.payroll.service.internal.repository.PayrollAllocationEntity;
+import io.mifos.payroll.service.internal.repository.PayrollAllocationRepository;
+import io.mifos.payroll.service.internal.repository.PayrollConfigurationEntity;
+import io.mifos.payroll.service.internal.repository.PayrollConfigurationRepository;
+import io.mifos.payroll.service.internal.service.PayrollConfigurationService;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.Clock;
+import java.time.LocalDateTime;
+import java.util.Optional;
+
+@Aggregate
+public class PayrollConfigurationAggregate {
+
+ private Logger logger;
+ private PayrollConfigurationService payrollConfigurationService;
+ private PayrollConfigurationRepository payrollConfigurationRepository;
+ private PayrollAllocationRepository payrollAllocationRepository;
+
+ @Autowired
+ public PayrollConfigurationAggregate(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+ final PayrollConfigurationService payrollConfigurationService,
+ final PayrollConfigurationRepository payrollConfigurationRepository,
+ final PayrollAllocationRepository payrollAllocationRepository) {
+ super();
+ this.logger = logger;
+ this.payrollConfigurationService = payrollConfigurationService;
+ this.payrollConfigurationRepository = payrollConfigurationRepository;
+ this.payrollAllocationRepository = payrollAllocationRepository;
+ }
+
+ @Transactional
+ @CommandHandler
+ @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.PUT_CONFIGURATION)
+ public String process(final PutPayrollConfigurationCommand putPayrollConfigurationCommand) {
+ final String customerIdentifier = putPayrollConfigurationCommand.customerIdentifier();
+ final PayrollConfiguration payrollConfiguration = putPayrollConfigurationCommand.payrollConfiguration();
+
+ final PayrollConfigurationEntity payrollConfigurationEntity;
+
+ final Optional<PayrollConfigurationEntity> optionalPayrollConfiguration =
+ this.payrollConfigurationRepository.findByCustomerIdentifier(customerIdentifier);
+ if (optionalPayrollConfiguration.isPresent()) {
+ payrollConfigurationEntity = optionalPayrollConfiguration.get();
+ this.payrollAllocationRepository.deleteByPayrollConfiguration(payrollConfigurationEntity);
+
+ payrollConfigurationEntity.setLastModifiedBy(UserContextHolder.checkedGetUser());
+ payrollConfigurationEntity.setLastModifiedOn(LocalDateTime.now(Clock.systemUTC()));
+ } else {
+ payrollConfigurationEntity = new PayrollConfigurationEntity();
+ payrollConfigurationEntity.setCustomerIdentifier(customerIdentifier);
+ payrollConfigurationEntity.setCreatedBy(UserContextHolder.checkedGetUser());
+ payrollConfigurationEntity.setCreatedOn(LocalDateTime.now(Clock.systemUTC()));
+ }
+
+ payrollConfigurationEntity.setMainAccountNumber(payrollConfiguration.getMainAccountNumber());
+ final PayrollConfigurationEntity savedPayrollConfigurationEntity =
+ this.payrollConfigurationRepository.save(payrollConfigurationEntity);
+
+ if (payrollConfiguration.getPayrollAllocations() != null) {
+ payrollConfiguration.getPayrollAllocations()
+ .forEach(payrollAllocation -> {
+ final PayrollAllocationEntity payrollAllocationEntity = PayrollAllocationMapper.map(payrollAllocation);
+ payrollAllocationEntity.setPayrollConfiguration(savedPayrollConfigurationEntity);
+ this.payrollAllocationRepository.save(payrollAllocationEntity);
+ });
+ }
+ return customerIdentifier;
+ }
+}
diff --git a/service/src/main/java/io/mifos/payroll/service/internal/command/handler/PayrollDistributionAggregate.java b/service/src/main/java/io/mifos/payroll/service/internal/command/handler/PayrollDistributionAggregate.java
new file mode 100644
index 0000000..86f4aae
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/internal/command/handler/PayrollDistributionAggregate.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.internal.command.handler;
+
+import io.mifos.core.api.util.UserContextHolder;
+import io.mifos.core.command.annotation.Aggregate;
+import io.mifos.core.command.annotation.CommandHandler;
+import io.mifos.core.command.annotation.EventEmitter;
+import io.mifos.payroll.api.v1.EventConstants;
+import io.mifos.payroll.api.v1.domain.PayrollCollectionSheet;
+import io.mifos.payroll.service.ServiceConstants;
+import io.mifos.payroll.service.internal.command.DistributePayrollCommand;
+import io.mifos.payroll.service.internal.repository.PayrollCollectionEntity;
+import io.mifos.payroll.service.internal.repository.PayrollCollectionRepository;
+import io.mifos.payroll.service.internal.repository.PayrollPaymentEntity;
+import io.mifos.payroll.service.internal.repository.PayrollPaymentRepository;
+import io.mifos.payroll.service.internal.service.PayrollConfigurationService;
+import io.mifos.payroll.service.internal.service.adaptor.AccountingAdaptor;
+import org.apache.commons.lang.RandomStringUtils;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.Clock;
+import java.time.LocalDateTime;
+
+@Aggregate
+public class PayrollDistributionAggregate {
+
+ private final Logger logger;
+ private final PayrollConfigurationService payrollConfigurationService;
+ private final PayrollCollectionRepository payrollCollectionRepository;
+ private final PayrollPaymentRepository payrollPaymentRepository;
+ private final AccountingAdaptor accountingAdaptor;
+
+ @Autowired
+ public PayrollDistributionAggregate(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+ PayrollConfigurationService payrollConfigurationService,
+ final PayrollCollectionRepository payrollCollectionRepository,
+ final PayrollPaymentRepository payrollPaymentRepository,
+ final AccountingAdaptor accountingAdaptor) {
+ super();
+ this.logger = logger;
+ this.payrollConfigurationService = payrollConfigurationService;
+ this.payrollCollectionRepository = payrollCollectionRepository;
+ this.payrollPaymentRepository = payrollPaymentRepository;
+ this.accountingAdaptor = accountingAdaptor;
+ }
+
+ @Transactional
+ @CommandHandler
+ @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.POST_DISTRIBUTION)
+ public String process(final DistributePayrollCommand distributePayrollCommand) {
+ final PayrollCollectionSheet payrollCollectionSheet = distributePayrollCommand.payrollCollectionSheet();
+
+ final PayrollCollectionEntity payrollCollectionEntity = new PayrollCollectionEntity();
+ payrollCollectionEntity.setIdentifier(RandomStringUtils.randomAlphanumeric(32));
+ payrollCollectionEntity.setSourceAccountNumber(payrollCollectionSheet.getSourceAccountNumber());
+ payrollCollectionEntity.setCreatedBy(UserContextHolder.checkedGetUser());
+ payrollCollectionEntity.setCreatedOn(LocalDateTime.now(Clock.systemUTC()));
+
+ final PayrollCollectionEntity savedPayrollCollectionEntity = this.payrollCollectionRepository.save(payrollCollectionEntity);
+
+ payrollCollectionSheet.getPayrollPayments().forEach(payrollPayment ->
+ this.payrollConfigurationService
+ .findPayrollConfiguration(payrollPayment.getCustomerIdentifier())
+ .ifPresent(payrollConfiguration -> {
+ final PayrollPaymentEntity payrollPaymentEntity = new PayrollPaymentEntity();
+ payrollPaymentEntity.setPayrollCollection(savedPayrollCollectionEntity);
+ payrollPaymentEntity.setCustomerIdentifier(payrollPayment.getCustomerIdentifier());
+ payrollPaymentEntity.setEmployer(payrollPayment.getEmployer());
+ payrollPaymentEntity.setSalary(payrollPayment.getSalary());
+
+ this.payrollPaymentRepository.save(payrollPaymentEntity);
+
+ this.accountingAdaptor.postPayrollPayment(savedPayrollCollectionEntity, payrollPayment, payrollConfiguration);
+ })
+ );
+
+ return payrollCollectionSheet.getSourceAccountNumber();
+ }
+}
diff --git a/service/src/main/java/io/mifos/payroll/service/internal/mapper/PayrollAllocationMapper.java b/service/src/main/java/io/mifos/payroll/service/internal/mapper/PayrollAllocationMapper.java
new file mode 100644
index 0000000..832fd12
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/internal/mapper/PayrollAllocationMapper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.internal.mapper;
+
+import io.mifos.payroll.api.v1.domain.PayrollAllocation;
+import io.mifos.payroll.service.internal.repository.PayrollAllocationEntity;
+
+public class PayrollAllocationMapper {
+
+ private PayrollAllocationMapper() {
+ super();
+ }
+
+ public static PayrollAllocation map(final PayrollAllocationEntity payrollAllocationEntity) {
+ final PayrollAllocation payrollAllocation = new PayrollAllocation();
+ payrollAllocation.setAccountNumber(payrollAllocationEntity.getAccountNumber());
+ payrollAllocation.setAmount(payrollAllocationEntity.getAmount());
+ payrollAllocation.setProportional(payrollAllocationEntity.getProportional());
+ return payrollAllocation;
+ }
+
+ public static PayrollAllocationEntity map(final PayrollAllocation payrollAllocation) {
+ final PayrollAllocationEntity payrollAllocationEntity = new PayrollAllocationEntity();
+ payrollAllocationEntity.setAccountNumber(payrollAllocation.getAccountNumber());
+ payrollAllocationEntity.setAmount(payrollAllocation.getAmount());
+ payrollAllocationEntity.setProportional(payrollAllocation.getProportional());
+ return payrollAllocationEntity;
+ }
+}
diff --git a/service/src/main/java/io/mifos/payroll/service/internal/mapper/PayrollConfigurationMapper.java b/service/src/main/java/io/mifos/payroll/service/internal/mapper/PayrollConfigurationMapper.java
new file mode 100644
index 0000000..140a2e0
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/internal/mapper/PayrollConfigurationMapper.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.internal.mapper;
+
+import io.mifos.core.lang.DateConverter;
+import io.mifos.payroll.api.v1.domain.PayrollConfiguration;
+import io.mifos.payroll.service.internal.repository.PayrollConfigurationEntity;
+
+public class PayrollConfigurationMapper {
+
+ private PayrollConfigurationMapper() {
+ super();
+ }
+
+ public static PayrollConfiguration map(final PayrollConfigurationEntity payrollConfigurationEntity) {
+ final PayrollConfiguration payrollConfiguration = new PayrollConfiguration();
+ payrollConfiguration.setMainAccountNumber(payrollConfigurationEntity.getMainAccountNumber());
+ payrollConfiguration.setCreatedBy(payrollConfiguration.getCreatedOn());
+ payrollConfiguration.setCreatedOn(DateConverter.toIsoString(payrollConfigurationEntity.getCreatedOn()));
+ if (payrollConfigurationEntity.getLastModifiedBy() != null) {
+ payrollConfiguration.setLastModifiedBy(payrollConfigurationEntity.getLastModifiedBy());
+ payrollConfiguration.setLastModifiedOn(DateConverter.toIsoString(payrollConfigurationEntity.getLastModifiedOn()));
+ }
+ return payrollConfiguration;
+ }
+}
diff --git a/service/src/main/java/io/mifos/payroll/service/internal/mapper/PayrollPaymentMapper.java b/service/src/main/java/io/mifos/payroll/service/internal/mapper/PayrollPaymentMapper.java
new file mode 100644
index 0000000..fd7538a
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/internal/mapper/PayrollPaymentMapper.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.internal.mapper;
+
+import io.mifos.payroll.api.v1.domain.PayrollPayment;
+import io.mifos.payroll.service.internal.repository.PayrollPaymentEntity;
+
+public class PayrollPaymentMapper {
+
+ private PayrollPaymentMapper() {
+ super();
+ }
+
+ public static PayrollPayment map(final PayrollPaymentEntity payrollPaymentEntity) {
+ final PayrollPayment payrollPayment = new PayrollPayment();
+ payrollPayment.setCustomerIdentifier(payrollPaymentEntity.getCustomerIdentifier());
+ payrollPayment.setEmployer(payrollPaymentEntity.getEmployer());
+ payrollPayment.setSalary(payrollPaymentEntity.getSalary());
+ return payrollPayment;
+ }
+}
diff --git a/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollAllocationEntity.java b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollAllocationEntity.java
new file mode 100644
index 0000000..d059f2a
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollAllocationEntity.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.internal.repository;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import java.math.BigDecimal;
+
+@Entity
+@Table(name = "meketre_payroll_allocations")
+public class PayrollAllocationEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id", nullable = false)
+ private Long id;
+ @ManyToOne
+ @JoinColumn(name = "payroll_configuration_id", nullable = false)
+ private PayrollConfigurationEntity payrollConfiguration;
+ @Column(name = "account_number", nullable = false, length = 34)
+ private String accountNumber;
+ @Column(name = "amount", nullable = false, precision = 15, scale = 5)
+ private BigDecimal amount;
+ @Column(name = "proportional", nullable = false)
+ private Boolean proportional = Boolean.FALSE;
+
+ public PayrollAllocationEntity() {
+ super();
+ }
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public void setId(final Long id) {
+ this.id = id;
+ }
+
+ public PayrollConfigurationEntity getPayrollConfiguration() {
+ return this.payrollConfiguration;
+ }
+
+ public void setPayrollConfiguration(final PayrollConfigurationEntity payrollConfiguration) {
+ this.payrollConfiguration = payrollConfiguration;
+ }
+
+ public String getAccountNumber() {
+ return this.accountNumber;
+ }
+
+ public void setAccountNumber(final String accountNumber) {
+ this.accountNumber = accountNumber;
+ }
+
+ public BigDecimal getAmount() {
+ return this.amount;
+ }
+
+ public void setAmount(final BigDecimal amount) {
+ this.amount = amount;
+ }
+
+ public Boolean getProportional() {
+ return this.proportional;
+ }
+
+ public void setProportional(final Boolean proportional) {
+ this.proportional = proportional;
+ }
+}
diff --git a/service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntityRepository.java b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollAllocationRepository.java
similarity index 62%
copy from service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntityRepository.java
copy to service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollAllocationRepository.java
index 87ea8a7..bcc43f5 100644
--- a/service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntityRepository.java
+++ b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollAllocationRepository.java
@@ -13,14 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.service.internal.repository;
+package io.mifos.payroll.service.internal.repository;
+
import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.stereotype.Repository;
-import java.util.Optional;
+import java.util.List;
+
+public interface PayrollAllocationRepository extends JpaRepository<PayrollAllocationEntity, Long> {
+
+ void deleteByPayrollConfiguration(final PayrollConfigurationEntity payrollConfigurationEntity);
-@Repository
-public interface SampleJpaEntityRepository extends JpaRepository<SampleJpaEntity, Long> {
- Optional<SampleJpaEntity> findByIdentifier(String identifier);
+ List<PayrollAllocationEntity> findByPayrollConfiguration(final PayrollConfigurationEntity payrollConfigurationEntity);
}
diff --git a/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollCollectionEntity.java b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollCollectionEntity.java
new file mode 100644
index 0000000..c896995
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollCollectionEntity.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.internal.repository;
+
+import io.mifos.core.mariadb.util.LocalDateTimeConverter;
+
+import javax.persistence.Column;
+import javax.persistence.Convert;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "meketre_payroll_collections")
+public class PayrollCollectionEntity {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id", nullable = false)
+ private Long id;
+ @Column(name = "identifier", nullable = false, length = 32)
+ private String identifier;
+ @Column(name = "source_account_number", nullable = false, length = 34)
+ private String sourceAccountNumber;
+ @Column(name = "created_by", nullable = false, length = 32)
+ private String createdBy;
+ @Column(name = "created_on")
+ @Convert(converter = LocalDateTimeConverter.class)
+ private LocalDateTime createdOn;
+
+ public PayrollCollectionEntity() {
+ super();
+ }
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public void setId(final Long id) {
+ this.id = id;
+ }
+
+ public String getIdentifier() {
+ return this.identifier;
+ }
+
+ public void setIdentifier(final String identifier) {
+ this.identifier = identifier;
+ }
+
+ public String getSourceAccountNumber() {
+ return this.sourceAccountNumber;
+ }
+
+ public void setSourceAccountNumber(final String sourceAccountNumber) {
+ this.sourceAccountNumber = sourceAccountNumber;
+ }
+
+ public String getCreatedBy() {
+ return this.createdBy;
+ }
+
+ public void setCreatedBy(final String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public LocalDateTime getCreatedOn() {
+ return this.createdOn;
+ }
+
+ public void setCreatedOn(final LocalDateTime createdOn) {
+ this.createdOn = createdOn;
+ }
+}
diff --git a/service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntityRepository.java b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollCollectionRepository.java
similarity index 70%
copy from service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntityRepository.java
copy to service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollCollectionRepository.java
index 87ea8a7..8986a79 100644
--- a/service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntityRepository.java
+++ b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollCollectionRepository.java
@@ -13,14 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.service.internal.repository;
+package io.mifos.payroll.service.internal.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
+import java.util.List;
import java.util.Optional;
@Repository
-public interface SampleJpaEntityRepository extends JpaRepository<SampleJpaEntity, Long> {
- Optional<SampleJpaEntity> findByIdentifier(String identifier);
+public interface PayrollCollectionRepository extends JpaRepository<PayrollCollectionEntity, Long> {
+ List<PayrollCollectionEntity> findAllByOrderByCreatedOnDesc();
+
+ Optional<PayrollCollectionEntity> findByIdentifier(String identifier);
}
diff --git a/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollConfigurationEntity.java b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollConfigurationEntity.java
new file mode 100644
index 0000000..0ccd490
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollConfigurationEntity.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.internal.repository;
+
+import io.mifos.core.mariadb.util.LocalDateTimeConverter;
+
+import javax.persistence.Column;
+import javax.persistence.Convert;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "meketre_payroll_configurations")
+public class PayrollConfigurationEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id", nullable = false)
+ private Long id;
+ @Column(name = "customer_identifier", nullable = false, length = 32)
+ private String customerIdentifier;
+ @Column(name = "main_account_number", nullable = false, length = 34)
+ private String mainAccountNumber;
+ @Column(name = "created_by")
+ private String createdBy;
+ @Column(name = "created_on")
+ @Convert(converter = LocalDateTimeConverter.class)
+ private LocalDateTime createdOn;
+ @Column(name = "last_modified_by")
+ private String lastModifiedBy;
+ @Column(name = "last_modified_on")
+ @Convert(converter = LocalDateTimeConverter.class)
+ private LocalDateTime lastModifiedOn;
+
+ public PayrollConfigurationEntity() {
+ super();
+ }
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public void setId(final Long id) {
+ this.id = id;
+ }
+
+ public String getCustomerIdentifier() {
+ return this.customerIdentifier;
+ }
+
+ public void setCustomerIdentifier(final String customerIdentifier) {
+ this.customerIdentifier = customerIdentifier;
+ }
+
+ public String getMainAccountNumber() {
+ return this.mainAccountNumber;
+ }
+
+ public void setMainAccountNumber(final String mainAccountNumber) {
+ this.mainAccountNumber = mainAccountNumber;
+ }
+
+ public String getCreatedBy() {
+ return this.createdBy;
+ }
+
+ public void setCreatedBy(final String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public LocalDateTime getCreatedOn() {
+ return this.createdOn;
+ }
+
+ public void setCreatedOn(final LocalDateTime createdOn) {
+ this.createdOn = createdOn;
+ }
+
+ public String getLastModifiedBy() {
+ return this.lastModifiedBy;
+ }
+
+ public void setLastModifiedBy(final String lastModifiedBy) {
+ this.lastModifiedBy = lastModifiedBy;
+ }
+
+ public LocalDateTime getLastModifiedOn() {
+ return this.lastModifiedOn;
+ }
+
+ public void setLastModifiedOn(final LocalDateTime lastModifiedOn) {
+ this.lastModifiedOn = lastModifiedOn;
+ }
+}
diff --git a/service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntityRepository.java b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollConfigurationRepository.java
similarity index 74%
copy from service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntityRepository.java
copy to service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollConfigurationRepository.java
index 87ea8a7..fb2944a 100644
--- a/service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntityRepository.java
+++ b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollConfigurationRepository.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.service.internal.repository;
+package io.mifos.payroll.service.internal.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@@ -21,6 +21,6 @@ import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
-public interface SampleJpaEntityRepository extends JpaRepository<SampleJpaEntity, Long> {
- Optional<SampleJpaEntity> findByIdentifier(String identifier);
+public interface PayrollConfigurationRepository extends JpaRepository<PayrollConfigurationEntity, Long> {
+ Optional<PayrollConfigurationEntity> findByCustomerIdentifier(final String customerIdentifier);
}
diff --git a/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollPaymentEntity.java b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollPaymentEntity.java
new file mode 100644
index 0000000..3b782ed
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollPaymentEntity.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.internal.repository;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import java.math.BigDecimal;
+
+@Entity
+@Table(name = "meketre_payroll_payments")
+public class PayrollPaymentEntity {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id", nullable = false)
+ private Long id;
+ @ManyToOne
+ @JoinColumn(name = "payroll_collection_id", nullable = false)
+ private PayrollCollectionEntity payrollCollection;
+ @Column(name = "customer_identifier", nullable = false, length = 32)
+ private String customerIdentifier;
+ @Column(name = "employer", nullable = false, length = 256)
+ private String employer;
+ @Column(name = "salary", nullable = false, precision = 15, scale = 5)
+ private BigDecimal salary;
+
+ public PayrollPaymentEntity() {
+ super();
+ }
+
+ public Long getId() {
+ return this.id;
+ }
+
+ public void setId(final Long id) {
+ this.id = id;
+ }
+
+ public PayrollCollectionEntity getPayrollCollection() {
+ return this.payrollCollection;
+ }
+
+ public void setPayrollCollection(final PayrollCollectionEntity payrollCollection) {
+ this.payrollCollection = payrollCollection;
+ }
+
+ public String getCustomerIdentifier() {
+ return this.customerIdentifier;
+ }
+
+ public void setCustomerIdentifier(final String customerIdentifier) {
+ this.customerIdentifier = customerIdentifier;
+ }
+
+ public String getEmployer() {
+ return this.employer;
+ }
+
+ public void setEmployer(final String employer) {
+ this.employer = employer;
+ }
+
+ public BigDecimal getSalary() {
+ return this.salary;
+ }
+
+ public void setSalary(final BigDecimal salary) {
+ this.salary = salary;
+ }
+}
diff --git a/service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntityRepository.java b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollPaymentRepository.java
similarity index 63%
rename from service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntityRepository.java
rename to service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollPaymentRepository.java
index 87ea8a7..91685ce 100644
--- a/service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntityRepository.java
+++ b/service/src/main/java/io/mifos/payroll/service/internal/repository/PayrollPaymentRepository.java
@@ -13,14 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.mifos.template.service.internal.repository;
+package io.mifos.payroll.service.internal.repository;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
-import java.util.Optional;
-
@Repository
-public interface SampleJpaEntityRepository extends JpaRepository<SampleJpaEntity, Long> {
- Optional<SampleJpaEntity> findByIdentifier(String identifier);
+public interface PayrollPaymentRepository extends JpaRepository<PayrollPaymentEntity, Long> {
+ Page<PayrollPaymentEntity> findByPayrollCollection(final PayrollCollectionEntity payrollCollectionEntity,
+ Pageable pageable);
}
diff --git a/service/src/main/java/io/mifos/payroll/service/internal/service/PayrollConfigurationService.java b/service/src/main/java/io/mifos/payroll/service/internal/service/PayrollConfigurationService.java
new file mode 100644
index 0000000..eefeca3
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/internal/service/PayrollConfigurationService.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.internal.service;
+
+import io.mifos.accounting.api.v1.domain.Account;
+import io.mifos.customer.api.v1.domain.Customer;
+import io.mifos.payroll.api.v1.domain.PayrollConfiguration;
+import io.mifos.payroll.service.ServiceConstants;
+import io.mifos.payroll.service.internal.mapper.PayrollAllocationMapper;
+import io.mifos.payroll.service.internal.mapper.PayrollConfigurationMapper;
+import io.mifos.payroll.service.internal.repository.PayrollAllocationRepository;
+import io.mifos.payroll.service.internal.repository.PayrollConfigurationRepository;
+import io.mifos.payroll.service.internal.service.adaptor.AccountingAdaptor;
+import io.mifos.payroll.service.internal.service.adaptor.CustomerAdaptor;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@Service
+public class PayrollConfigurationService {
+
+ private final Logger logger;
+ private final PayrollConfigurationRepository payrollConfigurationRepository;
+ private final PayrollAllocationRepository payrollAllocationRepository;
+ private final CustomerAdaptor customerAdaptor;
+ private final AccountingAdaptor accountingAdaptor;
+
+ @Autowired
+ public PayrollConfigurationService(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+ final PayrollConfigurationRepository payrollConfigurationRepository,
+ final PayrollAllocationRepository payrollAllocationRepository,
+ final CustomerAdaptor customerAdaptor,
+ final AccountingAdaptor accountingAdaptor) {
+ super();
+ this.logger = logger;
+ this.payrollConfigurationRepository = payrollConfigurationRepository;
+ this.payrollAllocationRepository = payrollAllocationRepository;
+ this.customerAdaptor = customerAdaptor;
+ this.accountingAdaptor = accountingAdaptor;
+ }
+
+ public Optional<Customer> findCustomer(final String customerIdentifier) {
+ return this.customerAdaptor.findCustomer(customerIdentifier);
+ }
+
+ public Optional<Account> findAccount(final String accountIdentifier) {
+ return this.accountingAdaptor.findAccount(accountIdentifier);
+ }
+
+ public Optional<PayrollConfiguration> findPayrollConfiguration(final String customerIdentifier) {
+ return this.payrollConfigurationRepository
+ .findByCustomerIdentifier(customerIdentifier)
+ .map(payrollConfigurationEntity -> {
+ final PayrollConfiguration payrollConfiguration = PayrollConfigurationMapper.map(payrollConfigurationEntity);
+
+ payrollConfiguration.setPayrollAllocations(
+ this.payrollAllocationRepository.findByPayrollConfiguration(payrollConfigurationEntity)
+ .stream()
+ .map(PayrollAllocationMapper::map)
+ .collect(Collectors.toSet())
+ );
+
+ return payrollConfiguration;
+ });
+ }
+}
diff --git a/service/src/main/java/io/mifos/payroll/service/internal/service/PayrollDistributionService.java b/service/src/main/java/io/mifos/payroll/service/internal/service/PayrollDistributionService.java
new file mode 100644
index 0000000..dd4012e
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/internal/service/PayrollDistributionService.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.internal.service;
+
+import io.mifos.core.lang.DateConverter;
+import io.mifos.core.lang.ServiceException;
+import io.mifos.payroll.api.v1.domain.PayrollCollectionHistory;
+import io.mifos.payroll.api.v1.domain.PayrollPaymentPage;
+import io.mifos.payroll.service.ServiceConstants;
+import io.mifos.payroll.service.internal.mapper.PayrollPaymentMapper;
+import io.mifos.payroll.service.internal.repository.PayrollCollectionEntity;
+import io.mifos.payroll.service.internal.repository.PayrollCollectionRepository;
+import io.mifos.payroll.service.internal.repository.PayrollPaymentEntity;
+import io.mifos.payroll.service.internal.repository.PayrollPaymentRepository;
+import io.mifos.payroll.service.internal.service.adaptor.AccountingAdaptor;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@Service
+public class PayrollDistributionService {
+
+ private final Logger logger;
+ private final PayrollCollectionRepository payrollCollectionRepository;
+ private final PayrollPaymentRepository payrollPaymentRepository;
+ private final AccountingAdaptor accountingAdaptor;
+
+ @Autowired
+ public PayrollDistributionService(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+ final PayrollCollectionRepository payrollCollectionRepository,
+ final PayrollPaymentRepository payrollPaymentRepository,
+ final AccountingAdaptor accountingAdaptor) {
+ super();
+ this.logger = logger;
+ this.payrollCollectionRepository = payrollCollectionRepository;
+ this.payrollPaymentRepository = payrollPaymentRepository;
+ this.accountingAdaptor = accountingAdaptor;
+ }
+
+
+ public List<PayrollCollectionHistory> fetchHistory() {
+ return this.payrollCollectionRepository.findAllByOrderByCreatedOnDesc()
+ .stream()
+ .map(this::mapPayrollCollection)
+ .collect(Collectors.toList());
+ }
+
+ public Optional<PayrollCollectionHistory> findDistribution(final String identifier) {
+ return this.payrollCollectionRepository.findByIdentifier(identifier)
+ .map(this::mapPayrollCollection);
+ }
+
+ public PayrollPaymentPage fetchPayments(final String identifier, final Pageable pageable) {
+ final PayrollPaymentPage payrollPaymentPage = new PayrollPaymentPage();
+
+ final PayrollCollectionEntity payrollCollectionEntity =
+ this.payrollCollectionRepository.findByIdentifier(identifier).orElseThrow(
+ () -> ServiceException.notFound("Payroll distribution {0} not found.", identifier)
+ );
+
+ final Page<PayrollPaymentEntity> pagedEntities =
+ this.payrollPaymentRepository.findByPayrollCollection(payrollCollectionEntity, pageable);
+ payrollPaymentPage.setTotalElements(pagedEntities.getTotalElements());
+ payrollPaymentPage.setTotalPages(pagedEntities.getTotalPages());
+ pagedEntities.forEach(
+ payrollPaymentEntity -> payrollPaymentPage.add(PayrollPaymentMapper.map(payrollPaymentEntity))
+ );
+
+ return payrollPaymentPage;
+ }
+
+ private PayrollCollectionHistory mapPayrollCollection(final PayrollCollectionEntity payrollCollectionEntity) {
+ final PayrollCollectionHistory payrollCollectionHistory = new PayrollCollectionHistory();
+ payrollCollectionHistory.setIdentifier(payrollCollectionEntity.getIdentifier());
+ payrollCollectionHistory.setSourceAccountNumber(payrollCollectionEntity.getSourceAccountNumber());
+ payrollCollectionHistory.setCreatedBy(payrollCollectionEntity.getCreatedBy());
+ payrollCollectionHistory.setCreatedOn(DateConverter.toIsoString(payrollCollectionEntity.getCreatedOn()));
+ return payrollCollectionHistory;
+ }
+}
diff --git a/service/src/main/java/io/mifos/payroll/service/internal/service/adaptor/AccountingAdaptor.java b/service/src/main/java/io/mifos/payroll/service/internal/service/adaptor/AccountingAdaptor.java
new file mode 100644
index 0000000..41f19df
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/internal/service/adaptor/AccountingAdaptor.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.internal.service.adaptor;
+
+import com.google.common.collect.Sets;
+import io.mifos.accounting.api.v1.client.AccountNotFoundException;
+import io.mifos.accounting.api.v1.client.LedgerManager;
+import io.mifos.accounting.api.v1.domain.Account;
+import io.mifos.accounting.api.v1.domain.Creditor;
+import io.mifos.accounting.api.v1.domain.Debtor;
+import io.mifos.accounting.api.v1.domain.JournalEntry;
+import io.mifos.core.lang.DateConverter;
+import io.mifos.payroll.api.v1.domain.PayrollConfiguration;
+import io.mifos.payroll.api.v1.domain.PayrollPayment;
+import io.mifos.payroll.service.ServiceConstants;
+import io.mifos.payroll.service.internal.repository.PayrollCollectionEntity;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.math.RoundingMode;
+import java.time.Clock;
+import java.time.LocalDateTime;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.UUID;
+
+@Service
+public class AccountingAdaptor {
+
+ private final Logger logger;
+ private final LedgerManager ledgerManager;
+
+ @Autowired
+ public AccountingAdaptor(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+ final LedgerManager ledgerManager) {
+ super();
+ this.logger = logger;
+ this.ledgerManager = ledgerManager;
+ }
+
+ public Optional<Account> findAccount(final String accountIdentifier) {
+ try {
+ return Optional.of(this.ledgerManager.findAccount(accountIdentifier));
+ } catch (final AccountNotFoundException anfex) {
+ this.logger.warn("Account {} not found.", accountIdentifier);
+ return Optional.empty();
+ }
+ }
+
+ public void postPayrollPayment(final PayrollCollectionEntity payrollCollectionEntity,
+ final PayrollPayment payrollPayment,
+ final PayrollConfiguration payrollConfiguration) {
+
+ final MathContext mathContext = new MathContext(2, RoundingMode.HALF_EVEN);
+
+ final JournalEntry journalEntry = new JournalEntry();
+ journalEntry.setTransactionIdentifier(UUID.randomUUID().toString());
+ journalEntry.setTransactionDate(DateConverter.toIsoString(LocalDateTime.now(Clock.systemUTC())));
+ journalEntry.setTransactionType("SALA");
+ journalEntry.setClerk(payrollCollectionEntity.getCreatedBy());
+ journalEntry.setNote("Payroll Distribution");
+
+ final Debtor debtor = new Debtor();
+ debtor.setAccountNumber(payrollCollectionEntity.getSourceAccountNumber());
+ debtor.setAmount(payrollPayment.getSalary().toString());
+ journalEntry.setDebtors(Sets.newHashSet(debtor));
+
+ final HashSet<Creditor> creditors = new HashSet<>();
+ journalEntry.setCreditors(creditors);
+
+ payrollConfiguration.getPayrollAllocations().forEach(payrollAllocation -> {
+ final Creditor allocationCreditor = new Creditor();
+ allocationCreditor.setAccountNumber(payrollAllocation.getAccountNumber());
+ if (!payrollAllocation.getProportional()) {
+ allocationCreditor.setAmount(payrollAllocation.getAmount().toString());
+ } else {
+ final BigDecimal value = payrollPayment.getSalary().multiply(
+ payrollAllocation.getAmount().divide(BigDecimal.valueOf(100.00D), mathContext)
+ ).round(mathContext);
+ allocationCreditor.setAmount(value.toString());
+ }
+ creditors.add(allocationCreditor);
+ });
+
+ final BigDecimal currentCreditorSum =
+ BigDecimal.valueOf(creditors.stream().mapToDouble(value -> Double.valueOf(value.getAmount())).sum());
+
+ final Creditor mainCreditor = new Creditor();
+ mainCreditor.setAccountNumber(payrollConfiguration.getMainAccountNumber());
+ mainCreditor.setAmount(payrollPayment.getSalary().subtract(currentCreditorSum).toString());
+ creditors.add(mainCreditor);
+
+ this.ledgerManager.createJournalEntry(journalEntry);
+ }
+}
diff --git a/service/src/main/java/io/mifos/payroll/service/internal/service/adaptor/CustomerAdaptor.java b/service/src/main/java/io/mifos/payroll/service/internal/service/adaptor/CustomerAdaptor.java
new file mode 100644
index 0000000..9fd9d0c
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/internal/service/adaptor/CustomerAdaptor.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.internal.service.adaptor;
+
+import io.mifos.customer.api.v1.client.CustomerManager;
+import io.mifos.customer.api.v1.client.CustomerNotFoundException;
+import io.mifos.customer.api.v1.domain.Customer;
+import io.mifos.payroll.service.ServiceConstants;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+
+@Service
+public class CustomerAdaptor {
+
+ private final Logger logger;
+ private final CustomerManager customerManager;
+
+ @Autowired
+ public CustomerAdaptor(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+ final CustomerManager customerManager) {
+ super();
+ this.logger = logger;
+ this.customerManager = customerManager;
+ }
+
+ public Optional<Customer> findCustomer(final String customerIdentifier) {
+ try {
+ return Optional.of(this.customerManager.findCustomer(customerIdentifier));
+ } catch (final CustomerNotFoundException cnfex) {
+ this.logger.warn("Customer {} not found.", customerIdentifier);
+ return Optional.empty();
+ }
+ }
+}
diff --git a/service/src/main/java/io/mifos/payroll/service/rest/MigrationRestController.java b/service/src/main/java/io/mifos/payroll/service/rest/MigrationRestController.java
new file mode 100644
index 0000000..84f58ef
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/rest/MigrationRestController.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.rest;
+
+import io.mifos.anubis.annotation.AcceptedTokenType;
+import io.mifos.anubis.annotation.Permittable;
+import io.mifos.core.command.gateway.CommandGateway;
+import io.mifos.payroll.service.internal.command.MigrateServiceCommand;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@SuppressWarnings("unused")
+@RestController
+@RequestMapping("/")
+public class MigrationRestController {
+
+ private final CommandGateway commandGateway;
+
+ @Autowired
+ public MigrationRestController(final CommandGateway commandGateway) {
+ super();
+ this.commandGateway = commandGateway;
+ }
+
+ @Permittable(AcceptedTokenType.SYSTEM)
+ @RequestMapping(
+ value = "/initialize",
+ method = RequestMethod.POST,
+ consumes = MediaType.ALL_VALUE,
+ produces = MediaType.APPLICATION_JSON_VALUE
+ )
+ public
+ @ResponseBody
+ ResponseEntity<Void> initialize() throws InterruptedException {
+ this.commandGateway.process(new MigrateServiceCommand());
+ return ResponseEntity.accepted().build();
+ }
+}
diff --git a/service/src/main/java/io/mifos/payroll/service/rest/PayrollConfigurationRestController.java b/service/src/main/java/io/mifos/payroll/service/rest/PayrollConfigurationRestController.java
new file mode 100644
index 0000000..100319d
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/rest/PayrollConfigurationRestController.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.rest;
+
+import io.mifos.anubis.annotation.AcceptedTokenType;
+import io.mifos.anubis.annotation.Permittable;
+import io.mifos.anubis.annotation.Permittables;
+import io.mifos.core.command.gateway.CommandGateway;
+import io.mifos.core.lang.ServiceException;
+import io.mifos.payroll.api.v1.PermittableGroupIds;
+import io.mifos.payroll.api.v1.domain.PayrollConfiguration;
+import io.mifos.payroll.service.ServiceConstants;
+import io.mifos.payroll.service.internal.command.PutPayrollConfigurationCommand;
+import io.mifos.payroll.service.internal.service.PayrollConfigurationService;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("/customers/{identifier}/payroll")
+public class PayrollConfigurationRestController {
+
+ private final Logger logger;
+ private final CommandGateway commandGateway;
+ private final PayrollConfigurationService payrollConfigurationService;
+
+ @Autowired
+ public PayrollConfigurationRestController(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+ final CommandGateway commandGateway,
+ final PayrollConfigurationService payrollConfigurationService) {
+ super();
+ this.logger = logger;
+ this.commandGateway = commandGateway;
+ this.payrollConfigurationService = payrollConfigurationService;
+ }
+
+ @Permittables({
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.CONFIGURATION)
+ })
+ @RequestMapping(
+ method = RequestMethod.PUT,
+ consumes = {
+ MediaType.APPLICATION_JSON_VALUE
+ },
+ produces = {
+ MediaType.APPLICATION_JSON_VALUE
+ }
+ )
+ @ResponseBody
+ public ResponseEntity<Void> setPayrollConfiguration(@PathVariable(value = "identifier") final String customerIdentifier,
+ @RequestBody @Valid final PayrollConfiguration payrollConfiguration) {
+ this.payrollConfigurationService.findCustomer(customerIdentifier)
+ .orElseThrow(() -> ServiceException.notFound("Customer {0} not found.", customerIdentifier)
+ );
+
+ this.payrollConfigurationService.findAccount(payrollConfiguration.getMainAccountNumber())
+ .orElseThrow(() -> ServiceException.notFound("Main account {0} not found.", payrollConfiguration.getMainAccountNumber()));
+
+ if (payrollConfiguration.getPayrollAllocations() != null
+ && payrollConfiguration.getPayrollAllocations()
+ .stream()
+ .filter(payrollAllocation ->
+ !this.payrollConfigurationService.findAccount(payrollAllocation.getAccountNumber()).isPresent()
+ ).count() > 0L) {
+ throw ServiceException.notFound("Certain allocated accounts not found.");
+ }
+
+ this.commandGateway.process(new PutPayrollConfigurationCommand(customerIdentifier, payrollConfiguration));
+
+ return ResponseEntity.accepted().build();
+ }
+
+ @Permittables({
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.CONFIGURATION)
+ })
+ @RequestMapping(
+ method = RequestMethod.GET,
+ consumes = {
+ MediaType.ALL_VALUE
+ },
+ produces = {
+ MediaType.APPLICATION_JSON_VALUE
+ }
+ )
+ @ResponseBody
+ PayrollConfiguration findPayrollConfiguration(@PathVariable(value = "identifier") final String customerIdentifier) {
+ return this.payrollConfigurationService.findPayrollConfiguration(customerIdentifier)
+ .orElseThrow(() -> ServiceException.notFound("Payroll configuration for customer {0} not found.", customerIdentifier));
+ }
+}
diff --git a/service/src/main/java/io/mifos/payroll/service/rest/PayrollDistributionRestController.java b/service/src/main/java/io/mifos/payroll/service/rest/PayrollDistributionRestController.java
new file mode 100644
index 0000000..86d3203
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/rest/PayrollDistributionRestController.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.rest;
+
+import io.mifos.anubis.annotation.AcceptedTokenType;
+import io.mifos.anubis.annotation.Permittable;
+import io.mifos.anubis.annotation.Permittables;
+import io.mifos.core.command.gateway.CommandGateway;
+import io.mifos.core.lang.ServiceException;
+import io.mifos.payroll.api.v1.PermittableGroupIds;
+import io.mifos.payroll.api.v1.domain.PayrollCollectionHistory;
+import io.mifos.payroll.api.v1.domain.PayrollCollectionSheet;
+import io.mifos.payroll.api.v1.domain.PayrollPaymentPage;
+import io.mifos.payroll.service.ServiceConstants;
+import io.mifos.payroll.service.internal.command.DistributePayrollCommand;
+import io.mifos.payroll.service.internal.service.PayrollConfigurationService;
+import io.mifos.payroll.service.internal.service.PayrollDistributionService;
+import io.mifos.payroll.service.rest.util.PageableBuilder;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+
+@RestController
+@RequestMapping("/distribution")
+public class PayrollDistributionRestController {
+
+ private final Logger logger;
+ private final CommandGateway commandGateway;
+ private final PayrollDistributionService payrollDistributionService;
+ private final PayrollConfigurationService payrollConfigurationService;
+
+ @Autowired
+ public PayrollDistributionRestController(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
+ final CommandGateway commandGateway,
+ final PayrollDistributionService payrollDistributionService,
+ final PayrollConfigurationService payrollConfigurationService) {
+ super();
+ this.logger = logger;
+ this.commandGateway = commandGateway;
+ this.payrollDistributionService = payrollDistributionService;
+ this.payrollConfigurationService = payrollConfigurationService;
+ }
+
+ @Permittables({
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DISTRIBUTION)
+ })
+ @RequestMapping(
+ method = RequestMethod.POST,
+ consumes = {
+ MediaType.APPLICATION_JSON_VALUE
+ },
+ produces = {
+ MediaType.APPLICATION_JSON_VALUE
+ }
+ )
+ @ResponseBody
+ public ResponseEntity<Void> distribute(@RequestBody @Valid final PayrollCollectionSheet payrollCollectionSheet) {
+
+ this.payrollConfigurationService.findAccount(payrollCollectionSheet.getSourceAccountNumber())
+ .orElseThrow(() -> ServiceException.notFound("Account {0} not found.", payrollCollectionSheet.getSourceAccountNumber()));
+
+ if (payrollCollectionSheet.getPayrollPayments()
+ .stream()
+ .filter(
+ payrollPayment -> !this.payrollConfigurationService
+ .findPayrollConfiguration(payrollPayment.getCustomerIdentifier())
+ .isPresent()
+ )
+ .count() > 0L) {
+ throw ServiceException.conflict("Missing payroll configuration for certain customers.");
+ }
+
+ this.commandGateway.process(new DistributePayrollCommand(payrollCollectionSheet));
+
+ return ResponseEntity.accepted().build();
+ }
+
+ @Permittables({
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DISTRIBUTION)
+ })
+ @RequestMapping(
+ method = RequestMethod.GET,
+ consumes = {
+ MediaType.ALL_VALUE
+ },
+ produces = {
+ MediaType.APPLICATION_JSON_VALUE
+ }
+ )
+ @ResponseBody
+ public ResponseEntity<List<PayrollCollectionHistory>> fetchDistributionHistory() {
+ return ResponseEntity.ok(this.payrollDistributionService.fetchHistory());
+ }
+
+ @Permittables({
+ @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.DISTRIBUTION)
+ })
+ @RequestMapping(
+ value = "/{identifier}/payments",
+ method = RequestMethod.GET,
+ consumes = {
+ MediaType.ALL_VALUE
+ },
+ produces = {
+ MediaType.APPLICATION_JSON_VALUE
+ }
+ )
+ @ResponseBody
+ ResponseEntity<PayrollPaymentPage> fetchPayments(
+ @PathVariable("identifier") final String identifier,
+ @RequestParam(value = "pageIndex", required = false) final Integer pageIndex,
+ @RequestParam(value = "size", required = false) final Integer size,
+ @RequestParam(value = "sortColumn", required = false) final String sortColumn,
+ @RequestParam(value = "sortDirection", required = false) final String sortDirection) {
+ this.payrollDistributionService.findDistribution(identifier)
+ .orElseThrow(() -> ServiceException.notFound("Payroll distribution {0} not found."));
+
+ return ResponseEntity.ok(this.payrollDistributionService
+ .fetchPayments(identifier, PageableBuilder.create(pageIndex, size, sortColumn, sortDirection)));
+ }
+}
diff --git a/service/src/main/java/io/mifos/payroll/service/rest/util/PageableBuilder.java b/service/src/main/java/io/mifos/payroll/service/rest/util/PageableBuilder.java
new file mode 100644
index 0000000..ff34371
--- /dev/null
+++ b/service/src/main/java/io/mifos/payroll/service/rest/util/PageableBuilder.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2017 The Mifos Initiative.
+ *
+ * Licensed 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 io.mifos.payroll.service.rest.util;
+
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+
+import javax.annotation.Nullable;
+
+public class PageableBuilder {
+
+ private PageableBuilder() {
+ super();
+ }
+
+ public static Pageable create(
+ @Nullable final Integer pageIndex,
+ @Nullable final Integer size,
+ @Nullable final String sortColumn,
+ @Nullable final String sortDirection) {
+ final Integer pageIndexToUse = pageIndex != null ? pageIndex : 0;
+ final Integer sizeToUse = size != null ? size : 20;
+ final String sortColumnToUse = sortColumn != null ? sortColumn : "customerIdentifier";
+ final Sort.Direction direction = sortDirection != null ? Sort.Direction.valueOf(sortDirection.toUpperCase()) : Sort.Direction.ASC;
+ return new PageRequest(pageIndexToUse, sizeToUse, direction, sortColumnToUse);
+ }
+}
diff --git a/service/src/main/java/io/mifos/template/service/internal/command/handler/SampleAggregate.java b/service/src/main/java/io/mifos/template/service/internal/command/handler/SampleAggregate.java
deleted file mode 100644
index 9a7c572..0000000
--- a/service/src/main/java/io/mifos/template/service/internal/command/handler/SampleAggregate.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright 2017 The Mifos Initiative.
- *
- * Licensed 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 io.mifos.template.service.internal.command.handler;
-
-import io.mifos.core.command.annotation.Aggregate;
-import io.mifos.core.command.annotation.CommandHandler;
-import io.mifos.core.command.annotation.CommandLogLevel;
-import io.mifos.core.command.annotation.EventEmitter;
-import io.mifos.template.api.v1.events.EventConstants;
-import io.mifos.template.service.internal.command.SampleCommand;
-import io.mifos.template.service.internal.repository.SampleJpaEntity;
-import io.mifos.template.service.internal.repository.SampleJpaEntityRepository;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.transaction.annotation.Transactional;
-
-@SuppressWarnings("unused")
-@Aggregate
-public class SampleAggregate {
-
- private final SampleJpaEntityRepository sampleJpaEntityRepository;
-
- @Autowired
- public SampleAggregate(final SampleJpaEntityRepository sampleJpaEntityRepository) {
- super();
- this.sampleJpaEntityRepository = sampleJpaEntityRepository;
- }
-
- //TODO: Think about your command handler logging, then delete this comment.
- // The log levels provided in the command handler cause log messages to be emitted each time this
- // command handler is called before and after the call. Before the call, the command is logged
- // using its toString() method, and after the call, the emitted event is logged via its toString()
- // method.
- //
- // If you wish to adjust the information in the log messages, do so via the toString() methods.
- // Financial transactions, passwords, and customer address data are examples of information which
- // should not be placed in the logs.
- //
- // If a command handler should not emit a log message, change logStart and logFinish to:
- // CommandLogLevel.NONE.
- @CommandHandler(logStart = CommandLogLevel.INFO, logFinish = CommandLogLevel.INFO)
- @Transactional
- @EventEmitter(selectorName = EventConstants.SELECTOR_NAME, selectorValue = EventConstants.POST_SAMPLE)
- public String sample(final SampleCommand sampleCommand) {
-
- final SampleJpaEntity entity = new SampleJpaEntity();
- entity.setIdentifier(sampleCommand.sample().getIdentifier());
- entity.setPayload(sampleCommand.sample().getPayload());
- this.sampleJpaEntityRepository.save(entity);
-
- return sampleCommand.sample().getIdentifier();
- }
-}
diff --git a/service/src/main/java/io/mifos/template/service/internal/mapper/SampleMapper.java b/service/src/main/java/io/mifos/template/service/internal/mapper/SampleMapper.java
deleted file mode 100644
index 983b5d5..0000000
--- a/service/src/main/java/io/mifos/template/service/internal/mapper/SampleMapper.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2017 The Mifos Initiative.
- *
- * Licensed 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 io.mifos.template.service.internal.mapper;
-
-import io.mifos.template.api.v1.domain.Sample;
-import io.mifos.template.service.internal.repository.SampleJpaEntity;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-public class SampleMapper {
-
- private SampleMapper() {
- super();
- }
-
- public static Sample map(final SampleJpaEntity sampleJpaEntity) {
- final Sample sample = new Sample();
- sample.setIdentifier(sampleJpaEntity.getIdentifier());
- sample.setPayload(sampleJpaEntity.getPayload());
- return sample;
- }
-
- public static List<Sample> map(final List<SampleJpaEntity> sampleJpaEntities) {
- final ArrayList<Sample> samples = new ArrayList<>(sampleJpaEntities.size());
- samples.addAll(sampleJpaEntities.stream().map(SampleMapper::map).collect(Collectors.toList()));
- return samples;
- }
-}
diff --git a/service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntity.java b/service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntity.java
deleted file mode 100644
index 9cbcd73..0000000
--- a/service/src/main/java/io/mifos/template/service/internal/repository/SampleJpaEntity.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2017 The Mifos Initiative.
- *
- * Licensed 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 io.mifos.template.service.internal.repository;
-
-import javax.persistence.*;
-
-@SuppressWarnings("unused")
-@Entity
-@Table(name = "template_samples")
-public class SampleJpaEntity {
-
- @Id
- @GeneratedValue(strategy = GenerationType.IDENTITY)
- @Column(name = "id")
- private Long id;
- @Column(name = "identifier")
- private String identifier;
- @Column(name = "payload")
- private String payload;
-
- public SampleJpaEntity() {
- super();
- }
-
- public Long getId() {
- return id;
- }
-
- public void setId(Long id) {
- this.id = id;
- }
-
- public String getIdentifier() {
- return this.identifier;
- }
-
- public void setIdentifier(final String identifier) {
- this.identifier = identifier;
- }
-
- public String getPayload() {
- return payload;
- }
-
- public void setPayload(String payload) {
- this.payload = payload;
- }
-}
diff --git a/service/src/main/java/io/mifos/template/service/internal/service/SampleService.java b/service/src/main/java/io/mifos/template/service/internal/service/SampleService.java
deleted file mode 100644
index caba840..0000000
--- a/service/src/main/java/io/mifos/template/service/internal/service/SampleService.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2017 The Mifos Initiative.
- *
- * Licensed 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 io.mifos.template.service.internal.service;
-
-import io.mifos.template.api.v1.domain.Sample;
-import io.mifos.template.service.internal.mapper.SampleMapper;
-import io.mifos.template.service.internal.repository.SampleJpaEntityRepository;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import java.util.List;
-import java.util.Optional;
-
-@Service
-public class SampleService {
-
- private final SampleJpaEntityRepository sampleJpaEntityRepository;
-
- @Autowired
- public SampleService(final SampleJpaEntityRepository sampleJpaEntityRepository) {
- super();
- this.sampleJpaEntityRepository = sampleJpaEntityRepository;
- }
-
- public List<Sample> findAllEntities() {
- return SampleMapper.map(this.sampleJpaEntityRepository.findAll());
- }
-
- public Optional<Sample> findByIdentifier(final String identifier) {
- return this.sampleJpaEntityRepository.findByIdentifier(identifier).map(SampleMapper::map);
- }
-}
diff --git a/service/src/main/java/io/mifos/template/service/rest/SampleRestController.java b/service/src/main/java/io/mifos/template/service/rest/SampleRestController.java
deleted file mode 100644
index 9919252..0000000
--- a/service/src/main/java/io/mifos/template/service/rest/SampleRestController.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2017 The Mifos Initiative.
- *
- * Licensed 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 io.mifos.template.service.rest;
-
-import io.mifos.anubis.annotation.AcceptedTokenType;
-import io.mifos.anubis.annotation.Permittable;
-import io.mifos.core.command.gateway.CommandGateway;
-import io.mifos.core.lang.ServiceException;
-import io.mifos.template.api.v1.PermittableGroupIds;
-import io.mifos.template.api.v1.domain.Sample;
-import io.mifos.template.service.ServiceConstants;
-import io.mifos.template.service.internal.command.InitializeServiceCommand;
-import io.mifos.template.service.internal.command.SampleCommand;
-import io.mifos.template.service.internal.service.SampleService;
-import org.slf4j.Logger;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.*;
-
-import javax.validation.Valid;
-import java.util.List;
-
-@SuppressWarnings("unused")
-@RestController
-@RequestMapping("/")
-public class SampleRestController {
-
- private final Logger logger;
- private final CommandGateway commandGateway;
- private final SampleService sampleService;
-
- @Autowired
- public SampleRestController(@Qualifier(ServiceConstants.LOGGER_NAME) final Logger logger,
- final CommandGateway commandGateway,
- final SampleService sampleService) {
- super();
- this.logger = logger;
- this.commandGateway = commandGateway;
- this.sampleService = sampleService;
- }
-
- @Permittable(value = AcceptedTokenType.SYSTEM)
- @RequestMapping(
- value = "/initialize",
- method = RequestMethod.POST,
- consumes = MediaType.ALL_VALUE,
- produces = MediaType.APPLICATION_JSON_VALUE
- )
- public
- @ResponseBody
- ResponseEntity<Void> initialize() throws InterruptedException {
- this.commandGateway.process(new InitializeServiceCommand());
- return ResponseEntity.accepted().build();
- }
-
- @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SAMPLE_MANAGEMENT)
- @RequestMapping(
- value = "/sample",
- method = RequestMethod.GET,
- consumes = MediaType.ALL_VALUE,
- produces = MediaType.APPLICATION_JSON_VALUE
- )
- public
- @ResponseBody
- List<Sample> findAllEntities() {
- return this.sampleService.findAllEntities();
- }
-
- @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SAMPLE_MANAGEMENT)
- @RequestMapping(
- value = "/sample/{identifier}",
- method = RequestMethod.GET,
- consumes = MediaType.ALL_VALUE,
- produces = MediaType.APPLICATION_JSON_VALUE
- )
- public
- @ResponseBody
- ResponseEntity<Sample> getEntity(@PathVariable("identifier") final String identifier) {
- return this.sampleService.findByIdentifier(identifier)
- .map(ResponseEntity::ok)
- .orElseThrow(() -> ServiceException.notFound("Instance with identifier " + identifier + " doesn't exist."));
- }
-
- @Permittable(value = AcceptedTokenType.TENANT, groupId = PermittableGroupIds.SAMPLE_MANAGEMENT)
- @RequestMapping(
- value = "/sample",
- method = RequestMethod.POST,
- consumes = MediaType.APPLICATION_JSON_VALUE,
- produces = MediaType.APPLICATION_JSON_VALUE
- )
- public
- @ResponseBody
- ResponseEntity<Void> createEntity(@RequestBody @Valid final Sample instance) throws InterruptedException {
- this.commandGateway.process(new SampleCommand(instance));
- return ResponseEntity.accepted().build();
- }
-}
diff --git a/service/src/main/resources/application.yml b/service/src/main/resources/application.yml
index 8b395ca..124f606 100644
--- a/service/src/main/resources/application.yml
+++ b/service/src/main/resources/application.yml
@@ -28,7 +28,7 @@ eureka:
server:
port: 8081
- contextPath: /template/v1/*
+ contextPath: /payroll/v1/*
cassandra:
clusterName: staging_cluster
diff --git a/service/src/main/resources/bootstrap.yml b/service/src/main/resources/bootstrap.yml
index 6b9e3e8..dac5589 100644
--- a/service/src/main/resources/bootstrap.yml
+++ b/service/src/main/resources/bootstrap.yml
@@ -16,4 +16,4 @@
spring:
application:
- name: template-v1
+ name: payroll-v1
diff --git a/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql b/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
index fb1b54e..578e373 100644
--- a/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
+++ b/service/src/main/resources/db/migrations/mariadb/V1__initial_setup.sql
@@ -14,9 +14,45 @@
-- limitations under the License.
--
-CREATE TABLE template_samples (
- id BIGINT NOT NULL AUTO_INCREMENT,
- identifier VARCHAR(8) NOT NULL,
- payload VARCHAR(512) NULL,
- CONSTRAINT template_samples_pk PRIMARY KEY (id)
+CREATE TABLE meketre_payroll_configurations (
+ id BIGINT NOT NULL AUTO_INCREMENT,
+ customer_identifier VARCHAR(32) NOT NULL,
+ main_account_number VARCHAR(34) NOT NULL,
+ created_by VARCHAR(32) NOT NULL,
+ created_on TIMESTAMP(3) NOT NULL,
+ last_modified_by VARCHAR(32) NULL,
+ last_modified_on TIMESTAMP(3) NULL,
+ CONSTRAINT meketre_payroll_config_pk PRIMARY KEY (id),
+ CONSTRAINT meketre_payroll_config_acct_uq UNIQUE (customer_identifier, main_account_number)
+);
+
+CREATE TABLE meketre_payroll_allocations (
+ id BIGINT NOT NULL AUTO_INCREMENT,
+ payroll_configuration_id BIGINT NOT NULL,
+ account_number VARCHAR(34) NOT NULL,
+ amount NUMERIC(15,5) NOT NULL,
+ proportional BOOLEAN NOT NULL,
+ CONSTRAINT meketre_payroll_allocations_pk PRIMARY KEY (id),
+ CONSTRAINT meketre_payroll_alloc_acct_uq UNIQUE (payroll_configuration_id, account_number),
+ CONSTRAINT meketre_payroll_alloc_config_fk FOREIGN KEY (payroll_configuration_id) REFERENCES meketre_payroll_configurations (id)
+);
+
+CREATE TABLE meketre_payroll_collections (
+ id BIGINT NOT NULL AUTO_INCREMENT,
+ identifier VARCHAR(32) NOT NULL,
+ source_account_number VARCHAR(34) NOT NULL,
+ created_by VARCHAR(32) NOT NULL,
+ created_on TIMESTAMP(3) NOT NULL,
+ CONSTRAINT meketre_payroll_collections_pk PRIMARY KEY (id),
+ CONSTRAINT meketre_pay_col_identifier_uq UNIQUE (identifier)
+);
+
+CREATE TABLE meketre_payroll_payments (
+ id BIGINT NOT NULL AUTO_INCREMENT,
+ payroll_collection_id BIGINT NOT NULL,
+ customer_identifier VARCHAR(32) NOT NULL,
+ employer VARCHAR(256) NOT NULL,
+ salary NUMERIC(15,5) NOT NULL,
+ CONSTRAINT meketre_payroll_payments_pk PRIMARY KEY (id),
+ CONSTRAINT meketre_payroll_pay_coll_fk FOREIGN KEY (payroll_collection_id) REFERENCES meketre_payroll_collections (id)
);
diff --git a/service/src/main/resources/logback.xml b/service/src/main/resources/logback.xml
new file mode 100644
index 0000000..e594df5
--- /dev/null
+++ b/service/src/main/resources/logback.xml
@@ -0,0 +1,55 @@
+<!--
+
+ Copyright 2017 The Mifos Initiative.
+
+ Licensed 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.
+
+-->
+<configuration>
+ <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>logs/payroll.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+ <fileNamePattern>logs/archive/payroll.%d{yyyy-MM-dd}.log</fileNamePattern>
+ <maxHistory>7</maxHistory>
+ <totalSizeCap>2GB</totalSizeCap>
+ </rollingPolicy>
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder>
+ <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+ </encoder>
+ </appender>
+
+ <logger name="com" level="INFO">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+ <logger name="org" level="INFO">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+ <logger name="io" level="INFO">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+ <logger name="net" level="INFO">
+ <appender-ref ref="STDOUT" />
+ </logger>
+
+ <root level="DEBUG">
+ <appender-ref ref="FILE"/>
+ </root>
+</configuration>
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 1630ef8..f97fef4 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,4 +1,4 @@
-rootProject.name = 'template'
+rootProject.name = 'payroll'
includeBuild 'api'
includeBuild 'service'
diff --git a/shared.gradle b/shared.gradle
index 1bfef46..831fede 100644
--- a/shared.gradle
+++ b/shared.gradle
@@ -1,4 +1,4 @@
-group 'io.mifos.template'
+group 'io.mifos.payroll'
version '0.1.0.BUILD-SNAPSHOT'
ext.versions = [
@@ -10,6 +10,8 @@ ext.versions = [
frameworkcommand : '0.1.0-BUILD-SNAPSHOT',
frameworktest: '0.1.0-BUILD-SNAPSHOT',
frameworkanubis: '0.1.0-BUILD-SNAPSHOT',
+ frameworkcustomer: '0.1.0-BUILD-SNAPSHOT',
+ frameworkaccounting: '0.1.0-BUILD-SNAPSHOT',
validator : '5.3.0.Final'
]